Compare commits

...

24 Commits

Author SHA1 Message Date
1fb90ab98c M3threshold (#475)
* vicin default changed to 800, only setting vthx directly allows to set dac even if counter disabled, else disable counter, setallthresholdenergy if an energy is -1, get module value, fix that reg was repaced by isettings

* vth3 disabled for interpolation enable, interpolation disable sets counter mask to what it was before (updating old mask whn setting counter mask except for setting all counters for interpolation enable) and enabling vth3 if counter was enabled

* refactor and test for previous commit

* pump probe only has vth2 enabled, handles both pump probe mode and interpolation mode as well

* wip

* refactored pump probe and interpolation and added to setmodule

* check dacs and trimbits out of range for setmodule (not just threshold)

* binaries in

* m3: pump probe and interpolation mutually exclusive

* minor
2022-06-07 16:55:33 +02:00
25b5b02302 m3 and g2: change in system clock (clkdiv2) should also change the time settings(exptime, period, gate delay etc.), g2: sys freq same irrespective of external or internal timing source (#470) 2022-06-02 11:02:10 +02:00
365ac835eb Get trimbits (#462)
* added the possibility to save settings file for m3 and eiger

* added save trimbits to gui

* update release notes

* python wip

* moved location of trimbits save option in gui

* python works

* updating getModule with all its parameters in the server side

* updating binaries
2022-05-24 11:08:08 +02:00
d61741c28b tests add to namespace sls (#466)
* tests add to namespace sls

* fixed for tests

* finish up namespace sls for tests
2022-05-23 16:17:32 +02:00
8656eeec25 Revert "tests add to namespace sls (#464)" (#465)
This reverts commit f5745fcf18.
2022-05-20 15:43:48 +02:00
f5745fcf18 tests add to namespace sls (#464) 2022-05-20 15:41:37 +02:00
c7ba79644a minor 2022-05-20 12:01:42 +02:00
70aed474dc fedora cant compile as make_unique in Implementation points to std and not sls namespace, but it compiles for DetectorImpl (#463) 2022-05-20 12:00:24 +02:00
f3edd4dc56 Not allowing / or spaces in file name prefix (#461) 2022-05-18 12:37:44 +02:00
a4bd2f1be7 updated release 2022-05-18 12:19:32 +02:00
73a45e1b5c nCe made high before programming blackfin to ensure seamless programming (#460) 2022-05-18 12:17:44 +02:00
4259363169 rxr sls namespace (#457)
* rxr src files and classes (detectordata, ZmqSocket) added to sls namespace

* moving defines inside namespace

* moving defines inside namespace, added helpdacs to namespace

* added namespace to gui

* gui also updated

* removed unnecessary sls:: when already in sls namespace for slsDetectoSoftware, receverSoftware, slsDetectorGui and slsSupportlib
2022-05-18 11:48:38 +02:00
fcc7f7aef8 Rx roi (#428)
* roi structure expanded to have ymin and ymax

* compile with 'detector roi'

* wip

* wip, rx_roi, rx_clearroi

* wip rxroi

* rxroi wip

* wip rxroi

* merge fix

* wip

* rx_roi works, impl wip, test

* tests in, impl left

* wip, rxroi impl

* wip, rxroi impl

* wip

* setrx_Roi works, getrx_roi, wip

* rx_roi impl done

* wip, rxroi

* wip, getrx_roi rxr ports

* fix ports

* wip

* wip

* fix positions on server side

* wip

* numports wip

* wip

* jungfrau top inner interface row increment

* x, y detpos, wip

* removed eiger row indices flipping in gui (bottom flipping maintained)

* wip

* wip, jungfrau numinterfaces2

* jungfrau virtual works

* eiger, jungfrau, g2 virtual server works

* eiger positions fix, wip

* binaries in

* minor printout

* binaries in

* merge fix

* merge fix

* removing getposition

* setrxroi wip

* set upto port

* get messed, wip

* roi multi to module works, wip

* wip

* roi dont return -1

* added rxroi metadata in master file

* added rxroifromshm, not yet in detector

* rx roi in gui with box, also for gap pixels (gappixels for jungfrau mess)

* fix for segfault in gui with detaching roi box in gui

* wip

* m3 gui: slave timing modes should be discarded when squashing

* fixed m3 virtual data, and fixed counters in gui asthetics

* m3 roi works

* wip, g2

* wip

* handling g225um boards, and showing roi for gainplot as well

* udpate python functions

* fix for 1d and a2d roi written

* fixed actual roi written to file

* no virtual hdf5 when handling rx roi

* test

* minor

* binarie in
2022-05-16 12:35:06 +02:00
9808376207 release notes 2022-05-16 12:33:07 +02:00
be617577c9 always enable gap pixels if they exist for detector in gui (#450) 2022-05-16 12:31:46 +02:00
e30ee445a1 m3 gui: slave timing modes should be discarded when squashing (#449) 2022-05-16 12:29:17 +02:00
8d6b8d66cc size of shm needs to be only sometimes checked when opening shared memory (#443) 2022-05-16 12:27:48 +02:00
88649a00b6 M3vtrim min (#454)
* Remove the vtrim min 600 check when setting threshold energy. vth1-3:200 - 2400, others 0-2800

* compile fix
2022-05-12 11:41:05 +02:00
b122c2fbdf Revert "Remove the vtrim min 600 check when setting threshold energy. vth1-3:200 - 2400, others 0-2800 (#452)" (#453)
This reverts commit 7d574375b4.
2022-05-12 11:38:34 +02:00
7d574375b4 Remove the vtrim min 600 check when setting threshold energy. vth1-3:200 - 2400, others 0-2800 (#452) 2022-05-12 11:06:14 +02:00
466d431081 update release notes 2022-05-10 15:35:44 +02:00
cd4520b051 not validating settings for dacs temporarily (#447) 2022-05-10 15:30:34 +02:00
0129c2c686 M3: master starts twice (non blocking) part 2 (#445)
* slaves and master vectors empty means all positions included: fixing double acquisition in masters

* debug print out
2022-05-10 15:23:39 +02:00
f55bdd6eae M3: master starts twice (non blocking) (#444)
* start acq for master m3 was sent twice (non blocking), removed redundant code, check that there is only one master

* m3 can have more than 1 master (when many master modules used independently)

* fix for singe mod m3 or other dets
2022-05-10 14:27:40 +02:00
160 changed files with 4286 additions and 2540 deletions

View File

@ -59,16 +59,26 @@ This document describes the differences between v7.0.0 and v6.x.x
- gotthard 25 um image reconstructed in gui and virtual hdf5 (firmware updated for slave to reverse channels) - gotthard 25 um image reconstructed in gui and virtual hdf5 (firmware updated for slave to reverse channels)
- master binary file in json format now - master binary file in json format now
- fixed bug introduced in 6.0.0: hdf5 files created 1 file per frame after the initial file which had maxframesperfile - fixed bug introduced in 6.0.0: hdf5 files created 1 file per frame after the initial file which had maxframesperfile
- rx_roi
- m3 polarity, interpolation (enables all counters when enabled), pump probe, analog pulsing, digital pulsing - m3 polarity, interpolation (enables all counters when enabled), pump probe, analog pulsing, digital pulsing
- updatedetectorserver - removes old server current binary pointing to for blackfin - updatedetectorserver - removes old server current binary pointing to for blackfin
- removing copydetectorserver using tftp - removing copydetectorserver using tftp
>>>>>>> developer
- registerCallBackRawDataReady and registerCallBackRawDataModifyReady now gives a sls_receiver_header* instead of a char*, and uint32_t to size_t - registerCallBackRawDataReady and registerCallBackRawDataModifyReady now gives a sls_receiver_header* instead of a char*, and uint32_t to size_t
- registerCallBackStartAcquisition gave incorrect imagesize (+120 bytes). corrected. - registerCallBackStartAcquisition gave incorrect imagesize (+120 bytes). corrected.
- registerCallBackStartAcquisition parameter is a const string reference - registerCallBackStartAcquisition parameter is a const string reference
- m3 (runnig config second time with tengiga 0, dr !=32, counters !=0x7) calculated incorrect image size expected - m3 (runnig config second time with tengiga 0, dr !=32, counters !=0x7) calculated incorrect image size expected
- fixed row column indexing (mainly for multi module Jungfrau 2 interfaces ) - fixed row column indexing (mainly for multi module Jungfrau 2 interfaces )
- eiger gui row indices not flipped anymore (fix in config) - eiger gui row indices not flipped anymore (fix in config)
- m3 (settings dac check disabled temporarily?)
- m3 virtual server sends the right pacets now
- gap pixels in gui enabled by default
- rxr src files and classes (detectordata, ZmqSocket, helpDacs) added to sls namespace, and macros (namely from logger (logINFO etc)), slsDetectorGui (make_unique in implemtnation requires sls nemspace (points to std otherwise) but not deectorImpl.cpp)
- blackfin programing made seamless (nCE fixed which helps)
-save settings file for m3 and eiger
- m3 threshold changes
- g2 and m3 clkdiv 2 (system clock) change should affect time settings (g2: exptime, period, delayaftertrigger, burstperiod, m3: exptime, gatedelay, gateperiod, period, delayaftertrigger)
- g2 system frequency is the same irrespective of timing source
- (apparently) rxr doesnt get stuck anymore from 6.1.1
2. Resolved Issues 2. Resolved Issues
================== ==================

View File

@ -6,6 +6,8 @@
#include "tests/globals.h" #include "tests/globals.h"
#include <iostream> #include <iostream>
namespace sls {
class MultiDetectorFixture { class MultiDetectorFixture {
protected: protected:
DetectorImpl d; DetectorImpl d;
@ -136,7 +138,7 @@ TEST_CASE_METHOD(MultiDetectorFixture, "Get ID", "[.eigerintegration][cli]") {
std::string hn = test::hostname; std::string hn = test::hostname;
hn.erase(std::remove(begin(hn), end(hn), 'b'), end(hn)); hn.erase(std::remove(begin(hn), end(hn), 'b'), end(hn));
hn.erase(std::remove(begin(hn), end(hn), 'e'), end(hn)); hn.erase(std::remove(begin(hn), end(hn), 'e'), end(hn));
auto hostnames = sls::split(hn, '+'); auto hostnames = split(hn, '+');
CHECK(hostnames.size() == d.getNumberOfDetectors()); CHECK(hostnames.size() == d.getNumberOfDetectors());
for (int i = 0; i != d.getNumberOfDetectors(); ++i) { for (int i = 0; i != d.getNumberOfDetectors(); ++i) {
CHECK(d.getId(defs::DETECTOR_SERIAL_NUMBER, 0) == CHECK(d.getId(defs::DETECTOR_SERIAL_NUMBER, 0) ==
@ -198,3 +200,5 @@ TEST_CASE_METHOD(MultiDetectorFixture, "rate correction",
d.setRateCorrection(200); d.setRateCorrection(200);
CHECK(d.getRateCorrection() == 200); CHECK(d.getRateCorrection() == 200);
} }
} // namespace sls

View File

@ -24,6 +24,8 @@
// extern std::string detector_type; // extern std::string detector_type;
// extern dt type; // extern dt type;
namespace sls {
TEST_CASE("Single detector no receiver", "[.integration][.single]") { TEST_CASE("Single detector no receiver", "[.integration][.single]") {
auto t = Module::getTypeFromDetector(test::hostname); auto t = Module::getTypeFromDetector(test::hostname);
CHECK(t == test::type); CHECK(t == test::type);
@ -283,14 +285,14 @@ TEST_CASE(
CHECK(m.getRateCorrection() == ratecorr); CHECK(m.getRateCorrection() == ratecorr);
// ratecorr fail with dr 4 or 8 // ratecorr fail with dr 4 or 8
CHECK_THROWS_AS(m.setDynamicRange(8), sls::RuntimeError); CHECK_THROWS_AS(m.setDynamicRange(8), RuntimeError);
CHECK(m.getRateCorrection() == 0); CHECK(m.getRateCorrection() == 0);
m.setDynamicRange(16); m.setDynamicRange(16);
m.setDynamicRange(16); m.setDynamicRange(16);
m.setRateCorrection(ratecorr); m.setRateCorrection(ratecorr);
m.setDynamicRange(16); m.setDynamicRange(16);
m.setRateCorrection(ratecorr); m.setRateCorrection(ratecorr);
CHECK_THROWS_AS(m.setDynamicRange(4), sls::RuntimeError); CHECK_THROWS_AS(m.setDynamicRange(4), RuntimeError);
CHECK(m.getRateCorrection() == 0); CHECK(m.getRateCorrection() == 0);
} }
@ -329,11 +331,11 @@ TEST_CASE("Chiptestboard Loading Patterns", "[.ctbintegration]") {
m.setPatternWord(addr, word); m.setPatternWord(addr, word);
CHECK(m.setPatternWord(addr, -1) == word); CHECK(m.setPatternWord(addr, -1) == word);
addr = MAX_ADDR; addr = MAX_ADDR;
CHECK_THROWS_AS(m.setPatternWord(addr, word), sls::RuntimeError); CHECK_THROWS_AS(m.setPatternWord(addr, word), RuntimeError);
CHECK_THROWS_WITH(m.setPatternWord(addr, word), CHECK_THROWS_WITH(m.setPatternWord(addr, word),
Catch::Matchers::Contains("be between 0 and")); Catch::Matchers::Contains("be between 0 and"));
addr = -1; addr = -1;
CHECK_THROWS_AS(m.setPatternWord(addr, word), sls::RuntimeError); CHECK_THROWS_AS(m.setPatternWord(addr, word), RuntimeError);
CHECK_THROWS_WITH(m.setPatternWord(addr, word), CHECK_THROWS_WITH(m.setPatternWord(addr, word),
Catch::Matchers::Contains("be between 0 and")); Catch::Matchers::Contains("be between 0 and"));
@ -408,7 +410,7 @@ TEST_CASE("Chiptestboard Dbit offset, list, sampling, advinvert",
CHECK(m.getReceiverDbitList().size() == 10); CHECK(m.getReceiverDbitList().size() == 10);
list.push_back(64); list.push_back(64);
CHECK_THROWS_AS(m.setReceiverDbitList(list), sls::RuntimeError); CHECK_THROWS_AS(m.setReceiverDbitList(list), RuntimeError);
CHECK_THROWS_WITH(m.setReceiverDbitList(list), CHECK_THROWS_WITH(m.setReceiverDbitList(list),
Catch::Matchers::Contains("be between 0 and 63")); Catch::Matchers::Contains("be between 0 and 63"));
@ -476,7 +478,7 @@ TEST_CASE("Eiger or Jungfrau nextframenumber",
CHECK(m.acquire() == slsDetectorDefs::OK); CHECK(m.acquire() == slsDetectorDefs::OK);
CHECK(m.getReceiverCurrentFrameIndex() == val); CHECK(m.getReceiverCurrentFrameIndex() == val);
CHECK_THROWS_AS(m.setNextFrameNumber(0), sls::RuntimeError); CHECK_THROWS_AS(m.setNextFrameNumber(0), RuntimeError);
if (m.getDetectorTypeAsString() == "Eiger") { if (m.getDetectorTypeAsString() == "Eiger") {
val = 281474976710655; val = 281474976710655;
@ -511,8 +513,10 @@ TEST_CASE("Eiger partialread", "[.eigerintegration][partialread]") {
m.setDynamicRange(8); m.setDynamicRange(8);
m.setPartialReadout(256); m.setPartialReadout(256);
CHECK(m.getPartialReadout() == 256); CHECK(m.getPartialReadout() == 256);
CHECK_THROWS_AS(m.setPartialReadout(1), sls::RuntimeError); CHECK_THROWS_AS(m.setPartialReadout(1), RuntimeError);
CHECK(m.getPartialReadout() == 256); CHECK(m.getPartialReadout() == 256);
CHECK_THROWS_AS(m.setPartialReadout(0), sls::RuntimeError); CHECK_THROWS_AS(m.setPartialReadout(0), RuntimeError);
m.setPartialReadout(256); m.setPartialReadout(256);
} }
} // namespace sls

View File

@ -6,10 +6,12 @@
#include "tests/globals.h" #include "tests/globals.h"
#include <iostream> #include <iostream>
namespace sls {
using namespace Catch::literals; using namespace Catch::literals;
TEST_CASE("Initialize a multi detector", "[.integration][.multi]") { TEST_CASE("Initialize a multi detector", "[.integration][.multi]") {
auto hostnames = sls::split(test::hostname, '+'); auto hostnames = split(test::hostname, '+');
DetectorImpl d(0, true, true); DetectorImpl d(0, true, true);
d.setHostname(test::hostname.c_str()); d.setHostname(test::hostname.c_str());
@ -102,3 +104,6 @@ TEST_CASE("Set and read timers", "[.integration][.multi]") {
d.freeSharedMemory(); d.freeSharedMemory();
} }
} // namespace sls

View File

@ -1442,20 +1442,21 @@ class Detector(CppDetectorApi):
@property @property
def trimbits(self): def trimbits(self):
""" """
[Eiger][Mythen3] Loads custom trimbit file to detector. [Eiger][Mythen3] Loads/Saves custom trimbit file to detector.
Note Note
----- -----
If no extension specified, serial number of each module is attached. If no extension specified, serial number of each module is attached.
:getter: Not implemented :setter: Loads the trimbit file to detector
:getter: Saves the trimbits from the detector to file. Not implemented with 'trimbits'. Use saveTrimbits().
Example Example
------- -------
>>> d.trimbits = '/path_to_file/noise' >>> d.trimbits = '/path_to_file/noise'
- 14:53:27.931 INFO: Settings file loaded: /path_to_file/noise.sn000 - 14:53:27.931 INFO: Settings file loaded: /path_to_file/noise.sn000
""" """
return NotImplementedError("trimbits are set only") raise NotImplementedError('trimbits is set only. Use saveTrimbits()')
@trimbits.setter @trimbits.setter
def trimbits(self, fname): def trimbits(self, fname):
@ -1833,13 +1834,13 @@ class Detector(CppDetectorApi):
@property @property
@element @element
def threshold(self): def threshold(self):
"""[Eiger] Threshold in eV """[Eiger][Mythen3] Threshold in eV
Note Note
---- ----
To change settings as well or set threshold without trimbits, use setThresholdEnergy. To change settings as well or set threshold without trimbits, use setThresholdEnergy.
:setter: It loads trim files from settingspath. :setter: It loads trim files from settingspath.\n [Mythen3] An energy of -1 will pick up values from detector.
""" """
if self.type == detectorType.MYTHEN3: if self.type == detectorType.MYTHEN3:
return self.getAllThresholdEnergy() return self.getAllThresholdEnergy()
@ -2617,7 +2618,7 @@ class Detector(CppDetectorApi):
------- -------
>>> d.vetophoton = (2, 24, 2560, '/tmp/bla.txt') >>> d.vetophoton = (2, 24, 2560, '/tmp/bla.txt')
""" """
raise NotImplementedError('vetofile is set only') raise NotImplementedError('vetophoton is set only')
@vetophoton.setter @vetophoton.setter
def vetophoton(self, args): def vetophoton(self, args):
@ -3515,7 +3516,7 @@ class Detector(CppDetectorApi):
@property @property
@element @element
def interpolation(self): def interpolation(self):
"""[Mythen3] Enable or disable interpolation. Enabling also enables all counters """ """[Mythen3] Enable or disable interpolation. interpolation mode enables all counters and disables vth3. Disabling sets back counter mask and vth3. """
return self.getInterpolation() return self.getInterpolation()
@interpolation.setter @interpolation.setter
@ -3525,7 +3526,7 @@ class Detector(CppDetectorApi):
@property @property
@element @element
def pumpprobe(self): def pumpprobe(self):
"""[Mythen3] Enable or disable pump probe mode. """ """[Mythen3] Enable or disable pump probe mode. Pump probe mode only enables vth2. Disabling sets back to previous value """
return self.getPumpProbe() return self.getPumpProbe()
@pumpprobe.setter @pumpprobe.setter

View File

@ -144,6 +144,10 @@ void init_det(py::module &m) {
(void (Detector::*)(const std::string &, sls::Positions)) & (void (Detector::*)(const std::string &, sls::Positions)) &
Detector::loadTrimbits, Detector::loadTrimbits,
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("saveTrimbits",
(void (Detector::*)(const std::string &, sls::Positions)) &
Detector::saveTrimbits,
py::arg(), py::arg() = Positions{})
.def("getAllTrimbits", .def("getAllTrimbits",
(Result<int>(Detector::*)(sls::Positions) const) & (Result<int>(Detector::*)(sls::Positions) const) &
Detector::getAllTrimbits, Detector::getAllTrimbits,
@ -187,12 +191,12 @@ void init_det(py::module &m) {
(void (Detector::*)(void (*)(double, int, void *), void *)) & (void (Detector::*)(void (*)(double, int, void *), void *)) &
Detector::registerAcquisitionFinishedCallback, Detector::registerAcquisitionFinishedCallback,
py::arg(), py::arg()) py::arg(), py::arg())
.def( .def("registerDataCallback",
"registerDataCallback", (void (Detector::*)(
(void (Detector::*)( void (*)(sls::detectorData *, uint64_t, uint32_t, void *),
void (*)(detectorData *, uint64_t, uint32_t, void *), void *)) & void *)) &
Detector::registerDataCallback, Detector::registerDataCallback,
py::arg(), py::arg()) py::arg(), py::arg())
.def("getNumberOfFrames", .def("getNumberOfFrames",
(Result<int64_t>(Detector::*)(sls::Positions) const) & (Result<int64_t>(Detector::*)(sls::Positions) const) &
Detector::getNumberOfFrames, Detector::getNumberOfFrames,
@ -786,6 +790,15 @@ void init_det(py::module &m) {
.def("setRxArping", .def("setRxArping",
(void (Detector::*)(bool, sls::Positions)) & Detector::setRxArping, (void (Detector::*)(bool, sls::Positions)) & Detector::setRxArping,
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("getIndividualRxROIs",
(Result<defs::ROI>(Detector::*)(sls::Positions) const) &
Detector::getIndividualRxROIs,
py::arg())
.def("getRxROI", (defs::ROI(Detector::*)() const) & Detector::getRxROI)
.def("setRxROI",
(void (Detector::*)(const defs::ROI)) & Detector::setRxROI,
py::arg())
.def("clearRxROI", (void (Detector::*)()) & Detector::clearRxROI)
.def("getFileFormat", .def("getFileFormat",
(Result<defs::fileFormat>(Detector::*)(sls::Positions) const) & (Result<defs::fileFormat>(Detector::*)(sls::Positions) const) &
Detector::getFileFormat, Detector::getFileFormat,
@ -1602,11 +1615,6 @@ void init_det(py::module &m) {
.def("rebootController", .def("rebootController",
(void (Detector::*)(sls::Positions)) & Detector::rebootController, (void (Detector::*)(sls::Positions)) & Detector::rebootController,
py::arg() = Positions{}) py::arg() = Positions{})
.def("updateFirmwareAndServer",
(void (Detector::*)(const std::string &, const std::string &,
const std::string &, sls::Positions)) &
Detector::updateFirmwareAndServer,
py::arg(), py::arg(), py::arg(), py::arg() = Positions{})
.def("updateFirmwareAndServer", .def("updateFirmwareAndServer",
(void (Detector::*)(const std::string &, const std::string &, (void (Detector::*)(const std::string &, const std::string &,
sls::Positions)) & sls::Positions)) &

View File

@ -235,6 +235,7 @@
</property> </property>
<addaction name="actionLoadConfiguration"/> <addaction name="actionLoadConfiguration"/>
<addaction name="actionLoadTrimbits"/> <addaction name="actionLoadTrimbits"/>
<addaction name="actionSaveTrimbits"/>
<addaction name="actionLoadParameters"/> <addaction name="actionLoadParameters"/>
</widget> </widget>
<widget class="QMenu" name="menuModes"> <widget class="QMenu" name="menuModes">
@ -419,6 +420,11 @@ p, li { white-space: pre-wrap; }
<string>&amp;About</string> <string>&amp;About</string>
</property> </property>
</action> </action>
<action name="actionSaveTrimbits">
<property name="text">
<string>Save Trimbits</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="../include/icons.qrc"/> <include location="../include/icons.qrc"/>

View File

@ -20,7 +20,105 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="2" column="0" colspan="4"> <item row="1" column="5">
<widget class="QLabel" name="lblRxRoiEnabled">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>139</red>
<green>142</green>
<blue>142</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>Rx Roi Enabled</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="7">
<widget class="QGroupBox" name="boxPlot">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="title">
<string>Sample Plot</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="plotLayout">
<property name="margin">
<number>9</number>
</property>
<property name="spacing">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="7">
<widget class="QWidget" name="widgetStatistics" native="true"> <widget class="QWidget" name="widgetStatistics" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -212,104 +310,6 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="0" column="0" colspan="4">
<widget class="QGroupBox" name="boxPlot">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="title">
<string>Sample Plot</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="plotLayout">
<property name="margin">
<number>9</number>
</property>
<property name="spacing">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="lblInCompleteImage">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>139</red>
<green>142</green>
<blue>142</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>Missing Packets</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="QLabel" name="lblCompleteImage"> <widget class="QLabel" name="lblCompleteImage">
<property name="sizePolicy"> <property name="sizePolicy">
@ -320,7 +320,7 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>40</width> <width>120</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -375,6 +375,71 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="2">
<widget class="QLabel" name="lblInCompleteImage">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>139</red>
<green>142</green>
<blue>142</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>Missing Packets</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>775</width> <width>775</width>
<height>380</height> <height>385</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -32,22 +32,25 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item row="4" column="3"> <item row="2" column="0">
<widget class="QCheckBox" name="chkCounter2"> <widget class="QLabel" name="lblThreshold">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>50</width> <width>110</width>
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string>2</string> <string>Threshold:</string>
</property>
<property name="checked">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
@ -70,237 +73,22 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2" colspan="3"> <item row="2" column="14">
<widget class="QComboBox" name="comboDynamicRange"> <spacer name="horizontalSpacer_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<item>
<property name="text">
<string>1.67772e+07</string>
</property>
</item>
<item>
<property name="text">
<string>65535</string>
</property>
</item>
<item>
<property name="text">
<string>4095</string>
</property>
</item>
<item>
<property name="text">
<string>255</string>
</property>
</item>
<item>
<property name="text">
<string>7</string>
</property>
</item>
</widget>
</item>
<item row="2" column="2" colspan="3">
<widget class="QSpinBox" name="spinThreshold">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="suffix">
<string> eV</string>
</property>
<property name="minimum">
<number>-100000</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QSpinBox" name="spinThreshold3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="suffix">
<string> eV</string>
</property>
<property name="minimum">
<number>-100000</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblDynamicRange">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Dynamic Range:</string>
</property>
</widget>
</item>
<item row="5" column="2">
<spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::Fixed</enum> <enum>QSizePolicy::Expanding</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>190</height> <height>20</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="2" column="8">
<widget class="QPushButton" name="btnSetThreshold">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>20</red>
<green>20</green>
<blue>20</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>20</red>
<green>20</green>
<blue>20</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>20</red>
<green>20</green>
<blue>20</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>Set</string>
</property>
<property name="icon">
<iconset resource="../include/icons.qrc">
<normaloff>:/icons/images/rightArrow.png</normaloff>:/icons/images/rightArrow.png</iconset>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="lblSettings"> <widget class="QLabel" name="lblSettings">
<property name="enabled"> <property name="enabled">
@ -323,119 +111,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblThreshold">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Threshold:</string>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QSpinBox" name="spinThreshold2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="suffix">
<string> eV</string>
</property>
<property name="minimum">
<number>-100000</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item row="2" column="9">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0">
<widget class="QLabel" name="lblCounter">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Counters:</string>
</property>
</widget>
</item>
<item row="4" column="2"> <item row="4" column="2">
<widget class="QCheckBox" name="chkCounter1"> <widget class="QCheckBox" name="chkCounter1">
<property name="enabled"> <property name="enabled">
@ -455,7 +130,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2" colspan="3"> <item row="0" column="2" colspan="9">
<widget class="QComboBox" name="comboSettings"> <widget class="QComboBox" name="comboSettings">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
@ -594,6 +269,268 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="2" column="11">
<widget class="QSpinBox" name="spinThreshold2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="suffix">
<string> eV</string>
</property>
<property name="minimum">
<number>-100000</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item row="2" column="13">
<widget class="QPushButton" name="btnSetThreshold">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>20</red>
<green>20</green>
<blue>20</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>20</red>
<green>20</green>
<blue>20</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>20</red>
<green>20</green>
<blue>20</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="text">
<string>Set</string>
</property>
<property name="icon">
<iconset resource="../include/icons.qrc">
<normaloff>:/icons/images/rightArrow.png</normaloff>:/icons/images/rightArrow.png</iconset>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="12">
<widget class="QSpinBox" name="spinThreshold3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="suffix">
<string> eV</string>
</property>
<property name="minimum">
<number>-100000</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item row="2" column="2" colspan="9">
<widget class="QSpinBox" name="spinThreshold">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="suffix">
<string> eV</string>
</property>
<property name="minimum">
<number>-100000</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="lblCounter">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Counters:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblDynamicRange">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Dynamic Range:</string>
</property>
</widget>
</item>
<item row="5" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>190</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="lblGainMode"> <widget class="QLabel" name="lblGainMode">
<property name="enabled"> <property name="enabled">
@ -616,7 +553,70 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="2"> <item row="3" column="2" colspan="9">
<widget class="QComboBox" name="comboDynamicRange">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<item>
<property name="text">
<string>1.67772e+07</string>
</property>
</item>
<item>
<property name="text">
<string>65535</string>
</property>
</item>
<item>
<property name="text">
<string>4095</string>
</property>
</item>
<item>
<property name="text">
<string>255</string>
</property>
</item>
<item>
<property name="text">
<string>7</string>
</property>
</item>
</widget>
</item>
<item row="4" column="3">
<widget class="QCheckBox" name="chkCounter2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>2</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2" colspan="9">
<widget class="QComboBox" name="comboGainMode"> <widget class="QComboBox" name="comboGainMode">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>

View File

@ -5,6 +5,8 @@
#include <QMainWindow> #include <QMainWindow>
#include <QString> #include <QString>
namespace sls {
class SlsQtH1D; class SlsQtH1D;
class SlsQt1DPlot; class SlsQt1DPlot;
class SlsQt2DPlot; class SlsQt2DPlot;
@ -43,3 +45,5 @@ class qCloneWidget : public QMainWindow, private Ui::ClonePlotObject {
static int NumClones; static int NumClones;
}; };
} // namespace sls

View File

@ -6,11 +6,13 @@
#include "ui_form_dac.h" #include "ui_form_dac.h"
#include <string> #include <string>
namespace sls {
class qDacWidget : public QWidget, private Ui::WidgetDacObject { class qDacWidget : public QWidget, private Ui::WidgetDacObject {
Q_OBJECT Q_OBJECT
public: public:
qDacWidget(QWidget *parent, sls::Detector *detector, bool d, std::string n, qDacWidget(QWidget *parent, Detector *detector, bool d, std::string n,
slsDetectorDefs::dacIndex i); slsDetectorDefs::dacIndex i);
~qDacWidget(); ~qDacWidget();
void SetDetectorIndex(int id); void SetDetectorIndex(int id);
@ -25,8 +27,10 @@ class qDacWidget : public QWidget, private Ui::WidgetDacObject {
void GetAdc(); void GetAdc();
void Refresh(); void Refresh();
sls::Detector *det; Detector *det;
bool isDac{true}; bool isDac{true};
slsDetectorDefs::dacIndex index; slsDetectorDefs::dacIndex index;
int detectorIndex{-1}; int detectorIndex{-1};
}; };
} // namespace sls

View File

@ -14,6 +14,8 @@
#include <ostream> #include <ostream>
#include <string> #include <string>
namespace sls {
using std::chrono::duration; using std::chrono::duration;
using std::chrono::duration_cast; using std::chrono::duration_cast;
using std::chrono::hours; using std::chrono::hours;
@ -47,9 +49,9 @@ class qDefs : public QWidget {
static void DisplayExceptions(std::string emsg, std::string src) { static void DisplayExceptions(std::string emsg, std::string src) {
try { try {
throw; throw;
} catch (const sls::SocketError &e) { } catch (const SocketError &e) {
throw; throw;
} catch (const sls::SharedMemoryError &e) { } catch (const SharedMemoryError &e) {
throw; throw;
} catch (const std::exception &e) { } catch (const std::exception &e) {
ExceptionMessage(emsg, e.what(), src); ExceptionMessage(emsg, e.what(), src);
@ -63,9 +65,9 @@ class qDefs : public QWidget {
typename NonDeduced<CT>::type... Args) { typename NonDeduced<CT>::type... Args) {
try { try {
throw; throw;
} catch (const sls::SocketError &e) { } catch (const SocketError &e) {
throw; throw;
} catch (const sls::SharedMemoryError &e) { } catch (const SharedMemoryError &e) {
throw; throw;
} catch (const std::exception &e) { } catch (const std::exception &e) {
ExceptionMessage(emsg, e.what(), src); ExceptionMessage(emsg, e.what(), src);
@ -329,3 +331,5 @@ class qDefs : public QWidget {
source); source);
} }
}; };
} // namespace sls

View File

@ -6,6 +6,11 @@
#include "ui_form_detectormain.h" #include "ui_form_detectormain.h"
#include <QTabWidget> #include <QTabWidget>
class QScrollArea;
class QResizeEvent;
namespace sls {
class qDrawPlot; class qDrawPlot;
class qTabMeasurement; class qTabMeasurement;
class qTabDataOutput; class qTabDataOutput;
@ -15,8 +20,6 @@ class qTabSettings;
class qTabDebugging; class qTabDebugging;
class qTabDeveloper; class qTabDeveloper;
class qTabMessages; class qTabMessages;
class QScrollArea;
class QResizeEvent;
/** To Over-ride the QTabWidget class to get the tabBar protected /** To Over-ride the QTabWidget class to get the tabBar protected
* methodTabWidget */ * methodTabWidget */
@ -70,7 +73,7 @@ class qDetectorMain : public QMainWindow, private Ui::DetectorMainObject {
NumberOfTabs NumberOfTabs
}; };
slsDetectorDefs::detectorType detType; slsDetectorDefs::detectorType detType;
std::unique_ptr<sls::Detector> det; std::unique_ptr<Detector> det;
qDrawPlot *plot; qDrawPlot *plot;
MyTabWidget *tabs; MyTabWidget *tabs;
QScrollArea *scroll[NumberOfTabs]; QScrollArea *scroll[NumberOfTabs];
@ -88,3 +91,5 @@ class qDetectorMain : public QMainWindow, private Ui::DetectorMainObject {
QString zoomToolTip; QString zoomToolTip;
QColor defaultTabColor; QColor defaultTabColor;
}; };
} // namespace sls

View File

@ -6,18 +6,21 @@
#include "ui_form_plot.h" #include "ui_form_plot.h"
#include <mutex> #include <mutex>
class QResizeEvent;
namespace sls {
class SlsQt1DPlot; class SlsQt1DPlot;
class SlsQtH1D; class SlsQtH1D;
class SlsQt2DPlot; class SlsQt2DPlot;
class qCloneWidget; class qCloneWidget;
class detectorData; class detectorData;
class QResizeEvent;
class qDrawPlot : public QWidget, private Ui::PlotObject { class qDrawPlot : public QWidget, private Ui::PlotObject {
Q_OBJECT Q_OBJECT
public: public:
qDrawPlot(QWidget *parent, sls::Detector *detector); qDrawPlot(QWidget *parent, Detector *detector);
~qDrawPlot(); ~qDrawPlot();
bool GetIsRunning(); bool GetIsRunning();
void SetRunning(bool enable); void SetRunning(bool enable);
@ -55,6 +58,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
void EnableGainPlot(bool enable); void EnableGainPlot(bool enable);
void ClonePlot(); void ClonePlot();
void SavePlot(); void SavePlot();
void SetGapPixels(bool enable);
protected: protected:
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
@ -95,7 +99,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
static const int NUM_PEDESTAL_FRAMES = 20; static const int NUM_PEDESTAL_FRAMES = 20;
static const int NUM_GOTTHARD25_CHANS = 1280; static const int NUM_GOTTHARD25_CHANS = 1280;
sls::Detector *det; Detector *det;
slsDetectorDefs::detectorType detType; slsDetectorDefs::detectorType detType;
SlsQt1DPlot *plot1d{nullptr}; SlsQt1DPlot *plot1d{nullptr};
@ -160,6 +164,9 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
int64_t currentFrame{0}; int64_t currentFrame{0};
mutable std::mutex mPlots; mutable std::mutex mPlots;
int64_t currentAcqIndex{0}; int64_t currentAcqIndex{0};
slsDetectorDefs::ROI rxRoi{};
bool isRxRoiDisplayed{false};
bool isGapPixels{false};
unsigned int nPixelsX{0}; unsigned int nPixelsX{0};
unsigned int nPixelsY{0}; unsigned int nPixelsY{0};
@ -168,3 +175,5 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
int gainOffset{0}; int gainOffset{0};
bool gotthard25; bool gotthard25;
}; };
} // namespace sls

View File

@ -4,13 +4,15 @@
#include "sls/Detector.h" #include "sls/Detector.h"
#include "ui_form_tab_advanced.h" #include "ui_form_tab_advanced.h"
namespace sls {
class qDrawPlot; class qDrawPlot;
class qTabAdvanced : public QWidget, private Ui::TabAdvancedObject { class qTabAdvanced : public QWidget, private Ui::TabAdvancedObject {
Q_OBJECT Q_OBJECT
public: public:
qTabAdvanced(QWidget *parent, sls::Detector *detector, qDrawPlot *p); qTabAdvanced(QWidget *parent, Detector *detector, qDrawPlot *p);
~qTabAdvanced(); ~qTabAdvanced();
public slots: public slots:
@ -74,6 +76,8 @@ class qTabAdvanced : public QWidget, private Ui::TabAdvancedObject {
void GetExposureTime(); void GetExposureTime();
void GetGateDelay(); void GetGateDelay();
sls::Detector *det; Detector *det;
qDrawPlot *plot; qDrawPlot *plot;
}; };
} // namespace sls

View File

@ -4,11 +4,13 @@
#include "sls/Detector.h" #include "sls/Detector.h"
#include "ui_form_tab_dataoutput.h" #include "ui_form_tab_dataoutput.h"
namespace sls {
class qTabDataOutput : public QWidget, private Ui::TabDataOutputObject { class qTabDataOutput : public QWidget, private Ui::TabDataOutputObject {
Q_OBJECT Q_OBJECT
public: public:
qTabDataOutput(QWidget *parent, sls::Detector *detector); qTabDataOutput(QWidget *parent, Detector *detector);
~qTabDataOutput(); ~qTabDataOutput();
void Refresh(); void Refresh();
@ -39,7 +41,9 @@ class qTabDataOutput : public QWidget, private Ui::TabDataOutputObject {
void GetSpeed(); void GetSpeed();
void GetParallel(); void GetParallel();
sls::Detector *det; Detector *det;
// Button group for radiobuttons for rate // Button group for radiobuttons for rate
QButtonGroup *btnGroupRate; QButtonGroup *btnGroupRate;
}; };
} // namespace sls

View File

@ -7,11 +7,13 @@
class QTreeWidget; class QTreeWidget;
class QTreeWidgetItem; class QTreeWidgetItem;
namespace sls {
class qTabDebugging : public QWidget, private Ui::TabDebuggingObject { class qTabDebugging : public QWidget, private Ui::TabDebuggingObject {
Q_OBJECT Q_OBJECT
public: public:
qTabDebugging(QWidget *parent, sls::Detector *detector); qTabDebugging(QWidget *parent, Detector *detector);
~qTabDebugging(); ~qTabDebugging();
void Refresh(); void Refresh();
@ -26,10 +28,12 @@ class qTabDebugging : public QWidget, private Ui::TabDebuggingObject {
void Initialization(); void Initialization();
void PopulateDetectors(); void PopulateDetectors();
sls::Detector *det; Detector *det;
/** Tree Widget displaying the detectors, modules */ /** Tree Widget displaying the detectors, modules */
QTreeWidget *treeDet; QTreeWidget *treeDet;
QLabel *lblDetectorHostname; QLabel *lblDetectorHostname;
QLabel *lblDetectorFirmware; QLabel *lblDetectorFirmware;
QLabel *lblDetectorSoftware; QLabel *lblDetectorSoftware;
}; };
} // namespace sls

View File

@ -6,13 +6,15 @@
#include "ui_form_tab_developer.h" #include "ui_form_tab_developer.h"
#include <vector> #include <vector>
namespace sls {
class qDacWidget; class qDacWidget;
class qTabDeveloper : public QWidget, private Ui::TabDeveloperObject { class qTabDeveloper : public QWidget, private Ui::TabDeveloperObject {
Q_OBJECT Q_OBJECT
public: public:
qTabDeveloper(QWidget *parent, sls::Detector *detector); qTabDeveloper(QWidget *parent, Detector *detector);
~qTabDeveloper(); ~qTabDeveloper();
public slots: public slots:
@ -29,7 +31,7 @@ class qTabDeveloper : public QWidget, private Ui::TabDeveloperObject {
slsDetectorDefs::dacIndex getSLSIndex(slsDetectorDefs::detectorType detType, slsDetectorDefs::dacIndex getSLSIndex(slsDetectorDefs::detectorType detType,
int index); int index);
sls::Detector *det; Detector *det;
std::vector<qDacWidget *> dacWidgets; std::vector<qDacWidget *> dacWidgets;
std::vector<qDacWidget *> adcWidgets; std::vector<qDacWidget *> adcWidgets;
@ -38,3 +40,5 @@ class qTabDeveloper : public QWidget, private Ui::TabDeveloperObject {
static const int HV_MIN = 60; static const int HV_MIN = 60;
static const int HV_MAX = 200; static const int HV_MAX = 200;
}; };
} // namespace sls

View File

@ -4,14 +4,17 @@
#include "sls/Detector.h" #include "sls/Detector.h"
#include "ui_form_tab_measurement.h" #include "ui_form_tab_measurement.h"
class qDrawPlot;
class QStandardItemModel; class QStandardItemModel;
namespace sls {
class qDrawPlot;
class qTabMeasurement : public QWidget, private Ui::TabMeasurementObject { class qTabMeasurement : public QWidget, private Ui::TabMeasurementObject {
Q_OBJECT Q_OBJECT
public: public:
qTabMeasurement(QWidget *parent, sls::Detector *detector, qDrawPlot *p); qTabMeasurement(QWidget *parent, Detector *detector, qDrawPlot *p);
~qTabMeasurement(); ~qTabMeasurement();
void Refresh(); void Refresh();
@ -81,7 +84,7 @@ class qTabMeasurement : public QWidget, private Ui::TabMeasurementObject {
void FileNameChangedSignal(QString); void FileNameChangedSignal(QString);
private: private:
sls::Detector *det; Detector *det;
qDrawPlot *plot; qDrawPlot *plot;
// enum for the timing mode // enum for the timing mode
enum { AUTO, TRIGGER, GATED, BURST_TRIGGER, TRIGGER_GATED, NUMTIMINGMODES }; enum { AUTO, TRIGGER, GATED, BURST_TRIGGER, TRIGGER_GATED, NUMTIMINGMODES };
@ -98,3 +101,5 @@ class qTabMeasurement : public QWidget, private Ui::TabMeasurementObject {
int numMeasurements{1}; int numMeasurements{1};
int currentMeasurement{0}; int currentMeasurement{0};
}; };
} // namespace sls

View File

@ -6,6 +6,8 @@
class QProcess; class QProcess;
class QKeyEvent; class QKeyEvent;
namespace sls {
class qTabMessages : public QWidget, private Ui::TabMessagesObject { class qTabMessages : public QWidget, private Ui::TabMessagesObject {
Q_OBJECT Q_OBJECT
@ -34,3 +36,5 @@ class qTabMessages : public QWidget, private Ui::TabMessagesObject {
QProcess *process; QProcess *process;
QStringList lastCommand; QStringList lastCommand;
}; };
} // namespace sls

View File

@ -4,13 +4,15 @@
#include "sls/Detector.h" #include "sls/Detector.h"
#include "ui_form_tab_plot.h" #include "ui_form_tab_plot.h"
namespace sls {
class qDrawPlot; class qDrawPlot;
class qTabPlot : public QWidget, private Ui::TabPlotObject { class qTabPlot : public QWidget, private Ui::TabPlotObject {
Q_OBJECT Q_OBJECT
public: public:
qTabPlot(QWidget *parent, sls::Detector *detector, qDrawPlot *p); qTabPlot(QWidget *parent, Detector *detector, qDrawPlot *p);
~qTabPlot(); ~qTabPlot();
void SetScanArgument(); void SetScanArgument();
void Refresh(); void Refresh();
@ -53,7 +55,7 @@ class qTabPlot : public QWidget, private Ui::TabPlotObject {
void SetXYRange(); void SetXYRange();
void MaintainAspectRatio(int dimension); void MaintainAspectRatio(int dimension);
sls::Detector *det; Detector *det;
qDrawPlot *plot; qDrawPlot *plot;
bool is1d; bool is1d;
@ -65,3 +67,5 @@ class qTabPlot : public QWidget, private Ui::TabPlotObject {
static QString defaultImageYAxisTitle; static QString defaultImageYAxisTitle;
static QString defaultImageZAxisTitle; static QString defaultImageZAxisTitle;
}; };
} // namespace sls

View File

@ -5,11 +5,13 @@
#include "ui_form_tab_settings.h" #include "ui_form_tab_settings.h"
#include <QCheckBox> #include <QCheckBox>
namespace sls {
class qTabSettings : public QWidget, private Ui::TabSettingsObject { class qTabSettings : public QWidget, private Ui::TabSettingsObject {
Q_OBJECT Q_OBJECT
public: public:
qTabSettings(QWidget *parent, sls::Detector *detector); qTabSettings(QWidget *parent, Detector *detector);
~qTabSettings(); ~qTabSettings();
void Refresh(); void Refresh();
public slots: public slots:
@ -37,7 +39,7 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject {
void GetThresholdEnergies(); void GetThresholdEnergies();
void GetCounterMask(); void GetCounterMask();
sls::Detector *det; Detector *det;
std::vector<QCheckBox *> counters; std::vector<QCheckBox *> counters;
enum { enum {
@ -77,3 +79,5 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject {
DYNAMICRANGE_4 DYNAMICRANGE_4
}; };
}; };
} // namespace sls

View File

@ -9,11 +9,15 @@
#include <qwt_plot_curve.h> #include <qwt_plot_curve.h>
#include <qwt_plot_marker.h> #include <qwt_plot_marker.h>
#include <qwt_scale_div.h> #include <qwt_scale_div.h>
#include <qwt_plot_shapeitem.h>
class QPen; class QPen;
class SlsQt1DPlot;
class QwtSymbol; class QwtSymbol;
namespace sls {
class SlsQt1DPlot;
class SlsQtH1D : public QwtPlotCurve { class SlsQtH1D : public QwtPlotCurve {
public: public:
@ -136,6 +140,9 @@ class SlsQt1DPlot : public QwtPlot {
void SetLogX(bool yes = 1); void SetLogX(bool yes = 1);
void SetLogY(bool yes = 1); void SetLogY(bool yes = 1);
void EnableRoiBox(std::array<int, 4> roi);
void DisableRoiBox();
private: private:
SlsQtH1DList *hist_list{nullptr}; SlsQtH1DList *hist_list{nullptr};
SlsQt1DZoomer *zoomer{nullptr}; SlsQt1DZoomer *zoomer{nullptr};
@ -159,9 +166,15 @@ class SlsQt1DPlot : public QwtPlot {
friend void SlsQtH1D::Attach(SlsQt1DPlot *p); friend void SlsQtH1D::Attach(SlsQt1DPlot *p);
friend void SlsQtH1D::Detach(SlsQt1DPlot *p); friend void SlsQtH1D::Detach(SlsQt1DPlot *p);
QwtPlotShapeItem *roiBox{nullptr};
public slots: public slots:
void UnZoom(); void UnZoom();
void Update(); void Update();
}; };
} // namespace sls
#endif #endif

View File

@ -8,6 +8,8 @@
#include <qwt_plot_panner.h> #include <qwt_plot_panner.h>
#include <qwt_plot_zoomer.h> #include <qwt_plot_zoomer.h>
namespace sls {
class SlsQtH1D; class SlsQtH1D;
class SlsQt1DZoomer : public QwtPlotZoomer { class SlsQt1DZoomer : public QwtPlotZoomer {
@ -51,4 +53,6 @@ class SlsQt1DZoomer : public QwtPlotZoomer {
} }
}; };
} // namespace sls
#endif #endif

View File

@ -9,6 +9,8 @@
#include <qwt_scale_draw.h> #include <qwt_scale_draw.h>
#include <qwt_scale_widget.h> #include <qwt_scale_widget.h>
namespace sls {
class SlsQt2DHist : public QwtRasterData { class SlsQt2DHist : public QwtRasterData {
private: private:
@ -125,4 +127,6 @@ class SlsQt2DHist : public QwtRasterData {
} }
}; };
} // namespace sls
#endif #endif

View File

@ -6,11 +6,14 @@
#include <qlist.h> #include <qlist.h>
#include <qwt_plot.h> #include <qwt_plot.h>
#include <qwt_plot_spectrogram.h> #include <qwt_plot_spectrogram.h>
#include <qwt_plot_shapeitem.h>
class QwtPlotPanner; class QwtPlotPanner;
class QwtScaleWidget; class QwtScaleWidget;
class QwtLinearColorMap; class QwtLinearColorMap;
namespace sls {
class SlsQt2DPlot : public QwtPlot { class SlsQt2DPlot : public QwtPlot {
Q_OBJECT Q_OBJECT
@ -67,6 +70,8 @@ class SlsQt2DPlot : public QwtPlot {
void SetLogz(bool enable, bool isMin, bool isMax, double min, double max); void SetLogz(bool enable, bool isMin, bool isMax, double min, double max);
void SetZRange(bool isMin, bool isMax, double min, double max); void SetZRange(bool isMin, bool isMax, double min, double max);
void LogZ(bool on = 1); void LogZ(bool on = 1);
void EnableRoiBox(std::array<int, 4> roi);
void DisableRoiBox();
public slots: public slots:
void showSpectrogram(bool on); void showSpectrogram(bool on);
@ -86,4 +91,7 @@ class SlsQt2DPlot : public QwtPlot {
QList<double> contourLevelsLog; QList<double> contourLevelsLog;
bool disableZoom{false}; bool disableZoom{false};
int isLog; int isLog;
QwtPlotShapeItem *roiBox{nullptr};
}; };
} // namespace sls

View File

@ -7,6 +7,8 @@
#include <qwt_plot_panner.h> #include <qwt_plot_panner.h>
#include <qwt_plot_zoomer.h> #include <qwt_plot_zoomer.h>
namespace sls {
class SlsQt2DZoomer : public QwtPlotZoomer { class SlsQt2DZoomer : public QwtPlotZoomer {
private: private:
SlsQt2DHist *hist; SlsQt2DHist *hist;
@ -40,4 +42,6 @@ class SlsQt2DZoomer : public QwtPlotZoomer {
} }
}; };
} // namespace sls
#endif #endif

View File

@ -15,6 +15,8 @@
#include <qwt_symbol.h> #include <qwt_symbol.h>
#include <stdlib.h> #include <stdlib.h>
namespace sls {
#define QwtLog10ScaleEngine QwtLogScaleEngine // hmm #define QwtLog10ScaleEngine QwtLogScaleEngine // hmm
SlsQtH1D::SlsQtH1D(QString title, int n, double min, double max, double *data) SlsQtH1D::SlsQtH1D(QString title, int n, double min, double max, double *data)
@ -442,6 +444,28 @@ void SlsQt1DPlot::SetLog(int axisId, bool yes) {
Update(); Update();
} }
void SlsQt1DPlot::EnableRoiBox(std::array<int, 4> roi) {
if (roiBox == nullptr) {
roiBox = new QwtPlotShapeItem();
roiBox->attach(this);
roiBox->setPen(QColor(Qt::yellow), 2.0, Qt::SolidLine);
}
// TopLeft - BottomRight (max points are +1 on graph)
QRect myRect(QPoint(roi[0], roi[2]), QPoint(roi[1] - 1, roi[3] - 1));
roiBox->setRect( QRectF(myRect) );
replot();
}
void SlsQt1DPlot::DisableRoiBox() {
if (roiBox != nullptr) {
roiBox->detach();
replot();
}
}
void SlsQt1DPlot::UnZoom() { void SlsQt1DPlot::UnZoom() {
setAxisScale(QwtPlot::xBottom, zoomer->x(), zoomer->x() + zoomer->w()); setAxisScale(QwtPlot::xBottom, zoomer->x(), zoomer->x() + zoomer->w());
setAxisScale(QwtPlot::yLeft, zoomer->y(), zoomer->y() + zoomer->h()); setAxisScale(QwtPlot::yLeft, zoomer->y(), zoomer->y() + zoomer->h());
@ -580,3 +604,5 @@ void SlsQt1DPlot::DisableZoom(bool disable) {
} }
} }
} }
} // namespace sls

View File

@ -7,6 +7,8 @@
#include <qwt_plot.h> #include <qwt_plot.h>
#include <qwt_scale_div.h> #include <qwt_scale_div.h>
namespace sls {
void SlsQt1DZoomer::ResetZoomBase() { void SlsQt1DZoomer::ResetZoomBase() {
SetZoomBase(x0, y0, x1 - x0, SetZoomBase(x0, y0, x1 - x0,
y1 - y0); // for going between log and nonlog plots y1 - y0); // for going between log and nonlog plots
@ -93,3 +95,5 @@ void SlsQt1DZoomer::ExtendZoomBase(SlsQtH1D *h) {
ResetZoomBase(); ResetZoomBase();
} }
} // namespace sls

View File

@ -9,6 +9,8 @@
using std::cout; using std::cout;
using std::endl; using std::endl;
namespace sls {
SlsQt2DHist::SlsQt2DHist(int nbinsx, double xmin, double xmax, int nbinsy, SlsQt2DHist::SlsQt2DHist(int nbinsx, double xmin, double xmax, int nbinsy,
double ymin, double ymax, double *d, double zmin, double ymin, double ymax, double *d, double zmin,
double zmax) double zmax)
@ -143,3 +145,5 @@ double SlsQt2DHist::SetMinimumToFirstGreaterThanZero() {
return z_min; return z_min;
} }
} // namespace sls

View File

@ -18,6 +18,8 @@
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
namespace sls {
SlsQt2DPlot::SlsQt2DPlot(QWidget *parent) : QwtPlot(parent) { SlsQt2DPlot::SlsQt2DPlot(QWidget *parent) : QwtPlot(parent) {
isLog = 0; isLog = 0;
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating); axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating);
@ -289,4 +291,27 @@ void SlsQt2DPlot::showSpectrogram(bool on) {
d_spectrogram->setDisplayMode(QwtPlotSpectrogram::ImageMode, on); d_spectrogram->setDisplayMode(QwtPlotSpectrogram::ImageMode, on);
d_spectrogram->setDefaultContourPen(on ? QPen() : QPen(Qt::NoPen)); d_spectrogram->setDefaultContourPen(on ? QPen() : QPen(Qt::NoPen));
Update(); Update();
} }
void SlsQt2DPlot::EnableRoiBox(std::array<int, 4> roi) {
if (roiBox == nullptr) {
roiBox = new QwtPlotShapeItem();
}
roiBox->setPen(QColor(Qt::yellow), 2.0, Qt::SolidLine);
// TopLeft - BottomRight (max points are +1 on graph)
QRect myRect(QPoint(roi[0], roi[2]), QPoint(roi[1] - 1, roi[3] - 1));
roiBox->setRect( QRectF(myRect) );
roiBox->attach(this);
replot();
}
void SlsQt2DPlot::DisableRoiBox() {
if (roiBox != nullptr) {
roiBox->detach();
replot();
}
}
} // namespace sls

View File

@ -11,6 +11,8 @@
#include <QPainter> #include <QPainter>
#include <qwt_text.h> #include <qwt_text.h>
namespace sls {
int qCloneWidget::NumClones{0}; int qCloneWidget::NumClones{0};
qCloneWidget::qCloneWidget(QWidget *parent, SlsQt1DPlot *p1, SlsQt2DPlot *p2, qCloneWidget::qCloneWidget(QWidget *parent, SlsQt1DPlot *p1, SlsQt2DPlot *p2,
@ -44,7 +46,7 @@ qCloneWidget::~qCloneWidget() {
void qCloneWidget::SetupWidgetWindow(QString title) { void qCloneWidget::SetupWidgetWindow(QString title) {
std::string winTitle = std::string("Snapshot:") + std::to_string(id) + std::string winTitle = std::string("Snapshot:") + std::to_string(id) +
std::string(" - ") + sls::Logger::Timestamp(); std::string(" - ") + Logger::Timestamp();
setWindowTitle(QString(winTitle.c_str())); setWindowTitle(QString(winTitle.c_str()));
boxPlot->setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal)); boxPlot->setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
@ -146,4 +148,6 @@ void qCloneWidget::resizeEvent(QResizeEvent *event) {
qDefs::DATA_GAIN_PLOT_RATIO); qDefs::DATA_GAIN_PLOT_RATIO);
} }
event->accept(); event->accept();
} }
} // namespace sls

View File

@ -3,7 +3,9 @@
#include "qDacWidget.h" #include "qDacWidget.h"
#include "qDefs.h" #include "qDefs.h"
qDacWidget::qDacWidget(QWidget *parent, sls::Detector *detector, bool d, namespace sls {
qDacWidget::qDacWidget(QWidget *parent, Detector *detector, bool d,
std::string n, slsDetectorDefs::dacIndex i) std::string n, slsDetectorDefs::dacIndex i)
: QWidget(parent), det(detector), isDac(d), index(i) { : QWidget(parent), det(detector), isDac(d), index(i) {
setupUi(this); setupUi(this);
@ -94,3 +96,5 @@ void qDacWidget::Refresh() {
GetAdc(); GetAdc();
} }
} }
} // namespace sls

View File

@ -59,7 +59,7 @@ int main(int argc, char **argv) {
case 'f': case 'f':
fname = optarg; fname = optarg;
LOG(logDEBUG) << long_options[option_index].name << " " << optarg; LOG(sls::logDEBUG) << long_options[option_index].name << " " << optarg;
break; break;
case 'd': case 'd':
@ -72,7 +72,7 @@ int main(int argc, char **argv) {
case 'v': case 'v':
tempval = APIGUI; tempval = APIGUI;
LOG(logINFO) << "SLS Detector GUI " << GITBRANCH << " (0x" LOG(sls::logINFO) << "SLS Detector GUI " << GITBRANCH << " (0x"
<< std::hex << tempval << ")"; << std::hex << tempval << ")";
return 0; return 0;
@ -88,7 +88,7 @@ int main(int argc, char **argv) {
"i. Default: 0. Required \n" + "i. Default: 0. Required \n" +
"\t only when more than one multi " "\t only when more than one multi "
"detector object is needed.\n\n"; "detector object is needed.\n\n";
LOG(logERROR) << help_message; LOG(sls::logERROR) << help_message;
return -1; return -1;
} }
} }
@ -96,16 +96,18 @@ int main(int argc, char **argv) {
QApplication app(argc, argv); QApplication app(argc, argv);
app.setStyle(new QPlastiqueStyle); // style is deleted by QApplication app.setStyle(new QPlastiqueStyle); // style is deleted by QApplication
try { try {
qDetectorMain det(multiId, fname, isDeveloper); sls::qDetectorMain det(multiId, fname, isDeveloper);
det.show(); det.show();
app.exec(); app.exec();
} catch (const std::exception &e) { } catch (const std::exception &e) {
qDefs::Message(qDefs::CRITICAL, sls::qDefs::Message(sls::qDefs::CRITICAL,
std::string(e.what()) + "\nExiting Gui :'( ", "main"); std::string(e.what()) + "\nExiting Gui :'( ", "main");
} }
return 0; return 0;
} }
namespace sls {
qDetectorMain::qDetectorMain(int multiId, const std::string &fname, qDetectorMain::qDetectorMain(int multiId, const std::string &fname,
bool isDevel) bool isDevel)
: QMainWindow(nullptr), detType(slsDetectorDefs::GENERIC), : QMainWindow(nullptr), detType(slsDetectorDefs::GENERIC),
@ -195,6 +197,7 @@ void qDetectorMain::SetUpWidgetWindow() {
tabs->setTabEnabled(ADVANCED, false); tabs->setTabEnabled(ADVANCED, false);
tabs->setTabEnabled(DEVELOPER, isDeveloper); tabs->setTabEnabled(DEVELOPER, isDeveloper);
actionLoadTrimbits->setVisible(false); actionLoadTrimbits->setVisible(false);
actionSaveTrimbits->setVisible(false);
dockWidgetPlot->setFloating(false); dockWidgetPlot->setFloating(false);
dockWidgetPlot->setFeatures(QDockWidget::NoDockWidgetFeatures); dockWidgetPlot->setFeatures(QDockWidget::NoDockWidgetFeatures);
@ -212,7 +215,7 @@ void qDetectorMain::SetUpWidgetWindow() {
void qDetectorMain::SetUpDetector(const std::string &config_file, int multiID) { void qDetectorMain::SetUpDetector(const std::string &config_file, int multiID) {
// instantiate detector and set window title // instantiate detector and set window title
det = sls::make_unique<sls::Detector>(multiID); det = make_unique<Detector>(multiID);
// create messages tab to capture config file loading logs // create messages tab to capture config file loading logs
tabMessages = new qTabMessages(this); tabMessages = new qTabMessages(this);
@ -225,10 +228,12 @@ void qDetectorMain::SetUpDetector(const std::string &config_file, int multiID) {
detType = det->getDetectorType().tsquash( detType = det->getDetectorType().tsquash(
"Different detector type for all modules."); "Different detector type for all modules.");
actionLoadTrimbits->setEnabled(false); actionLoadTrimbits->setEnabled(false);
actionSaveTrimbits->setEnabled(false);
switch (detType) { switch (detType) {
case slsDetectorDefs::EIGER: case slsDetectorDefs::EIGER:
case slsDetectorDefs::MYTHEN3: case slsDetectorDefs::MYTHEN3:
actionLoadTrimbits->setEnabled(true); actionLoadTrimbits->setEnabled(true);
actionSaveTrimbits->setEnabled(true);
break; break;
case slsDetectorDefs::GOTTHARD: case slsDetectorDefs::GOTTHARD:
case slsDetectorDefs::JUNGFRAU: case slsDetectorDefs::JUNGFRAU:
@ -238,15 +243,15 @@ void qDetectorMain::SetUpDetector(const std::string &config_file, int multiID) {
default: default:
std::ostringstream os; std::ostringstream os;
os << det->getHostname() << " has " os << det->getHostname() << " has "
<< sls::ToString(det->getDetectorType().squash()) << ToString(det->getDetectorType().squash())
<< " detector type (" << std::to_string(detType) << " detector type (" << std::to_string(detType)
<< "). Exiting GUI."; << "). Exiting GUI.";
std::string errorMess = os.str(); std::string errorMess = os.str();
throw sls::RuntimeError(errorMess.c_str()); throw RuntimeError(errorMess.c_str());
} }
std::ostringstream os; std::ostringstream os;
os << "SLS Detector GUI : " os << "SLS Detector GUI : "
<< sls::ToString(det->getDetectorType().squash()) << " - " << ToString(det->getDetectorType().squash()) << " - "
<< det->getHostname(); << det->getHostname();
std::string title = os.str(); std::string title = os.str();
LOG(logINFO) << title; LOG(logINFO) << title;
@ -339,9 +344,9 @@ void qDetectorMain::EnableModes(QAction *action) {
enable = actionExpert->isChecked(); enable = actionExpert->isChecked();
tabs->setTabEnabled(ADVANCED, enable); tabs->setTabEnabled(ADVANCED, enable);
actionLoadTrimbits->setVisible(enable && bool visible = enable && (detType == slsDetectorDefs::EIGER || detType == slsDetectorDefs::MYTHEN3);
(detType == slsDetectorDefs::EIGER || actionLoadTrimbits->setVisible(visible);
detType == slsDetectorDefs::MYTHEN3)); actionSaveTrimbits->setVisible(visible);
tabSettings->SetExportMode(enable); tabSettings->SetExportMode(enable);
LOG(logINFO) << "Expert Mode: " << qDefs::stringEnable(enable); LOG(logINFO) << "Expert Mode: " << qDefs::stringEnable(enable);
} }
@ -417,6 +422,22 @@ void qDetectorMain::ExecuteUtilities(QAction *action) {
LOG(logINFO) << "Trimbits loaded successfully"; LOG(logINFO) << "Trimbits loaded successfully";
} }
} }
else if (action == actionSaveTrimbits) {
QString fPath =
QString((det->getSettingsPath().squash("/tmp/")).c_str());
LOG(logDEBUG) << "Saving Trimbits";
QString fName = QFileDialog::getSaveFileName(
this, tr("Save Detector Trimbits"), fPath,
tr("Trimbit files (*.trim noise.sn*);;All Files(*)"));
if (!fName.isEmpty()) {
det->saveTrimbits(std::string(fName.toAscii().constData()));
qDefs::Message(qDefs::INFORMATION,
"The Trimbits have been saved successfully.",
"qDetectorMain::ExecuteUtilities");
LOG(logINFO) << "Trimbits saved successfully";
}
}
} }
CATCH_DISPLAY("Could not execute utilities.", CATCH_DISPLAY("Could not execute utilities.",
"qDetectorMain::ExecuteUtilities") "qDetectorMain::ExecuteUtilities")
@ -441,10 +462,10 @@ void qDetectorMain::ExecuteHelp(QAction *action) {
LOG(logINFO) << "About Common GUI for Jungfrau, Eiger, Mythen3, " LOG(logINFO) << "About Common GUI for Jungfrau, Eiger, Mythen3, "
"Gotthard, Gotthard2 and Moench detectors"; "Gotthard, Gotthard2 and Moench detectors";
std::string guiVersion = sls::ToStringHex(APIGUI); std::string guiVersion = ToStringHex(APIGUI);
std::string clientVersion = "unknown"; std::string clientVersion = "unknown";
try { try {
clientVersion = sls::ToStringHex(det->getClientVersion()); clientVersion = ToStringHex(det->getClientVersion());
} }
CATCH_DISPLAY("Could not get client version.", CATCH_DISPLAY("Could not get client version.",
"qDetectorMain::ExecuteHelp") "qDetectorMain::ExecuteHelp")
@ -577,6 +598,8 @@ void qDetectorMain::EnableTabs(bool enable) {
tabs->setTabEnabled(ADVANCED, expertTab); tabs->setTabEnabled(ADVANCED, expertTab);
actionLoadTrimbits->setVisible(expertTab && actionLoadTrimbits->setVisible(expertTab &&
detType == slsDetectorDefs::EIGER); detType == slsDetectorDefs::EIGER);
actionSaveTrimbits->setVisible(expertTab &&
detType == slsDetectorDefs::EIGER);
// moved to here, so that its all in order, instead of signals and different // moved to here, so that its all in order, instead of signals and different
// threads // threads
@ -609,3 +632,5 @@ void qDetectorMain::SetZoomToolTip(bool disable) {
else else
dockWidgetPlot->setToolTip(zoomToolTip); dockWidgetPlot->setToolTip(zoomToolTip);
} }
} // namespace sls

View File

@ -14,7 +14,9 @@
#include <QResizeEvent> #include <QResizeEvent>
#include <QtConcurrentRun> #include <QtConcurrentRun>
qDrawPlot::qDrawPlot(QWidget *parent, sls::Detector *detector) namespace sls {
qDrawPlot::qDrawPlot(QWidget *parent, Detector *detector)
: QWidget(parent), det(detector) { : QWidget(parent), det(detector) {
setupUi(this); setupUi(this);
SetupWidgetWindow(); SetupWidgetWindow();
@ -278,11 +280,13 @@ void qDrawPlot::Select1dPlot(bool enable) {
} }
void qDrawPlot::SetPlotTitlePrefix(QString title) { void qDrawPlot::SetPlotTitlePrefix(QString title) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting Title to " << title.toAscii().constData(); LOG(logINFO) << "Setting Title to " << title.toAscii().constData();
plotTitlePrefix = title; plotTitlePrefix = title;
} }
void qDrawPlot::SetXAxisTitle(QString title) { void qDrawPlot::SetXAxisTitle(QString title) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting X Axis Title to " << title.toAscii().constData(); LOG(logINFO) << "Setting X Axis Title to " << title.toAscii().constData();
if (is1d) { if (is1d) {
xTitle1d = title; xTitle1d = title;
@ -292,6 +296,7 @@ void qDrawPlot::SetXAxisTitle(QString title) {
} }
void qDrawPlot::SetYAxisTitle(QString title) { void qDrawPlot::SetYAxisTitle(QString title) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting Y Axis Title to " << title.toAscii().constData(); LOG(logINFO) << "Setting Y Axis Title to " << title.toAscii().constData();
if (is1d) { if (is1d) {
yTitle1d = title; yTitle1d = title;
@ -301,6 +306,7 @@ void qDrawPlot::SetYAxisTitle(QString title) {
} }
void qDrawPlot::SetZAxisTitle(QString title) { void qDrawPlot::SetZAxisTitle(QString title) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting Z Axis Title to " << title.toAscii().constData(); LOG(logINFO) << "Setting Z Axis Title to " << title.toAscii().constData();
zTitle2d = title; zTitle2d = title;
} }
@ -318,6 +324,7 @@ void qDrawPlot::SetXYRangeChanged(bool disable, double *xy, bool *isXY) {
} }
void qDrawPlot::SetZRange(double *z, bool *isZ) { void qDrawPlot::SetZRange(double *z, bool *isZ) {
std::lock_guard<std::mutex> lock(mPlots);
std::copy(z, z + 2, zRange); std::copy(z, z + 2, zRange);
std::copy(isZ, isZ + 2, isZRange); std::copy(isZ, isZ + 2, isZRange);
} }
@ -351,6 +358,7 @@ double qDrawPlot::GetYMaximum() {
} }
void qDrawPlot::SetDataCallBack(bool enable) { void qDrawPlot::SetDataCallBack(bool enable) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting data call back to " << std::boolalpha << enable LOG(logINFO) << "Setting data call back to " << std::boolalpha << enable
<< std::noboolalpha; << std::noboolalpha;
try { try {
@ -369,6 +377,7 @@ void qDrawPlot::SetDataCallBack(bool enable) {
} }
void qDrawPlot::SetBinary(bool enable, int from, int to) { void qDrawPlot::SetBinary(bool enable, int from, int to) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << (enable ? "Enabling" : "Disabling") LOG(logINFO) << (enable ? "Enabling" : "Disabling")
<< " Binary output from " << from << " to " << to; << " Binary output from " << from << " to " << to;
binaryFrom = from; binaryFrom = from;
@ -377,6 +386,7 @@ void qDrawPlot::SetBinary(bool enable, int from, int to) {
} }
void qDrawPlot::SetPersistency(int val) { void qDrawPlot::SetPersistency(int val) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting Persistency to " << val; LOG(logINFO) << "Setting Persistency to " << val;
persistency = val; persistency = val;
} }
@ -458,17 +468,20 @@ void qDrawPlot::ResetAccumulate() {
} }
void qDrawPlot::DisplayStatistics(bool enable) { void qDrawPlot::DisplayStatistics(bool enable) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << (enable ? "Enabling" : "Disabling") LOG(logINFO) << (enable ? "Enabling" : "Disabling")
<< " Statistics Display"; << " Statistics Display";
displayStatistics = enable; displayStatistics = enable;
} }
void qDrawPlot::SetNumDiscardBits(int value) { void qDrawPlot::SetNumDiscardBits(int value) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting number of bits to discard: " << value; LOG(logINFO) << "Setting number of bits to discard: " << value;
numDiscardBits = value; numDiscardBits = value;
} }
void qDrawPlot::EnableGainPlot(bool enable) { void qDrawPlot::EnableGainPlot(bool enable) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << (enable ? "Enabling" : "Disabling") << " Gain Plot"; LOG(logINFO) << (enable ? "Enabling" : "Disabling") << " Gain Plot";
hasGainData = enable; hasGainData = enable;
} }
@ -609,6 +622,13 @@ void qDrawPlot::SavePlot() {
} }
} }
void qDrawPlot::SetGapPixels(bool enable) {
LOG(logDEBUG) << "Gap pixels enabled";
std::lock_guard<std::mutex> lock(mPlots);
isGapPixels = enable;
}
void qDrawPlot::GetStatistics(double &min, double &max, double &sum) { void qDrawPlot::GetStatistics(double &min, double &max, double &sum) {
LOG(logDEBUG) << "Calculating Statistics"; LOG(logDEBUG) << "Calculating Statistics";
double *array = data2d; double *array = data2d;
@ -642,6 +662,7 @@ void qDrawPlot::StartAcquisition() {
currentFrame = 0; currentFrame = 0;
boxPlot->setTitle("Old Plot"); boxPlot->setTitle("Old Plot");
det->clearAcquiringFlag(); // (from previous exit) or if running det->clearAcquiringFlag(); // (from previous exit) or if running
isRxRoiDisplayed = false;
// ensure data streaming in receiver (if plot enabled) // ensure data streaming in receiver (if plot enabled)
if (isPlot) { if (isPlot) {
@ -709,7 +730,7 @@ void qDrawPlot::AcquisitionFinished(double currentProgress,
int detectorStatus) { int detectorStatus) {
progress = currentProgress; progress = currentProgress;
std::string status = std::string status =
sls::ToString(static_cast<slsDetectorDefs::runStatus>(detectorStatus)); ToString(static_cast<slsDetectorDefs::runStatus>(detectorStatus));
if (detectorStatus == slsDetectorDefs::ERROR) { if (detectorStatus == slsDetectorDefs::ERROR) {
qDefs::Message(qDefs::WARNING, qDefs::Message(qDefs::WARNING,
@ -742,6 +763,7 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
<< " \t dynamic range: " << data->dynamicRange << std::endl << " \t dynamic range: " << data->dynamicRange << std::endl
<< " \t file index: " << data->fileIndex << std::endl << " \t file index: " << data->fileIndex << std::endl
<< " \t complete image: " << data->completeImage << std::endl << " \t complete image: " << data->completeImage << std::endl
<< " \t rx Roi: " << ToString(data->rxRoi) << std::endl
<< " ]"; << " ]";
progress = data->progressIndex; progress = data->progressIndex;
@ -749,6 +771,22 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
currentFrame = frameIndex; currentFrame = frameIndex;
LOG(logDEBUG) << "[ Progress:" << progress << "%, Frame:" << currentFrame LOG(logDEBUG) << "[ Progress:" << progress << "%, Frame:" << currentFrame
<< " ]"; << " ]";
if (!isRxRoiDisplayed) {
rxRoi.xmin = data->rxRoi[0];
rxRoi.xmax = data->rxRoi[1];
rxRoi.ymin = data->rxRoi[2];
rxRoi.ymax = data->rxRoi[3];
// only for 2d anyway
if (isGapPixels) {
rxRoi.xmin += ((rxRoi.xmin/1024) * 6 + (rxRoi.xmin/256) * 2);
rxRoi.xmax += ((rxRoi.xmax/1024) * 6 + (rxRoi.xmax/256) * 2);
rxRoi.ymin += ((rxRoi.ymin/512) * 34 + (rxRoi.ymin/256) * 2);
rxRoi.ymax += ((rxRoi.ymax/512) * 34 + (rxRoi.ymax/256) * 2);
LOG(logINFO) << "Rx_roi recalculated with gap pixels: " << ToString(rxRoi);
}
LOG(logDEBUG) << "Rx_roi: " << ToString(rxRoi);
}
// 1d check if npixelX has changed (m3 for different counters enabled) // 1d check if npixelX has changed (m3 for different counters enabled)
if (is1d && static_cast<int>(nPixelsX) != data->nx) { if (is1d && static_cast<int>(nPixelsX) != data->nx) {
@ -987,6 +1025,26 @@ void qDrawPlot::Update1dPlot() {
xyRangeChanged = false; xyRangeChanged = false;
} }
plot1d->DisableZoom(disableZoom); plot1d->DisableZoom(disableZoom);
if (!isRxRoiDisplayed) {
isRxRoiDisplayed = true;
if (rxRoi.completeRoi()) {
plot1d->DisableRoiBox();
if (isGainDataExtracted) {
gainplot1d->DisableRoiBox();
}
lblRxRoiEnabled->hide();
} else {
plot1d->EnableRoiBox(std::array<int, 4>{rxRoi.xmin, rxRoi.xmax, (int)plot1d->GetYMinimum(), (int)plot1d->GetYMaximum()});
if (isGainDataExtracted) {
gainplot1d->EnableRoiBox(std::array<int, 4>{rxRoi.xmin, rxRoi.xmax, 0, 3});
}
lblRxRoiEnabled->show();
}
}
// ymin and ymax could change (so replot roi every time)
if (!rxRoi.completeRoi()) {
plot1d->EnableRoiBox(std::array<int, 4>{rxRoi.xmin, rxRoi.xmax, (int)plot1d->GetYMinimum(), (int)plot1d->GetYMaximum()});
}
} }
void qDrawPlot::Update2dPlot() { void qDrawPlot::Update2dPlot() {
@ -1015,6 +1073,22 @@ void qDrawPlot::Update2dPlot() {
} }
plot2d->DisableZoom(disableZoom); plot2d->DisableZoom(disableZoom);
plot2d->SetZRange(isZRange[0], isZRange[1], zRange[0], zRange[1]); plot2d->SetZRange(isZRange[0], isZRange[1], zRange[0], zRange[1]);
if (!isRxRoiDisplayed) {
isRxRoiDisplayed = true;
if (rxRoi.completeRoi()) {
plot2d->DisableRoiBox();
if (isGainDataExtracted) {
gainplot2d->DisableRoiBox();
}
lblRxRoiEnabled->hide();
} else {
plot2d->EnableRoiBox(rxRoi.getIntArray());
if (isGainDataExtracted) {
gainplot2d->EnableRoiBox(rxRoi.getIntArray());
}
lblRxRoiEnabled->show();
}
}
} }
void qDrawPlot::Update1dXYRange() { void qDrawPlot::Update1dXYRange() {
@ -1200,3 +1274,5 @@ void qDrawPlot::UpdatePlot() {
LOG(logDEBUG) << "End of Update Plot"; LOG(logDEBUG) << "End of Update Plot";
} }
} // namespace sls

View File

@ -5,7 +5,9 @@
#include "qDrawPlot.h" #include "qDrawPlot.h"
#include "sls/network_utils.h" #include "sls/network_utils.h"
qTabAdvanced::qTabAdvanced(QWidget *parent, sls::Detector *detector, namespace sls {
qTabAdvanced::qTabAdvanced(QWidget *parent, Detector *detector,
qDrawPlot *p) qDrawPlot *p)
: QWidget(parent), det(detector), plot(p) { : QWidget(parent), det(detector), plot(p) {
setupUi(this); setupUi(this);
@ -443,7 +445,7 @@ void qTabAdvanced::SetDetectorUDPIP(bool force) {
std::string s = dispDetectorUDPIP->text().toAscii().constData(); std::string s = dispDetectorUDPIP->text().toAscii().constData();
LOG(logINFO) << "Setting Detector UDP IP:" << s; LOG(logINFO) << "Setting Detector UDP IP:" << s;
try { try {
det->setSourceUDPIP(sls::IpAddr{s}, det->setSourceUDPIP(IpAddr{s},
{comboDetector->currentIndex()}); {comboDetector->currentIndex()});
} }
CATCH_HANDLE("Could not set Detector UDP IP.", CATCH_HANDLE("Could not set Detector UDP IP.",
@ -461,7 +463,7 @@ void qTabAdvanced::SetDetectorUDPMAC(bool force) {
std::string s = dispDetectorUDPMAC->text().toAscii().constData(); std::string s = dispDetectorUDPMAC->text().toAscii().constData();
LOG(logINFO) << "Setting Detector UDP MAC:" << s; LOG(logINFO) << "Setting Detector UDP MAC:" << s;
try { try {
det->setSourceUDPMAC(sls::MacAddr{s}, det->setSourceUDPMAC(MacAddr{s},
{comboDetector->currentIndex()}); {comboDetector->currentIndex()});
} }
CATCH_HANDLE("Could not set Detector UDP MAC.", CATCH_HANDLE("Could not set Detector UDP MAC.",
@ -489,7 +491,7 @@ void qTabAdvanced::SetCltZMQIP(bool force) {
std::string s = dispZMQIP->text().toAscii().constData(); std::string s = dispZMQIP->text().toAscii().constData();
LOG(logINFO) << "Setting Client ZMQ IP:" << s; LOG(logINFO) << "Setting Client ZMQ IP:" << s;
try { try {
det->setClientZmqIp(sls::IpAddr{s}, det->setClientZmqIp(IpAddr{s},
{comboDetector->currentIndex()}); {comboDetector->currentIndex()});
} }
CATCH_HANDLE("Could not set Client ZMQ IP.", CATCH_HANDLE("Could not set Client ZMQ IP.",
@ -547,7 +549,7 @@ void qTabAdvanced::SetRxrUDPIP(bool force) {
std::string s = dispRxrUDPIP->text().toAscii().constData(); std::string s = dispRxrUDPIP->text().toAscii().constData();
LOG(logINFO) << "Setting Receiver UDP IP:" << s; LOG(logINFO) << "Setting Receiver UDP IP:" << s;
try { try {
det->setDestinationUDPIP(sls::IpAddr{s}, det->setDestinationUDPIP(IpAddr{s},
{comboDetector->currentIndex()}); {comboDetector->currentIndex()});
} }
CATCH_HANDLE("Could not set Receiver UDP IP.", CATCH_HANDLE("Could not set Receiver UDP IP.",
@ -565,7 +567,7 @@ void qTabAdvanced::SetRxrUDPMAC(bool force) {
std::string s = dispRxrUDPMAC->text().toAscii().constData(); std::string s = dispRxrUDPMAC->text().toAscii().constData();
LOG(logINFO) << "Setting Receiver UDP MAC:" << s; LOG(logINFO) << "Setting Receiver UDP MAC:" << s;
try { try {
det->setDestinationUDPMAC(sls::MacAddr{s}, det->setDestinationUDPMAC(MacAddr{s},
{comboDetector->currentIndex()}); {comboDetector->currentIndex()});
} }
CATCH_HANDLE("Could not set Receiver UDP MAC.", CATCH_HANDLE("Could not set Receiver UDP MAC.",
@ -593,7 +595,7 @@ void qTabAdvanced::SetRxrZMQIP(bool force) {
std::string s = dispRxrZMQIP->text().toAscii().constData(); std::string s = dispRxrZMQIP->text().toAscii().constData();
LOG(logINFO) << "Setting Receiver ZMQ IP:" << s; LOG(logINFO) << "Setting Receiver ZMQ IP:" << s;
try { try {
det->setRxZmqIP(sls::IpAddr{s}, {comboDetector->currentIndex()}); det->setRxZmqIP(IpAddr{s}, {comboDetector->currentIndex()});
} }
CATCH_HANDLE("Could not set Receiver ZMQ IP.", CATCH_HANDLE("Could not set Receiver ZMQ IP.",
"qTabAdvanced::SetRxrZMQIP", this, "qTabAdvanced::SetRxrZMQIP", this,
@ -891,3 +893,5 @@ void qTabAdvanced::Refresh() {
} }
LOG(logDEBUG) << "**Updated Advanced Tab"; LOG(logDEBUG) << "**Updated Advanced Tab";
} }
} // namespace sls

View File

@ -11,7 +11,9 @@
#include <unistd.h> #include <unistd.h>
qTabDataOutput::qTabDataOutput(QWidget *parent, sls::Detector *detector) namespace sls {
qTabDataOutput::qTabDataOutput(QWidget *parent, Detector *detector)
: QWidget(parent), det(detector), btnGroupRate(nullptr) { : QWidget(parent), det(detector), btnGroupRate(nullptr) {
setupUi(this); setupUi(this);
SetupWidgetWindow(); SetupWidgetWindow();
@ -232,7 +234,7 @@ void qTabDataOutput::GetFileFormat() {
comboFileFormat->setCurrentIndex(static_cast<int>(retval)); comboFileFormat->setCurrentIndex(static_cast<int>(retval));
break; break;
default: default:
throw sls::RuntimeError(std::string("Unknown file format: ") + throw RuntimeError(std::string("Unknown file format: ") +
std::to_string(static_cast<int>(retval))); std::to_string(static_cast<int>(retval)));
} }
} }
@ -339,7 +341,7 @@ void qTabDataOutput::EnableRateCorrection() {
LOG(logINFO) << "Disabling Rate correction"; LOG(logINFO) << "Disabling Rate correction";
// disable // disable
try { try {
det->setRateCorrection(sls::ns(0)); det->setRateCorrection(ns(0));
} }
CATCH_HANDLE("Could not switch off rate correction.", CATCH_HANDLE("Could not switch off rate correction.",
"qTabDataOutput::EnableRateCorrection", this, "qTabDataOutput::EnableRateCorrection", this,
@ -357,7 +359,7 @@ void qTabDataOutput::SetRateCorrection() {
int64_t deadtime = spinCustomDeadTime->value(); int64_t deadtime = spinCustomDeadTime->value();
LOG(logINFO) << "Setting Rate Correction with custom dead time: " LOG(logINFO) << "Setting Rate Correction with custom dead time: "
<< deadtime; << deadtime;
det->setRateCorrection(sls::ns(deadtime)); det->setRateCorrection(ns(deadtime));
} }
// default dead time // default dead time
else { else {
@ -442,3 +444,5 @@ void qTabDataOutput::Refresh() {
LOG(logDEBUG) << "**Updated DataOutput Tab"; LOG(logDEBUG) << "**Updated DataOutput Tab";
} }
} // namespace sls

View File

@ -7,7 +7,9 @@
#include <QGridLayout> #include <QGridLayout>
#include <QTreeWidget> #include <QTreeWidget>
qTabDebugging::qTabDebugging(QWidget *parent, sls::Detector *detector) namespace sls {
qTabDebugging::qTabDebugging(QWidget *parent, Detector *detector)
: QWidget(parent), det(detector), treeDet(nullptr), : QWidget(parent), det(detector), treeDet(nullptr),
lblDetectorHostname(nullptr), lblDetectorFirmware(nullptr), lblDetectorHostname(nullptr), lblDetectorFirmware(nullptr),
lblDetectorSoftware(nullptr) { lblDetectorSoftware(nullptr) {
@ -62,7 +64,7 @@ void qTabDebugging::GetDetectorStatus() {
LOG(logDEBUG) << "Getting Status"; LOG(logDEBUG) << "Getting Status";
try { try {
std::string status = sls::ToString( std::string status = ToString(
det->getDetectorStatus({comboDetector->currentIndex()})[0]); det->getDetectorStatus({comboDetector->currentIndex()})[0]);
lblStatus->setText(QString(status.c_str()).toUpper()); lblStatus->setText(QString(status.c_str()).toUpper());
} }
@ -88,7 +90,7 @@ void qTabDebugging::GetInfo() {
lblDetectorFirmware->setFixedWidth(100); lblDetectorFirmware->setFixedWidth(100);
layout->addWidget(dispFrame, 0, 1); layout->addWidget(dispFrame, 0, 1);
QString detName = QString detName =
QString(sls::ToString(det->getDetectorType().squash()).c_str()); QString(ToString(det->getDetectorType().squash()).c_str());
switch (det->getDetectorType().squash()) { switch (det->getDetectorType().squash()) {
@ -241,3 +243,5 @@ void qTabDebugging::Refresh() {
GetDetectorStatus(); GetDetectorStatus();
LOG(logDEBUG) << "**Updated Debugging Tab"; LOG(logDEBUG) << "**Updated Debugging Tab";
} }
} // namespace sls

View File

@ -4,7 +4,9 @@
#include "qDacWidget.h" #include "qDacWidget.h"
#include "qDefs.h" #include "qDefs.h"
qTabDeveloper::qTabDeveloper(QWidget *parent, sls::Detector *detector) namespace sls {
qTabDeveloper::qTabDeveloper(QWidget *parent, Detector *detector)
: QWidget(parent), det(detector) { : QWidget(parent), det(detector) {
setupUi(this); setupUi(this);
SetupWidgetWindow(); SetupWidgetWindow();
@ -324,7 +326,7 @@ void qTabDeveloper::GetHighVoltage() {
// spinHV // spinHV
if (spinHV->isVisible()) { if (spinHV->isVisible()) {
if (retval != 0 && retval < hvmin && retval > HV_MAX) { if (retval != 0 && retval < hvmin && retval > HV_MAX) {
throw sls::RuntimeError(std::string("Unknown High Voltage: ") + throw RuntimeError(std::string("Unknown High Voltage: ") +
std::to_string(retval)); std::to_string(retval));
} }
spinHV->setValue(retval); spinHV->setValue(retval);
@ -354,7 +356,7 @@ void qTabDeveloper::GetHighVoltage() {
comboHV->setCurrentIndex(HV_200); comboHV->setCurrentIndex(HV_200);
break; break;
default: default:
throw sls::RuntimeError(std::string("Unknown High Voltage: ") + throw RuntimeError(std::string("Unknown High Voltage: ") +
std::to_string(retval)); std::to_string(retval));
} }
} }
@ -431,7 +433,7 @@ qTabDeveloper::getSLSIndex(slsDetectorDefs::detectorType detType, int index) {
case 22: case 22:
return slsDetectorDefs::TEMPERATURE_FPGA; return slsDetectorDefs::TEMPERATURE_FPGA;
default: default:
throw sls::RuntimeError(std::string("Unknown dac/adc index") + throw RuntimeError(std::string("Unknown dac/adc index") +
std::to_string(index)); std::to_string(index));
} }
break; break;
@ -458,7 +460,7 @@ qTabDeveloper::getSLSIndex(slsDetectorDefs::detectorType detType, int index) {
case 9: case 9:
return slsDetectorDefs::TEMPERATURE_FPGA; return slsDetectorDefs::TEMPERATURE_FPGA;
default: default:
throw sls::RuntimeError(std::string("Unknown dac/adc index") + throw RuntimeError(std::string("Unknown dac/adc index") +
std::to_string(index)); std::to_string(index));
} }
break; break;
@ -484,7 +486,7 @@ qTabDeveloper::getSLSIndex(slsDetectorDefs::detectorType detType, int index) {
case 8: case 8:
return slsDetectorDefs::TEMPERATURE_ADC; return slsDetectorDefs::TEMPERATURE_ADC;
default: default:
throw sls::RuntimeError(std::string("Unknown dac/adc index") + throw RuntimeError(std::string("Unknown dac/adc index") +
std::to_string(index)); std::to_string(index));
} }
break; break;
@ -508,7 +510,7 @@ qTabDeveloper::getSLSIndex(slsDetectorDefs::detectorType detType, int index) {
case 7: case 7:
return slsDetectorDefs::IBIAS_SFP; return slsDetectorDefs::IBIAS_SFP;
default: default:
throw sls::RuntimeError(std::string("Unknown dac/adc index") + throw RuntimeError(std::string("Unknown dac/adc index") +
std::to_string(index)); std::to_string(index));
} }
break; break;
@ -550,7 +552,7 @@ qTabDeveloper::getSLSIndex(slsDetectorDefs::detectorType detType, int index) {
case 16: case 16:
return slsDetectorDefs::VTHRESHOLD; return slsDetectorDefs::VTHRESHOLD;
default: default:
throw sls::RuntimeError(std::string("Unknown dac/adc index") + throw RuntimeError(std::string("Unknown dac/adc index") +
std::to_string(index)); std::to_string(index));
} }
break; break;
@ -586,13 +588,13 @@ qTabDeveloper::getSLSIndex(slsDetectorDefs::detectorType detType, int index) {
case 13: case 13:
return slsDetectorDefs::VCOM_ADC2; return slsDetectorDefs::VCOM_ADC2;
default: default:
throw sls::RuntimeError(std::string("Unknown dac/adc index") + throw RuntimeError(std::string("Unknown dac/adc index") +
std::to_string(index)); std::to_string(index));
} }
break; break;
default: default:
throw sls::RuntimeError(std::string("Unknown detector type")); throw RuntimeError(std::string("Unknown detector type"));
} }
} }
@ -607,3 +609,5 @@ void qTabDeveloper::Refresh() {
GetHighVoltage(); GetHighVoltage();
LOG(logDEBUG) << "**Updated Developer Tab"; LOG(logDEBUG) << "**Updated Developer Tab";
} }
} // namespace sls

View File

@ -7,7 +7,9 @@
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QTimer> #include <QTimer>
qTabMeasurement::qTabMeasurement(QWidget *parent, sls::Detector *detector, namespace sls {
qTabMeasurement::qTabMeasurement(QWidget *parent, Detector *detector,
qDrawPlot *p) qDrawPlot *p)
: QWidget(parent), det(detector), plot(p), progressTimer(nullptr) { : QWidget(parent), det(detector), plot(p), progressTimer(nullptr) {
setupUi(this); setupUi(this);
@ -337,9 +339,26 @@ void qTabMeasurement::GetTimingMode() {
disconnect(comboTimingMode, SIGNAL(currentIndexChanged(int)), this, disconnect(comboTimingMode, SIGNAL(currentIndexChanged(int)), this,
SLOT(SetTimingMode(int))); SLOT(SetTimingMode(int)));
try { try {
slsDetectorDefs::timingMode retval{slsDetectorDefs::AUTO_TIMING};
// m3: remove slave modes (always trigger) before squashing
if (det->getDetectorType().squash() == slsDetectorDefs::MYTHEN3) {
auto retvals = det->getTimingMode();
auto is_master = det->getMaster();
Result<slsDetectorDefs::timingMode> masterRetvals;
for (size_t i = 0; i != is_master.size(); ++i) {
if (is_master[i]) {
masterRetvals.push_back(retvals[i]);
}
}
retval = masterRetvals.tsquash(
"Inconsistent timing mode for all detectors.");
} else {
retval = det->getTimingMode().tsquash(
"Inconsistent timing mode for all detectors.");
}
auto oldMode = comboTimingMode->currentIndex(); auto oldMode = comboTimingMode->currentIndex();
auto retval = det->getTimingMode().tsquash(
"Inconsistent timing mode for all detectors.");
switch (retval) { switch (retval) {
case slsDetectorDefs::AUTO_TIMING: case slsDetectorDefs::AUTO_TIMING:
case slsDetectorDefs::TRIGGER_EXPOSURE: case slsDetectorDefs::TRIGGER_EXPOSURE:
@ -353,7 +372,7 @@ void qTabMeasurement::GetTimingMode() {
} }
break; break;
default: default:
throw sls::RuntimeError(std::string("Unknown timing mode: ") + throw RuntimeError(std::string("Unknown timing mode: ") +
std::to_string(retval)); std::to_string(retval));
} }
} }
@ -390,7 +409,7 @@ void qTabMeasurement::GetBurstMode() {
ShowTriggerDelay(); ShowTriggerDelay();
break; break;
default: default:
throw sls::RuntimeError(std::string("Unknown burst mode: ") + throw RuntimeError(std::string("Unknown burst mode: ") +
std::to_string(retval)); std::to_string(retval));
} }
} }
@ -1000,3 +1019,5 @@ void qTabMeasurement::Refresh() {
LOG(logDEBUG) << "**Updated Measurement Tab"; LOG(logDEBUG) << "**Updated Measurement Tab";
} }
} // namespace sls

View File

@ -11,6 +11,8 @@
#include <QTextStream> #include <QTextStream>
#include <string> #include <string>
namespace sls {
qTabMessages::qTabMessages(QWidget *parent) : QWidget(parent) { qTabMessages::qTabMessages(QWidget *parent) : QWidget(parent) {
setupUi(this); setupUi(this);
SetupWidgetWindow(); SetupWidgetWindow();
@ -142,3 +144,5 @@ void qTabMessages::Refresh() {
dispCommand->clear(); dispCommand->clear();
dispCommand->setFocus(); dispCommand->setFocus();
} }
} // namespace sls

View File

@ -6,6 +6,8 @@
#include <QStackedLayout> #include <QStackedLayout>
#include <QStandardItemModel> #include <QStandardItemModel>
namespace sls {
QString qTabPlot::defaultPlotTitle(""); QString qTabPlot::defaultPlotTitle("");
QString qTabPlot::defaultHistXAxisTitle("Channel Number"); QString qTabPlot::defaultHistXAxisTitle("Channel Number");
QString qTabPlot::defaultHistYAxisTitle("Counts"); QString qTabPlot::defaultHistYAxisTitle("Counts");
@ -13,7 +15,7 @@ QString qTabPlot::defaultImageXAxisTitle("Pixel");
QString qTabPlot::defaultImageYAxisTitle("Pixel"); QString qTabPlot::defaultImageYAxisTitle("Pixel");
QString qTabPlot::defaultImageZAxisTitle("Intensity"); QString qTabPlot::defaultImageZAxisTitle("Intensity");
qTabPlot::qTabPlot(QWidget *parent, sls::Detector *detector, qDrawPlot *p) qTabPlot::qTabPlot(QWidget *parent, Detector *detector, qDrawPlot *p)
: QWidget(parent), det(detector), plot(p), is1d(false) { : QWidget(parent), det(detector), plot(p), is1d(false) {
setupUi(this); setupUi(this);
SetupWidgetWindow(); SetupWidgetWindow();
@ -74,6 +76,10 @@ void qTabPlot::SetupWidgetWindow() {
// set zmq high water mark to GUI_ZMQ_RCV_HWM (2) // set zmq high water mark to GUI_ZMQ_RCV_HWM (2)
spinSndHwm->setValue(qDefs::GUI_ZMQ_RCV_HWM); spinSndHwm->setValue(qDefs::GUI_ZMQ_RCV_HWM);
spinRcvHwm->setValue(qDefs::GUI_ZMQ_RCV_HWM); spinRcvHwm->setValue(qDefs::GUI_ZMQ_RCV_HWM);
if (chkGapPixels->isEnabled()) {
chkGapPixels->setChecked(true);
}
} }
void qTabPlot::Initialization() { void qTabPlot::Initialization() {
@ -327,6 +333,7 @@ void qTabPlot::SetGapPixels(bool enable) {
LOG(logINFO) << "Setting Gap Pixels Enable to " << enable; LOG(logINFO) << "Setting Gap Pixels Enable to " << enable;
try { try {
det->setGapPixelsinCallback(enable); det->setGapPixelsinCallback(enable);
plot->SetGapPixels(enable);
} }
CATCH_HANDLE("Could not set gap pixels enable.", "qTabPlot::SetGapPixels", CATCH_HANDLE("Could not set gap pixels enable.", "qTabPlot::SetGapPixels",
this, &qTabPlot::GetGapPixels) this, &qTabPlot::GetGapPixels)
@ -792,3 +799,5 @@ void qTabPlot::Refresh() {
LOG(logDEBUG) << "**Updated Plot Tab"; LOG(logDEBUG) << "**Updated Plot Tab";
} }
} // namespace sls

View File

@ -6,7 +6,9 @@
#include "sls/bit_utils.h" #include "sls/bit_utils.h"
#include <QStandardItemModel> #include <QStandardItemModel>
qTabSettings::qTabSettings(QWidget *parent, sls::Detector *detector) namespace sls {
qTabSettings::qTabSettings(QWidget *parent, Detector *detector)
: QWidget(parent), det(detector) { : QWidget(parent), det(detector) {
setupUi(this); setupUi(this);
SetupWidgetWindow(); SetupWidgetWindow();
@ -215,7 +217,7 @@ void qTabSettings::GetSettings() {
break; break;
default: default:
if ((int)retval < -1 || (int)retval >= comboSettings->count()) { if ((int)retval < -1 || (int)retval >= comboSettings->count()) {
throw sls::RuntimeError(std::string("Unknown settings: ") + throw RuntimeError(std::string("Unknown settings: ") +
std::to_string(retval)); std::to_string(retval));
} }
comboSettings->setCurrentIndex(retval); comboSettings->setCurrentIndex(retval);
@ -231,7 +233,7 @@ void qTabSettings::SetSettings(int index) {
// settings // settings
auto val = static_cast<slsDetectorDefs::detectorSettings>(index); auto val = static_cast<slsDetectorDefs::detectorSettings>(index);
try { try {
LOG(logINFO) << "Setting Settings to " << sls::ToString(val); LOG(logINFO) << "Setting Settings to " << ToString(val);
det->setSettings(val); det->setSettings(val);
} }
CATCH_HANDLE("Could not set settings.", "qTabSettings::SetSettings", this, CATCH_HANDLE("Could not set settings.", "qTabSettings::SetSettings", this,
@ -250,7 +252,7 @@ void qTabSettings::GetGainMode() {
auto retval = det->getGainMode().tsquash( auto retval = det->getGainMode().tsquash(
"Inconsistent gain mode for all detectors."); "Inconsistent gain mode for all detectors.");
if ((int)retval < 0 || (int)retval >= comboGainMode->count()) { if ((int)retval < 0 || (int)retval >= comboGainMode->count()) {
throw sls::RuntimeError(std::string("Unknown gain mode: ") + throw RuntimeError(std::string("Unknown gain mode: ") +
std::to_string(retval)); std::to_string(retval));
} }
// warning when using fix_g0 and not in export mode // warning when using fix_g0 and not in export mode
@ -321,7 +323,7 @@ void qTabSettings::GetDynamicRange() {
comboDynamicRange->setCurrentIndex(DYNAMICRANGE_4); comboDynamicRange->setCurrentIndex(DYNAMICRANGE_4);
break; break;
default: default:
throw sls::RuntimeError(std::string("Unknown dynamic range: ") + throw RuntimeError(std::string("Unknown dynamic range: ") +
std::to_string(retval)); std::to_string(retval));
} }
} }
@ -352,7 +354,7 @@ void qTabSettings::SetDynamicRange(int index) {
det->setDynamicRange(4); det->setDynamicRange(4);
break; break;
default: default:
throw sls::RuntimeError(std::string("Unknown dynamic range: ") + throw RuntimeError(std::string("Unknown dynamic range: ") +
std::to_string(index)); std::to_string(index));
} }
} }
@ -399,7 +401,7 @@ void qTabSettings::SetThresholdEnergies() {
slsDetectorDefs::detectorSettings sett = slsDetectorDefs::detectorSettings sett =
static_cast<slsDetectorDefs::detectorSettings>( static_cast<slsDetectorDefs::detectorSettings>(
comboSettings->currentIndex()); comboSettings->currentIndex());
LOG(logINFO) << "Setting Threshold Energies to " << sls::ToString(eV) LOG(logINFO) << "Setting Threshold Energies to " << ToString(eV)
<< " (eV)"; << " (eV)";
try { try {
det->setThresholdEnergy(eV, sett); det->setThresholdEnergy(eV, sett);
@ -430,7 +432,7 @@ void qTabSettings::GetCounterMask() {
disconnect(chkCounter3, SIGNAL(toggled(bool)), this, disconnect(chkCounter3, SIGNAL(toggled(bool)), this,
SLOT(SetCounterMask())); SLOT(SetCounterMask()));
try { try {
auto retval = sls::getSetBits(det->getCounterMask().tsquash( auto retval = getSetBits(det->getCounterMask().tsquash(
"Counter mask is inconsistent for all detectors.")); "Counter mask is inconsistent for all detectors."));
// default to unchecked // default to unchecked
for (auto p : counters) { for (auto p : counters) {
@ -439,7 +441,7 @@ void qTabSettings::GetCounterMask() {
// if retval[i] = 2, chkCounter2 is checked // if retval[i] = 2, chkCounter2 is checked
for (auto i : retval) { for (auto i : retval) {
if (i > 3) { if (i > 3) {
throw sls::RuntimeError( throw RuntimeError(
std::string("Unknown counter index : ") + std::string("Unknown counter index : ") +
std::to_string(static_cast<int>(i))); std::to_string(static_cast<int>(i)));
} }
@ -496,3 +498,5 @@ void qTabSettings::Refresh() {
LOG(logDEBUG) << "**Updated Settings Tab"; LOG(logDEBUG) << "**Updated Settings Tab";
} }
} // namespace sls

View File

@ -57,7 +57,6 @@ int normal = 0;
int eiger_highvoltage = 0; int eiger_highvoltage = 0;
int eiger_theo_highvoltage = 0; int eiger_theo_highvoltage = 0;
int eiger_iodelay = 0; int eiger_iodelay = 0;
int eiger_photonenergy = 0;
int eiger_dynamicrange = 0; int eiger_dynamicrange = 0;
int eiger_parallelmode = 0; int eiger_parallelmode = 0;
int eiger_overflow32 = 0; int eiger_overflow32 = 0;
@ -682,17 +681,17 @@ void allocateDetectorStructureMemory() {
("modules from 0x%x to 0x%x\n", detectorModules, detectorModules)); ("modules from 0x%x to 0x%x\n", detectorModules, detectorModules));
LOG(logDEBUG1, ("chans from 0x%x to 0x%x\n", detectorChans, detectorChans)); LOG(logDEBUG1, ("chans from 0x%x to 0x%x\n", detectorChans, detectorChans));
LOG(logDEBUG1, ("dacs from 0x%x to 0x%x\n", detectorDacs, detectorDacs)); LOG(logDEBUG1, ("dacs from 0x%x to 0x%x\n", detectorDacs, detectorDacs));
(detectorModules)->dacs = detectorDacs; detectorModules->dacs = detectorDacs;
(detectorModules)->chanregs = detectorChans; detectorModules->chanregs = detectorChans;
(detectorModules)->ndac = NDAC; detectorModules->ndac = NDAC;
(detectorModules)->nchip = NCHIP; detectorModules->nchip = NCHIP;
(detectorModules)->nchan = NCHIP * NCHAN; detectorModules->nchan = NCHIP * NCHAN;
(detectorModules)->reg = 0; detectorModules->reg = 0;
(detectorModules)->iodelay = 0; detectorModules->iodelay = 0;
(detectorModules)->tau = 0; detectorModules->tau = 0;
(detectorModules)->eV[0] = 0; detectorModules->eV[0] = -1;
(detectorModules)->eV[1] = 0; detectorModules->eV[1] = -1;
(detectorModules)->eV[2] = 0; detectorModules->eV[2] = -1;
thisSettings = UNINITIALIZED; thisSettings = UNINITIALIZED;
// if trimval requested, should return -1 to acknowledge unknown // if trimval requested, should return -1 to acknowledge unknown
@ -732,9 +731,8 @@ void setupDetector() {
getSubExpTime(DEFAULT_SUBFRAME_DEADTIME); getSubExpTime(DEFAULT_SUBFRAME_DEADTIME);
setPeriod(DEFAULT_PERIOD); setPeriod(DEFAULT_PERIOD);
setNumTriggers(DEFAULT_NUM_CYCLES); setNumTriggers(DEFAULT_NUM_CYCLES);
eiger_dynamicrange = DEFAULT_DYNAMIC_RANGE;
setDynamicRange(DEFAULT_DYNAMIC_RANGE); setDynamicRange(DEFAULT_DYNAMIC_RANGE);
eiger_photonenergy = DEFAULT_PHOTON_ENERGY; detectorModules->eV[0] = DEFAULT_PHOTON_ENERGY;
setParallelMode(DEFAULT_PARALLEL_MODE); setParallelMode(DEFAULT_PARALLEL_MODE);
setOverFlowMode(DEFAULT_READOUT_OVERFLOW32_MODE); setOverFlowMode(DEFAULT_READOUT_OVERFLOW32_MODE);
setReadoutSpeed(DEFAULT_CLK_SPEED); setReadoutSpeed(DEFAULT_CLK_SPEED);
@ -1127,25 +1125,43 @@ int64_t getMeasuredSubPeriod() {
/* parameters - channel, module, settings */ /* parameters - channel, module, settings */
void getModule(sls_detector_module* myMod) {
// serial number
myMod->serialnumber = detectorModules->serialnumber;
// reg (settings)
myMod->reg = detectorModules->reg;
// iodelay
myMod->iodelay = setIODelay(-1);
// tau
myMod->tau = (int) getCurrentTau();
// eV
myMod->eV[0] = detectorModules->eV[0];
// dacs
for (int idac = 0; idac < (detectorModules->ndac); idac++) {
*((myMod->dacs) + idac) = *((detectorModules->dacs) + idac);
}
// trimbits
for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) {
*((myMod->chanregs) + ichan) = *((detectorModules->chanregs) + ichan);
}
}
int setModule(sls_detector_module myMod, char *mess) { int setModule(sls_detector_module myMod, char *mess) {
LOG(logINFO, ("Setting module with settings %d\n", myMod.reg)); LOG(logINFO, ("Setting module with settings %d\n", myMod.reg));
if (((myMod.nchan) > (detectorModules->nchan)) || ((myMod.ndac) > (detectorModules->ndac))) {
strcpy(mess, "Could not set module as the number of channels or dacs do not match to the one in the detector server\n");
LOG(logERROR, (mess));
return FAIL;
}
// serial number (pointless)
detectorModules->serialnumber = myMod.serialnumber;
// settings // settings
setSettings((enum detectorSettings)myMod.reg); setSettings((enum detectorSettings)myMod.reg);
// copy module locally (module number, serial number
// dacs (pointless), trimbit values(if needed)
if (detectorModules) {
if (copyModule(detectorModules, &myMod) == FAIL) {
sprintf(mess, "Could not copy module\n");
LOG(logERROR, (mess));
setSettings(UNDEFINED);
LOG(logERROR, ("Settings has been changed to undefined\n"));
return FAIL;
}
}
// iodelay // iodelay
if (setIODelay(myMod.iodelay) != myMod.iodelay) { if (setIODelay(myMod.iodelay) != myMod.iodelay) {
sprintf(mess, "Could not set module. Could not set iodelay %d\n", sprintf(mess, "Could not set module. Could not set iodelay %d\n",
@ -1178,60 +1194,15 @@ int setModule(sls_detector_module myMod, char *mess) {
} }
} }
#ifndef VIRTUAL
// trimbits // trimbits
#ifndef VIRTUAL
if (myMod.nchan == 0) { if (myMod.nchan == 0) {
LOG(logINFO, ("Setting module without trimbits\n")); LOG(logINFO, ("Setting module without trimbits\n"));
} else { } else {
LOG(logINFO, ("Setting module with trimbits\n")); LOG(logINFO, ("Setting module with trimbits\n"));
// includ gap pixels if (setTrimbits(myMod.chanregs, mess) == FAIL) {
unsigned int tt[263680];
int ip = 0, ich = 0;
for (int iy = 0; iy < 256; ++iy) {
for (int ichip = 0; ichip < 4; ++ichip) {
for (int ix = 0; ix < 256; ++ix) {
tt[ip++] = myMod.chanregs[ich++];
}
if (ichip < 3) {
tt[ip++] = 0;
tt[ip++] = 0;
}
}
}
// set trimbits
sharedMemory_lockLocalLink();
// if quad, set M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(1)) {
sharedMemory_unlockLocalLink();
return FAIL; return FAIL;
} }
if (!Feb_Control_SetTrimbits(tt, top)) {
sprintf(mess, "Could not set module. Could not set trimbits\n");
LOG(logERROR, (mess));
setSettings(UNDEFINED);
LOG(logERROR, ("Settings has been changed to undefined (random "
"trim file)\n"));
// if quad, reset M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
sharedMemory_unlockLocalLink();
return FAIL;
}
sharedMemory_unlockLocalLink();
return FAIL;
}
// if quad, reset M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
sharedMemory_unlockLocalLink();
return FAIL;
}
sharedMemory_unlockLocalLink();
} }
#endif #endif
@ -1284,6 +1255,7 @@ enum detectorSettings setSettings(enum detectorSettings sett) {
return thisSettings; return thisSettings;
} }
thisSettings = sett; thisSettings = sett;
detectorModules->reg = sett;
LOG(logINFO, ("Settings: %d\n", thisSettings)); LOG(logINFO, ("Settings: %d\n", thisSettings));
return thisSettings; return thisSettings;
} }
@ -1294,13 +1266,14 @@ enum detectorSettings getSettings() { return thisSettings; }
int getThresholdEnergy() { int getThresholdEnergy() {
LOG(logDEBUG1, ("Getting Threshold energy\n")); LOG(logDEBUG1, ("Getting Threshold energy\n"));
return eiger_photonenergy; return detectorModules->eV[0];
} }
int setThresholdEnergy(int ev) { int setThresholdEnergy(int ev) {
LOG(logINFO, ("Setting threshold energy:%d\n", ev)); LOG(logINFO, ("Setting threshold energy:%d\n", ev));
if (ev >= 0) if (ev >= 0) {
eiger_photonenergy = ev; detectorModules->eV[0] = ev;
}
return getThresholdEnergy(); return getThresholdEnergy();
} }
@ -1910,6 +1883,7 @@ int setIODelay(int val) {
#else #else
eiger_iodelay = val; eiger_iodelay = val;
#endif #endif
detectorModules->iodelay = val;
} }
return eiger_iodelay; return eiger_iodelay;
} }
@ -2153,7 +2127,6 @@ void setDefaultSettingsTau_in_nsec(int t) {
int64_t getCurrentTau() { int64_t getCurrentTau() {
if (!getRateCorrectionEnable()) { if (!getRateCorrectionEnable()) {
eiger_tau_ns = 0; eiger_tau_ns = 0;
return 0;
} else { } else {
#ifndef VIRTUAL #ifndef VIRTUAL
sharedMemory_lockLocalLink(); sharedMemory_lockLocalLink();
@ -2162,8 +2135,9 @@ int64_t getCurrentTau() {
#else #else
eiger_tau_ns = eiger_virtual_ratetable_tau_in_ns; eiger_tau_ns = eiger_virtual_ratetable_tau_in_ns;
#endif #endif
return eiger_tau_ns;
} }
detectorModules->tau = eiger_tau_ns;
return eiger_tau_ns;
} }
void setExternalGating(int enable[]) { void setExternalGating(int enable[]) {
@ -2184,6 +2158,68 @@ void setExternalGating(int enable[]) {
enable[1] = eiger_extgatingpolarity; enable[1] = eiger_extgatingpolarity;
} }
int setTrimbits(int* chanregs, char* mess) {
LOG(logINFO, ("Setting module with trimbits\n"));
#ifndef VIRTUAL
// include gap pixels
unsigned int tt[263680];
int ip = 0, ich = 0;
for (int iy = 0; iy < 256; ++iy) {
for (int ichip = 0; ichip < 4; ++ichip) {
for (int ix = 0; ix < 256; ++ix) {
tt[ip++] = chanregs[ich++];
}
if (ichip < 3) {
tt[ip++] = 0;
tt[ip++] = 0;
}
}
}
// set trimbits
sharedMemory_lockLocalLink();
// if quad, set M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(1)) {
sharedMemory_unlockLocalLink();
return FAIL;
}
if (!Feb_Control_SetTrimbits(tt, top)) {
sprintf(mess, "Could not set module. Could not set trimbits\n");
LOG(logERROR, (mess));
setSettings(UNDEFINED);
LOG(logERROR, ("Settings has been changed to undefined (random "
"trim file)\n"));
// if quad, reset M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
sharedMemory_unlockLocalLink();
return FAIL;
}
sharedMemory_unlockLocalLink();
return FAIL;
}
// if quad, reset M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
sharedMemory_unlockLocalLink();
return FAIL;
}
sharedMemory_unlockLocalLink();
// copying trimbits locally (if tirmbit value > -1)
for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) {
if (*(chanregs + ichan) >= 0)
*((detectorModules->chanregs) + ichan) = *(chanregs + ichan);
}
#endif
return OK;
}
int setAllTrimbits(int val) { int setAllTrimbits(int val) {
LOG(logINFO, ("Setting all trimbits to %d\n", val)); LOG(logINFO, ("Setting all trimbits to %d\n", val));
#ifndef VIRTUAL #ifndef VIRTUAL
@ -2195,6 +2231,8 @@ int setAllTrimbits(int val) {
} }
sharedMemory_unlockLocalLink(); sharedMemory_unlockLocalLink();
#endif #endif
// copying trimbits locally
if (detectorModules) { if (detectorModules) {
for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) { for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) {
*((detectorModules->chanregs) + ichan) = val; *((detectorModules->chanregs) + ichan) = val;
@ -2906,53 +2944,6 @@ void readFrame(int *ret, char *mess) {
/* common */ /* common */
int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
LOG(logDEBUG1, ("Copying module\n"));
if (srcMod->serialnumber >= 0) {
destMod->serialnumber = srcMod->serialnumber;
}
// no trimbit feature
if (destMod->nchan && ((srcMod->nchan) > (destMod->nchan))) {
LOG(logINFO, ("Number of channels of source is larger than number of "
"channels of destination\n"));
return FAIL;
}
if ((srcMod->ndac) > (destMod->ndac)) {
LOG(logINFO, ("Number of dacs of source is larger than number of dacs "
"of destination\n"));
return FAIL;
}
LOG(logDEBUG1, ("DACs: src %d, dest %d\n", srcMod->ndac, destMod->ndac));
LOG(logDEBUG1, ("Chans: src %d, dest %d\n", srcMod->nchan, destMod->nchan));
if (srcMod->reg >= 0)
destMod->reg = srcMod->reg;
if (srcMod->iodelay >= 0)
destMod->iodelay = srcMod->iodelay;
if (srcMod->tau >= 0)
destMod->tau = srcMod->tau;
if (srcMod->eV[0] >= 0)
destMod->eV[0] = srcMod->eV[0];
LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg));
if (destMod->nchan != 0 && srcMod->nchan != 0) {
for (int ichan = 0; ichan < (srcMod->nchan); ichan++) {
if (*((srcMod->chanregs) + ichan) >= 0)
*((destMod->chanregs) + ichan) = *((srcMod->chanregs) + ichan);
}
} else
LOG(logINFO, ("Not Copying trimbits\n"));
for (int idac = 0; idac < (srcMod->ndac); idac++) {
if (*((srcMod->dacs) + idac) >= 0) {
*((destMod->dacs) + idac) = *((srcMod->dacs) + idac);
}
}
return OK;
}
int calculateDataBytes() { int calculateDataBytes() {
if (send_to_ten_gig) if (send_to_ten_gig)
return eiger_dynamicrange * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE; return eiger_dynamicrange * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE;

View File

@ -2297,6 +2297,24 @@ int setClockDivider(enum CLKINDEX ind, int val) {
setPhase(i, oldPhases[i], 1); setPhase(i, oldPhases[i], 1);
} }
} }
// update system frequency and time settings that depend on it
if (ind == SYSTEM_C0) {
LOG(logINFO, ("\tUpdating time settings (sys freq change)\n"));
int64_t exptime = getExpTime();
int64_t period = getPeriod();
int64_t delayAfterTrigger = getDelayAfterTrigger();
int64_t burstPeriod = getBurstPeriod();
systemFrequency = ((double)getVCOFrequency(SYSTEM_C0) /
(double)clkDivider[SYSTEM_C0]);
setExpTime(exptime);
setPeriod(period);
setDelayAfterTrigger(delayAfterTrigger);
setBurstPeriod(burstPeriod);
LOG(logINFO, ("\tDone updating time settings\n"));
}
return OK; return OK;
} }
@ -2798,13 +2816,10 @@ void setTimingSource(enum timingSourceType value) {
case TIMING_INTERNAL: case TIMING_INTERNAL:
LOG(logINFO, ("Setting timing source to internal\n")); LOG(logINFO, ("Setting timing source to internal\n"));
bus_w(addr, (bus_r(addr) & ~CONTROL_TIMING_SOURCE_EXT_MSK)); bus_w(addr, (bus_r(addr) & ~CONTROL_TIMING_SOURCE_EXT_MSK));
systemFrequency = INT_SYSTEM_C0_FREQUENCY;
break; break;
case TIMING_EXTERNAL: case TIMING_EXTERNAL:
LOG(logINFO, ("Setting timing source to exernal\n")); LOG(logINFO, ("Setting timing source to exernal\n"));
bus_w(addr, (bus_r(addr) | CONTROL_TIMING_SOURCE_EXT_MSK)); bus_w(addr, (bus_r(addr) | CONTROL_TIMING_SOURCE_EXT_MSK));
systemFrequency = ((double)getVCOFrequency(SYSTEM_C0) /
(double)clkDivider[SYSTEM_C0]);
break; break;
default: default:
LOG(logERROR, ("Unknown timing source %d\n", value)); LOG(logERROR, ("Unknown timing source %d\n", value));

View File

@ -432,6 +432,8 @@ void setupDetector() {
// roi, gbit readout // roi, gbit readout
rois.xmin = -1; rois.xmin = -1;
rois.xmax = -1; rois.xmax = -1;
rois.ymin = -1;
rois.ymax = -1;
setROI(rois); // set adcsyncreg, daqreg, chipofinterestreg, cleanfifos, setROI(rois); // set adcsyncreg, daqreg, chipofinterestreg, cleanfifos,
setGbitReadout(); setGbitReadout();
@ -857,8 +859,10 @@ int setROI(ROI arg) {
LOG(logINFO, ("Clearing ROI\n")); LOG(logINFO, ("Clearing ROI\n"));
rois.xmin = -1; rois.xmin = -1;
rois.xmax = -1; rois.xmax = -1;
rois.ymin = -1;
rois.ymax = -1;
} else { } else {
LOG(logINFO, ("Setting ROI:(%d, %d)\n", arg.xmin, arg.xmax)); LOG(logINFO, ("Setting ROI:(%d, %d, %d, %d)\n", arg.xmin, arg.xmax, arg.ymin, arg.ymax));
// validation // validation
// xmin divisible by 256 and less than 1280 // xmin divisible by 256 and less than 1280
if (((arg.xmin % NCHAN_PER_ADC) != 0) || if (((arg.xmin % NCHAN_PER_ADC) != 0) ||
@ -892,7 +896,7 @@ ROI getROI() {
if (rois.xmin == -1) { if (rois.xmin == -1) {
LOG(logINFO, ("\tROI: None\n")); LOG(logINFO, ("\tROI: None\n"));
} else { } else {
LOG(logINFO, ("ROI: (%d,%d)\n", rois.xmin, rois.xmax)); LOG(logINFO, ("ROI: (%d,%d,%d,%d)\n", rois.xmin, rois.xmax, rois.ymin, rois.ymax));
} }
return rois; return rois;
} }

View File

@ -25,7 +25,7 @@ target_include_directories(jungfrauDetectorServer_virtual
) )
target_compile_definitions(jungfrauDetectorServer_virtual target_compile_definitions(jungfrauDetectorServer_virtual
PUBLIC JUNGFRAUD VIRTUAL STOP_SERVER PUBLIC JUNGFRAUD VIRTUAL STOP_SERVER #TEST_MOD_GEOMETRY
) )
target_link_libraries(jungfrauDetectorServer_virtual target_link_libraries(jungfrauDetectorServer_virtual

View File

@ -68,6 +68,7 @@ int64_t exptimeReg[NCOUNTERS] = {0, 0, 0};
int64_t gateDelayReg[NCOUNTERS] = {0, 0, 0}; int64_t gateDelayReg[NCOUNTERS] = {0, 0, 0};
int vthEnabledVals[NCOUNTERS] = {0, 0, 0}; int vthEnabledVals[NCOUNTERS] = {0, 0, 0};
int detID = 0; int detID = 0;
int counterMask = 0x0;
int isInitCheckDone() { return initCheckDone; } int isInitCheckDone() { return initCheckDone; }
@ -421,7 +422,7 @@ void allocateDetectorStructureMemory() {
detectorDacs[idac] = 0; detectorDacs[idac] = 0;
} }
// trimbits start at 0 //TODO: restart server will not have 0 always // trimbits start at 0
for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) { for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) {
*((detectorModules->chanregs) + ichan) = 0; *((detectorModules->chanregs) + ichan) = 0;
} }
@ -474,17 +475,19 @@ void setupDetector() {
// defaults // defaults
setHighVoltage(DEFAULT_HIGH_VOLTAGE); setHighVoltage(DEFAULT_HIGH_VOLTAGE);
resetToDefaultDacs(0);
setASICDefaults(); setASICDefaults();
setADIFDefaults(); setADIFDefaults();
// enable all counters before setting dacs (vthx)
setCounterMask(MAX_COUNTER_MSK);
resetToDefaultDacs(0);
// set trigger flow for m3 (for all timing modes) // set trigger flow for m3 (for all timing modes)
bus_w(FLOW_TRIGGER_REG, bus_r(FLOW_TRIGGER_REG) | FLOW_TRIGGER_MSK); bus_w(FLOW_TRIGGER_REG, bus_r(FLOW_TRIGGER_REG) | FLOW_TRIGGER_MSK);
// dynamic range // dynamic range
setDynamicRange(DEFAULT_DYNAMIC_RANGE); setDynamicRange(DEFAULT_DYNAMIC_RANGE);
// enable all counters
setCounterMask(MAX_COUNTER_MSK);
// Initialization of acquistion parameters // Initialization of acquistion parameters
setNumFrames(DEFAULT_NUM_FRAMES); setNumFrames(DEFAULT_NUM_FRAMES);
@ -596,8 +599,8 @@ int resetToDefaultDacs(int hardReset) {
} }
} }
// set to defualt // set to default (last arg to ensure counter check)
setDAC((enum DACINDEX)i, value, 0); setDAC((enum DACINDEX)i, value, 0, 1);
if (detectorDacs[i] != value) { if (detectorDacs[i] != value) {
LOG(logERROR, ("Setting dac %d failed, wrote %d, read %d\n", i, LOG(logERROR, ("Setting dac %d failed, wrote %d, read %d\n", i,
value, detectorDacs[i])); value, detectorDacs[i]));
@ -1087,12 +1090,44 @@ int64_t getGateDelay(int gateIndex) {
return retval / (1E-9 * getFrequency(SYSTEM_C0)); return retval / (1E-9 * getFrequency(SYSTEM_C0));
} }
void updateVthAndCounterMask() {
LOG(logINFO, ("\tUpdating Vth and countermask\n"));
int interpolation = getInterpolation();
int pumpProbe = getPumpProbe();
if (interpolation) {
// enable all counters
setCounterMaskWithUpdateFlag(MAX_COUNTER_MSK, 0);
// disable vth3
setVthDac(2, 0);
} else {
// previous counter values
setCounterMaskWithUpdateFlag(counterMask, 0);
}
if (pumpProbe) {
// enable only vth2
setVthDac(0, 0);
setVthDac(1, 1);
setVthDac(2, 0);
} else {
setVthDac(0, (counterMask & (1 << 0)));
setVthDac(1, (counterMask & (1 << 1)));
}
if (!interpolation && !pumpProbe) {
setVthDac(2, (counterMask & (1 << 2)));
}
}
void setCounterMask(uint32_t arg) { void setCounterMask(uint32_t arg) {
setCounterMaskWithUpdateFlag(arg, 1);
updateVthAndCounterMask();
}
void setCounterMaskWithUpdateFlag(uint32_t arg, int updateMaskFlag) {
if (arg == 0 || arg > MAX_COUNTER_MSK) { if (arg == 0 || arg > MAX_COUNTER_MSK) {
return; return;
} }
uint32_t oldmask = getCounterMask(); LOG(logINFO, ("\tSetting counter mask to 0x%x\n", arg));
LOG(logINFO, ("Setting counter mask to 0x%x\n", arg));
uint32_t addr = CONFIG_REG; uint32_t addr = CONFIG_REG;
bus_w(addr, bus_r(addr) & ~CONFIG_COUNTERS_ENA_MSK); bus_w(addr, bus_r(addr) & ~CONFIG_COUNTERS_ENA_MSK);
bus_w(addr, bus_r(addr) | ((arg << CONFIG_COUNTERS_ENA_OFST) & bus_w(addr, bus_r(addr) | ((arg << CONFIG_COUNTERS_ENA_OFST) &
@ -1108,19 +1143,8 @@ void setCounterMask(uint32_t arg) {
setGateDelay(i, ns); setGateDelay(i, ns);
} }
LOG(logINFO, ("\tUpdating Vth dacs\n")); if (updateMaskFlag) {
enum DACINDEX vthdacs[] = {M_VTH1, M_VTH2, M_VTH3}; counterMask = arg;
for (int i = 0; i < NCOUNTERS; ++i) {
// if change in enable
if ((arg & (1 << i)) ^ (oldmask & (1 << i))) {
// disable, disable value
int value = DEFAULT_COUNTER_DISABLED_VTH_VAL;
// enable, set saved values
if (arg & (1 << i)) {
value = vthEnabledVals[i];
}
setGeneralDAC(vthdacs[i], value, 0);
}
} }
} }
@ -1241,7 +1265,8 @@ int64_t getMeasurementTime() {
int setDACS(int *dacs) { int setDACS(int *dacs) {
for (int i = 0; i < NDAC; ++i) { for (int i = 0; i < NDAC; ++i) {
if (dacs[i] != -1) { if (dacs[i] != -1) {
setDAC((enum DACINDEX)i, dacs[i], 0); // set to default (last arg to ensure counter check)
setDAC((enum DACINDEX)i, dacs[i], 0, 1);
if (dacs[i] != detectorDacs[i]) { if (dacs[i] != detectorDacs[i]) {
// dont complain if that counter was disabled // dont complain if that counter was disabled
if ((i == M_VTH1 || i == M_VTH2 || i == M_VTH3) && if ((i == M_VTH1 || i == M_VTH2 || i == M_VTH3) &&
@ -1255,21 +1280,55 @@ int setDACS(int *dacs) {
return OK; return OK;
} }
void getModule(sls_detector_module* myMod) {
// serial number
myMod->serialnumber = detectorModules->serialnumber;
// csr reg
myMod->reg = detectorModules->reg;
// eV
myMod->eV[0] = detectorModules->eV[0];
myMod->eV[1] = detectorModules->eV[1];
myMod->eV[2] = detectorModules->eV[2];
// dacs
for (int idac = 0; idac < (detectorModules->ndac); idac++) {
*((myMod->dacs) + idac) = *((detectorModules->dacs) + idac);
}
// trimbits
for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) {
*((myMod->chanregs) + ichan) = *((detectorModules->chanregs) + ichan);
}
}
int setModule(sls_detector_module myMod, char *mess) { int setModule(sls_detector_module myMod, char *mess) {
LOG(logINFO, ("Setting module\n")); LOG(logINFO, ("Setting module\n"));
if (((myMod.nchan) > (detectorModules->nchan)) || ((myMod.ndac) > (detectorModules->ndac))) {
strcpy(mess, "Could not set module as the number of channels or dacs do not match to the one in the detector server\n");
LOG(logERROR, (mess));
return FAIL;
}
// serial number (pointless)
detectorModules->serialnumber = myMod.serialnumber;
// csr reg
if (setChipStatusRegister(myMod.reg)) { if (setChipStatusRegister(myMod.reg)) {
sprintf(mess, "Could not CSR from module\n"); sprintf(mess, "Could not CSR from module\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
// dacs
if (setDACS(myMod.dacs)) { if (setDACS(myMod.dacs)) {
sprintf(mess, "Could not set dacs\n"); sprintf(mess, "Could not set dacs\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
// update vth and countermask
updateVthAndCounterMask();
// threshold energy
for (int i = 0; i < NCOUNTERS; ++i) { for (int i = 0; i < NCOUNTERS; ++i) {
if (myMod.eV[i] >= 0) { if (myMod.eV[i] >= 0) {
setThresholdEnergy(i, myMod.eV[i]); setThresholdEnergy(i, myMod.eV[i]);
@ -1300,7 +1359,7 @@ int setTrimbits(int *trimbits) {
uint32_t prevRunClk = clkDivider[SYSTEM_C0]; uint32_t prevRunClk = clkDivider[SYSTEM_C0];
// set to trimming clock // set to trimming clock
if (setClockDivider(SYSTEM_C0, DEFAULT_TRIMMING_RUN_CLKDIV) == FAIL) { if (setClockDividerWithTimeUpdateOption(SYSTEM_C0, DEFAULT_TRIMMING_RUN_CLKDIV, 0) == FAIL) {
LOG(logERROR, LOG(logERROR,
("Could not start trimming. Could not set to trimming clock\n")); ("Could not start trimming. Could not set to trimming clock\n"));
return FAIL; return FAIL;
@ -1333,11 +1392,17 @@ int setTrimbits(int *trimbits) {
} }
// set back to previous clock // set back to previous clock
if (setClockDivider(SYSTEM_C0, prevRunClk) == FAIL) { if (setClockDividerWithTimeUpdateOption(SYSTEM_C0, prevRunClk, 0) == FAIL) {
LOG(logERROR, ("Could not set to previous run clock after trimming\n")); LOG(logERROR, ("Could not set to previous run clock after trimming\n"));
return FAIL; return FAIL;
} }
// copying trimbits locally (if tirmbit value > -1)
for (int ichan = 0; ichan < (detectorModules->nchan); ichan++) {
if (*(trimbits + ichan) >= 0)
*((detectorModules->chanregs) + ichan) = *(trimbits + ichan);
}
return (error ? FAIL : OK); return (error ? FAIL : OK);
} }
@ -1403,7 +1468,8 @@ enum detectorSettings setSettings(enum detectorSettings sett) {
// set special dacs // set special dacs
const int specialDacs[] = SPECIALDACINDEX; const int specialDacs[] = SPECIALDACINDEX;
for (int i = 0; i < NSPECIALDACS; ++i) { for (int i = 0; i < NSPECIALDACS; ++i) {
setDAC(specialDacs[i], dacVals[i], 0); // set to default (last arg to ensure counter check)
setDAC(specialDacs[i], dacVals[i], 0, 1);
} }
LOG(logINFO, ("Settings: %d\n", thisSettings)); LOG(logINFO, ("Settings: %d\n", thisSettings));
@ -1411,6 +1477,9 @@ enum detectorSettings setSettings(enum detectorSettings sett) {
} }
void validateSettings() { void validateSettings() {
LOG(logWARNING, ("Not validating dac settings temporarily"));
return;
// if any special dac value is changed individually => undefined // if any special dac value is changed individually => undefined
const int specialDacs[NSPECIALDACS] = SPECIALDACINDEX; const int specialDacs[NSPECIALDACS] = SPECIALDACINDEX;
int *specialDacValues[] = {defaultDacValue_standard, defaultDacValue_fast, int *specialDacValues[] = {defaultDacValue_standard, defaultDacValue_fast,
@ -1460,7 +1529,8 @@ void setThresholdEnergy(int counterIndex, int eV) {
} }
/* parameters - dac, hv */ /* parameters - dac, hv */
void setDAC(enum DACINDEX ind, int val, int mV) { // counterEnableCheck false only if setDAC called directly
void setDAC(enum DACINDEX ind, int val, int mV, int counterEnableCheck) {
// invalid value // invalid value
if (val < 0) { if (val < 0) {
return; return;
@ -1471,7 +1541,10 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
return; return;
} }
// threshold dacs (remember value, vthreshold: skip disabled) // threshold dacs
// remember value, vthreshold: skip disabled,
// others: disable or enable dac if counter mask
// setDAC called directly: will set independent of counter enable
if (ind == M_VTHRESHOLD || ind == M_VTH1 || ind == M_VTH2 || if (ind == M_VTHRESHOLD || ind == M_VTH1 || ind == M_VTH2 ||
ind == M_VTH3) { ind == M_VTH3) {
char *dac_names[] = {DAC_NAMES}; char *dac_names[] = {DAC_NAMES};
@ -1482,7 +1555,6 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
int dacval = val; int dacval = val;
// if not disabled value, remember value // if not disabled value, remember value
if (dacval != DEFAULT_COUNTER_DISABLED_VTH_VAL) { if (dacval != DEFAULT_COUNTER_DISABLED_VTH_VAL) {
// convert mv to dac
if (mV) { if (mV) {
if (LTC2620_D_VoltageToDac(val, &dacval) == FAIL) { if (LTC2620_D_VoltageToDac(val, &dacval) == FAIL) {
return; return;
@ -1492,9 +1564,16 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
LOG(logINFO, LOG(logINFO,
("Remembering %s [%d]\n", dac_names[ind], dacval)); ("Remembering %s [%d]\n", dac_names[ind], dacval));
} }
// if vthreshold,skip for disabled counters // disabled counter
if ((ind == M_VTHRESHOLD) && (!(counters & (1 << i)))) { if (!(counters & (1 << i))) {
continue; // skip setting vthx dac (value remembered anyway)
if (ind == M_VTHRESHOLD) {
continue;
}
// disable dac (except when setting dac directly)
if (counterEnableCheck) {
val = DEFAULT_COUNTER_DISABLED_VTH_VAL;
}
} }
setGeneralDAC(vthdacs[i], val, mV); setGeneralDAC(vthdacs[i], val, mV);
} }
@ -1535,6 +1614,19 @@ void setGeneralDAC(enum DACINDEX ind, int val, int mV) {
} }
} }
void setVthDac(int index, int enable) {
LOG(logINFO, ("\t%s vth%d\n", (enable ? "Enabling" : "Disabing"), index));
// enables (from remembered values) or disables vthx
enum DACINDEX vthdacs[] = {M_VTH1, M_VTH2, M_VTH3};
// disable value
int value = DEFAULT_COUNTER_DISABLED_VTH_VAL;
// enable, set saved values
if (enable) {
value = vthEnabledVals[index];
}
setGeneralDAC(vthdacs[index], value, 0);
}
int getDAC(enum DACINDEX ind, int mV) { int getDAC(enum DACINDEX ind, int mV) {
if (ind == M_VTHRESHOLD) { if (ind == M_VTHRESHOLD) {
int ret = -1, ret1 = -1; int ret = -1, ret1 = -1;
@ -1698,23 +1790,24 @@ int setGainCaps(int caps) {
int setInterpolation(int enable) { int setInterpolation(int enable) {
LOG(logINFO, LOG(logINFO,
("%s Interpolation\n", enable == 0 ? "Disabling" : "Enabling")); ("%s Interpolation\n", enable == 0 ? "Disabling" : "Enabling"));
if (enable) {
setCounterMask(MAX_COUNTER_MSK);
if (getCounterMask() != MAX_COUNTER_MSK) {
LOG(logERROR,
("Could not set interpolation. Could not enable all counters"));
return FAIL;
}
LOG(logINFO, ("\tEnabled all counters\n"));
}
int csr = M3SetInterpolation(enable); int csr = M3SetInterpolation(enable);
return setChipStatusRegister(csr); int ret = setChipStatusRegister(csr);
if (ret == OK) {
updateVthAndCounterMask();
}
return ret;
} }
int setPumpProbe(int enable) { int setPumpProbe(int enable) {
LOG(logINFO, ("%s Pump Probe\n", enable == 0 ? "Disabling" : "Enabling")); LOG(logINFO, ("%s Pump Probe\n", enable == 0 ? "Disabling" : "Enabling"));
int csr = M3SetPumpProbe(enable); int csr = M3SetPumpProbe(enable);
return setChipStatusRegister(csr); int ret = setChipStatusRegister(csr);
if (ret == OK) {
updateVthAndCounterMask();
}
return ret;
} }
int setDigitalPulsing(int enable) { int setDigitalPulsing(int enable) {
@ -2175,6 +2268,10 @@ int getVCOFrequency(enum CLKINDEX ind) {
int getMaxClockDivider() { return ALTERA_PLL_C10_GetMaxClockDivider(); } int getMaxClockDivider() { return ALTERA_PLL_C10_GetMaxClockDivider(); }
int setClockDivider(enum CLKINDEX ind, int val) { int setClockDivider(enum CLKINDEX ind, int val) {
return setClockDividerWithTimeUpdateOption(ind, val, 1);
}
int setClockDividerWithTimeUpdateOption(enum CLKINDEX ind, int val, int timeUpdate) {
if (ind < 0 || ind >= NUM_CLOCKS) { if (ind < 0 || ind >= NUM_CLOCKS) {
LOG(logERROR, ("Unknown clock index %d to set clock divider\n", ind)); LOG(logERROR, ("Unknown clock index %d to set clock divider\n", ind));
return FAIL; return FAIL;
@ -2199,6 +2296,32 @@ int setClockDivider(enum CLKINDEX ind, int val) {
int pllIndex = (int)(ind >= SYSTEM_C0 ? SYSTEM_PLL : READOUT_PLL); int pllIndex = (int)(ind >= SYSTEM_C0 ? SYSTEM_PLL : READOUT_PLL);
int clkIndex = (int)(ind >= SYSTEM_C0 ? ind - SYSTEM_C0 : ind); int clkIndex = (int)(ind >= SYSTEM_C0 ? ind - SYSTEM_C0 : ind);
ALTERA_PLL_C10_SetOuputClockDivider(pllIndex, clkIndex, val); ALTERA_PLL_C10_SetOuputClockDivider(pllIndex, clkIndex, val);
// Update time settings that depend on system frequency
// timeUpdate = 0 for setChipRegister/setTrimbits etc
// as clk reverted back again
if (timeUpdate && ind == SYSTEM_C0) {
LOG(logINFO, ("\tUpdating time settings (sys freq change)\n"));
int64_t exptime[3] = {0, 0, 0};
int64_t gateDelay[3] = {0, 0, 0};
for (int i = 0; i != 3; ++i) {
exptime[i] = getExpTime(i);
gateDelay[i] = getGateDelay(i);
}
int64_t period = getPeriod();
int64_t delayAfterTrigger = getDelayAfterTrigger();
clkDivider[ind] = val;
for (int i = 0; i != 3; ++i) {
setExpTime(i, exptime[i]);
setGateDelay(i, gateDelay[i]);
}
setPeriod(period);
setDelayAfterTrigger(delayAfterTrigger);
LOG(logINFO, ("\tDone updating time settings\n"));
}
clkDivider[ind] = val; clkDivider[ind] = val;
LOG(logINFO, ("\t%s clock (%d) divider set to %d\n", clock_names[ind], ind, LOG(logINFO, ("\t%s clock (%d) divider set to %d\n", clock_names[ind], ind,
clkDivider[ind])); clkDivider[ind]));
@ -2314,6 +2437,7 @@ void *start_timer(void *arg) {
if (dr == 32 && ncounters > 1) { if (dr == 32 && ncounters > 1) {
packetsPerFrame = 2; packetsPerFrame = 2;
} }
dataSize = imageSize / packetsPerFrame;
} }
// 1g // 1g
else { else {
@ -2335,27 +2459,22 @@ void *start_timer(void *arg) {
{ {
const int nchannels = NCHAN_1_COUNTER * NCHIP * ncounters; const int nchannels = NCHAN_1_COUNTER * NCHIP * ncounters;
switch (dr) { for (int i = 0; i < nchannels; ++i) {
/*case 1: // TODO: Not implemented in firmware yet switch (dr) {
break;*/ //case 1: // TODO: Not implemented in firmware yet
case 8: // break;
for (int i = 0; i < nchannels; ++i) { case 8:
*((uint8_t *)(imageData + i)) = (uint8_t)i; *((uint8_t *)(imageData + i)) = (uint8_t)i;
} break;
break; case 16:
case 16:
for (int i = 0; i < nchannels; ++i) {
*((uint16_t *)(imageData + i * sizeof(uint16_t))) = (uint16_t)i; *((uint16_t *)(imageData + i * sizeof(uint16_t))) = (uint16_t)i;
break;
case 32:
*((uint32_t *)(imageData + i * sizeof(uint32_t))) = ((uint32_t)i & 0xFFFFFF); // 24 bit
break;
default:
break;
} }
break;
case 32:
for (int i = 0; i < nchannels; ++i) {
*((uint32_t *)(imageData + i * sizeof(uint32_t))) =
((uint32_t)i & 0xFFFFFF); // 24 bit
}
break;
default:
break;
} }
} }
@ -2372,7 +2491,8 @@ void *start_timer(void *arg) {
struct timespec begin, end; struct timespec begin, end;
clock_gettime(CLOCK_REALTIME, &begin); clock_gettime(CLOCK_REALTIME, &begin);
usleep(expUs); usleep(expUs);
int srcOffset = 0; int srcOffset = 0;
// loop packet // loop packet
for (int i = 0; i != packetsPerFrame; ++i) { for (int i = 0; i != packetsPerFrame; ++i) {
@ -2393,7 +2513,6 @@ void *start_timer(void *arg) {
memcpy(packetData + sizeof(sls_detector_header), memcpy(packetData + sizeof(sls_detector_header),
imageData + srcOffset, dataSize); imageData + srcOffset, dataSize);
srcOffset += dataSize; srcOffset += dataSize;
sendUDPPacket(0, 0, packetData, packetSize); sendUDPPacket(0, 0, packetData, packetSize);
} }
LOG(logINFO, ("Sent frame: %d [%lld]\n", frameNr, LOG(logINFO, ("Sent frame: %d [%lld]\n", frameNr,
@ -2573,56 +2692,6 @@ u_int32_t runBusy() {
/* common */ /* common */
int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
LOG(logDEBUG1, ("Copying module\n"));
if (srcMod->serialnumber >= 0) {
destMod->serialnumber = srcMod->serialnumber;
}
// no trimbit feature
if (destMod->nchan && ((srcMod->nchan) > (destMod->nchan))) {
LOG(logINFO, ("Number of channels of source is larger than number of "
"channels of destination\n"));
return FAIL;
}
if ((srcMod->ndac) > (destMod->ndac)) {
LOG(logINFO, ("Number of dacs of source is larger than number of dacs "
"of destination\n"));
return FAIL;
}
LOG(logDEBUG1, ("DACs: src %d, dest %d\n", srcMod->ndac, destMod->ndac));
LOG(logDEBUG1, ("Chans: src %d, dest %d\n", srcMod->nchan, destMod->nchan));
if (srcMod->reg >= 0)
destMod->reg = srcMod->reg;
/*
if (srcMod->iodelay >= 0)
destMod->iodelay = srcMod->iodelay;
if (srcMod->tau >= 0)
destMod->tau = srcMod->tau;
*/
for (int i = 0; i < NCOUNTERS; ++i) {
if (srcMod->eV[i] >= 0)
destMod->eV[i] = srcMod->eV[i];
}
LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg));
if (destMod->nchan != 0 && srcMod->nchan != 0) {
for (int ichan = 0; ichan < (srcMod->nchan); ichan++) {
*((destMod->chanregs) + ichan) = *((srcMod->chanregs) + ichan);
}
} else
LOG(logINFO, ("Not Copying trimbits\n"));
for (int idac = 0; idac < (srcMod->ndac); idac++) {
if (*((srcMod->dacs) + idac) >= 0) {
*((destMod->dacs) + idac) = *((srcMod->dacs) + idac);
}
}
return OK;
}
int calculateDataBytes() { int calculateDataBytes() {
int numCounters = __builtin_popcount(getCounterMask()); int numCounters = __builtin_popcount(getCounterMask());
int dr = 0; int dr = 0;
@ -2643,7 +2712,7 @@ int setChipStatusRegister(int csr) {
uint32_t prevRunClk = clkDivider[SYSTEM_C0]; uint32_t prevRunClk = clkDivider[SYSTEM_C0];
// set to trimming clock // set to trimming clock
if (setClockDivider(SYSTEM_C0, DEFAULT_TRIMMING_RUN_CLKDIV) == FAIL) { if (setClockDividerWithTimeUpdateOption(SYSTEM_C0, DEFAULT_TRIMMING_RUN_CLKDIV, 0) == FAIL) {
LOG(logERROR, LOG(logERROR,
("Could not set to trimming clock in order to change CSR\n")); ("Could not set to trimming clock in order to change CSR\n"));
return FAIL; return FAIL;
@ -2665,11 +2734,12 @@ int setChipStatusRegister(int csr) {
} }
// set back to previous clock // set back to previous clock
if (setClockDivider(SYSTEM_C0, prevRunClk) == FAIL) { if (setClockDividerWithTimeUpdateOption(SYSTEM_C0, prevRunClk, 0) == FAIL) {
LOG(logERROR, LOG(logERROR,
("Could not set to previous run clock after changing CSR\n")); ("Could not set to previous run clock after changing CSR\n"));
return FAIL; return FAIL;
} }
detectorModules->reg = csr;
return iret; return iret;
} }

View File

@ -105,7 +105,7 @@ enum DACINDEX {
1220, /* vIpreOut */ \ 1220, /* vIpreOut */ \
2800, /* Vth3 */ \ 2800, /* Vth3 */ \
2800, /* Vth1 */ \ 2800, /* Vth1 */ \
1708, /* vIcin */ \ 800, /* vIcin */ \
1800, /* cas */ \ 1800, /* cas */ \
1100, /* Vrpreamp */ \ 1100, /* Vrpreamp */ \
1100, /* Vcal_n */ \ 1100, /* Vcal_n */ \

View File

@ -26,6 +26,7 @@ int receiveData(int file_des, void *buf, int length, intType itype);
int sendDataOnly(int file_des, void *buf, int length); int sendDataOnly(int file_des, void *buf, int length);
int receiveDataOnly(int file_des, void *buf, int length); int receiveDataOnly(int file_des, void *buf, int length);
int sendModule(int file_des, sls_detector_module *myMod);
int receiveModule(int file_des, sls_detector_module *myMod); int receiveModule(int file_des, sls_detector_module *myMod);
/** /**

View File

@ -11,8 +11,8 @@
#define BLACKFIN_DEFINED #define BLACKFIN_DEFINED
int defineGPIOpins(char *mess); int defineGPIOpins(char *mess);
int FPGAdontTouchFlash(char *mess); int FPGAdontTouchFlash(char *mess, int programming);
int FPGATouchFlash(char *mess); int FPGATouchFlash(char *mess, int programming);
int resetFPGA(char *mess); int resetFPGA(char *mess);
int emptyTempFolder(char *mess); int emptyTempFolder(char *mess);

View File

@ -281,6 +281,7 @@ int getNumDigitalSamples();
#endif #endif
#ifdef MYTHEN3D #ifdef MYTHEN3D
void setCounterMask(uint32_t arg); void setCounterMask(uint32_t arg);
void setCounterMaskWithUpdateFlag(uint32_t arg, int updateMaskFlag);
uint32_t getCounterMask(); uint32_t getCounterMask();
void updatePacketizing(); void updatePacketizing();
#endif #endif
@ -308,9 +309,16 @@ int64_t getMeasurementTime();
#endif #endif
// parameters - module, settings // parameters - module, settings
#if defined(MYTHEN3D) || defined(EIGERD)
void getModule(sls_detector_module* myMod);
#endif
#if (!defined(CHIPTESTBOARDD)) && (!defined(MOENCHD)) && (!defined(GOTTHARD2D)) #if (!defined(CHIPTESTBOARDD)) && (!defined(MOENCHD)) && (!defined(GOTTHARD2D))
int setModule(sls_detector_module myMod, char *mess); int setModule(sls_detector_module myMod, char *mess);
#endif #endif
#ifdef EIGERD
int setTrimbits(int* chanregs, char* mess);
#endif
#ifdef MYTHEN3D #ifdef MYTHEN3D
int setTrimbits(int *trimbits); int setTrimbits(int *trimbits);
int setAllTrimbits(int val); int setAllTrimbits(int val);
@ -340,9 +348,12 @@ void setThresholdEnergy(int counterIndex, int eV);
int setOnChipDAC(enum ONCHIP_DACINDEX ind, int chipIndex, int val); int setOnChipDAC(enum ONCHIP_DACINDEX ind, int chipIndex, int val);
int getOnChipDAC(enum ONCHIP_DACINDEX ind, int chipIndex); int getOnChipDAC(enum ONCHIP_DACINDEX ind, int chipIndex);
#endif #endif
void setDAC(enum DACINDEX ind, int val, int mV);
#ifdef MYTHEN3D #ifdef MYTHEN3D
void setDAC(enum DACINDEX ind, int val, int mV, int counterEnableCheck);
void setGeneralDAC(enum DACINDEX ind, int val, int mV); void setGeneralDAC(enum DACINDEX ind, int val, int mV);
void setVthDac(int index, int enable);
#else
void setDAC(enum DACINDEX ind, int val, int mV);
#endif #endif
int getDAC(enum DACINDEX ind, int mV); int getDAC(enum DACINDEX ind, int mV);
int getMaxDacSteps(); int getMaxDacSteps();
@ -558,6 +569,7 @@ int getFrequency(enum CLKINDEX ind);
int getVCOFrequency(enum CLKINDEX ind); int getVCOFrequency(enum CLKINDEX ind);
int getMaxClockDivider(); int getMaxClockDivider();
int setClockDivider(enum CLKINDEX ind, int val); int setClockDivider(enum CLKINDEX ind, int val);
int setClockDividerWithTimeUpdateOption(enum CLKINDEX ind, int val, int timeUpdate);
int getClockDivider(enum CLKINDEX ind); int getClockDivider(enum CLKINDEX ind);
#elif GOTTHARD2D #elif GOTTHARD2D
@ -662,9 +674,6 @@ u_int32_t runState(enum TLogLevel lev);
#endif #endif
// common // common
#if defined(EIGERD) || defined(MYTHEN3D)
int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod);
#endif
int calculateDataBytes(); int calculateDataBytes();
int getTotalNumberOfChannels(); int getTotalNumberOfChannels();
#if defined(MOENCHD) || defined(CHIPTESTBOARDD) #if defined(MOENCHD) || defined(CHIPTESTBOARDD)

View File

@ -303,3 +303,4 @@ int get_analog_pulsing(int);
int set_analog_pulsing(int); int set_analog_pulsing(int);
int get_digital_pulsing(int); int get_digital_pulsing(int);
int set_digital_pulsing(int); int set_digital_pulsing(int);
int get_module(int);

View File

@ -406,66 +406,139 @@ int receiveDataOnly(int file_des, void *buf, int length) {
return total_received; return total_received;
} }
int sendModule(int file_des, sls_detector_module *myMod) {
enum TLogLevel level = logDEBUG1;
LOG(level, ("Sending Module\n"));
int ts = 0, n = 0;
n = sendData(file_des, &(myMod->serialnumber),
sizeof(myMod->serialnumber), INT32);
if (!n) {
return -1;
}
ts += n;
LOG(level, ("serialno sent %d bytes. serialno: %d\n", n,
myMod->serialnumber));
n = sendData(file_des, &(myMod->nchan), sizeof(myMod->nchan), INT32);
if (!n) {
return -1;
}
ts += n;
LOG(level, ("nchan sent %d bytes. nchan: %d\n", n, myMod->nchan));
n = sendData(file_des, &(myMod->nchip), sizeof(myMod->nchip), INT32);
if (!n) {
return -1;
}
ts += n;
LOG(level, ("nchip sent %d bytes. nchip: %d\n", n, myMod->nchip));
n = sendData(file_des, &(myMod->ndac), sizeof(myMod->ndac), INT32);
if (!n) {
return -1;
}
ts += n;
LOG(level, ("ndac sent %d bytes. ndac: %d\n", n, myMod->ndac));
n = sendData(file_des, &(myMod->reg), sizeof(myMod->reg), INT32);
if (!n) {
return -1;
}
ts += n;
LOG(level, ("reg sent %d bytes. reg: %d\n", n, myMod->reg));
n = sendData(file_des, &(myMod->iodelay), sizeof(myMod->iodelay), INT32);
if (!n) {
return -1;
}
ts += n;
LOG(level,
("iodelay sent %d bytes. iodelay: %d\n", n, myMod->iodelay));
n = sendData(file_des, &(myMod->tau), sizeof(myMod->tau), INT32);
if (!n) {
return -1;
}
ts += n;
LOG(level, ("tau sent %d bytes. tau: %d\n", n, myMod->tau));
n = sendData(file_des, myMod->eV, sizeof(myMod->eV), INT32);
if (!n) {
return -1;
}
ts += n;
LOG(level, ("eV sent %d bytes. eV: %d\n", n, myMod->eV[0]));
// dacs
n = sendData(file_des, myMod->dacs, sizeof(int) * (myMod->ndac), INT32);
if (!n) {
return -1;
}
ts += n;
LOG(level, ("dacs sent %d bytes.\n", n));
// channels
n = sendData(file_des, myMod->chanregs, sizeof(int) * (myMod->nchan),
INT32);
LOG(level, ("chanregs sent %d bytes.\n", n));
if (!n) {
return -1;
}
ts += n;
LOG(level, ("received module of size %d register %x\n", ts, myMod->reg));
return ts;
}
int receiveModule(int file_des, sls_detector_module *myMod) { int receiveModule(int file_des, sls_detector_module *myMod) {
enum TLogLevel level = logDEBUG1; enum TLogLevel level = logDEBUG1;
LOG(level, ("Receiving Module\n")); LOG(level, ("Receiving Module\n"));
int ts = 0, n = 0; int ts = 0, n = 0;
int nDacs = myMod->ndac; int nDacs = myMod->ndac;
#if defined(EIGERD) || defined(MYTHEN3D)
int nChans = myMod->nchan; // can be zero for no trimbits int nChans = myMod->nchan; // can be zero for no trimbits
LOG(level, ("nChans: %d\n", nChans)); LOG(level, ("nChans: %d\n", nChans));
#endif
n = receiveData(file_des, &(myMod->serialnumber), n = receiveData(file_des, &(myMod->serialnumber),
sizeof(myMod->serialnumber), INT32); sizeof(myMod->serialnumber), INT32);
if (!n) { if (!n) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, ("serialno received. %d bytes. serialno: %d\n", n, LOG(level, ("serialno received %d bytes. serialno: %d\n", n,
myMod->serialnumber)); myMod->serialnumber));
n = receiveData(file_des, &(myMod->nchan), sizeof(myMod->nchan), INT32); n = receiveData(file_des, &(myMod->nchan), sizeof(myMod->nchan), INT32);
if (!n) { if (!n) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, ("nchan received. %d bytes. nchan: %d\n", n, myMod->nchan)); LOG(level, ("nchan received %d bytes. nchan: %d\n", n, myMod->nchan));
n = receiveData(file_des, &(myMod->nchip), sizeof(myMod->nchip), INT32); n = receiveData(file_des, &(myMod->nchip), sizeof(myMod->nchip), INT32);
if (!n) { if (!n) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, ("nchip received. %d bytes. nchip: %d\n", n, myMod->nchip)); LOG(level, ("nchip received %d bytes. nchip: %d\n", n, myMod->nchip));
n = receiveData(file_des, &(myMod->ndac), sizeof(myMod->ndac), INT32); n = receiveData(file_des, &(myMod->ndac), sizeof(myMod->ndac), INT32);
if (!n) { if (!n) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, ("ndac received. %d bytes. ndac: %d\n", n, myMod->ndac)); LOG(level, ("ndac received %d bytes. ndac: %d\n", n, myMod->ndac));
n = receiveData(file_des, &(myMod->reg), sizeof(myMod->reg), INT32); n = receiveData(file_des, &(myMod->reg), sizeof(myMod->reg), INT32);
if (!n) { if (!n) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, ("reg received. %d bytes. reg: %d\n", n, myMod->reg)); LOG(level, ("reg received %d bytes. reg: %d\n", n, myMod->reg));
n = receiveData(file_des, &(myMod->iodelay), sizeof(myMod->iodelay), INT32); n = receiveData(file_des, &(myMod->iodelay), sizeof(myMod->iodelay), INT32);
if (!n) { if (!n) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, LOG(level,
("iodelay received. %d bytes. iodelay: %d\n", n, myMod->iodelay)); ("iodelay received %d bytes. iodelay: %d\n", n, myMod->iodelay));
n = receiveData(file_des, &(myMod->tau), sizeof(myMod->tau), INT32); n = receiveData(file_des, &(myMod->tau), sizeof(myMod->tau), INT32);
if (!n) { if (!n) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, ("tau received. %d bytes. tau: %d\n", n, myMod->tau)); LOG(level, ("tau received %d bytes. tau: %d\n", n, myMod->tau));
n = receiveData(file_des, myMod->eV, sizeof(myMod->eV), INT32); n = receiveData(file_des, myMod->eV, sizeof(myMod->eV), INT32);
if (!n) { if (!n) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, ("eV received. %d bytes. eV: %d\n", n, myMod->eV[0])); LOG(level, ("eV received %d bytes. eV: %d\n", n, myMod->eV[0]));
// dacs // dacs
if (nDacs != (myMod->ndac)) { if (nDacs != (myMod->ndac)) {
LOG(logERROR, ("received wrong number of dacs. " LOG(logERROR, ("received wrong number of dacs. "
@ -478,24 +551,22 @@ int receiveModule(int file_des, sls_detector_module *myMod) {
return -1; return -1;
} }
ts += n; ts += n;
LOG(level, ("dacs received. %d bytes.\n", n)); LOG(level, ("dacs received %d bytes.\n", n));
// channels // channels
#if defined(EIGERD) || defined(MYTHEN3D)
if (((myMod->nchan) != 0) && // no trimbits if (((myMod->nchan) != 0) && // no trimbits
(nChans != (myMod->nchan))) { // with trimbits (nChans != (myMod->nchan))) { // with trimbits
LOG(logERROR, ("received wrong number of channels. " LOG(logERROR, ("received wrong number of channels. "
"Expected %d, got %d\n", "Expected %d, got %d\n",
nChans, (myMod->nchan))); nChans, (myMod->nchan)));
return 0; return -1;
} }
n = receiveData(file_des, myMod->chanregs, sizeof(int) * (myMod->nchan), n = receiveData(file_des, myMod->chanregs, sizeof(int) * (myMod->nchan),
INT32); INT32);
LOG(level, ("chanregs received. %d bytes.\n", n)); LOG(level, ("chanregs received %d bytes.\n", n));
if (!n && myMod->nchan != 0) { if (!n && myMod->nchan != 0) {
return -1; return -1;
} }
ts += n; ts += n;
#endif
LOG(level, ("received module of size %d register %x\n", ts, myMod->reg)); LOG(level, ("received module of size %d register %x\n", ts, myMod->reg));
return ts; return ts;
} }

View File

@ -19,8 +19,11 @@
#define CMD_GPIO9_DEFINE "echo 9 > /sys/class/gpio/export" #define CMD_GPIO9_DEFINE "echo 9 > /sys/class/gpio/export"
#define CMD_GPIO3_DEFINE "echo 3 > /sys/class/gpio/export" #define CMD_GPIO3_DEFINE "echo 3 > /sys/class/gpio/export"
// N config done
#define CMD_GPIO7_EXIST "/sys/class/gpio/gpio7" #define CMD_GPIO7_EXIST "/sys/class/gpio/gpio7"
// N Config
#define CMD_GPIO9_EXIST "/sys/class/gpio/gpio9" #define CMD_GPIO9_EXIST "/sys/class/gpio/gpio9"
// N CE (access to AS interface)
#define CMD_GPIO3_EXIST "/sys/class/gpio/gpio3" #define CMD_GPIO3_EXIST "/sys/class/gpio/gpio3"
#define CMD_GPIO9_DEFINE_OUT "echo out > /sys/class/gpio/gpio9/direction" #define CMD_GPIO9_DEFINE_OUT "echo out > /sys/class/gpio/gpio9/direction"
@ -29,8 +32,11 @@
#define CMD_GPIO9_DEFINE_IN "echo in > /sys/class/gpio/gpio9/direction" #define CMD_GPIO9_DEFINE_IN "echo in > /sys/class/gpio/gpio9/direction"
#define CMD_GPIO3_DEFINE_IN "echo in > /sys/class/gpio/gpio3/direction" #define CMD_GPIO3_DEFINE_IN "echo in > /sys/class/gpio/gpio3/direction"
// nConfig
#define CMD_GPIO9_DONT_TOUCH_FLASH "echo 0 > /sys/class/gpio/gpio9/value" #define CMD_GPIO9_DONT_TOUCH_FLASH "echo 0 > /sys/class/gpio/gpio9/value"
#define CMD_GPIO3_DONT_TOUCH_FLASH "echo 0 > /sys/class/gpio/gpio3/value" // nCE
#define CMD_GPIO3_DONT_TOUCH_FLASH "echo 1 > /sys/class/gpio/gpio3/value"
// CD
#define CMD_FPGA_PICKED_STATUS "cat /sys/class/gpio/gpio7/value" #define CMD_FPGA_PICKED_STATUS "cat /sys/class/gpio/gpio7/value"
#define CMD_GET_FPGA_FLASH_DRIVE "awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd" #define CMD_GET_FPGA_FLASH_DRIVE "awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd"
@ -69,7 +75,7 @@ int defineGPIOpins(char *mess) {
if (FAIL == validateKernelVersion(KERNEL_DATE_VRSN_3GPIO)) { if (FAIL == validateKernelVersion(KERNEL_DATE_VRSN_3GPIO)) {
latestKernelVerified = 0; latestKernelVerified = 0;
LOG(logWARNING, LOG(logWARNING,
("Kernel too old to use gpio 3 pins. Update kernel to " ("Kernel too old to use gpio3 (nCE). Update kernel to "
"guarantee error-free fpga programming. \n\tNot the end " "guarantee error-free fpga programming. \n\tNot the end "
"of the world. Continuing with current kernel...\n")); "of the world. Continuing with current kernel...\n"));
} else { } else {
@ -82,35 +88,35 @@ int defineGPIOpins(char *mess) {
if (access(CMD_GPIO7_EXIST, F_OK) != 0) { if (access(CMD_GPIO7_EXIST, F_OK) != 0) {
if (executeCommand(CMD_GPIO7_DEFINE, retvals, logDEBUG1) == FAIL) { if (executeCommand(CMD_GPIO7_DEFINE, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not define gpio7 pins for fpga (%s)\n", retvals); "Could not define gpio7 (CD) for fpga (%s)\n", retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio7: defined\n")); LOG(logINFO, ("\tgpio7 (CD): defined\n"));
} else { } else {
LOG(logINFO, ("\tgpio7: already defined\n")); LOG(logINFO, ("\tgpio7 (CD): already defined\n"));
} }
// define gpio7 direction // define gpio7 direction
if (executeCommand(CMD_GPIO7_DEFINE_IN, retvals, logDEBUG1) == FAIL) { if (executeCommand(CMD_GPIO7_DEFINE_IN, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio7 as input for fpga (%s)\n", retvals); "Could not set gpio7 (CD) as input for fpga (%s)\n", retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio7: setting intput\n")); LOG(logINFO, ("\tgpio7 (CD): setting intput\n"));
// define gpio9 // define gpio9
if (access(CMD_GPIO9_EXIST, F_OK) != 0) { if (access(CMD_GPIO9_EXIST, F_OK) != 0) {
if (executeCommand(CMD_GPIO9_DEFINE, retvals, logDEBUG1) == FAIL) { if (executeCommand(CMD_GPIO9_DEFINE, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not define gpio9 pins for fpga (%s)\n", retvals); "Could not define gpio9 (nConfig) for fpga (%s)\n", retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio9: defined\n")); LOG(logINFO, ("\tgpio9 (nConfig): defined\n"));
} else { } else {
LOG(logINFO, ("\tgpio9: already defined\n")); LOG(logINFO, ("\tgpio9 (nConfig): already defined\n"));
} }
// define gpio3 (not chip enable) // define gpio3 (not chip enable)
@ -118,21 +124,21 @@ int defineGPIOpins(char *mess) {
if (access(CMD_GPIO3_EXIST, F_OK) != 0) { if (access(CMD_GPIO3_EXIST, F_OK) != 0) {
if (executeCommand(CMD_GPIO3_DEFINE, retvals, logDEBUG1) == FAIL) { if (executeCommand(CMD_GPIO3_DEFINE, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not define gpio3 pins for fpga (%s)\n", "Could not define gpio3 (nCE) for fpga (%s)\n",
retvals); retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio3: defined\n")); LOG(logINFO, ("\tgpio3 (nCE): defined\n"));
} else { } else {
LOG(logINFO, ("\tgpio3: already defined\n")); LOG(logINFO, ("\tgpio3 (nCE): already defined\n"));
} }
} }
return OK; return OK;
} }
int FPGAdontTouchFlash(char *mess) { int FPGAdontTouchFlash(char *mess, int programming) {
#ifdef VIRTUAL #ifdef VIRTUAL
return OK; return OK;
#endif #endif
@ -140,51 +146,51 @@ int FPGAdontTouchFlash(char *mess) {
// define gpio9 as output // define gpio9 as output
if (executeCommand(CMD_GPIO9_DEFINE_OUT, retvals, logDEBUG1) == FAIL) { if (executeCommand(CMD_GPIO9_DEFINE_OUT, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio9 as output for fpga (%s)\n", retvals); "Could not set gpio9 (nConfig) as output for fpga (%s)\n", retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio9: setting output\n")); LOG(logINFO, ("\tgpio9 (nConfig): setting output\n"));
// define gpio3 as output // define gpio3 as output
if (latestKernelVerified == 1) { if (programming && latestKernelVerified == 1) {
if (executeCommand(CMD_GPIO3_DEFINE_OUT, retvals, logDEBUG1) == FAIL) { if (executeCommand(CMD_GPIO3_DEFINE_OUT, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio3 as output for fpga (%s)\n", retvals); "Could not set gpio3 (nCE) as output for fpga (%s)\n", retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio3: setting output\n")); LOG(logINFO, ("\tgpio3 (nCE): setting output\n"));
} }
// tell FPGA to not: gpio9 // tell FPGA to not: gpio9
if (executeCommand(CMD_GPIO9_DONT_TOUCH_FLASH, retvals, logDEBUG1) == if (executeCommand(CMD_GPIO9_DONT_TOUCH_FLASH, retvals, logDEBUG1) ==
FAIL) { FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio9 to not touch flash for fpga (%s)\n", "Could not set gpio9 (nConfig) to not touch flash for fpga (%s)\n",
retvals); retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio9: fpga dont touch flash\n")); LOG(logINFO, ("\tgpio9 (nConfig): fpga dont touch flash (Low)\n"));
// tell FPGA to not: gpio3 // tell FPGA to not: gpio3
if (latestKernelVerified == 1) { if (programming && latestKernelVerified == 1) {
if (executeCommand(CMD_GPIO3_DONT_TOUCH_FLASH, retvals, logDEBUG1) == if (executeCommand(CMD_GPIO3_DONT_TOUCH_FLASH, retvals, logDEBUG1) ==
FAIL) { FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio3 to not touch flash for fpga (%s)\n", "Could not set gpio3 (nCE) to not touch flash for fpga (%s)\n",
retvals); retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio3: fpga dont touch flash\n")); LOG(logINFO, ("\tgpio3 (nCE): fpga dont touch flash (High)\n"));
} }
// usleep(100*1000); // usleep(100*1000);
return OK; return OK;
} }
int FPGATouchFlash(char *mess) { int FPGATouchFlash(char *mess, int programming) {
#ifdef VIRTUAL #ifdef VIRTUAL
return OK; return OK;
#endif #endif
@ -192,20 +198,20 @@ int FPGATouchFlash(char *mess) {
// tell FPGA to touch flash to program itself // tell FPGA to touch flash to program itself
if (executeCommand(CMD_GPIO9_DEFINE_IN, retvals, logDEBUG1) == FAIL) { if (executeCommand(CMD_GPIO9_DEFINE_IN, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio9 as input for fpga (%s)\n", retvals); "Could not set gpio9 (nConfig) as input for fpga (%s)\n", retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio9: setting input\n")); LOG(logINFO, ("\tgpio9 (nConfig): setting input\n"));
if (latestKernelVerified == 1) { if (programming && latestKernelVerified == 1) {
if (executeCommand(CMD_GPIO3_DEFINE_IN, retvals, logDEBUG1) == FAIL) { if (executeCommand(CMD_GPIO3_DEFINE_IN, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio3 as input for fpga (%s)\n", retvals); "Could not set gpio3 (nCE) as input for fpga (%s)\n", retvals);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tgpio3: setting input\n")); LOG(logINFO, ("\tgpio3 (nCE): setting input\n"));
} }
return OK; return OK;
} }
@ -215,10 +221,10 @@ int resetFPGA(char *mess) {
#ifdef VIRTUAL #ifdef VIRTUAL
return OK; return OK;
#endif #endif
if (FPGAdontTouchFlash(mess) == FAIL) { if (FPGAdontTouchFlash(mess, 0) == FAIL) {
return FAIL; return FAIL;
} }
if (FPGATouchFlash(mess) == FAIL) { if (FPGATouchFlash(mess, 0) == FAIL) {
return FAIL; return FAIL;
} }
usleep(CTRL_SRVR_INIT_TIME_US); usleep(CTRL_SRVR_INIT_TIME_US);
@ -341,7 +347,7 @@ int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index,
} }
if (index == PROGRAM_FPGA) { if (index == PROGRAM_FPGA) {
if (FPGAdontTouchFlash(mess) == FAIL) { if (FPGAdontTouchFlash(mess, 1) == FAIL) {
return FAIL; return FAIL;
} }
} }
@ -665,14 +671,14 @@ int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, FILE *srcfd) {
int waitForFPGAtoTouchFlash(char *mess) { int waitForFPGAtoTouchFlash(char *mess) {
// touch and program // touch and program
if (FPGATouchFlash(mess) == FAIL) { if (FPGATouchFlash(mess, 1) == FAIL) {
return FAIL; return FAIL;
} }
#ifdef VIRTUAL #ifdef VIRTUAL
return OK; return OK;
#endif #endif
LOG(logINFO, ("\tWaiting for FPGA to program from flash\n")); LOG(logINFO, ("\tWaiting for FPGA to program from flash... \n\t[gpio7 (CD) should be High when done]\n"));
int timeSpent = 0; int timeSpent = 0;
int result = 0; int result = 0;
@ -710,8 +716,8 @@ int waitForFPGAtoTouchFlash(char *mess) {
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logDEBUG1, ("gpi07 returned %d\n", result)); LOG(logDEBUG1, ("gpi07 (CD)returned %d\n", result));
} }
LOG(logINFO, ("\tFPGA has picked up the program from flash\n")); LOG(logINFO, ("\tFPGA has picked up the program from flash. gpio7 (CD) is High\n"));
return OK; return OK;
} }

View File

@ -468,6 +468,7 @@ void function_table() {
flist[F_SET_ANALOG_PULSING] = &set_analog_pulsing; flist[F_SET_ANALOG_PULSING] = &set_analog_pulsing;
flist[F_GET_DIGITAL_PULSING] = &get_digital_pulsing; flist[F_GET_DIGITAL_PULSING] = &get_digital_pulsing;
flist[F_SET_DIGITAL_PULSING] = &set_digital_pulsing; flist[F_SET_DIGITAL_PULSING] = &set_digital_pulsing;
flist[F_GET_MODULE] = &get_module;
// check // check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
@ -1287,7 +1288,12 @@ int validateAndSetDac(enum dacIndex ind, int val, int mV) {
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else } else
#endif #endif
#ifdef MYTHEN3D
// ignore counter enable to force vth dac values
setDAC(serverDacIndex, val, mV, 0);
#else
setDAC(serverDacIndex, val, mV); setDAC(serverDacIndex, val, mV);
#endif
retval = getDAC(serverDacIndex, mV); retval = getDAC(serverDacIndex, mV);
} }
#ifdef EIGERD #ifdef EIGERD
@ -1555,6 +1561,71 @@ int read_register(int file_des) {
return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
} }
int get_module(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
sls_detector_module module;
int *myDac = NULL;
int *myChan = NULL;
module.dacs = NULL;
module.chanregs = NULL;
#if !defined(MYTHEN3D) && !defined(EIGERD)
functionNotImplemented();
#else
// allocate to receive module structure
// allocate dacs
myDac = malloc(getNumberOfDACs() * sizeof(int));
// error
if (getNumberOfDACs() > 0 && myDac == NULL) {
ret = FAIL;
sprintf(mess, "Could not allocate dacs\n");
LOG(logERROR, (mess));
} else
module.dacs = myDac;
// allocate chans
if (ret == OK) {
myChan = malloc(getTotalNumberOfChannels() * sizeof(int));
if (getTotalNumberOfChannels() > 0 && myChan == NULL) {
ret = FAIL;
sprintf(mess, "Could not allocate chans\n");
LOG(logERROR, (mess));
} else
module.chanregs = myChan;
}
// receive module structure
if (ret == OK) {
module.nchip = getNumberOfChips();
module.nchan = getTotalNumberOfChannels();
module.ndac = getNumberOfDACs();
// ensure nchan is not 0, else trimbits not copied
if (module.nchan == 0) {
strcpy(mess, "Could not get module as the number of channels to copy is 0\n");
LOG(logERROR, (mess));
return FAIL;
}
getModule(&module);
}
#endif
Server_SendResult(file_des, INT32, NULL, 0);
if (ret != FAIL) {
if (sendModule(file_des, &module) < 0) {
ret = FAIL;
}
}
if (myChan != NULL)
free(myChan);
if (myDac != NULL)
free(myDac);
return ret;
}
int set_module(int file_des) { int set_module(int file_des) {
ret = OK; ret = OK;
memset(mess, 0, sizeof(mess)); memset(mess, 0, sizeof(mess));
@ -1631,8 +1702,10 @@ int set_module(int file_des) {
#endif #endif
LOG(logDEBUG1, ("Settings: %d\n", retval)); LOG(logDEBUG1, ("Settings: %d\n", retval));
} }
free(myChan); if (myChan != NULL)
free(myDac); free(myChan);
if (myDac != NULL)
free(myDac);
#endif #endif
return Server_SendResult(file_des, INT32, NULL, 0); return Server_SendResult(file_des, INT32, NULL, 0);
@ -2045,7 +2118,7 @@ int set_num_frames(int file_des) {
arg > MAX_FRAMES_IN_BURST_MODE) { arg > MAX_FRAMES_IN_BURST_MODE) {
ret = FAIL; ret = FAIL;
sprintf(mess, sprintf(mess,
"Could not set number of frames %lld. Must be <= %d in " "Could not set number of frames %lld. Must be less than equal to %d in "
"burst mode.\n", "burst mode.\n",
(long long unsigned int)arg, MAX_FRAMES_IN_BURST_MODE); (long long unsigned int)arg, MAX_FRAMES_IN_BURST_MODE);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
@ -2863,7 +2936,12 @@ int set_roi(int file_des) {
return printSocketReadError(); return printSocketReadError();
if (receiveData(file_des, &arg.xmax, sizeof(int), INT32) < 0) if (receiveData(file_des, &arg.xmax, sizeof(int), INT32) < 0)
return printSocketReadError(); return printSocketReadError();
LOG(logDEBUG1, ("Set ROI: [%d, %d]\n", arg.xmin, arg.xmax)); if (receiveData(file_des, &arg.ymin, sizeof(int), INT32) < 0)
return printSocketReadError();
if (receiveData(file_des, &arg.ymax, sizeof(int), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Set ROI: [%d, %d, %d, %d]\n", arg.xmin, arg.xmax, arg.ymin,
arg.ymax));
#ifndef GOTTHARDD #ifndef GOTTHARDD
functionNotImplemented(); functionNotImplemented();
@ -2895,13 +2973,16 @@ int get_roi(int file_des) {
#else #else
// only get // only get
retval = getROI(); retval = getROI();
LOG(logDEBUG1, ("nRois: (%d, %d)\n", retval.xmin, retval.xmax)); LOG(logDEBUG1, ("nRois: (%d, %d, %d, %d)\n", retval.xmin, retval.xmax,
retval.ymin, retval.ymax));
#endif #endif
Server_SendResult(file_des, INT32, NULL, 0); Server_SendResult(file_des, INT32, NULL, 0);
if (ret != FAIL) { if (ret != FAIL) {
sendData(file_des, &retval.xmin, sizeof(int), INT32); sendData(file_des, &retval.xmin, sizeof(int), INT32);
sendData(file_des, &retval.xmax, sizeof(int), INT32); sendData(file_des, &retval.xmax, sizeof(int), INT32);
sendData(file_des, &retval.ymin, sizeof(int), INT32);
sendData(file_des, &retval.ymax, sizeof(int), INT32);
} }
return ret; return ret;
} }
@ -7134,6 +7215,8 @@ int get_receiver_parameters(int file_des) {
#else #else
roi.xmin = -1; roi.xmin = -1;
roi.xmax = -1; roi.xmax = -1;
roi.ymin = -1;
roi.ymax = -1;
#endif #endif
n += sendData(file_des, &roi.xmin, sizeof(int), INT32); n += sendData(file_des, &roi.xmin, sizeof(int), INT32);
if (n < 0) if (n < 0)
@ -7141,6 +7224,12 @@ int get_receiver_parameters(int file_des) {
n += sendData(file_des, &roi.xmax, sizeof(int), INT32); n += sendData(file_des, &roi.xmax, sizeof(int), INT32);
if (n < 0) if (n < 0)
return printSocketReadError(); return printSocketReadError();
n += sendData(file_des, &roi.ymin, sizeof(int), INT32);
if (n < 0)
return printSocketReadError();
n += sendData(file_des, &roi.ymax, sizeof(int), INT32);
if (n < 0)
return printSocketReadError();
} }
// counter mask // counter mask
@ -9860,19 +9949,25 @@ int set_interpolation(int file_des) {
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
ret = setInterpolation(arg); if (getPumpProbe() && arg) {
if (ret == FAIL) { ret = FAIL;
if (arg) sprintf(mess, "Could not set interpolation. Disable pump probe mode first.\n");
sprintf(mess, "Could not set interpolation or enable all "
"counters for it.\n");
else
sprintf(mess, "Could not set interpolation\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else { } else {
int retval = getInterpolation(); ret = setInterpolation(arg);
validate(&ret, mess, (int)arg, (int)retval, "set interpolation", if (ret == FAIL) {
DEC); if (arg)
LOG(logDEBUG1, ("interpolation retval: %u\n", retval)); sprintf(mess, "Could not set interpolation or enable all "
"counters for it.\n");
else
sprintf(mess, "Could not set interpolation\n");
LOG(logERROR, (mess));
} else {
int retval = getInterpolation();
validate(&ret, mess, (int)arg, (int)retval, "set interpolation",
DEC);
LOG(logDEBUG1, ("interpolation retval: %u\n", retval));
}
} }
} }
#endif #endif
@ -9910,14 +10005,20 @@ int set_pump_probe(int file_des) {
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
ret = setPumpProbe(arg); if (getInterpolation() && arg) {
if (ret == FAIL) { ret = FAIL;
sprintf(mess, "Could not set pump probe\n"); sprintf(mess, "Could not set pump probe mode. Disable interpolation mode first.\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else { } else {
int retval = getPumpProbe(); ret = setPumpProbe(arg);
validate(&ret, mess, (int)arg, (int)retval, "set pump probe", DEC); if (ret == FAIL) {
LOG(logDEBUG1, ("pump probe retval: %u\n", retval)); sprintf(mess, "Could not set pump probe\n");
LOG(logERROR, (mess));
} else {
int retval = getPumpProbe();
validate(&ret, mess, (int)arg, (int)retval, "set pump probe", DEC);
LOG(logDEBUG1, ("pump probe retval: %u\n", retval));
}
} }
} }
#endif #endif

View File

@ -10,10 +10,10 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
class detectorData;
namespace sls { namespace sls {
using ns = std::chrono::nanoseconds; using ns = std::chrono::nanoseconds;
class detectorData;
class DetectorImpl; class DetectorImpl;
class MacAddr; class MacAddr;
class IpAddr; class IpAddr;
@ -144,7 +144,7 @@ class Detector {
defs::detectorSettings settings = defs::STANDARD, defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {}); bool trimbits = true, Positions pos = {});
/** [Mythen3] It loads trim files from settingspath */ /** [Mythen3] It loads trim files from settingspath. An energy of -1 will pick up values from detector */
void setThresholdEnergy(std::array<int, 3> threshold_ev, void setThresholdEnergy(std::array<int, 3> threshold_ev,
defs::detectorSettings settings = defs::STANDARD, defs::detectorSettings settings = defs::STANDARD,
bool trimbits = true, Positions pos = {}); bool trimbits = true, Positions pos = {});
@ -159,6 +159,10 @@ class Detector {
* is attached. */ * is attached. */
void loadTrimbits(const std::string &fname, Positions pos = {}); void loadTrimbits(const std::string &fname, Positions pos = {});
/** [Eiger][Mythen3] If no extension specified, serial number of each module
* is attached. */
void saveTrimbits(const std::string &fname, Positions pos = {});
/** [Eiger][Mythen3] -1 if they are all different */ /** [Eiger][Mythen3] -1 if they are all different */
Result<int> getAllTrimbits(Positions pos = {}) const; Result<int> getAllTrimbits(Positions pos = {}) const;
@ -884,7 +888,7 @@ class Detector {
void setRxLock(bool value, Positions pos = {}); void setRxLock(bool value, Positions pos = {});
/** Client IP Address that last communicated with the receiver */ /** Client IP Address that last communicated with the receiver */
Result<sls::IpAddr> getRxLastClientIP(Positions pos = {}) const; Result<IpAddr> getRxLastClientIP(Positions pos = {}) const;
/** Get thread ids from the receiver in order of [parent, tcp, listener 0, /** Get thread ids from the receiver in order of [parent, tcp, listener 0,
* processor 0, streamer 0, listener 1, processor 1, streamer 1, arping]. If * processor 0, streamer 0, listener 1, processor 1, streamer 1, arping]. If
@ -899,6 +903,16 @@ class Detector {
* every minute. Useful in 10G mode. */ * every minute. Useful in 10G mode. */
void setRxArping(bool value, Positions pos = {}); void setRxArping(bool value, Positions pos = {});
/** at module level */
Result<defs::ROI> getIndividualRxROIs(Positions pos) const;
defs::ROI getRxROI() const;
/** only at multi module level without gap pixels */
void setRxROI(const defs::ROI value);
void clearRxROI();
///@} ///@}
/** @name File */ /** @name File */
@ -1481,13 +1495,13 @@ class Detector {
/** [Mythen3] */ /** [Mythen3] */
Result<bool> getInterpolation(Positions pos = {}) const; Result<bool> getInterpolation(Positions pos = {}) const;
/** [Mythen3] Also enables all counters */ /** [Mythen3] interpolation mode enables all counters and disables vth3. Disabling sets back counter mask and vth3. */
void setInterpolation(bool value, Positions pos = {}); void setInterpolation(bool value, Positions pos = {});
/** [Mythen3] */ /** [Mythen3] */
Result<bool> getPumpProbe(Positions pos = {}) const; Result<bool> getPumpProbe(Positions pos = {}) const;
/** [Mythen3] */ /** [Mythen3] pump probe mode only enables vth2. Disabling sets back to previous value */
void setPumpProbe(bool value, Positions pos = {}); void setPumpProbe(bool value, Positions pos = {});
/** [Mythen3] */ /** [Mythen3] */
@ -1909,7 +1923,7 @@ class Detector {
void setDetectorLock(bool lock, Positions pos = {}); void setDetectorLock(bool lock, Positions pos = {});
/** Client IP Address that last communicated with the detector */ /** Client IP Address that last communicated with the detector */
Result<sls::IpAddr> getLastClientIP(Positions pos = {}) const; Result<IpAddr> getLastClientIP(Positions pos = {}) const;
/** Execute a command on the detector server console */ /** Execute a command on the detector server console */
Result<std::string> executeCommand(const std::string &value, Result<std::string> executeCommand(const std::string &value,

View File

@ -4,32 +4,19 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
namespace sls {
/** /**
@short data structure to hold the detector data after postprocessing @short data structure to hold the detector data after postprocessing
*/ */
class detectorData { class detectorData {
public: public:
/** detectorData(double progressIndex, std::string fileName, int nx, int ny, char *data, int databytes, int dynamicRange, uint64_t fileIndex, bool completeImage)
* Constructor : progressIndex(progressIndex), fileName(fileName), fileIndex(fileIndex), nx(nx), ny(ny), data(data), databytes(databytes), dynamicRange(dynamicRange), completeImage(completeImage){};
* @param progress progress index
* @param fname file name prefix
* @param x number of detector channels (1D detector) or dimension in x (2D
* detector)
* @param y dimension in y (2D detector)
* @param d pointer to data in char* format
* @param dbytes number of bytes of image pointed to by cval pointer
* @param dr dynamic range or bits per pixel
* @param fIndex file index
* @param complete true if complete image, else missing packets
*/
detectorData(double progress, std::string fname, int x, int y, char *d,
int dbytes, int dr, uint64_t fIndex, bool complete)
: progressIndex(progress), fileName(fname), fileIndex(fIndex), nx(x),
ny(y), data(d), databytes(dbytes), dynamicRange(dr),
completeImage(complete){};
detectorData(double progressIndex, std::string fileName, int nx, int ny, char *data, int databytes, int dynamicRange, uint64_t fileIndex, bool completeImage, std::array<int, 4> rxRoi)
: progressIndex(progressIndex), fileName(fileName), fileIndex(fileIndex), nx(nx), ny(ny), data(data), databytes(databytes), dynamicRange(dynamicRange), completeImage(completeImage), rxRoi(rxRoi) {};
/** /**
* Destructor
* data has to be deleted by caller * data has to be deleted by caller
*/ */
~detectorData(){}; ~detectorData(){};
@ -60,8 +47,11 @@ class detectorData {
uint64_t fileIndex; uint64_t fileIndex;
int nx; int nx;
int ny; int ny;
char *data; char *data{nullptr};
int databytes; int databytes;
int dynamicRange; int dynamicRange;
bool completeImage; bool completeImage;
std::array<int,4> rxRoi{{-1, -1, -1, -1}};
}; };
} // namespace sls

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
namespace sls {
/** Macro to make an integer command. /** Macro to make an integer command.
* CMDNAME name of the function that does the command * CMDNAME name of the function that does the command
* GETFCN Detector function to get * GETFCN Detector function to get
@ -53,7 +55,7 @@
os << args[0] << '\n'; \ os << args[0] << '\n'; \
} \ } \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -75,9 +77,9 @@
WrongNumberOfParameters(1); \ WrongNumberOfParameters(1); \
} \ } \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
throw sls::RuntimeError("cannot put"); \ throw RuntimeError("cannot put"); \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -102,7 +104,7 @@
det->SETFCN(args[0], std::vector<int>{det_id}); \ det->SETFCN(args[0], std::vector<int>{det_id}); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -128,7 +130,7 @@
det->SETFCN(val, std::vector<int>{det_id}); \ det->SETFCN(val, std::vector<int>{det_id}); \
os << ToStringHex(val, 16) << '\n'; \ os << ToStringHex(val, 16) << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -154,7 +156,7 @@
det->SETFCN(val, std::vector<int>{det_id}); \ det->SETFCN(val, std::vector<int>{det_id}); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -180,7 +182,7 @@
det->SETFCN(val, std::vector<int>{det_id}); \ det->SETFCN(val, std::vector<int>{det_id}); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -206,7 +208,7 @@
det->SETFCN(val, det_id); \ det->SETFCN(val, det_id); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -232,7 +234,7 @@
det->SETFCN(val, det_id); \ det->SETFCN(val, det_id); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -252,7 +254,7 @@
os << OutString(t) << '\n'; \ os << OutString(t) << '\n'; \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
if (det_id != -1) { \ if (det_id != -1) { \
throw sls::RuntimeError( \ throw RuntimeError( \
"Cannot execute this at module level"); \ "Cannot execute this at module level"); \
} \ } \
if (args.size() != 1) { \ if (args.size() != 1) { \
@ -262,7 +264,7 @@
det->SETFCN(val); \ det->SETFCN(val); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -273,7 +275,7 @@
std::ostringstream os; \ std::ostringstream os; \
os << cmd << ' '; \ os << cmd << ' '; \
if (det_id != -1) { \ if (det_id != -1) { \
throw sls::RuntimeError("Cannot execute this at module level"); \ throw RuntimeError("Cannot execute this at module level"); \
} \ } \
if (action == slsDetectorDefs::HELP_ACTION) \ if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \ os << HLPSTR << '\n'; \
@ -291,7 +293,7 @@
det->SETFCN(val); \ det->SETFCN(val); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -317,7 +319,7 @@
det->SETFCN(INDEX, val, std::vector<int>{det_id}); \ det->SETFCN(INDEX, val, std::vector<int>{det_id}); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -345,7 +347,7 @@
std::vector<int>{det_id}); \ std::vector<int>{det_id}); \
os << args[0] << ' ' << args[1] << '\n'; \ os << args[0] << ' ' << args[1] << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -356,12 +358,12 @@
std::ostringstream os; \ std::ostringstream os; \
os << cmd << ' '; \ os << cmd << ' '; \
if (det_id != -1) { \ if (det_id != -1) { \
throw sls::RuntimeError("Cannot execute this at module level"); \ throw RuntimeError("Cannot execute this at module level"); \
} \ } \
if (action == slsDetectorDefs::HELP_ACTION) \ if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \ os << HLPSTR << '\n'; \
else if (action == slsDetectorDefs::GET_ACTION) { \ else if (action == slsDetectorDefs::GET_ACTION) { \
throw sls::RuntimeError("Cannot get"); \ throw RuntimeError("Cannot get"); \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
if (!args.empty()) { \ if (!args.empty()) { \
WrongNumberOfParameters(0); \ WrongNumberOfParameters(0); \
@ -369,7 +371,7 @@
det->SETFCN(); \ det->SETFCN(); \
os << "successful\n"; \ os << "successful\n"; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -382,7 +384,7 @@
if (action == slsDetectorDefs::HELP_ACTION) \ if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \ os << HLPSTR << '\n'; \
else if (action == slsDetectorDefs::GET_ACTION) { \ else if (action == slsDetectorDefs::GET_ACTION) { \
throw sls::RuntimeError("Cannot get"); \ throw RuntimeError("Cannot get"); \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
if (!args.empty()) { \ if (!args.empty()) { \
WrongNumberOfParameters(0); \ WrongNumberOfParameters(0); \
@ -390,7 +392,7 @@
det->SETFCN(std::vector<int>{det_id}); \ det->SETFCN(std::vector<int>{det_id}); \
os << "successful\n"; \ os << "successful\n"; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -401,12 +403,12 @@
std::ostringstream os; \ std::ostringstream os; \
os << cmd << ' '; \ os << cmd << ' '; \
if (det_id != -1) { \ if (det_id != -1) { \
throw sls::RuntimeError("Cannot execute this at module level"); \ throw RuntimeError("Cannot execute this at module level"); \
} \ } \
if (action == slsDetectorDefs::HELP_ACTION) \ if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \ os << HLPSTR << '\n'; \
else if (action == slsDetectorDefs::GET_ACTION) { \ else if (action == slsDetectorDefs::GET_ACTION) { \
throw sls::RuntimeError("Cannot get"); \ throw RuntimeError("Cannot get"); \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
if (args.size() != 1) { \ if (args.size() != 1) { \
WrongNumberOfParameters(1); \ WrongNumberOfParameters(1); \
@ -414,7 +416,7 @@
det->SETFCN(args[0]); \ det->SETFCN(args[0]); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -427,7 +429,7 @@
if (action == slsDetectorDefs::HELP_ACTION) \ if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \ os << HLPSTR << '\n'; \
else if (action == slsDetectorDefs::GET_ACTION) { \ else if (action == slsDetectorDefs::GET_ACTION) { \
throw sls::RuntimeError("Cannot get"); \ throw RuntimeError("Cannot get"); \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
if (args.size() != 1) { \ if (args.size() != 1) { \
WrongNumberOfParameters(1); \ WrongNumberOfParameters(1); \
@ -435,7 +437,7 @@
det->SETFCN(args[0], std::vector<int>{det_id}); \ det->SETFCN(args[0], std::vector<int>{det_id}); \
os << args.front() << '\n'; \ os << args.front() << '\n'; \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -454,9 +456,9 @@
auto t = det->GETFCN(std::vector<int>{det_id}); \ auto t = det->GETFCN(std::vector<int>{det_id}); \
os << OutString(t) << '\n'; \ os << OutString(t) << '\n'; \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
throw sls::RuntimeError("Cannot put"); \ throw RuntimeError("Cannot put"); \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -473,11 +475,11 @@
WrongNumberOfParameters(0); \ WrongNumberOfParameters(0); \
} \ } \
auto t = det->GETFCN(); \ auto t = det->GETFCN(); \
os << sls::ToString(t) << '\n'; \ os << ToString(t) << '\n'; \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
throw sls::RuntimeError("Cannot put"); \ throw RuntimeError("Cannot put"); \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -496,9 +498,9 @@
auto t = det->GETFCN(std::vector<int>{det_id}); \ auto t = det->GETFCN(std::vector<int>{det_id}); \
os << OutStringHex(t) << '\n'; \ os << OutStringHex(t) << '\n'; \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
throw sls::RuntimeError("Cannot put"); \ throw RuntimeError("Cannot put"); \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
@ -516,15 +518,13 @@
auto t = det->GETFCN(VAL, std::vector<int>{det_id}); \ auto t = det->GETFCN(VAL, std::vector<int>{det_id}); \
os << OutString(t) << APPEND << '\n'; \ os << OutString(t) << APPEND << '\n'; \
} else if (action == slsDetectorDefs::PUT_ACTION) { \ } else if (action == slsDetectorDefs::PUT_ACTION) { \
throw sls::RuntimeError("Cannot put"); \ throw RuntimeError("Cannot put"); \
} else { \ } else { \
throw sls::RuntimeError("Unknown action"); \ throw RuntimeError("Unknown action"); \
} \ } \
return os.str(); \ return os.str(); \
} }
namespace sls {
class CmdProxy { class CmdProxy {
public: public:
explicit CmdProxy(Detector *ptr) : det(ptr) {} explicit CmdProxy(Detector *ptr) : det(ptr) {}
@ -558,7 +558,7 @@ class CmdProxy {
return ToStringHex(value, width); return ToStringHex(value, width);
} }
template <typename V> std::string OutString(const sls::Result<V> &value) { template <typename V> std::string OutString(const Result<V> &value) {
if (value.equal()) if (value.equal())
return ToString(value.front()); return ToString(value.front());
return ToString(value); return ToString(value);
@ -743,11 +743,10 @@ class CmdProxy {
/* Pattern */ /* Pattern */
/* Moench */ /* Moench */
/* Advanced */ /* Advanced */
{"copydetectorserver", "updatedetectorserver"}, {"copydetectorserver", "updatedetectorserver"},
/* Insignificant */ /* Insignificant */
{"nframes", "framecounter"}, {"nframes", "framecounter"},
{"now", "runtime"}, {"now", "runtime"},
@ -783,7 +782,7 @@ class CmdProxy {
{"threshold", &CmdProxy::Threshold}, {"threshold", &CmdProxy::Threshold},
{"thresholdnotb", &CmdProxy::Threshold}, {"thresholdnotb", &CmdProxy::Threshold},
{"settingspath", &CmdProxy::settingspath}, {"settingspath", &CmdProxy::settingspath},
{"trimbits", &CmdProxy::trimbits}, {"trimbits", &CmdProxy::Trimbits},
{"trimval", &CmdProxy::trimval}, {"trimval", &CmdProxy::trimval},
{"trimen", &CmdProxy::TrimEnergies}, {"trimen", &CmdProxy::TrimEnergies},
{"gappixels", &CmdProxy::GapPixels}, {"gappixels", &CmdProxy::GapPixels},
@ -910,6 +909,8 @@ class CmdProxy {
{"rx_lastclient", &CmdProxy::rx_lastclient}, {"rx_lastclient", &CmdProxy::rx_lastclient},
{"rx_threads", &CmdProxy::rx_threads}, {"rx_threads", &CmdProxy::rx_threads},
{"rx_arping", &CmdProxy::rx_arping}, {"rx_arping", &CmdProxy::rx_arping},
{"rx_roi", &CmdProxy::Rx_ROI},
{"rx_clearroi", &CmdProxy::rx_clearroi},
/* File */ /* File */
{"fformat", &CmdProxy::fformat}, {"fformat", &CmdProxy::fformat},
@ -965,7 +966,7 @@ class CmdProxy {
/* Gotthard Specific */ /* Gotthard Specific */
{"roi", &CmdProxy::ROI}, {"roi", &CmdProxy::ROI},
{"clearroi", &CmdProxy::ClearROI}, {"clearroi", &CmdProxy::clearroi},
{"exptimel", &CmdProxy::exptimel}, {"exptimel", &CmdProxy::exptimel},
/* Gotthard2 Specific */ /* Gotthard2 Specific */
@ -1114,6 +1115,7 @@ class CmdProxy {
std::string ClientVersion(int action); std::string ClientVersion(int action);
std::string DetectorSize(int action); std::string DetectorSize(int action);
std::string Threshold(int action); std::string Threshold(int action);
std::string Trimbits(int action);
std::string TrimEnergies(int action); std::string TrimEnergies(int action);
std::string GapPixels(int action); std::string GapPixels(int action);
/* acquisition parameters */ /* acquisition parameters */
@ -1150,6 +1152,7 @@ class CmdProxy {
std::string UDPDestinationIP2(int action); std::string UDPDestinationIP2(int action);
/* Receiver Config */ /* Receiver Config */
std::string ReceiverHostname(int action); std::string ReceiverHostname(int action);
std::string Rx_ROI(int action);
/* File */ /* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */ /* ZMQ Streaming Parameters (Receiver<->Client) */
std::string ZMQHWM(int action); std::string ZMQHWM(int action);
@ -1164,7 +1167,6 @@ class CmdProxy {
std::string TemperatureEvent(int action); std::string TemperatureEvent(int action);
/* Gotthard Specific */ /* Gotthard Specific */
std::string ROI(int action); std::string ROI(int action);
std::string ClearROI(int action);
/* Gotthard2 Specific */ /* Gotthard2 Specific */
std::string InjectChannel(int action); std::string InjectChannel(int action);
std::string VetoPhoton(int action); std::string VetoPhoton(int action);
@ -1250,7 +1252,7 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
settings, getSettings, setSettings, settings, getSettings, setSettings,
sls::StringTo<slsDetectorDefs::detectorSettings>, StringTo<slsDetectorDefs::detectorSettings>,
"[standard, fast, highgain, dynamicgain, lowgain, " "[standard, fast, highgain, dynamicgain, lowgain, "
"mediumgain, veryhighgain, highgain0, " "mediumgain, veryhighgain, highgain0, "
"fixgain1, fixgain2, forceswitchg1, forceswitchg2, " "fixgain1, fixgain2, forceswitchg1, forceswitchg2, "
@ -1272,11 +1274,6 @@ class CmdProxy {
"[path]\n\t[Eiger][Mythen3] Directory where settings files " "[path]\n\t[Eiger][Mythen3] Directory where settings files "
"are loaded from/to."); "are loaded from/to.");
EXECUTE_SET_COMMAND_1ARG(
trimbits, loadTrimbits,
"[fname]\n\t[Eiger][Mythen3] Loads the trimbit file to detector. If no "
"extension specified, serial number of each module is attached.");
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
trimval, getAllTrimbits, setAllTrimbits, StringTo<int>, trimval, getAllTrimbits, setAllTrimbits, StringTo<int>,
"[n_trimval]\n\t[Eiger][Mythen3] All trimbits set to this " "[n_trimval]\n\t[Eiger][Mythen3] All trimbits set to this "
@ -1353,7 +1350,7 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
timing, getTimingMode, setTimingMode, timing, getTimingMode, setTimingMode,
sls::StringTo<slsDetectorDefs::timingMode>, StringTo<slsDetectorDefs::timingMode>,
"[auto|trigger|gating|burst_trigger]\n\tTiming Mode of " "[auto|trigger|gating|burst_trigger]\n\tTiming Mode of "
"detector.\n\t[Jungfrau][Gotthard][Ctb][Moench][Gotthard2] " "detector.\n\t[Jungfrau][Gotthard][Ctb][Moench][Gotthard2] "
"[auto|trigger]\n\t[Mythen3] " "[auto|trigger]\n\t[Mythen3] "
@ -1725,7 +1722,7 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
rx_discardpolicy, getRxFrameDiscardPolicy, setRxFrameDiscardPolicy, rx_discardpolicy, getRxFrameDiscardPolicy, setRxFrameDiscardPolicy,
sls::StringTo<slsDetectorDefs::frameDiscardPolicy>, StringTo<slsDetectorDefs::frameDiscardPolicy>,
"[nodiscard (default)|discardempty|discardpartial(fastest)]\n\tFrame " "[nodiscard (default)|discardempty|discardpartial(fastest)]\n\tFrame "
"discard policy of receiver. nodiscard does not discard frames, " "discard policy of receiver. nodiscard does not discard frames, "
"discardempty discards empty frames, discardpartial discards partial " "discardempty discards empty frames, discardpartial discards partial "
@ -1766,11 +1763,16 @@ class CmdProxy {
"the interface it is " "the interface it is "
"listening to every minute. Useful in 10G mode."); "listening to every minute. Useful in 10G mode.");
EXECUTE_SET_COMMAND_NOID(
rx_clearroi, clearRxROI,
"Resets Region of interest in receiver. Default is all "
"channels/pixels enabled.");
/* File */ /* File */
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
fformat, getFileFormat, setFileFormat, fformat, getFileFormat, setFileFormat,
sls::StringTo<slsDetectorDefs::fileFormat>, StringTo<slsDetectorDefs::fileFormat>,
"[binary|hdf5]\n\tFile format of data file. For HDF5, package must be " "[binary|hdf5]\n\tFile format of data file. For HDF5, package must be "
"compiled with HDF5 flags. Default is binary."); "compiled with HDF5 flags. Default is binary.");
@ -1986,13 +1988,13 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
gainmode, getGainMode, setGainMode, gainmode, getGainMode, setGainMode,
sls::StringTo<slsDetectorDefs::gainMode>, StringTo<slsDetectorDefs::gainMode>,
"[dynamicgain|forceswitchg1|forceswitchg2|fixg1|fixg2|fixg0]\n\t[" "[dynamicgain|forceswitchg1|forceswitchg2|fixg1|fixg2|fixg0]\n\t["
"Jungfrau] Gain mode.\n\tCAUTION: Do not use fixg0 without caution, " "Jungfrau] Gain mode.\n\tCAUTION: Do not use fixg0 without caution, "
"you can damage the detector!!!"); "you can damage the detector!!!");
INTEGER_COMMAND_VEC_ID(filtercells, getNumberOfFilterCells, INTEGER_COMMAND_VEC_ID(filtercells, getNumberOfFilterCells,
setNumberOfFilterCells, sls::StringTo<int>, setNumberOfFilterCells, StringTo<int>,
"[0-12]\n\t[Jungfrau] Set Filter Cell. Only for " "[0-12]\n\t[Jungfrau] Set Filter Cell. Only for "
"chipv1.1. Advanced user Command"); "chipv1.1. Advanced user Command");
@ -2001,6 +2003,10 @@ class CmdProxy {
"[(optional unit) ns|us|ms|s]\n\t[Gotthard] Exposure time " "[(optional unit) ns|us|ms|s]\n\t[Gotthard] Exposure time "
"left for current frame. "); "left for current frame. ");
EXECUTE_SET_COMMAND(clearroi, clearROI,
"[Gotthard] Resets Region of interest in detector. All "
"channels enabled. Default is all channels enabled.");
/* Gotthard2 Specific */ /* Gotthard2 Specific */
INTEGER_COMMAND_SET_NOID_GET_ID( INTEGER_COMMAND_SET_NOID_GET_ID(
bursts, getNumberOfBursts, setNumberOfBursts, StringTo<int64_t>, bursts, getNumberOfBursts, setNumberOfBursts, StringTo<int64_t>,
@ -2024,7 +2030,7 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
timingsource, getTimingSource, setTimingSource, timingsource, getTimingSource, setTimingSource,
sls::StringTo<slsDetectorDefs::timingSourceType>, StringTo<slsDetectorDefs::timingSourceType>,
"[internal|external]\n\t[Gotthard2] Timing source. Internal is crystal " "[internal|external]\n\t[Gotthard2] Timing source. Internal is crystal "
"and external is system timing. Default is internal."); "and external is system timing. Default is internal.");
@ -2047,12 +2053,11 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID(interpolation, getInterpolation, setInterpolation, INTEGER_COMMAND_VEC_ID(interpolation, getInterpolation, setInterpolation,
StringTo<int>, StringTo<int>,
"[0, 1]\n\t[Mythen3] Enables or disables " "[0, 1]\n\t[Mythen3] Enables or disables "
"interpolation. Default is disabled. Enabling also " "interpolation. Default is disabled. Interpolation mode enables all counters and disables vth3. Disabling sets back counter mask and vth3.");
"enables all counters. ");
INTEGER_COMMAND_VEC_ID(pumpprobe, getPumpProbe, setPumpProbe, StringTo<int>, INTEGER_COMMAND_VEC_ID(pumpprobe, getPumpProbe, setPumpProbe, StringTo<int>,
"[0, 1]\n\t[Mythen3] Enables or disables pump probe " "[0, 1]\n\t[Mythen3] Enables or disables pump probe "
"mode. Default is disabled"); "mode. Default is disabled. Pump probe mode only enables vth2. Disabling sets back to previous value.");
INTEGER_COMMAND_VEC_ID(apulse, getAnalogPulsing, setAnalogPulsing, INTEGER_COMMAND_VEC_ID(apulse, getAnalogPulsing, setAnalogPulsing,
StringTo<int>, StringTo<int>,
@ -2111,7 +2116,7 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
romode, getReadoutMode, setReadoutMode, romode, getReadoutMode, setReadoutMode,
sls::StringTo<slsDetectorDefs::readoutMode>, StringTo<slsDetectorDefs::readoutMode>,
"[analog|digital|analog_digital]\n\t[CTB] Readout mode. " "[analog|digital|analog_digital]\n\t[CTB] Readout mode. "
"Default is analog."); "Default is analog.");

View File

@ -37,8 +37,8 @@ void freeSharedMemory(int detectorIndex, int moduleIndex) {
int numDetectors = 0; int numDetectors = 0;
if (detectorShm.exists()) { if (detectorShm.exists()) {
detectorShm.openSharedMemory(); detectorShm.openSharedMemory(false);
numDetectors = detectorShm()->numberOfModules; numDetectors = detectorShm()->totalNumberOfModules;
detectorShm.removeSharedMemory(); detectorShm.removeSharedMemory();
} }
@ -56,7 +56,7 @@ void freeSharedMemory(int detectorIndex, int moduleIndex) {
using defs = slsDetectorDefs; using defs = slsDetectorDefs;
Detector::Detector(int shm_id) Detector::Detector(int shm_id)
: pimpl(sls::make_unique<DetectorImpl>(shm_id)) {} : pimpl(make_unique<DetectorImpl>(shm_id)) {}
Detector::~Detector() = default; Detector::~Detector() = default;
@ -66,7 +66,7 @@ void Detector::freeSharedMemory() { pimpl->freeSharedMemory(); }
void Detector::loadConfig(const std::string &fname) { void Detector::loadConfig(const std::string &fname) {
int shm_id = getShmId(); int shm_id = getShmId();
freeSharedMemory(); freeSharedMemory();
pimpl = sls::make_unique<DetectorImpl>(shm_id); pimpl = make_unique<DetectorImpl>(shm_id);
LOG(logINFO) << "Loading configuration file: " << fname; LOG(logINFO) << "Loading configuration file: " << fname;
loadParameters(fname); loadParameters(fname);
} }
@ -273,6 +273,10 @@ void Detector::loadTrimbits(const std::string &fname, Positions pos) {
pimpl->Parallel(&Module::loadTrimbits, pos, fname); pimpl->Parallel(&Module::loadTrimbits, pos, fname);
} }
void Detector::saveTrimbits(const std::string &fname, Positions pos) {
pimpl->Parallel(&Module::saveTrimbits, pos, fname);
}
Result<int> Detector::getAllTrimbits(Positions pos) const { Result<int> Detector::getAllTrimbits(Positions pos) const {
return pimpl->Parallel(&Module::getAllTrimbits, pos); return pimpl->Parallel(&Module::getAllTrimbits, pos);
} }
@ -781,24 +785,7 @@ void Detector::startReceiver() { pimpl->Parallel(&Module::startReceiver, {}); }
void Detector::stopReceiver() { pimpl->Parallel(&Module::stopReceiver, {}); } void Detector::stopReceiver() { pimpl->Parallel(&Module::stopReceiver, {}); }
void Detector::startDetector(Positions pos) { void Detector::startDetector(Positions pos) {
auto detector_type = getDetectorType(pos).squash(); pimpl->startAcquisition(false, pos);
if (detector_type == defs::MYTHEN3 && size() > 1) {
std::vector<int> slaves(pos);
auto is_master = getMaster(pos);
int masterPosition = -1;
for (unsigned int i = 0; i < is_master.size(); ++i) {
if (is_master[i]) {
masterPosition = i;
slaves.erase(slaves.begin() + i);
}
}
pimpl->Parallel(&Module::startAcquisition, pos);
if (masterPosition != -1) {
pimpl->Parallel(&Module::startAcquisition, {masterPosition});
}
} else {
pimpl->Parallel(&Module::startAcquisition, pos);
}
} }
void Detector::startDetectorReadout() { void Detector::startDetectorReadout() {
@ -888,7 +875,7 @@ Result<int> Detector::getNumberofUDPInterfaces(Positions pos) const {
void Detector::setNumberofUDPInterfaces(int n, Positions pos) { void Detector::setNumberofUDPInterfaces(int n, Positions pos) {
if (getDetectorType().squash() != defs::JUNGFRAU) { if (getDetectorType().squash() != defs::JUNGFRAU) {
throw sls::RuntimeError( throw RuntimeError(
"Cannot set number of udp interfaces for this detector."); "Cannot set number of udp interfaces for this detector.");
} }
// also called by vetostream (for gotthard2) // also called by vetostream (for gotthard2)
@ -968,7 +955,7 @@ Result<UdpDestination> Detector::getDestinationUDPList(const uint32_t entry,
void Detector::setDestinationUDPList(const UdpDestination dest, void Detector::setDestinationUDPList(const UdpDestination dest,
const int module_id) { const int module_id) {
if (module_id == -1 && size() > 1) { if (module_id == -1 && size() > 1) {
throw sls::RuntimeError("Cannot set this parameter at detector level."); throw RuntimeError("Cannot set this parameter at detector level.");
} }
pimpl->Parallel(&Module::setDestinationUDPList, {module_id}, dest); pimpl->Parallel(&Module::setDestinationUDPList, {module_id}, dest);
} }
@ -1211,7 +1198,7 @@ void Detector::setRxLock(bool value, Positions pos) {
pimpl->Parallel(&Module::setReceiverLock, pos, value); pimpl->Parallel(&Module::setReceiverLock, pos, value);
} }
Result<sls::IpAddr> Detector::getRxLastClientIP(Positions pos) const { Result<IpAddr> Detector::getRxLastClientIP(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverLastClientIP, pos); return pimpl->Parallel(&Module::getReceiverLastClientIP, pos);
} }
@ -1228,6 +1215,16 @@ void Detector::setRxArping(bool value, Positions pos) {
pimpl->Parallel(&Module::setRxArping, pos, value); pimpl->Parallel(&Module::setRxArping, pos, value);
} }
Result<defs::ROI> Detector::getIndividualRxROIs(Positions pos) const {
return pimpl->Parallel(&Module::getRxROI, pos);
}
defs::ROI Detector::getRxROI() const { return pimpl->getRxROI(); }
void Detector::setRxROI(const defs::ROI value) { pimpl->setRxROI(value); }
void Detector::clearRxROI() { pimpl->clearRxROI(); }
// File // File
Result<defs::fileFormat> Detector::getFileFormat(Positions pos) const { Result<defs::fileFormat> Detector::getFileFormat(Positions pos) const {
@ -1251,6 +1248,9 @@ Result<std::string> Detector::getFileNamePrefix(Positions pos) const {
} }
void Detector::setFileNamePrefix(const std::string &fname, Positions pos) { void Detector::setFileNamePrefix(const std::string &fname, Positions pos) {
if (fname.find_first_of("/ ") != std::string::npos) {
throw RuntimeError("Cannot set file name prefix with '/' or ' '");
}
pimpl->Parallel(&Module::setFileName, pos, fname); pimpl->Parallel(&Module::setFileName, pos, fname);
} }
@ -1794,7 +1794,7 @@ Detector::getVetoAlgorithm(const defs::streamingInterface interface,
void Detector::setVetoAlgorithm(const defs::vetoAlgorithm alg, void Detector::setVetoAlgorithm(const defs::vetoAlgorithm alg,
defs::streamingInterface interface, defs::streamingInterface interface,
Positions pos) { Positions pos) {
LOG(logINFOBLUE) << "alg:" << ToString(alg) LOG(logDEBUG) << "alg:" << ToString(alg)
<< " interface:" << ToString(interface); << " interface:" << ToString(interface);
pimpl->Parallel(&Module::setVetoAlgorithm, pos, alg, interface); pimpl->Parallel(&Module::setVetoAlgorithm, pos, alg, interface);
} }
@ -2285,7 +2285,7 @@ void Detector::resetFPGA(Positions pos) {
void Detector::updateDetectorServer(const std::string &fname, Positions pos) { void Detector::updateDetectorServer(const std::string &fname, Positions pos) {
LOG(logINFO) << "Updating Detector Server (no tftp)..."; LOG(logINFO) << "Updating Detector Server (no tftp)...";
std::vector<char> buffer = readBinaryFile(fname, "Update Detector Server"); std::vector<char> buffer = readBinaryFile(fname, "Update Detector Server");
std::string filename = sls::getFileNameFromFilePath(fname); std::string filename = getFileNameFromFilePath(fname);
pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename); pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename);
if (getDetectorType().squash() != defs::EIGER) { if (getDetectorType().squash() != defs::EIGER) {
rebootController(pos); rebootController(pos);
@ -2294,7 +2294,7 @@ void Detector::updateDetectorServer(const std::string &fname, Positions pos) {
void Detector::updateKernel(const std::string &fname, Positions pos) { void Detector::updateKernel(const std::string &fname, Positions pos) {
LOG(logINFO) << "Updating Kernel..."; LOG(logINFO) << "Updating Kernel...";
std::vector<char> buffer = sls::readBinaryFile(fname, "Update Kernel"); std::vector<char> buffer = readBinaryFile(fname, "Update Kernel");
pimpl->Parallel(&Module::updateKernel, pos, buffer); pimpl->Parallel(&Module::updateKernel, pos, buffer);
rebootController(pos); rebootController(pos);
} }
@ -2309,7 +2309,7 @@ void Detector::updateFirmwareAndServer(const std::string &sname,
LOG(logINFO) << "Updating Firmware and Detector Server (no tftp)..."; LOG(logINFO) << "Updating Firmware and Detector Server (no tftp)...";
LOG(logINFO) << "Updating Detector Server (no tftp)..."; LOG(logINFO) << "Updating Detector Server (no tftp)...";
std::vector<char> buffer = readBinaryFile(sname, "Update Detector Server"); std::vector<char> buffer = readBinaryFile(sname, "Update Detector Server");
std::string filename = sls::getFileNameFromFilePath(sname); std::string filename = getFileNameFromFilePath(sname);
pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename); pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename);
programFPGA(fname, false, pos); programFPGA(fname, false, pos);
} }
@ -2397,7 +2397,7 @@ void Detector::setDetectorLock(bool lock, Positions pos) {
pimpl->Parallel(&Module::setLockDetector, pos, lock); pimpl->Parallel(&Module::setLockDetector, pos, lock);
} }
Result<sls::IpAddr> Detector::getLastClientIP(Positions pos) const { Result<IpAddr> Detector::getLastClientIP(Positions pos) const {
return pimpl->Parallel(&Module::getLastClientIP, pos); return pimpl->Parallel(&Module::getLastClientIP, pos);
} }

View File

@ -47,7 +47,7 @@ void DetectorImpl::setupDetector(bool verify, bool update) {
} }
if (ctb_shm.exists()) if (ctb_shm.exists())
ctb_shm.openSharedMemory(); ctb_shm.openSharedMemory(verify);
} }
void DetectorImpl::setAcquiringFlag(bool flag) { shm()->acquiringFlag = flag; } void DetectorImpl::setAcquiringFlag(bool flag) { shm()->acquiringFlag = flag; }
@ -69,8 +69,8 @@ void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
int numModules = 0; int numModules = 0;
if (detectorShm.exists()) { if (detectorShm.exists()) {
detectorShm.openSharedMemory(); detectorShm.openSharedMemory(false);
numModules = detectorShm()->numberOfModules; numModules = detectorShm()->totalNumberOfModules;
detectorShm.removeSharedMemory(); detectorShm.removeSharedMemory();
} }
@ -144,7 +144,7 @@ void DetectorImpl::initSharedMemory(bool verify) {
shm.createSharedMemory(); shm.createSharedMemory();
initializeDetectorStructure(); initializeDetectorStructure();
} else { } else {
shm.openSharedMemory(); shm.openSharedMemory(verify);
if (verify && shm()->shmversion != DETECTOR_SHMVERSION) { if (verify && shm()->shmversion != DETECTOR_SHMVERSION) {
LOG(logERROR) << "Detector shared memory (" << detectorIndex LOG(logERROR) << "Detector shared memory (" << detectorIndex
<< ") version mismatch " << ") version mismatch "
@ -161,10 +161,10 @@ void DetectorImpl::initSharedMemory(bool verify) {
void DetectorImpl::initializeDetectorStructure() { void DetectorImpl::initializeDetectorStructure() {
shm()->shmversion = DETECTOR_SHMVERSION; shm()->shmversion = DETECTOR_SHMVERSION;
shm()->numberOfModules = 0; shm()->totalNumberOfModules = 0;
shm()->detType = GENERIC; shm()->detType = GENERIC;
shm()->numberOfModule.x = 0; shm()->numberOfModules.x = 0;
shm()->numberOfModule.y = 0; shm()->numberOfModules.y = 0;
shm()->numberOfChannels.x = 0; shm()->numberOfChannels.x = 0;
shm()->numberOfChannels.y = 0; shm()->numberOfChannels.y = 0;
shm()->acquiringFlag = false; shm()->acquiringFlag = false;
@ -172,6 +172,10 @@ void DetectorImpl::initializeDetectorStructure() {
shm()->gapPixels = false; shm()->gapPixels = false;
// zmqlib default // zmqlib default
shm()->zmqHwm = -1; shm()->zmqHwm = -1;
shm()->rx_roi.xmin = -1;
shm()->rx_roi.xmax = -1;
shm()->rx_roi.ymin = -1;
shm()->rx_roi.ymax = -1;
} }
void DetectorImpl::initializeMembers(bool verify) { void DetectorImpl::initializeMembers(bool verify) {
@ -179,10 +183,10 @@ void DetectorImpl::initializeMembers(bool verify) {
zmqSocket.clear(); zmqSocket.clear();
// get objects from single det shared memory (open) // get objects from single det shared memory (open)
for (int i = 0; i < shm()->numberOfModules; i++) { for (int i = 0; i < shm()->totalNumberOfModules; i++) {
try { try {
modules.push_back( modules.push_back(
sls::make_unique<Module>(detectorIndex, i, verify)); make_unique<Module>(detectorIndex, i, verify));
} catch (...) { } catch (...) {
modules.clear(); modules.clear();
throw; throw;
@ -195,11 +199,11 @@ void DetectorImpl::updateUserdetails() {
memset(shm()->lastUser, 0, sizeof(shm()->lastUser)); memset(shm()->lastUser, 0, sizeof(shm()->lastUser));
memset(shm()->lastDate, 0, sizeof(shm()->lastDate)); memset(shm()->lastDate, 0, sizeof(shm()->lastDate));
try { try {
sls::strcpy_safe(shm()->lastUser, exec("whoami").c_str()); strcpy_safe(shm()->lastUser, exec("whoami").c_str());
sls::strcpy_safe(shm()->lastDate, exec("date").c_str()); strcpy_safe(shm()->lastDate, exec("date").c_str());
} catch (...) { } catch (...) {
sls::strcpy_safe(shm()->lastUser, "errorreading"); strcpy_safe(shm()->lastUser, "errorreading");
sls::strcpy_safe(shm()->lastDate, "errorreading"); strcpy_safe(shm()->lastDate, "errorreading");
} }
} }
@ -246,7 +250,7 @@ void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) {
void DetectorImpl::setHostname(const std::vector<std::string> &name) { void DetectorImpl::setHostname(const std::vector<std::string> &name) {
// this check is there only to allow the previous detsizechan command // this check is there only to allow the previous detsizechan command
if (shm()->numberOfModules != 0) { if (shm()->totalNumberOfModules != 0) {
LOG(logWARNING) << "There are already module(s) in shared memory." LOG(logWARNING) << "There are already module(s) in shared memory."
"Freeing Shared memory now."; "Freeing Shared memory now.";
bool initialChecks = shm()->initialChecks; bool initialChecks = shm()->initialChecks;
@ -264,7 +268,7 @@ void DetectorImpl::setHostname(const std::vector<std::string> &name) {
if (shm()->detType == defs::CHIPTESTBOARD) { if (shm()->detType == defs::CHIPTESTBOARD) {
if (ctb_shm.exists()) if (ctb_shm.exists())
ctb_shm.openSharedMemory(); ctb_shm.openSharedMemory(true);
else else
ctb_shm.createSharedMemory(); ctb_shm.createSharedMemory();
} }
@ -275,7 +279,7 @@ void DetectorImpl::addModule(const std::string &hostname) {
int port = DEFAULT_PORTNO; int port = DEFAULT_PORTNO;
std::string host = hostname; std::string host = hostname;
auto res = sls::split(hostname, ':'); auto res = split(hostname, ':');
if (res.size() > 1) { if (res.size() > 1) {
host = res[0]; host = res[0];
port = StringTo<int>(res[1]); port = StringTo<int>(res[1]);
@ -299,13 +303,13 @@ void DetectorImpl::addModule(const std::string &hostname) {
// gotthard cannot have more than 2 modules (50um=1, 25um=2 // gotthard cannot have more than 2 modules (50um=1, 25um=2
if ((type == GOTTHARD || type == GOTTHARD2) && modules.size() > 2) { if ((type == GOTTHARD || type == GOTTHARD2) && modules.size() > 2) {
freeSharedMemory(); freeSharedMemory();
throw sls::RuntimeError("Gotthard cannot have more than 2 modules"); throw RuntimeError("Gotthard cannot have more than 2 modules");
} }
auto pos = modules.size(); auto pos = modules.size();
modules.emplace_back( modules.emplace_back(
sls::make_unique<Module>(type, detectorIndex, pos, false)); make_unique<Module>(type, detectorIndex, pos, false));
shm()->numberOfModules = modules.size(); shm()->totalNumberOfModules = modules.size();
modules[pos]->setControlPort(port); modules[pos]->setControlPort(port);
modules[pos]->setStopPort(port + 1); modules[pos]->setStopPort(port + 1);
modules[pos]->setHostname(host, shm()->initialChecks); modules[pos]->setHostname(host, shm()->initialChecks);
@ -328,49 +332,48 @@ void DetectorImpl::addModule(const std::string &hostname) {
void DetectorImpl::updateDetectorSize() { void DetectorImpl::updateDetectorSize() {
LOG(logDEBUG) << "Updating Detector Size: " << size(); LOG(logDEBUG) << "Updating Detector Size: " << size();
const slsDetectorDefs::xy det_size = modules[0]->getNumberOfChannels(); const slsDetectorDefs::xy modSize = modules[0]->getNumberOfChannels();
if (modSize.x == 0 || modSize.y == 0) {
if (det_size.x == 0 || det_size.y == 0) { throw RuntimeError(
throw sls::RuntimeError(
"Module size for x or y dimensions is 0. Unable to proceed in " "Module size for x or y dimensions is 0. Unable to proceed in "
"updating detector size. "); "updating detector size. ");
} }
int maxx = shm()->numberOfChannels.x; int maxx = shm()->numberOfChannels.x;
int maxy = shm()->numberOfChannels.y; int maxy = shm()->numberOfChannels.y;
int ndetx = 0, ndety = 0; int nModx = 0, nMody = 0;
// 1d, add modules along x axis // 1d, add modules along x axis
if (det_size.y == 1) { if (modSize.y == 1) {
if (maxx == 0) { if (maxx == 0) {
maxx = det_size.x * size(); maxx = modSize.x * size();
} }
ndetx = maxx / det_size.x; nModx = maxx / modSize.x;
ndety = size() / ndetx; nMody = size() / nModx;
if ((maxx % det_size.x) > 0) { if ((maxx % modSize.x) > 0) {
++ndety; ++nMody;
} }
} }
// 2d, add modules along y axis (due to eiger top/bottom) // 2d, add modules along y axis (due to eiger top/bottom)
else { else {
if (maxy == 0) { if (maxy == 0) {
maxy = det_size.y * size(); maxy = modSize.y * size();
} }
ndety = maxy / det_size.y; nMody = maxy / modSize.y;
ndetx = size() / ndety; nModx = size() / nMody;
if ((maxy % det_size.y) > 0) { if ((maxy % modSize.y) > 0) {
++ndetx; ++nModx;
} }
} }
shm()->numberOfModule.x = ndetx; shm()->numberOfModules.x = nModx;
shm()->numberOfModule.y = ndety; shm()->numberOfModules.y = nMody;
shm()->numberOfChannels.x = det_size.x * ndetx; shm()->numberOfChannels.x = modSize.x * nModx;
shm()->numberOfChannels.y = det_size.y * ndety; shm()->numberOfChannels.y = modSize.y * nMody;
LOG(logDEBUG) << "\n\tNumber of Modules in X direction:" LOG(logDEBUG) << "\n\tNumber of Modules in X direction:"
<< shm()->numberOfModule.x << shm()->numberOfModules.x
<< "\n\tNumber of Modules in Y direction:" << "\n\tNumber of Modules in Y direction:"
<< shm()->numberOfModule.y << shm()->numberOfModules.y
<< "\n\tNumber of Channels in X direction:" << "\n\tNumber of Channels in X direction:"
<< shm()->numberOfChannels.x << shm()->numberOfChannels.x
<< "\n\tNumber of Channels in Y direction:" << "\n\tNumber of Channels in Y direction:"
@ -378,7 +381,7 @@ void DetectorImpl::updateDetectorSize() {
for (auto &module : modules) { for (auto &module : modules) {
if (module->getUpdateMode() == 0) { if (module->getUpdateMode() == 0) {
module->updateNumberOfModule(shm()->numberOfModule); module->updateNumberOfModule(shm()->numberOfModules);
} }
} }
} }
@ -386,7 +389,7 @@ void DetectorImpl::updateDetectorSize() {
int DetectorImpl::size() const { return modules.size(); } int DetectorImpl::size() const { return modules.size(); }
slsDetectorDefs::xy DetectorImpl::getNumberOfModules() const { slsDetectorDefs::xy DetectorImpl::getNumberOfModules() const {
return shm()->numberOfModule; return shm()->numberOfModules;
} }
slsDetectorDefs::xy DetectorImpl::getNumberOfChannels() const { slsDetectorDefs::xy DetectorImpl::getNumberOfChannels() const {
@ -412,7 +415,7 @@ void DetectorImpl::setGapPixelsinCallback(const bool enable) {
if (size() && modules[0]->getQuad()) { if (size() && modules[0]->getQuad()) {
break; break;
} }
if (shm()->numberOfModule.y % 2 != 0) { if (shm()->numberOfModules.y % 2 != 0) {
throw RuntimeError("Gap pixels can only be used " throw RuntimeError("Gap pixels can only be used "
"for full modules."); "for full modules.");
} }
@ -455,7 +458,7 @@ int DetectorImpl::createReceivingDataSockets() {
portnum += (iSocket % numUDPInterfaces); portnum += (iSocket % numUDPInterfaces);
try { try {
zmqSocket.push_back( zmqSocket.push_back(
sls::make_unique<ZmqSocket>(modules[iSocket / numUDPInterfaces] make_unique<ZmqSocket>(modules[iSocket / numUDPInterfaces]
->getClientStreamingIP() ->getClientStreamingIP()
.str() .str()
.c_str(), .c_str(),
@ -465,7 +468,7 @@ int DetectorImpl::createReceivingDataSockets() {
if (hwm >= 0) { if (hwm >= 0) {
zmqSocket[iSocket]->SetReceiveHighWaterMark(hwm); zmqSocket[iSocket]->SetReceiveHighWaterMark(hwm);
if (zmqSocket[iSocket]->GetReceiveHighWaterMark() != hwm) { if (zmqSocket[iSocket]->GetReceiveHighWaterMark() != hwm) {
throw sls::ZmqSocketError("Could not set zmq rcv hwm to " + throw ZmqSocketError("Could not set zmq rcv hwm to " +
std::to_string(hwm)); std::to_string(hwm));
} }
} }
@ -495,6 +498,7 @@ void DetectorImpl::readFrameFromReceiver() {
bool quadEnable = false; bool quadEnable = false;
// to flip image // to flip image
bool eiger = false; bool eiger = false;
std::array<int, 4> rxRoi = shm()->rx_roi.getIntArray();
std::vector<bool> runningList(zmqSocket.size()); std::vector<bool> runningList(zmqSocket.size());
std::vector<bool> connectList(zmqSocket.size()); std::vector<bool> connectList(zmqSocket.size());
@ -562,8 +566,8 @@ void DetectorImpl::readFrameFromReceiver() {
// allocate // allocate
size = zHeader.imageSize; size = zHeader.imageSize;
multisize = size * zmqSocket.size(); multisize = size * zmqSocket.size();
image = sls::make_unique<char[]>(size); image = make_unique<char[]>(size);
multiframe = sls::make_unique<char[]>(multisize); multiframe = make_unique<char[]>(multisize);
memset(multiframe.get(), 0xFF, multisize); memset(multiframe.get(), 0xFF, multisize);
// dynamic range // dynamic range
dynamicRange = zHeader.dynamicRange; dynamicRange = zHeader.dynamicRange;
@ -571,7 +575,7 @@ void DetectorImpl::readFrameFromReceiver() {
// shape // shape
nPixelsX = zHeader.npixelsx; nPixelsX = zHeader.npixelsx;
nPixelsY = zHeader.npixelsy; nPixelsY = zHeader.npixelsy;
// module shape (port) // port geometry
nX = zHeader.ndetx; nX = zHeader.ndetx;
nY = zHeader.ndety; nY = zHeader.ndety;
nDetPixelsX = nX * nPixelsX; nDetPixelsX = nX * nPixelsX;
@ -668,6 +672,7 @@ void DetectorImpl::readFrameFromReceiver() {
<< "\n\t databytes: " << multisize << "\n\t databytes: " << multisize
<< "\n\t dynamicRange: " << dynamicRange; << "\n\t dynamicRange: " << dynamicRange;
// send data to callback // send data to callback
if (data) { if (data) {
char *callbackImage = multiframe.get(); char *callbackImage = multiframe.get();
@ -691,7 +696,7 @@ void DetectorImpl::readFrameFromReceiver() {
thisData = new detectorData(currentProgress, currentFileName, thisData = new detectorData(currentProgress, currentFileName,
nDetActualPixelsX, nDetActualPixelsY, nDetActualPixelsX, nDetActualPixelsY,
callbackImage, imagesize, dynamicRange, callbackImage, imagesize, dynamicRange,
currentFileIndex, completeImage); currentFileIndex, completeImage, rxRoi);
try { try {
dataReady( dataReady(
thisData, currentFrameIndex, thisData, currentFrameIndex,
@ -1032,7 +1037,7 @@ int DetectorImpl::getClientStreamingHwm() const {
return shm()->zmqHwm; return shm()->zmqHwm;
} }
// enabled // enabled
sls::Result<int> result; Result<int> result;
result.reserve(zmqSocket.size()); result.reserve(zmqSocket.size());
for (auto &it : zmqSocket) { for (auto &it : zmqSocket) {
result.push_back(it->GetReceiveHighWaterMark()); result.push_back(it->GetReceiveHighWaterMark());
@ -1043,7 +1048,7 @@ int DetectorImpl::getClientStreamingHwm() const {
void DetectorImpl::setClientStreamingHwm(const int limit) { void DetectorImpl::setClientStreamingHwm(const int limit) {
if (limit < -1) { if (limit < -1) {
throw sls::RuntimeError( throw RuntimeError(
"Cannot set hwm to less than -1 (-1 is lib default)."); "Cannot set hwm to less than -1 (-1 is lib default).");
} }
// update shm // update shm
@ -1057,7 +1062,7 @@ void DetectorImpl::setClientStreamingHwm(const int limit) {
it->SetReceiveHighWaterMark(limit); it->SetReceiveHighWaterMark(limit);
if (it->GetReceiveHighWaterMark() != limit) { if (it->GetReceiveHighWaterMark() != limit) {
shm()->zmqHwm = -1; shm()->zmqHwm = -1;
throw sls::ZmqSocketError("Could not set zmq rcv hwm to " + throw ZmqSocketError("Could not set zmq rcv hwm to " +
std::to_string(limit)); std::to_string(limit));
} }
} }
@ -1094,9 +1099,6 @@ int DetectorImpl::acquire() {
return FAIL; return FAIL;
} }
// We need this to handle Mythen3 synchronization
auto detector_type = Parallel(&Module::getDetectorType, {}).squash();
try { try {
struct timespec begin, end; struct timespec begin, end;
clock_gettime(CLOCK_REALTIME, &begin); clock_gettime(CLOCK_REALTIME, &begin);
@ -1124,25 +1126,7 @@ int DetectorImpl::acquire() {
// start and read all // start and read all
try { try {
if (detector_type == defs::MYTHEN3 && modules.size() > 1) { startAcquisition(true, {});
// Multi module mythen
std::vector<int> master;
std::vector<int> slaves;
auto is_master = Parallel(&Module::isMaster, {});
slaves.reserve(modules.size() - 1); // check this one!!
for (size_t i = 0; i < modules.size(); ++i) {
if (is_master[i])
master.push_back(i);
else
slaves.push_back(i);
}
Parallel(&Module::startAcquisition, slaves);
Parallel(&Module::startAndReadAll, master);
} else {
// Normal acquire
Parallel(&Module::startAndReadAll, {});
}
} catch (...) { } catch (...) {
if (receiver) if (receiver)
Parallel(&Module::stopReceiver, {}); Parallel(&Module::stopReceiver, {});
@ -1191,6 +1175,45 @@ int DetectorImpl::acquire() {
return OK; return OK;
} }
void DetectorImpl::startAcquisition(bool blocking, std::vector<int> positions) {
// handle Mythen3 synchronization
if (shm()->detType == defs::MYTHEN3 && size() > 1) {
std::vector<int> master;
std::vector<int> slaves;
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
// could be all slaves in positions
slaves.reserve(positions.size());
auto is_master = Parallel(&Module::isMaster, positions);
for (size_t i : positions) {
if (is_master[i])
master.push_back(i);
else
slaves.push_back(i);
}
if (!slaves.empty()) {
Parallel(&Module::startAcquisition, slaves);
}
if (!master.empty()) {
if (blocking) {
Parallel(&Module::startAndReadAll, master);
} else {
Parallel(&Module::startAcquisition, master);
}
}
} else {
if (blocking) {
Parallel(&Module::startAndReadAll, positions);
} else {
Parallel(&Module::startAcquisition, positions);
}
}
}
void DetectorImpl::printProgress(double progress) { void DetectorImpl::printProgress(double progress) {
// spaces for python printout // spaces for python printout
std::cout << " " << std::fixed << std::setprecision(2) << std::setw(6) std::cout << " " << std::fixed << std::setprecision(2) << std::setw(6)
@ -1313,7 +1336,7 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
} }
// get srcSize to print progress // get srcSize to print progress
ssize_t srcSize = sls::getFileSize(src, "Program FPGA"); ssize_t srcSize = getFileSize(src, "Program FPGA");
// create temp destination file // create temp destination file
char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX"; char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX";
@ -1394,7 +1417,7 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
return buffer; return buffer;
} }
sls::Result<int> DetectorImpl::getDefaultDac(defs::dacIndex index, Result<int> DetectorImpl::getDefaultDac(defs::dacIndex index,
defs::detectorSettings sett, defs::detectorSettings sett,
Positions pos) { Positions pos) {
return Parallel(&Module::getDefaultDac, pos, index, sett); return Parallel(&Module::getDefaultDac, pos, index, sett);
@ -1405,6 +1428,218 @@ void DetectorImpl::setDefaultDac(defs::dacIndex index, int defaultValue,
Parallel(&Module::setDefaultDac, pos, index, defaultValue, sett); Parallel(&Module::setDefaultDac, pos, index, defaultValue, sett);
} }
defs::xy DetectorImpl::getPortGeometry() const {
defs::xy portGeometry(1, 1);
switch (shm()->detType) {
case EIGER:
portGeometry.x = modules[0]->getNumberofUDPInterfacesFromShm();
break;
case JUNGFRAU:
portGeometry.y = modules[0]->getNumberofUDPInterfacesFromShm();
break;
default:
break;
}
return portGeometry;
}
defs::xy DetectorImpl::calculatePosition(int moduleIndex,
defs::xy geometry) const {
defs::xy pos{};
int maxYMods = shm()->numberOfModules.y;
pos.y = (moduleIndex % maxYMods) * geometry.y;
pos.x = (moduleIndex / maxYMods) * geometry.x;
return pos;
}
defs::ROI DetectorImpl::getRxROI() const {
if (shm()->detType == CHIPTESTBOARD || shm()->detType == MOENCH) {
throw RuntimeError("RxRoi not implemented for this Detector");
}
if (modules.size() == 0) {
throw RuntimeError("No Modules added");
}
// complete detector in roi
auto t = Parallel(&Module::getRxROI, {});
if (t.equal() && t.front().completeRoi()) {
LOG(logDEBUG) << "no roi";
return defs::ROI (0, shm()->numberOfChannels.x - 1, 0, shm()->numberOfChannels.y - 1);
}
defs::xy numChansPerMod = modules[0]->getNumberOfChannels();
bool is2D = (numChansPerMod.y > 1 ? true : false);
defs::xy geometry = getPortGeometry();
defs::ROI retval{};
for (size_t iModule = 0; iModule != modules.size(); ++iModule) {
defs::ROI moduleRoi = modules[iModule]->getRxROI();
if (moduleRoi.noRoi()) {
LOG(logDEBUG) << iModule << ": no roi";
} else {
// expand complete roi
if (moduleRoi.completeRoi()) {
moduleRoi.xmin = 0;
moduleRoi.xmax = numChansPerMod.x;
if (is2D) {
moduleRoi.ymin = 0;
moduleRoi.ymax = numChansPerMod.y;
}
}
LOG(logDEBUG) << iModule << ": " << moduleRoi;
// get roi at detector level
defs::xy pos = calculatePosition(iModule, geometry);
defs::ROI moduleFullRoi{};
moduleFullRoi.xmin = numChansPerMod.x * pos.x + moduleRoi.xmin;
moduleFullRoi.xmax = numChansPerMod.x * pos.x + moduleRoi.xmax;
if (is2D) {
moduleFullRoi.ymin = numChansPerMod.y * pos.y + moduleRoi.ymin;
moduleFullRoi.ymax = numChansPerMod.y * pos.y + moduleRoi.ymax;
}
LOG(logDEBUG) << iModule << ": (full roi)" << moduleFullRoi;
// get min and max
if (retval.xmin == -1 || moduleFullRoi.xmin < retval.xmin) {
LOG(logDEBUG) << iModule << ": xmin updated";
retval.xmin = moduleFullRoi.xmin;
}
if (retval.xmax == -1 || moduleFullRoi.xmax > retval.xmax) {
LOG(logDEBUG) << iModule << ": xmax updated";
retval.xmax = moduleFullRoi.xmax;
}
if (retval.ymin == -1 || moduleFullRoi.ymin < retval.ymin) {
LOG(logDEBUG) << iModule << ": ymin updated";
retval.ymin = moduleFullRoi.ymin;
}
if (retval.ymax == -1 || moduleFullRoi.ymax > retval.ymax) {
LOG(logDEBUG) << iModule << ": ymax updated";
retval.ymax = moduleFullRoi.ymax;
}
}
LOG(logDEBUG) << iModule << ": (retval): " << retval;
}
if (retval.ymin == -1) {
retval.ymin = 0;
retval.ymax = 0;
}
return retval;
}
void DetectorImpl::setRxROI(const defs::ROI arg) {
if (shm()->detType == CHIPTESTBOARD || shm()->detType == MOENCH) {
throw RuntimeError("RxRoi not implemented for this Detector");
}
if (modules.size() == 0) {
throw RuntimeError("No Modules added");
}
if (arg.noRoi()) {
throw RuntimeError("Invalid Roi of size 0.");
}
if (arg.completeRoi()) {
throw RuntimeError("Did you mean the clear roi command (API: clearRxROI, cmd: rx_clearroi)?");
}
if (arg.xmin > arg.xmax || arg.ymin > arg.ymax) {
throw RuntimeError("Invalid Receiver Roi. xmin/ymin exceeds xmax/ymax.");
}
defs::xy numChansPerMod = modules[0]->getNumberOfChannels();
bool is2D = (numChansPerMod.y > 1 ? true : false);
defs::xy geometry = getPortGeometry();
if (!is2D && ((arg.ymin != -1 && arg.ymin != 0) || (arg.ymax != -1 && arg.ymax != 0))) {
throw RuntimeError("Invalid Receiver roi. Cannot set 2d roi for a 1d detector.");
}
if (arg.xmin < 0 || arg.xmax >= shm()->numberOfChannels.x || (is2D && (arg.ymin < 0 || arg.ymax >= shm()->numberOfChannels.y))) {
throw RuntimeError("Invalid Receiver Roi. Outside detector range.");
}
for (size_t iModule = 0; iModule != modules.size(); ++iModule) {
// default init = complete roi
defs::ROI moduleRoi{};
// incomplete roi
if (!arg.completeRoi()) {
// multi module Gotthard2
if (shm()->detType == GOTTHARD2 && size() > 1) {
moduleRoi.xmin = arg.xmin / 2;
moduleRoi.xmax = arg.xmax / 2;
if (iModule == 0) {
// all should be even
if (arg.xmin % 2 != 0) {
++moduleRoi.xmin;
}
} else if (iModule == 1) {
// all should be odd
if (arg.xmax % 2 == 0) {
--moduleRoi.xmax;
}
} else {
throw RuntimeError("Cannot have more than 2 modules for a Gotthard2 detector");
}
} else {
// get module limits
defs::xy pos = calculatePosition(iModule, geometry);
defs::ROI moduleFullRoi{};
moduleFullRoi.xmin = numChansPerMod.x * pos.x;
moduleFullRoi.xmax = numChansPerMod.x * (pos.x + 1) - 1;
if (is2D) {
moduleFullRoi.ymin = numChansPerMod.y * pos.y;
moduleFullRoi.ymax = numChansPerMod.y * (pos.y + 1) - 1;
}
// no roi
if (arg.xmin > moduleFullRoi.xmax ||
arg.xmax < moduleFullRoi.xmin ||
(is2D && (arg.ymin > moduleFullRoi.ymax ||
arg.ymax < moduleFullRoi.ymin))) {
moduleRoi.setNoRoi();
}
// incomplete module roi
else if (arg.xmin > moduleFullRoi.xmin ||
arg.xmax < moduleFullRoi.xmax ||
(is2D && (arg.ymin > moduleFullRoi.ymin ||
arg.ymax < moduleFullRoi.ymax))) {
moduleRoi.xmin = (arg.xmin <= moduleFullRoi.xmin)
? 0
: (arg.xmin % numChansPerMod.x);
moduleRoi.xmax = (arg.xmax >= moduleFullRoi.xmax)
? numChansPerMod.x - 1
: (arg.xmax % numChansPerMod.x);
if (is2D) {
moduleRoi.ymin = (arg.ymin <= moduleFullRoi.ymin)
? 0
: (arg.ymin % numChansPerMod.y);
moduleRoi.ymax = (arg.ymax >= moduleFullRoi.ymax)
? numChansPerMod.y - 1
: (arg.ymax % numChansPerMod.y);
}
}
}
}
modules[iModule]->setRxROI(moduleRoi);
}
// updating shm rx_roi for gui purposes
shm()->rx_roi = arg;
// metadata
if (arg.completeRoi()) {
modules[0]->setRxROIMetadata(defs::ROI (0, shm()->numberOfChannels.x - 1, 0, shm()->numberOfChannels.y - 1));
} else {
modules[0]->setRxROIMetadata(arg);
}
}
void DetectorImpl::clearRxROI() {
Parallel(&Module::setRxROI, {}, defs::ROI{});
shm()->rx_roi.xmin = -1;
shm()->rx_roi.ymin = -1;
shm()->rx_roi.xmax = -1;
shm()->rx_roi.ymax = -1;
}
std::vector<std::string> DetectorImpl::getCtbDacNames() const { std::vector<std::string> DetectorImpl::getCtbDacNames() const {
return ctb_shm()->getDacNames(); return ctb_shm()->getDacNames();
} }

View File

@ -6,11 +6,7 @@
#include "sls/Result.h" #include "sls/Result.h"
#include "sls/logger.h" #include "sls/logger.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "CtbConfig.h" #include "CtbConfig.h"
class ZmqSocket;
class detectorData;
#include <memory> #include <memory>
#include <mutex> #include <mutex>
@ -18,18 +14,19 @@ class detectorData;
#include <string> #include <string>
#include <thread> #include <thread>
#include <vector> #include <vector>
#define DETECTOR_SHMAPIVERSION 0x190809
#define DETECTOR_SHMVERSION 0x201007
#define SHORT_STRING_LENGTH 50
#include <future> #include <future>
#include <numeric> #include <numeric>
namespace sls { namespace sls {
class ZmqSocket;
class detectorData;
class Module; class Module;
#define DETECTOR_SHMAPIVERSION 0x190809
#define DETECTOR_SHMVERSION 0x220505
#define SHORT_STRING_LENGTH 50
/** /**
* @short structure allocated in shared memory to store detector settings * @short structure allocated in shared memory to store detector settings
* for IPC and cache * for IPC and cache
@ -51,14 +48,14 @@ struct sharedDetector {
/** last time stamp when accessing the shared memory */ /** last time stamp when accessing the shared memory */
char lastDate[SHORT_STRING_LENGTH]; char lastDate[SHORT_STRING_LENGTH];
int numberOfModules; int totalNumberOfModules;
slsDetectorDefs::detectorType detType; slsDetectorDefs::detectorType detType;
/** END OF FIXED PATTERN /** END OF FIXED PATTERN
* -----------------------------------------------*/ * -----------------------------------------------*/
/** Number of modules operated at once */ /** Number of modules operated at once */
slsDetectorDefs::xy numberOfModule; slsDetectorDefs::xy numberOfModules;
/** max number of channels for complete detector*/ /** max number of channels for complete detector*/
slsDetectorDefs::xy numberOfChannels; slsDetectorDefs::xy numberOfChannels;
@ -68,6 +65,8 @@ struct sharedDetector {
bool gapPixels; bool gapPixels;
/** high water mark of listening tcp port (only data) */ /** high water mark of listening tcp port (only data) */
int zmqHwm; int zmqHwm;
/** in shm for gui purposes */
defs::ROI rx_roi{};
}; };
class DetectorImpl : public virtual slsDetectorDefs { class DetectorImpl : public virtual slsDetectorDefs {
@ -87,12 +86,12 @@ class DetectorImpl : public virtual slsDetectorDefs {
template <class CT> struct NonDeduced { using type = CT; }; template <class CT> struct NonDeduced { using type = CT; };
template <typename RT, typename... CT> template <typename RT, typename... CT>
sls::Result<RT> Parallel(RT (sls::Module::*somefunc)(CT...), Result<RT> Parallel(RT (Module::*somefunc)(CT...),
std::vector<int> positions, std::vector<int> positions,
typename NonDeduced<CT>::type... Args) { typename NonDeduced<CT>::type... Args) {
if (modules.empty()) if (modules.empty())
throw sls::RuntimeError("No modules added"); throw RuntimeError("No modules added");
if (positions.empty() || if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) { (positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size()); positions.resize(modules.size());
@ -102,11 +101,11 @@ class DetectorImpl : public virtual slsDetectorDefs {
futures.reserve(positions.size()); futures.reserve(positions.size());
for (size_t i : positions) { for (size_t i : positions) {
if (i >= modules.size()) if (i >= modules.size())
throw sls::RuntimeError("Module out of range"); throw RuntimeError("Module out of range");
futures.push_back(std::async(std::launch::async, somefunc, futures.push_back(std::async(std::launch::async, somefunc,
modules[i].get(), Args...)); modules[i].get(), Args...));
} }
sls::Result<RT> result; Result<RT> result;
result.reserve(positions.size()); result.reserve(positions.size());
for (auto &i : futures) { for (auto &i : futures) {
result.push_back(i.get()); result.push_back(i.get());
@ -115,12 +114,12 @@ class DetectorImpl : public virtual slsDetectorDefs {
} }
template <typename RT, typename... CT> template <typename RT, typename... CT>
sls::Result<RT> Parallel(RT (sls::Module::*somefunc)(CT...) const, Result<RT> Parallel(RT (Module::*somefunc)(CT...) const,
std::vector<int> positions, std::vector<int> positions,
typename NonDeduced<CT>::type... Args) const { typename NonDeduced<CT>::type... Args) const {
if (modules.empty()) if (modules.empty())
throw sls::RuntimeError("No modules added"); throw RuntimeError("No modules added");
if (positions.empty() || if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) { (positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size()); positions.resize(modules.size());
@ -130,11 +129,11 @@ class DetectorImpl : public virtual slsDetectorDefs {
futures.reserve(positions.size()); futures.reserve(positions.size());
for (size_t i : positions) { for (size_t i : positions) {
if (i >= modules.size()) if (i >= modules.size())
throw sls::RuntimeError("Module out of range"); throw RuntimeError("Module out of range");
futures.push_back(std::async(std::launch::async, somefunc, futures.push_back(std::async(std::launch::async, somefunc,
modules[i].get(), Args...)); modules[i].get(), Args...));
} }
sls::Result<RT> result; Result<RT> result;
result.reserve(positions.size()); result.reserve(positions.size());
for (auto &i : futures) { for (auto &i : futures) {
result.push_back(i.get()); result.push_back(i.get());
@ -143,12 +142,12 @@ class DetectorImpl : public virtual slsDetectorDefs {
} }
template <typename... CT> template <typename... CT>
void Parallel(void (sls::Module::*somefunc)(CT...), void Parallel(void (Module::*somefunc)(CT...),
std::vector<int> positions, std::vector<int> positions,
typename NonDeduced<CT>::type... Args) { typename NonDeduced<CT>::type... Args) {
if (modules.empty()) if (modules.empty())
throw sls::RuntimeError("No modules added"); throw RuntimeError("No modules added");
if (positions.empty() || if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) { (positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size()); positions.resize(modules.size());
@ -158,7 +157,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
futures.reserve(positions.size()); futures.reserve(positions.size());
for (size_t i : positions) { for (size_t i : positions) {
if (i >= modules.size()) if (i >= modules.size())
throw sls::RuntimeError("Module out of range"); throw RuntimeError("Module out of range");
futures.push_back(std::async(std::launch::async, somefunc, futures.push_back(std::async(std::launch::async, somefunc,
modules[i].get(), Args...)); modules[i].get(), Args...));
} }
@ -168,12 +167,12 @@ class DetectorImpl : public virtual slsDetectorDefs {
} }
template <typename... CT> template <typename... CT>
void Parallel(void (sls::Module::*somefunc)(CT...) const, void Parallel(void (Module::*somefunc)(CT...) const,
std::vector<int> positions, std::vector<int> positions,
typename NonDeduced<CT>::type... Args) const { typename NonDeduced<CT>::type... Args) const {
if (modules.empty()) if (modules.empty())
throw sls::RuntimeError("No modules added"); throw RuntimeError("No modules added");
if (positions.empty() || if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) { (positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size()); positions.resize(modules.size());
@ -183,7 +182,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
futures.reserve(positions.size()); futures.reserve(positions.size());
for (size_t i : positions) { for (size_t i : positions) {
if (i >= modules.size()) if (i >= modules.size())
throw sls::RuntimeError("Module out of range"); throw RuntimeError("Module out of range");
futures.push_back(std::async(std::launch::async, somefunc, futures.push_back(std::async(std::launch::async, somefunc,
modules[i].get(), Args...)); modules[i].get(), Args...));
} }
@ -278,6 +277,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/ */
int acquire(); int acquire();
/** also takes care of master and slave for multi module mythen */
void startAcquisition(bool blocking, std::vector<int> positions);
/** /**
* Combines data from all readouts and gives it to the gui * Combines data from all readouts and gives it to the gui
* or just gives progress of acquisition by polling receivers * or just gives progress of acquisition by polling receivers
@ -294,16 +296,18 @@ class DetectorImpl : public virtual slsDetectorDefs {
std::vector<char> readProgrammingFile(const std::string &fname); std::vector<char> readProgrammingFile(const std::string &fname);
void setNumberofUDPInterfaces(int n, Positions pos); void setNumberofUDPInterfaces(int n, Positions pos);
sls::Result<int> getDefaultDac(defs::dacIndex index, Result<int> getDefaultDac(defs::dacIndex index,
defs::detectorSettings sett, defs::detectorSettings sett,
Positions pos = {}); Positions pos = {});
void setDefaultDac(defs::dacIndex index, int defaultValue, void setDefaultDac(defs::dacIndex index, int defaultValue,
defs::detectorSettings sett, Positions pos); defs::detectorSettings sett, Positions pos);
defs::ROI getRxROI() const;
void setRxROI(const defs::ROI arg);
void clearRxROI();
std::vector<std::string> getCtbDacNames() const; std::vector<std::string> getCtbDacNames() const;
std::string getCtbDacName(defs::dacIndex i) const; std::string getCtbDacName(defs::dacIndex i) const;
void setCtbDacNames(const std::vector<std::string>& names); void setCtbDacNames(const std::vector<std::string> &names);
private: private:
/** /**
@ -386,10 +390,13 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/ */
int kbhit(); int kbhit();
defs::xy getPortGeometry() const;
defs::xy calculatePosition(int moduleIndex, defs::xy geometry) const;
const int detectorIndex{0}; const int detectorIndex{0};
sls::SharedMemory<sharedDetector> shm{0, -1}; SharedMemory<sharedDetector> shm{0, -1};
sls::SharedMemory<CtbConfig> ctb_shm{0, -1, CtbConfig::shm_tag()}; SharedMemory<CtbConfig> ctb_shm{0, -1, CtbConfig::shm_tag()};
std::vector<std::unique_ptr<sls::Module>> modules; std::vector<std::unique_ptr<Module>> modules;
/** data streaming (down stream) enabled in client (zmq sckets created) */ /** data streaming (down stream) enabled in client (zmq sckets created) */
bool client_downstream{false}; bool client_downstream{false};

View File

@ -2,6 +2,8 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#include "sls/string_utils.h" #include "sls/string_utils.h"
namespace sls {
std::string GetHelpDac(std::string dac) { std::string GetHelpDac(std::string dac) {
if (sls::is_int(dac)) { if (sls::is_int(dac)) {
return std::string("[dac name] [dac or mV value] [(optional unit) mV] " return std::string("[dac name] [dac or mV value] [(optional unit) mV] "
@ -303,4 +305,6 @@ std::string GetHelpDac(std::string dac) {
// clang-format on // clang-format on
throw sls::RuntimeError("Unknown dac command"); throw sls::RuntimeError("Unknown dac command");
} }
} // namespace sls

View File

@ -68,7 +68,7 @@ std::string Module::getHostname() const { return shm()->hostname; }
void Module::setHostname(const std::string &hostname, void Module::setHostname(const std::string &hostname,
const bool initialChecks) { const bool initialChecks) {
sls::strcpy_safe(shm()->hostname, hostname.c_str()); strcpy_safe(shm()->hostname, hostname.c_str());
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.close(); client.close();
try { try {
@ -117,7 +117,7 @@ int64_t Module::getReceiverSoftwareVersion() const {
slsDetectorDefs::detectorType slsDetectorDefs::detectorType
Module::getTypeFromDetector(const std::string &hostname, int cport) { Module::getTypeFromDetector(const std::string &hostname, int cport) {
LOG(logDEBUG1) << "Getting Module type "; LOG(logDEBUG1) << "Getting Module type ";
sls::ClientSocket socket("Detector", hostname, cport); ClientSocket socket("Detector", hostname, cport);
socket.Send(F_GET_DETECTOR_TYPE); socket.Send(F_GET_DETECTOR_TYPE);
socket.Receive<int>(); // TODO! Should we look at this OK/FAIL? socket.Receive<int>(); // TODO! Should we look at this OK/FAIL?
auto retval = socket.Receive<detectorType>(); auto retval = socket.Receive<detectorType>();
@ -173,7 +173,9 @@ std::array<int, 3> Module::getAllThresholdEnergy() const {
void Module::setThresholdEnergy(int e_eV, detectorSettings isettings, void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits) { bool trimbits) {
if (shm()->detType == MYTHEN3) {
throw RuntimeError("Mythen3 should have called with 3 energies");
}
// verify e_eV exists in trimEneregies[] // verify e_eV exists in trimEneregies[]
if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) || if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) ||
(e_eV > shm()->trimEnergies.back())) { (e_eV > shm()->trimEnergies.back())) {
@ -214,21 +216,9 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
myMod.iodelay = myMod1.iodelay; myMod.iodelay = myMod1.iodelay;
myMod.tau = myMod.tau =
linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau); linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau);
// m3, reg is used for gaincaps
if (shm()->detType == MYTHEN3) {
if (myMod1.reg != myMod2.reg) {
throw RuntimeError(
"setThresholdEnergyAndSettings: gaincaps do not "
"match between files");
}
myMod.reg = myMod1.reg;
}
}
// m3, reg is used for gaincaps
if (shm()->detType != MYTHEN3) {
myMod.reg = isettings;
} }
myMod.reg = isettings;
myMod.eV[0] = e_eV; myMod.eV[0] = e_eV;
setModule(myMod, trimbits); setModule(myMod, trimbits);
if (getSettings() != isettings) { if (getSettings() != isettings) {
@ -243,42 +233,35 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
void Module::setAllThresholdEnergy(std::array<int, 3> e_eV, void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
detectorSettings isettings, bool trimbits) { detectorSettings isettings, bool trimbits) {
// only mythen3 if (shm()->detType != MYTHEN3) {
throw RuntimeError("This detector should have called with 3 energies");
}
if (shm()->trimEnergies.empty()) { if (shm()->trimEnergies.empty()) {
throw RuntimeError( throw RuntimeError(
"Trim energies have not been defined for this module yet!"); "Trim energies have not been defined for this module yet! Use trimen.");
} }
auto counters = getSetBits(getCounterMask());
enum mythen3_DacIndex {
M_VCASSH,
M_VTH2,
M_VRSHAPER,
M_VRSHAPER_N,
M_VIPRE_OUT,
M_VTH3,
M_VTH1,
M_VICIN,
M_VCAS,
M_VRPREAMP,
M_VCAL_N,
M_VIPRE,
M_VISHAPER,
M_VCAL_P,
M_VTRIM,
M_VDCSH
};
std::vector<sls_detector_module> myMods{shm()->detType};
std::vector<int> energy(e_eV.begin(), e_eV.end()); std::vector<int> energy(e_eV.begin(), e_eV.end());
// if all energies are same // if all energies are same
if (allEqualTo(energy, energy[0])) { if (allEqualTo(energy, energy[0])) {
if (energy[0] == -1) {
throw RuntimeError("Every energy provided to set threshold energy is -1. Typo?");
}
energy.resize(1); energy.resize(1);
} }
myMods.resize(energy.size());
// for each threshold // for each threshold
std::vector<sls_detector_module> myMods;
for (size_t i = 0; i < energy.size(); ++i) { for (size_t i = 0; i < energy.size(); ++i) {
if (energy[i] == -1) {
sls_detector_module mod = getModule();
myMods.push_back(mod);
continue;
}
sls_detector_module mod{shm()->detType};
myMods.push_back(mod);
// don't interpolate // don't interpolate
if (shm()->trimEnergies.anyEqualTo(energy[i])) { if (shm()->trimEnergies.anyEqualTo(energy[i])) {
std::string settingsfname = std::string settingsfname =
@ -324,10 +307,9 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
myMods[i] = interpolateTrim(&myMod1, &myMod2, energy[i], trim1, myMods[i] = interpolateTrim(&myMod1, &myMod2, energy[i], trim1,
trim2, trimbits); trim2, trimbits);
// gaincaps // csr
if (myMod1.reg != myMod2.reg) { if (myMod1.reg != myMod2.reg) {
throw RuntimeError("setAllThresholdEnergy: gaincaps do not " throw RuntimeError("setAllThresholdEnergy: chip shift register values do not match between files for energy (eV) " +
"match between files for energy (eV) " +
std::to_string(energy[i])); std::to_string(energy[i]));
} }
myMods[i].reg = myMod1.reg; myMods[i].reg = myMod1.reg;
@ -337,8 +319,11 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
sls_detector_module myMod{shm()->detType}; sls_detector_module myMod{shm()->detType};
myMod = myMods[0]; myMod = myMods[0];
// if multiple thresholds, combine // if multiple thresholds, combine
if (myMods.size() > 1) { if (myMods.size() > 1) {
auto counters = getSetBits(getCounterMask());
// average vtrim of enabled counters // average vtrim of enabled counters
int sum = 0; int sum = 0;
@ -377,50 +362,15 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
for (int i = 0; i < myMod.nchan; ++i) { for (int i = 0; i < myMod.nchan; ++i) {
myMod.chanregs[i] = myMods[i % 3].chanregs[i]; myMod.chanregs[i] = myMods[i % 3].chanregs[i];
} }
// gain caps // csr
if (myMods[0].reg != myMods[1].reg || myMods[1].reg != myMods[2].reg) { if (myMods[0].reg != myMods[1].reg || myMods[1].reg != myMods[2].reg) {
throw RuntimeError("setAllThresholdEnergy: gaincaps do not " throw RuntimeError("setAllThresholdEnergy: chip shift register values do not match between files for all energies");
"match between files for all energies");
} }
} }
myMod.reg = isettings;
std::copy(e_eV.begin(), e_eV.end(), myMod.eV); std::copy(e_eV.begin(), e_eV.end(), myMod.eV);
LOG(logDEBUG) << "ev:" << ToString(myMod.eV); LOG(logDEBUG) << "ev:" << ToString(myMod.eV);
// check for trimbits that are out of range
bool out_of_range = false;
for (int i = 0; i != myMod.nchan; ++i) {
if (myMod.chanregs[i] < 0) {
myMod.chanregs[i] = 0;
out_of_range = true;
} else if (myMod.chanregs[i] > 63) {
myMod.chanregs[i] = 63;
out_of_range = true;
}
}
if (out_of_range) {
LOG(logWARNING)
<< "Some trimbits were out of range after interpolation, these "
"have been replaced with 0 or 63.";
}
// check dacs
out_of_range = false;
for (auto dac : {M_VTRIM, M_VTH1, M_VTH2, M_VTH3}) {
if (myMod.dacs[dac] < 600) {
myMod.dacs[dac] = 600;
out_of_range = true;
} else if (myMod.dacs[dac] > 2400) {
myMod.dacs[dac] = 2400;
out_of_range = true;
}
}
if (out_of_range) {
LOG(logWARNING) << "Some dacs were out of range after interpolation, "
"these have been replaced with 600 or 2400.";
}
setModule(myMod, trimbits); setModule(myMod, trimbits);
if (getSettings() != isettings) { if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set " throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
@ -437,7 +387,7 @@ std::string Module::getSettingsDir() const {
} }
std::string Module::setSettingsDir(const std::string &dir) { std::string Module::setSettingsDir(const std::string &dir) {
sls::strcpy_safe(shm()->settingsDir, dir.c_str()); strcpy_safe(shm()->settingsDir, dir.c_str());
return shm()->settingsDir; return shm()->settingsDir;
} }
@ -462,6 +412,27 @@ void Module::loadTrimbits(const std::string &fname) {
} }
} }
void Module::saveTrimbits(const std::string &fname) {
// find specific file if it has detid in file name (.snxxx)
if (shm()->detType == EIGER || shm()->detType == MYTHEN3) {
std::ostringstream ostfn;
ostfn << fname;
int moduleIdWidth = 3;
if (shm()->detType == MYTHEN3) {
moduleIdWidth = 4;
}
if ((fname.find(".sn") == std::string::npos) &&
(fname.find(".trim") == std::string::npos)) {
ostfn << ".sn" << std::setfill('0') << std::setw(moduleIdWidth)
<< std::dec << getModuleId();
}
auto myMod = getModule();
saveSettingsFile(myMod, ostfn.str());
} else {
throw RuntimeError("not implemented for this detector");
}
}
int Module::getAllTrimbits() const { int Module::getAllTrimbits() const {
return sendToDetector<int>(F_SET_ALL_TRIMBITS, GET_FLAG); return sendToDetector<int>(F_SET_ALL_TRIMBITS, GET_FLAG);
} }
@ -888,7 +859,7 @@ std::vector<int64_t> Module::getFramesCaughtByReceiver() const {
std::vector<int64_t> retval(nports); std::vector<int64_t> retval(nports);
client.Receive(retval); client.Receive(retval);
LOG(logDEBUG1) << "Frames caught of Receiver" << moduleIndex << ": " LOG(logDEBUG1) << "Frames caught of Receiver" << moduleIndex << ": "
<< sls::ToString(retval); << ToString(retval);
return retval; return retval;
} }
} }
@ -910,7 +881,7 @@ std::vector<int64_t> Module::getNumMissingPackets() const {
std::vector<int64_t> retval(nports); std::vector<int64_t> retval(nports);
client.Receive(retval); client.Receive(retval);
LOG(logDEBUG1) << "Missing packets of Receiver" << moduleIndex LOG(logDEBUG1) << "Missing packets of Receiver" << moduleIndex
<< ": " << sls::ToString(retval); << ": " << ToString(retval);
return retval; return retval;
} }
} }
@ -932,7 +903,7 @@ std::vector<int64_t> Module::getReceiverCurrentFrameIndex() const {
std::vector<int64_t> retval(nports); std::vector<int64_t> retval(nports);
client.Receive(retval); client.Receive(retval);
LOG(logDEBUG1) << "Frame index of Receiver" << moduleIndex << ": " LOG(logDEBUG1) << "Frame index of Receiver" << moduleIndex << ": "
<< sls::ToString(retval); << ToString(retval);
return retval; return retval;
} }
} }
@ -996,8 +967,8 @@ void Module::selectUDPInterface(int n) {
sendToDetector(F_SET_INTERFACE_SEL, n, nullptr); sendToDetector(F_SET_INTERFACE_SEL, n, nullptr);
} }
sls::IpAddr Module::getSourceUDPIP() const { IpAddr Module::getSourceUDPIP() const {
return sendToDetector<sls::IpAddr>(F_GET_SOURCE_UDP_IP); return sendToDetector<IpAddr>(F_GET_SOURCE_UDP_IP);
} }
void Module::setSourceUDPIP(const IpAddr ip) { void Module::setSourceUDPIP(const IpAddr ip) {
@ -1007,8 +978,8 @@ void Module::setSourceUDPIP(const IpAddr ip) {
sendToDetector(F_SET_SOURCE_UDP_IP, ip, nullptr); sendToDetector(F_SET_SOURCE_UDP_IP, ip, nullptr);
} }
sls::IpAddr Module::getSourceUDPIP2() const { IpAddr Module::getSourceUDPIP2() const {
return sendToDetector<sls::IpAddr>(F_GET_SOURCE_UDP_IP2); return sendToDetector<IpAddr>(F_GET_SOURCE_UDP_IP2);
} }
void Module::setSourceUDPIP2(const IpAddr ip) { void Module::setSourceUDPIP2(const IpAddr ip) {
@ -1018,33 +989,33 @@ void Module::setSourceUDPIP2(const IpAddr ip) {
sendToDetector(F_SET_SOURCE_UDP_IP2, ip, nullptr); sendToDetector(F_SET_SOURCE_UDP_IP2, ip, nullptr);
} }
sls::MacAddr Module::getSourceUDPMAC() const { MacAddr Module::getSourceUDPMAC() const {
return sendToDetector<sls::MacAddr>(F_GET_SOURCE_UDP_MAC); return sendToDetector<MacAddr>(F_GET_SOURCE_UDP_MAC);
} }
void Module::setSourceUDPMAC(const sls::MacAddr mac) { void Module::setSourceUDPMAC(const MacAddr mac) {
if (mac == 0) { if (mac == 0) {
throw RuntimeError("Invalid source udp mac address"); throw RuntimeError("Invalid source udp mac address");
} }
sendToDetector(F_SET_SOURCE_UDP_MAC, mac, nullptr); sendToDetector(F_SET_SOURCE_UDP_MAC, mac, nullptr);
} }
sls::MacAddr Module::getSourceUDPMAC2() const { MacAddr Module::getSourceUDPMAC2() const {
return sendToDetector<sls::MacAddr>(F_GET_SOURCE_UDP_MAC2); return sendToDetector<MacAddr>(F_GET_SOURCE_UDP_MAC2);
} }
void Module::setSourceUDPMAC2(const sls::MacAddr mac) { void Module::setSourceUDPMAC2(const MacAddr mac) {
if (mac == 0) { if (mac == 0) {
throw RuntimeError("Invalid source udp mac address2"); throw RuntimeError("Invalid source udp mac address2");
} }
sendToDetector(F_SET_SOURCE_UDP_MAC2, mac, nullptr); sendToDetector(F_SET_SOURCE_UDP_MAC2, mac, nullptr);
} }
sls::UdpDestination Module::getDestinationUDPList(const uint32_t entry) const { UdpDestination Module::getDestinationUDPList(const uint32_t entry) const {
return sendToDetector<sls::UdpDestination>(F_GET_DEST_UDP_LIST, entry); return sendToDetector<UdpDestination>(F_GET_DEST_UDP_LIST, entry);
} }
void Module::setDestinationUDPList(const sls::UdpDestination dest) { void Module::setDestinationUDPList(const UdpDestination dest) {
// set them in the default way so the receivers are also set up // set them in the default way so the receivers are also set up
if (dest.entry == 0) { if (dest.entry == 0) {
if (dest.port != 0) { if (dest.port != 0) {
@ -1084,8 +1055,8 @@ void Module::setFirstUDPDestination(const int value) {
sendToDetector(F_SET_UDP_FIRST_DEST, value, nullptr); sendToDetector(F_SET_UDP_FIRST_DEST, value, nullptr);
} }
sls::IpAddr Module::getDestinationUDPIP() const { IpAddr Module::getDestinationUDPIP() const {
return sendToDetector<sls::IpAddr>(F_GET_DEST_UDP_IP); return sendToDetector<IpAddr>(F_GET_DEST_UDP_IP);
} }
void Module::setDestinationUDPIP(const IpAddr ip) { void Module::setDestinationUDPIP(const IpAddr ip) {
@ -1098,7 +1069,7 @@ void Module::setDestinationUDPIP(const IpAddr ip) {
} }
sendToDetector(F_SET_DEST_UDP_IP, ip, nullptr); sendToDetector(F_SET_DEST_UDP_IP, ip, nullptr);
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
sls::MacAddr retval(0LU); MacAddr retval(0LU);
sendToReceiver(F_SET_RECEIVER_UDP_IP, ip, retval); sendToReceiver(F_SET_RECEIVER_UDP_IP, ip, retval);
LOG(logINFO) << "Setting destination udp mac of Module " << moduleIndex LOG(logINFO) << "Setting destination udp mac of Module " << moduleIndex
<< " to " << retval; << " to " << retval;
@ -1106,8 +1077,8 @@ void Module::setDestinationUDPIP(const IpAddr ip) {
} }
} }
sls::IpAddr Module::getDestinationUDPIP2() const { IpAddr Module::getDestinationUDPIP2() const {
return sendToDetector<sls::IpAddr>(F_GET_DEST_UDP_IP2); return sendToDetector<IpAddr>(F_GET_DEST_UDP_IP2);
} }
void Module::setDestinationUDPIP2(const IpAddr ip) { void Module::setDestinationUDPIP2(const IpAddr ip) {
@ -1121,7 +1092,7 @@ void Module::setDestinationUDPIP2(const IpAddr ip) {
} }
sendToDetector(F_SET_DEST_UDP_IP2, ip, nullptr); sendToDetector(F_SET_DEST_UDP_IP2, ip, nullptr);
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
sls::MacAddr retval(0LU); MacAddr retval(0LU);
sendToReceiver(F_SET_RECEIVER_UDP_IP2, ip, retval); sendToReceiver(F_SET_RECEIVER_UDP_IP2, ip, retval);
LOG(logINFO) << "Setting destination udp mac2 of Module " << moduleIndex LOG(logINFO) << "Setting destination udp mac2 of Module " << moduleIndex
<< " to " << retval; << " to " << retval;
@ -1129,8 +1100,8 @@ void Module::setDestinationUDPIP2(const IpAddr ip) {
} }
} }
sls::MacAddr Module::getDestinationUDPMAC() const { MacAddr Module::getDestinationUDPMAC() const {
return sendToDetector<sls::MacAddr>(F_GET_DEST_UDP_MAC); return sendToDetector<MacAddr>(F_GET_DEST_UDP_MAC);
} }
void Module::setDestinationUDPMAC(const MacAddr mac) { void Module::setDestinationUDPMAC(const MacAddr mac) {
@ -1140,8 +1111,8 @@ void Module::setDestinationUDPMAC(const MacAddr mac) {
sendToDetector(F_SET_DEST_UDP_MAC, mac, nullptr); sendToDetector(F_SET_DEST_UDP_MAC, mac, nullptr);
} }
sls::MacAddr Module::getDestinationUDPMAC2() const { MacAddr Module::getDestinationUDPMAC2() const {
return sendToDetector<sls::MacAddr>(F_GET_DEST_UDP_MAC2); return sendToDetector<MacAddr>(F_GET_DEST_UDP_MAC2);
} }
void Module::setDestinationUDPMAC2(const MacAddr mac) { void Module::setDestinationUDPMAC2(const MacAddr mac) {
@ -1273,19 +1244,19 @@ void Module::setReceiverHostname(const std::string &receiverIP) {
if (receiverIP == "none") { if (receiverIP == "none") {
memset(shm()->rxHostname, 0, MAX_STR_LENGTH); memset(shm()->rxHostname, 0, MAX_STR_LENGTH);
sls::strcpy_safe(shm()->rxHostname, "none"); strcpy_safe(shm()->rxHostname, "none");
shm()->useReceiverFlag = false; shm()->useReceiverFlag = false;
return; return;
} }
// start updating // start updating
std::string host = receiverIP; std::string host = receiverIP;
auto res = sls::split(host, ':'); auto res = split(host, ':');
if (res.size() > 1) { if (res.size() > 1) {
host = res[0]; host = res[0];
shm()->rxTCPPort = std::stoi(res[1]); shm()->rxTCPPort = std::stoi(res[1]);
} }
sls::strcpy_safe(shm()->rxHostname, host.c_str()); strcpy_safe(shm()->rxHostname, host.c_str());
shm()->useReceiverFlag = true; shm()->useReceiverFlag = true;
checkReceiverVersionCompatibility(); checkReceiverVersionCompatibility();
@ -1301,7 +1272,7 @@ void Module::setReceiverHostname(const std::string &receiverIP) {
memset(retval.hostname, 0, sizeof(retval.hostname)); memset(retval.hostname, 0, sizeof(retval.hostname));
strcpy_safe(retval.hostname, shm()->hostname); strcpy_safe(retval.hostname, shm()->hostname);
sls::MacAddr retvals[2]; MacAddr retvals[2];
sendToReceiver(F_SETUP_RECEIVER, retval, retvals); sendToReceiver(F_SETUP_RECEIVER, retval, retvals);
// update Modules with dest mac // update Modules with dest mac
if (retval.udp_dstmac == 0 && retvals[0] != 0) { if (retval.udp_dstmac == 0 && retvals[0] != 0) {
@ -1387,8 +1358,8 @@ void Module::setReceiverLock(bool lock) {
sendToReceiver<int>(F_LOCK_RECEIVER, static_cast<int>(lock)); sendToReceiver<int>(F_LOCK_RECEIVER, static_cast<int>(lock));
} }
sls::IpAddr Module::getReceiverLastClientIP() const { IpAddr Module::getReceiverLastClientIP() const {
return sendToReceiver<sls::IpAddr>(F_GET_LAST_RECEIVER_CLIENT_IP); return sendToReceiver<IpAddr>(F_GET_LAST_RECEIVER_CLIENT_IP);
} }
std::array<pid_t, NUM_RX_THREAD_IDS> Module::getReceiverThreadIds() const { std::array<pid_t, NUM_RX_THREAD_IDS> Module::getReceiverThreadIds() const {
@ -1404,6 +1375,19 @@ void Module::setRxArping(bool enable) {
sendToReceiver(F_SET_RECEIVER_ARPING, static_cast<int>(enable), nullptr); sendToReceiver(F_SET_RECEIVER_ARPING, static_cast<int>(enable), nullptr);
} }
defs::ROI Module::getRxROI() const {
return sendToReceiver<slsDetectorDefs::ROI>(F_RECEIVER_GET_RECEIVER_ROI);
}
void Module::setRxROI(const slsDetectorDefs::ROI arg) {
LOG(logDEBUG) << moduleIndex << ": " << arg;
sendToReceiver(F_RECEIVER_SET_RECEIVER_ROI, arg, nullptr);
}
void Module::setRxROIMetadata(const slsDetectorDefs::ROI arg) {
sendToReceiver(F_RECEIVER_SET_RECEIVER_ROI_METADATA, arg, nullptr);
}
// File // File
slsDetectorDefs::fileFormat Module::getFileFormat() const { slsDetectorDefs::fileFormat Module::getFileFormat() const {
return sendToReceiver<fileFormat>(F_GET_RECEIVER_FILE_FORMAT); return sendToReceiver<fileFormat>(F_GET_RECEIVER_FILE_FORMAT);
@ -1424,7 +1408,7 @@ void Module::setFilePath(const std::string &path) {
throw RuntimeError("Cannot set empty file path"); throw RuntimeError("Cannot set empty file path");
} }
char args[MAX_STR_LENGTH]{}; char args[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, path.c_str()); strcpy_safe(args, path.c_str());
sendToReceiver(F_SET_RECEIVER_FILE_PATH, args, nullptr); sendToReceiver(F_SET_RECEIVER_FILE_PATH, args, nullptr);
} }
@ -1439,7 +1423,7 @@ void Module::setFileName(const std::string &fname) {
throw RuntimeError("Cannot set empty file name prefix"); throw RuntimeError("Cannot set empty file name prefix");
} }
char args[MAX_STR_LENGTH]{}; char args[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, fname.c_str()); strcpy_safe(args, fname.c_str());
sendToReceiver(F_SET_RECEIVER_FILE_NAME, args, nullptr); sendToReceiver(F_SET_RECEIVER_FILE_NAME, args, nullptr);
} }
@ -1536,11 +1520,11 @@ void Module::setReceiverStreamingPort(int port) {
sendToReceiver(F_SET_RECEIVER_STREAMING_PORT, port, nullptr); sendToReceiver(F_SET_RECEIVER_STREAMING_PORT, port, nullptr);
} }
sls::IpAddr Module::getReceiverStreamingIP() const { IpAddr Module::getReceiverStreamingIP() const {
return sendToReceiver<sls::IpAddr>(F_GET_RECEIVER_STREAMING_SRC_IP); return sendToReceiver<IpAddr>(F_GET_RECEIVER_STREAMING_SRC_IP);
} }
void Module::setReceiverStreamingIP(const sls::IpAddr ip) { void Module::setReceiverStreamingIP(const IpAddr ip) {
if (ip == 0) { if (ip == 0) {
throw RuntimeError("Invalid receiver zmq ip address"); throw RuntimeError("Invalid receiver zmq ip address");
} }
@ -1555,9 +1539,9 @@ int Module::getClientStreamingPort() const { return shm()->zmqport; }
void Module::setClientStreamingPort(int port) { shm()->zmqport = port; } void Module::setClientStreamingPort(int port) { shm()->zmqport = port; }
sls::IpAddr Module::getClientStreamingIP() const { return shm()->zmqip; } IpAddr Module::getClientStreamingIP() const { return shm()->zmqip; }
void Module::setClientStreamingIP(const sls::IpAddr ip) { void Module::setClientStreamingIP(const IpAddr ip) {
if (ip == 0) { if (ip == 0) {
throw RuntimeError("Invalid client zmq ip address"); throw RuntimeError("Invalid client zmq ip address");
} }
@ -1831,7 +1815,7 @@ void Module::setROI(slsDetectorDefs::ROI arg) {
} }
sendToDetector(F_SET_ROI, arg, nullptr); sendToDetector(F_SET_ROI, arg, nullptr);
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_ROI, arg, nullptr); sendToReceiver(F_RECEIVER_SET_DETECTOR_ROI, arg, nullptr);
} }
} }
@ -2212,10 +2196,8 @@ uint32_t Module::getCounterMask() const {
} }
void Module::setCounterMask(uint32_t countermask) { void Module::setCounterMask(uint32_t countermask) {
LOG(logDEBUG1) << "Setting Counter mask to " << countermask;
sendToDetector(F_SET_COUNTER_MASK, countermask, nullptr); sendToDetector(F_SET_COUNTER_MASK, countermask, nullptr);
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending Reciver counter mask: " << countermask;
sendToReceiver(F_RECEIVER_SET_COUNTER_MASK, countermask, nullptr); sendToReceiver(F_RECEIVER_SET_COUNTER_MASK, countermask, nullptr);
} }
} }
@ -2275,7 +2257,10 @@ bool Module::getInterpolation() const {
void Module::setInterpolation(const bool enable) { void Module::setInterpolation(const bool enable) {
sendToDetector(F_SET_INTERPOLATION, static_cast<int>(enable), nullptr); sendToDetector(F_SET_INTERPOLATION, static_cast<int>(enable), nullptr);
setCounterMask(getCounterMask()); int mask = getCounterMask();
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_COUNTER_MASK, mask, nullptr);
}
} }
bool Module::getPumpProbe() const { bool Module::getPumpProbe() const {
@ -2358,12 +2343,9 @@ int Module::getNumberOfDigitalSamples() const {
} }
void Module::setNumberOfDigitalSamples(int value) { void Module::setNumberOfDigitalSamples(int value) {
LOG(logDEBUG1) << "Setting number of digital samples to " << value;
sendToDetector(F_SET_NUM_DIGITAL_SAMPLES, value, nullptr); sendToDetector(F_SET_NUM_DIGITAL_SAMPLES, value, nullptr);
updateNumberOfChannels(); // depends on samples and adcmask updateNumberOfChannels(); // depends on samples and adcmask
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending number of digital samples to Receiver: "
<< value;
sendToReceiver(F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, value, nullptr); sendToReceiver(F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, value, nullptr);
} }
} }
@ -2401,18 +2383,18 @@ void Module::setExternalSampling(bool value) {
} }
std::vector<int> Module::getReceiverDbitList() const { std::vector<int> Module::getReceiverDbitList() const {
return sendToReceiver<sls::StaticVector<int, MAX_RX_DBIT>>( return sendToReceiver<StaticVector<int, MAX_RX_DBIT>>(
F_GET_RECEIVER_DBIT_LIST); F_GET_RECEIVER_DBIT_LIST);
} }
void Module::setReceiverDbitList(std::vector<int> list) { void Module::setReceiverDbitList(std::vector<int> list) {
LOG(logDEBUG1) << "Setting Receiver Dbit List"; LOG(logDEBUG1) << "Setting Receiver Dbit List";
if (list.size() > 64) { if (list.size() > 64) {
throw sls::RuntimeError("Dbit list size cannot be greater than 64\n"); throw RuntimeError("Dbit list size cannot be greater than 64\n");
} }
for (auto &it : list) { for (auto &it : list) {
if (it < 0 || it > 63) { if (it < 0 || it > 63) {
throw sls::RuntimeError( throw RuntimeError(
"Dbit list value must be between 0 and 63\n"); "Dbit list value must be between 0 and 63\n");
} }
} }
@ -2420,7 +2402,7 @@ void Module::setReceiverDbitList(std::vector<int> list) {
auto last = std::unique(begin(list), end(list)); auto last = std::unique(begin(list), end(list));
list.erase(last, list.end()); list.erase(last, list.end());
sls::StaticVector<int, MAX_RX_DBIT> arg = list; StaticVector<int, MAX_RX_DBIT> arg = list;
sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr); sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr);
} }
@ -2609,7 +2591,7 @@ void Module::setAdditionalJsonHeader(
std::string Module::getAdditionalJsonParameter(const std::string &key) const { std::string Module::getAdditionalJsonParameter(const std::string &key) const {
char arg[SHORT_STR_LENGTH]{}; char arg[SHORT_STR_LENGTH]{};
sls::strcpy_safe(arg, key.c_str()); strcpy_safe(arg, key.c_str());
char retval[SHORT_STR_LENGTH]{}; char retval[SHORT_STR_LENGTH]{};
sendToReceiver(F_GET_ADDITIONAL_JSON_PARAMETER, arg, retval); sendToReceiver(F_GET_ADDITIONAL_JSON_PARAMETER, arg, retval);
return retval; return retval;
@ -2625,8 +2607,8 @@ void Module::setAdditionalJsonParameter(const std::string &key,
"Key cannot be empty. Both can have max 2 characters"); "Key cannot be empty. Both can have max 2 characters");
} }
char args[2][SHORT_STR_LENGTH]{}; char args[2][SHORT_STR_LENGTH]{};
sls::strcpy_safe(args[0], key.c_str()); strcpy_safe(args[0], key.c_str());
sls::strcpy_safe(args[1], value.c_str()); strcpy_safe(args[1], value.c_str());
sendToReceiver(F_SET_ADDITIONAL_JSON_PARAMETER, args, nullptr); sendToReceiver(F_SET_ADDITIONAL_JSON_PARAMETER, args, nullptr);
} }
@ -2778,14 +2760,14 @@ void Module::setLockDetector(bool lock) {
sendToDetector<int>(F_LOCK_SERVER, static_cast<int>(lock)); sendToDetector<int>(F_LOCK_SERVER, static_cast<int>(lock));
} }
sls::IpAddr Module::getLastClientIP() const { IpAddr Module::getLastClientIP() const {
return sendToDetector<sls::IpAddr>(F_GET_LAST_CLIENT_IP); return sendToDetector<IpAddr>(F_GET_LAST_CLIENT_IP);
} }
std::string Module::executeCommand(const std::string &cmd) { std::string Module::executeCommand(const std::string &cmd) {
char arg[MAX_STR_LENGTH]{}; char arg[MAX_STR_LENGTH]{};
char retval[MAX_STR_LENGTH]{}; char retval[MAX_STR_LENGTH]{};
sls::strcpy_safe(arg, cmd.c_str()); strcpy_safe(arg, cmd.c_str());
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
<< "): Sending command " << cmd; << "): Sending command " << cmd;
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
@ -3196,7 +3178,7 @@ slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id,
"memory. Please free shared memory."); "memory. Please free shared memory.");
} }
shm.openSharedMemory(); shm.openSharedMemory(verify);
if (verify && shm()->shmversion != MODULE_SHMVERSION) { if (verify && shm()->shmversion != MODULE_SHMVERSION) {
std::ostringstream ss; std::ostringstream ss;
ss << "Single shared memory (" << det_id << "-" << moduleIndex ss << "Single shared memory (" << det_id << "-" << moduleIndex
@ -3215,7 +3197,7 @@ void Module::initSharedMemory(detectorType type, int det_id, bool verify) {
shm.createSharedMemory(); shm.createSharedMemory();
initializeModuleStructure(type); initializeModuleStructure(type);
} else { } else {
shm.openSharedMemory(); shm.openSharedMemory(verify);
if (verify && shm()->shmversion != MODULE_SHMVERSION) { if (verify && shm()->shmversion != MODULE_SHMVERSION) {
std::ostringstream ss; std::ostringstream ss;
ss << "Single shared memory (" << det_id << "-" << moduleIndex ss << "Single shared memory (" << det_id << "-" << moduleIndex
@ -3235,8 +3217,8 @@ void Module::initializeModuleStructure(detectorType type) {
shm()->numberOfModule.y = 0; shm()->numberOfModule.y = 0;
shm()->controlPort = DEFAULT_PORTNO; shm()->controlPort = DEFAULT_PORTNO;
shm()->stopPort = DEFAULT_PORTNO + 1; shm()->stopPort = DEFAULT_PORTNO + 1;
sls::strcpy_safe(shm()->settingsDir, getenv("HOME")); strcpy_safe(shm()->settingsDir, getenv("HOME"));
sls::strcpy_safe(shm()->rxHostname, "none"); strcpy_safe(shm()->rxHostname, "none");
shm()->rxTCPPort = DEFAULT_PORTNO + 2; shm()->rxTCPPort = DEFAULT_PORTNO + 2;
shm()->useReceiverFlag = false; shm()->useReceiverFlag = false;
shm()->numUDPInterfaces = 1; shm()->numUDPInterfaces = 1;
@ -3291,7 +3273,75 @@ void Module::checkReceiverVersionCompatibility() {
sendToReceiver(F_RECEIVER_CHECK_VERSION, int64_t(APIRECEIVER), nullptr); sendToReceiver(F_RECEIVER_CHECK_VERSION, int64_t(APIRECEIVER), nullptr);
} }
int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) { void Module::setModule(sls_detector_module &module, bool trimbits) {
LOG(logDEBUG1) << "Setting module with trimbits:" << trimbits;
// to exclude trimbits
if (!trimbits) {
module.nchan = 0;
module.nchip = 0;
}
// validate dacs and trimbits
if (shm()->detType == MYTHEN3) {
// check for trimbits that are out of range
bool out_of_range = false;
for (int i = 0; i != module.nchan; ++i) {
if (module.chanregs[i] < 0) {
module.chanregs[i] = 0;
out_of_range = true;
} else if (module.chanregs[i] > 63) {
module.chanregs[i] = 63;
out_of_range = true;
}
}
if (out_of_range) {
LOG(logWARNING)
<< "Some trimbits were out of range, these have been replaced with 0 or 63.";
}
// check dacs
out_of_range = false;
for (int i = 0; i != module.ndac; ++i) {
int dacMin = 0;
int dacMax = 2800;
if (i == M_VTH1 || i == M_VTH2 || i == M_VTH3) {
dacMin = 200;
dacMax = 2400;
}
if (module.dacs[i] < dacMin) {
module.dacs[i] = dacMin;
out_of_range = true;
} else if (module.dacs[i] > dacMax) {
module.dacs[i] = dacMax;
out_of_range = true;
}
}
if (out_of_range) {
LOG(logWARNING) << "Some dacs were out of range, "
"these have been replaced with 0/200 or 2800/2400.";
}
}
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_SET_MODULE);
sendModule(&module, client);
if (client.Receive<int>() == FAIL) {
throw DetectorError("Module " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
}
sls_detector_module Module::getModule() {
LOG(logDEBUG1) << "Getting module";
sls_detector_module module(shm()->detType);
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_GET_MODULE);
if (client.Receive<int>() == FAIL) {
throw DetectorError("Module " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage());
}
receiveModule(&module, client);
return module;
}
void Module::sendModule(sls_detector_module *myMod, ClientSocket &client) {
constexpr TLogLevel level = logDEBUG1; constexpr TLogLevel level = logDEBUG1;
LOG(level) << "Sending Module"; LOG(level) << "Sending Module";
int ts = 0; int ts = 0;
@ -3334,35 +3384,48 @@ int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) {
ts += n; ts += n;
LOG(level) << "dacs sent. " << n << " bytes"; LOG(level) << "dacs sent. " << n << " bytes";
if (shm()->detType == EIGER || shm()->detType == MYTHEN3) { n = client.Send(myMod->chanregs, sizeof(int) * (myMod->nchan));
n = client.Send(myMod->chanregs, sizeof(int) * (myMod->nchan)); ts += n;
ts += n; LOG(level) << "channels sent. " << n << " bytes";
LOG(level) << "channels sent. " << n << " bytes";
int expectedBytesSent = sizeof(sls_detector_module) - sizeof(myMod->dacs) - sizeof(myMod->chanregs) + (myMod->ndac * sizeof(int)) + (myMod->nchan * sizeof(int));
if (expectedBytesSent != ts) {
throw RuntimeError("Module size " + std::to_string(ts) + " sent does not match expected size to be sent " + std::to_string(expectedBytesSent));
} }
return ts;
} }
void Module::setModule(sls_detector_module &module, bool trimbits) {
LOG(logDEBUG1) << "Setting module with trimbits:" << trimbits; void Module::receiveModule(sls_detector_module *myMod, ClientSocket &client) {
// to exclude trimbits constexpr TLogLevel level = logDEBUG1;
if (!trimbits) { LOG(level) << "Receiving Module";
module.nchan = 0; myMod->serialnumber = client.Receive<int>();
module.nchip = 0; LOG(level) << "serialno: " << myMod->serialnumber;
} myMod->nchan = client.Receive<int>();
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); LOG(level) << "nchan: " << myMod->nchan;
client.Send(F_SET_MODULE); myMod->nchip = client.Receive<int>();
sendModule(&module, client); LOG(level) << "nchip: " << myMod->nchip;
if (client.Receive<int>() == FAIL) { myMod->ndac = client.Receive<int>();
throw DetectorError("Module " + std::to_string(moduleIndex) + LOG(level) << "ndac: " << myMod->ndac;
" returned error: " + client.readErrorMessage()); myMod->reg = client.Receive<int>();
} LOG(level) << "reg: " << myMod->reg;
myMod->iodelay = client.Receive<int>();
LOG(level) << "iodelay: " << myMod->iodelay;
myMod->tau = client.Receive<int>();
LOG(level) << "tau: " << myMod->tau;
client.Receive(myMod->eV);
LOG(level) << "eV: " << ToString(myMod->eV);
client.Receive(myMod->dacs, sizeof(int) * (myMod->ndac));
LOG(level) << myMod->ndac << " dacs received";
client.Receive(myMod->chanregs, sizeof(int) * (myMod->nchan));
LOG(level) << myMod->nchan << " chans received";
} }
void Module::updateReceiverStreamingIP() { void Module::updateReceiverStreamingIP() {
auto ip = getReceiverStreamingIP(); auto ip = getReceiverStreamingIP();
if (ip == 0) { if (ip == 0) {
// Hostname could be ip try to decode otherwise look up the hostname // Hostname could be ip try to decode otherwise look up the hostname
ip = sls::IpAddr{shm()->rxHostname}; ip = IpAddr{shm()->rxHostname};
if (ip == 0) { if (ip == 0) {
ip = HostnameToIp(shm()->rxHostname); ip = HostnameToIp(shm()->rxHostname);
} }
@ -3387,42 +3450,6 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
} }
sls_detector_module myMod{shm()->detType}; sls_detector_module myMod{shm()->detType};
enum eiger_DacIndex {
E_SVP,
E_VTR,
E_VRF,
E_VRS,
E_SVN,
E_VTGSTV,
E_VCMP_LL,
E_VCMP_LR,
E_CAL,
E_VCMP_RL,
E_RXB_RB,
E_RXB_LB,
E_VCMP_RR,
E_VCP,
E_VCN,
E_VIS
};
enum mythen3_DacIndex {
M_VCASSH,
M_VTH2,
M_VRSHAPER,
M_VRSHAPER_N,
M_VIPRE_OUT,
M_VTH3,
M_VTH1,
M_VICIN,
M_VCAS,
M_VRPREAMP,
M_VCAL_N,
M_VIPRE,
M_VISHAPER,
M_VCAL_P,
M_VTRIM,
M_VDCSH
};
// create copy and interpolate dac lists // create copy and interpolate dac lists
std::vector<int> dacs_to_copy, dacs_to_interpolate; std::vector<int> dacs_to_copy, dacs_to_interpolate;
@ -3596,10 +3623,39 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
else { else {
throw RuntimeError("Not implemented for this detector"); throw RuntimeError("Not implemented for this detector");
} }
LOG(logINFO) << "Settings file loaded: " << fname.c_str(); LOG(logINFO) << "Settings file loaded: " << fname;
return myMod; return myMod;
} }
void Module::saveSettingsFile(sls_detector_module &myMod, const std::string &fname) {
LOG(logDEBUG1) << moduleIndex << ": Saving settings to " << fname;
std::ofstream outfile(fname);
if (!outfile) {
throw RuntimeError("Could not write settings file: " + fname);
}
switch (shm()->detType) {
case MYTHEN3:
outfile.write(reinterpret_cast<char *>(&myMod.reg), sizeof(myMod.reg));
outfile.write(reinterpret_cast<char *>(myMod.dacs),
sizeof(int) * (myMod.ndac));
outfile.write(reinterpret_cast<char *>(myMod.chanregs),
sizeof(int) * (myMod.nchan));
break;
case EIGER:
outfile.write(reinterpret_cast<char *>(myMod.dacs),
sizeof(int) * (myMod.ndac));
outfile.write(reinterpret_cast<char *>(&myMod.iodelay),
sizeof(myMod.iodelay));
outfile.write(reinterpret_cast<char *>(&myMod.tau), sizeof(myMod.tau));
outfile.write(reinterpret_cast<char *>(myMod.chanregs),
sizeof(int) * (myMod.nchan));
break;
default:
throw RuntimeError("Saving settings file is not implemented for this detector.");
}
LOG(logINFO) << "Settings for " << shm()->hostname << " written to " << fname;
}
void Module::sendProgram(bool blackfin, std::vector<char> buffer, void Module::sendProgram(bool blackfin, std::vector<char> buffer,
const int functionEnum, const int functionEnum,
const std::string &functionType, const std::string &functionType,
@ -3615,7 +3671,7 @@ void Module::sendProgram(bool blackfin, std::vector<char> buffer,
client.Send(filesize); client.Send(filesize);
// send checksum // send checksum
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize); std::string checksum = md5_calculate_checksum(buffer.data(), filesize);
LOG(logDEBUG1) << "Checksum:" << checksum; LOG(logDEBUG1) << "Checksum:" << checksum;
char cChecksum[MAX_STR_LENGTH] = {0}; char cChecksum[MAX_STR_LENGTH] = {0};
strcpy(cChecksum, checksum.c_str()); strcpy(cChecksum, checksum.c_str());

View File

@ -14,13 +14,13 @@
#include <map> #include <map>
#include <vector> #include <vector>
namespace sls {
class ServerInterface; class ServerInterface;
#define MODULE_SHMAPIVERSION 0x190726 #define MODULE_SHMAPIVERSION 0x190726
#define MODULE_SHMVERSION 0x200402 #define MODULE_SHMVERSION 0x200402
namespace sls {
/** /**
* @short structure allocated in shared memory to store Module settings for * @short structure allocated in shared memory to store Module settings for
* IPC and cache * IPC and cache
@ -40,7 +40,7 @@ struct sharedModule {
int stopPort; int stopPort;
char settingsDir[MAX_STR_LENGTH]; char settingsDir[MAX_STR_LENGTH];
/** list of the energies at which the Module has been trimmed */ /** list of the energies at which the Module has been trimmed */
sls::StaticVector<int, MAX_TRIMEN> trimEnergies; StaticVector<int, MAX_TRIMEN> trimEnergies;
/** number of channels per chip */ /** number of channels per chip */
slsDetectorDefs::xy nChan; slsDetectorDefs::xy nChan;
slsDetectorDefs::xy nChip; slsDetectorDefs::xy nChip;
@ -52,7 +52,7 @@ struct sharedModule {
/** Listening tcp port from gui (only data) */ /** Listening tcp port from gui (only data) */
int zmqport; int zmqport;
/** Listening tcp ip address from gui (only data) **/ /** Listening tcp ip address from gui (only data) **/
sls::IpAddr zmqip; IpAddr zmqip;
int numUDPInterfaces; int numUDPInterfaces;
/** to inform rxr when stopping rxr */ /** to inform rxr when stopping rxr */
bool stoppedFlag; bool stoppedFlag;
@ -114,6 +114,7 @@ class Module : public virtual slsDetectorDefs {
std::string getSettingsDir() const; std::string getSettingsDir() const;
std::string setSettingsDir(const std::string &dir); std::string setSettingsDir(const std::string &dir);
void loadTrimbits(const std::string &fname); void loadTrimbits(const std::string &fname);
void saveTrimbits(const std::string &fname);
int getAllTrimbits() const; int getAllTrimbits() const;
void setAllTrimbits(int val); void setAllTrimbits(int val);
std::vector<int> getTrimEn() const; std::vector<int> getTrimEn() const;
@ -223,28 +224,28 @@ class Module : public virtual slsDetectorDefs {
void setNumberofUDPInterfaces(int n); void setNumberofUDPInterfaces(int n);
int getSelectedUDPInterface() const; int getSelectedUDPInterface() const;
void selectUDPInterface(int n); void selectUDPInterface(int n);
sls::IpAddr getSourceUDPIP() const; IpAddr getSourceUDPIP() const;
void setSourceUDPIP(const sls::IpAddr ip); void setSourceUDPIP(const IpAddr ip);
sls::IpAddr getSourceUDPIP2() const; IpAddr getSourceUDPIP2() const;
void setSourceUDPIP2(const sls::IpAddr ip); void setSourceUDPIP2(const IpAddr ip);
sls::MacAddr getSourceUDPMAC() const; MacAddr getSourceUDPMAC() const;
void setSourceUDPMAC(const sls::MacAddr mac); void setSourceUDPMAC(const MacAddr mac);
sls::MacAddr getSourceUDPMAC2() const; MacAddr getSourceUDPMAC2() const;
void setSourceUDPMAC2(const sls::MacAddr mac); void setSourceUDPMAC2(const MacAddr mac);
sls::UdpDestination getDestinationUDPList(const uint32_t entry) const; UdpDestination getDestinationUDPList(const uint32_t entry) const;
void setDestinationUDPList(const sls::UdpDestination dest); void setDestinationUDPList(const UdpDestination dest);
int getNumberofUDPDestinations() const; int getNumberofUDPDestinations() const;
void clearUDPDestinations(); void clearUDPDestinations();
int getFirstUDPDestination() const; int getFirstUDPDestination() const;
void setFirstUDPDestination(const int value); void setFirstUDPDestination(const int value);
sls::IpAddr getDestinationUDPIP() const; IpAddr getDestinationUDPIP() const;
void setDestinationUDPIP(const sls::IpAddr ip); void setDestinationUDPIP(const IpAddr ip);
sls::IpAddr getDestinationUDPIP2() const; IpAddr getDestinationUDPIP2() const;
void setDestinationUDPIP2(const sls::IpAddr ip); void setDestinationUDPIP2(const IpAddr ip);
sls::MacAddr getDestinationUDPMAC() const; MacAddr getDestinationUDPMAC() const;
void setDestinationUDPMAC(const sls::MacAddr mac); void setDestinationUDPMAC(const MacAddr mac);
sls::MacAddr getDestinationUDPMAC2() const; MacAddr getDestinationUDPMAC2() const;
void setDestinationUDPMAC2(const sls::MacAddr mac); void setDestinationUDPMAC2(const MacAddr mac);
int getDestinationUDPPort() const; int getDestinationUDPPort() const;
void setDestinationUDPPort(int udpport); void setDestinationUDPPort(int udpport);
int getDestinationUDPPort2() const; int getDestinationUDPPort2() const;
@ -286,10 +287,13 @@ class Module : public virtual slsDetectorDefs {
void setReceiverUDPSocketBufferSize(int udpsockbufsize); void setReceiverUDPSocketBufferSize(int udpsockbufsize);
bool getReceiverLock() const; bool getReceiverLock() const;
void setReceiverLock(bool lock); void setReceiverLock(bool lock);
sls::IpAddr getReceiverLastClientIP() const; IpAddr getReceiverLastClientIP() const;
std::array<pid_t, NUM_RX_THREAD_IDS> getReceiverThreadIds() const; std::array<pid_t, NUM_RX_THREAD_IDS> getReceiverThreadIds() const;
bool getRxArping() const; bool getRxArping() const;
void setRxArping(bool enable); void setRxArping(bool enable);
defs::ROI getRxROI() const;
void setRxROI(const slsDetectorDefs::ROI arg);
void setRxROIMetadata(const slsDetectorDefs::ROI arg);
/************************************************** /**************************************************
* * * *
@ -331,12 +335,12 @@ class Module : public virtual slsDetectorDefs {
void setReceiverStreamingStartingFrame(int fnum); void setReceiverStreamingStartingFrame(int fnum);
int getReceiverStreamingPort() const; int getReceiverStreamingPort() const;
void setReceiverStreamingPort(int port); void setReceiverStreamingPort(int port);
sls::IpAddr getReceiverStreamingIP() const; IpAddr getReceiverStreamingIP() const;
void setReceiverStreamingIP(const sls::IpAddr ip); void setReceiverStreamingIP(const IpAddr ip);
int getClientStreamingPort() const; int getClientStreamingPort() const;
void setClientStreamingPort(int port); void setClientStreamingPort(int port);
sls::IpAddr getClientStreamingIP() const; IpAddr getClientStreamingIP() const;
void setClientStreamingIP(const sls::IpAddr ip); void setClientStreamingIP(const IpAddr ip);
int getReceiverStreamingHwm() const; int getReceiverStreamingHwm() const;
void setReceiverStreamingHwm(const int limit); void setReceiverStreamingHwm(const int limit);
@ -586,7 +590,7 @@ class Module : public virtual slsDetectorDefs {
void setStopPort(int port_number); void setStopPort(int port_number);
bool getLockDetector() const; bool getLockDetector() const;
void setLockDetector(bool lock); void setLockDetector(bool lock);
sls::IpAddr getLastClientIP() const; IpAddr getLastClientIP() const;
std::string executeCommand(const std::string &cmd); std::string executeCommand(const std::string &cmd);
int64_t getNumberOfFramesFromStart() const; int64_t getNumberOfFramesFromStart() const;
int64_t getActualTime() const; int64_t getActualTime() const;
@ -733,7 +737,9 @@ class Module : public virtual slsDetectorDefs {
void checkDetectorVersionCompatibility(); void checkDetectorVersionCompatibility();
void checkReceiverVersionCompatibility(); void checkReceiverVersionCompatibility();
void setModule(sls_detector_module &module, bool trimbits = true); void setModule(sls_detector_module &module, bool trimbits = true);
int sendModule(sls_detector_module *myMod, sls::ClientSocket &client); sls_detector_module getModule();
void sendModule(sls_detector_module *myMod, ClientSocket &client);
void receiveModule(sls_detector_module *myMod, ClientSocket &client);
void updateReceiverStreamingIP(); void updateReceiverStreamingIP();
void updateRateCorrection(); void updateRateCorrection();
@ -767,6 +773,7 @@ class Module : public virtual slsDetectorDefs {
std::string getTrimbitFilename(detectorSettings settings, int e_eV); std::string getTrimbitFilename(detectorSettings settings, int e_eV);
sls_detector_module readSettingsFile(const std::string &fname, sls_detector_module readSettingsFile(const std::string &fname,
bool trimbits = true); bool trimbits = true);
void saveSettingsFile(sls_detector_module &myMod, const std::string &fname);
void sendProgram(bool blackfin, std::vector<char> buffer, void sendProgram(bool blackfin, std::vector<char> buffer,
const int functionEnum, const std::string &functionType, const int functionEnum, const std::string &functionType,
const std::string serverName = "", const std::string serverName = "",
@ -775,13 +782,51 @@ class Module : public virtual slsDetectorDefs {
const int timeRequired); const int timeRequired);
const int moduleIndex; const int moduleIndex;
mutable sls::SharedMemory<sharedModule> shm{0, 0}; mutable SharedMemory<sharedModule> shm{0, 0};
static const int BLACKFIN_ERASE_FLASH_TIME = 65; static const int BLACKFIN_ERASE_FLASH_TIME = 65;
static const int BLACKFIN_WRITE_TO_FLASH_TIME = 30; static const int BLACKFIN_WRITE_TO_FLASH_TIME = 30;
static const int NIOS_ERASE_FLASH_TIME_FPGA = 10; static const int NIOS_ERASE_FLASH_TIME_FPGA = 10;
static const int NIOS_WRITE_TO_FLASH_TIME_FPGA = 45; static const int NIOS_WRITE_TO_FLASH_TIME_FPGA = 45;
static const int NIOS_ERASE_FLASH_TIME_KERNEL = 9; static const int NIOS_ERASE_FLASH_TIME_KERNEL = 9;
static const int NIOS_WRITE_TO_FLASH_TIME_KERNEL = 40; static const int NIOS_WRITE_TO_FLASH_TIME_KERNEL = 40;
enum mythen3_DacIndex {
M_VCASSH,
M_VTH2,
M_VRSHAPER,
M_VRSHAPER_N,
M_VIPRE_OUT,
M_VTH3,
M_VTH1,
M_VICIN,
M_VCAS,
M_VRPREAMP,
M_VCAL_N,
M_VIPRE,
M_VISHAPER,
M_VCAL_P,
M_VTRIM,
M_VDCSH
};
enum eiger_DacIndex {
E_SVP,
E_VTR,
E_VRF,
E_VRS,
E_SVN,
E_VTGSTV,
E_VCMP_LL,
E_VCMP_LR,
E_CAL,
E_VCMP_RL,
E_RXB_RB,
E_RXB_LB,
E_VCMP_RR,
E_VCP,
E_VCN,
E_VIS
};
}; };
} // namespace sls } // namespace sls

View File

@ -13,7 +13,6 @@
#include "sls/logger.h" #include "sls/logger.h"
#include "sls/sls_detector_exceptions.h" #include "sls/sls_detector_exceptions.h"
// #include "stdlib.h"
#include <cstdlib> #include <cstdlib>
#include <cerrno> // errno #include <cerrno> // errno
#include <cstring> // strerror #include <cstring> // strerror
@ -23,16 +22,15 @@
#include <sys/mman.h> // shared memory #include <sys/mman.h> // shared memory
#include <sys/stat.h> // fstat #include <sys/stat.h> // fstat
#include <unistd.h> #include <unistd.h>
#define SHM_DETECTOR_PREFIX "/slsDetectorPackage_detector_"
#define SHM_MODULE_PREFIX "_module_"
#define SHM_ENV_NAME "SLSDETNAME"
#include <iostream> #include <iostream>
#include <string> #include <string>
namespace sls { namespace sls {
#define SHM_DETECTOR_PREFIX "/slsDetectorPackage_detector_"
#define SHM_MODULE_PREFIX "_module_"
#define SHM_ENV_NAME "SLSDETNAME"
template <typename T> class SharedMemory { template <typename T> class SharedMemory {
static constexpr int NAME_MAX_LENGTH = 255; static constexpr int NAME_MAX_LENGTH = 255;
std::string name; std::string name;
@ -101,14 +99,15 @@ template <typename T> class SharedMemory {
LOG(logINFO) << "Shared memory created " << name; LOG(logINFO) << "Shared memory created " << name;
} }
void openSharedMemory() { void openSharedMemory(bool verifySize) {
int fd = shm_open(name.c_str(), O_RDWR, 0); int fd = shm_open(name.c_str(), O_RDWR, 0);
if (fd < 0) { if (fd < 0) {
std::string msg = "Open existing shared memory " + name + std::string msg = "Open existing shared memory " + name +
" failed: " + strerror(errno); " failed: " + strerror(errno);
throw SharedMemoryError(msg); throw SharedMemoryError(msg);
} }
checkSize(fd); if (verifySize)
checkSize(fd);
shared_struct = mapSharedMemory(fd); shared_struct = mapSharedMemory(fd);
} }

View File

@ -21,4 +21,9 @@ target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-CtbConfig.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-CtbConfig.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>"
PRIVATE
${SLS_INTERNAL_RAPIDJSON_DIR}
)

View File

@ -9,8 +9,9 @@
// help for all docs // help for all docs
// command for all depreciated commands // command for all depreciated commands
namespace sls {
using vs = std::vector<std::string>; using vs = std::vector<std::string>;
using sls::CmdParser;
SCENARIO("Construction", "[support]") { SCENARIO("Construction", "[support]") {
GIVEN("A default constructed CmdParser") { GIVEN("A default constructed CmdParser") {
@ -406,4 +407,6 @@ TEST_CASE("Parse a command in the form 0-1:command") {
REQUIRE(p.multi_id() == 3); REQUIRE(p.multi_id() == 3);
REQUIRE(p.detector_id() == 5); REQUIRE(p.detector_id() == 5);
REQUIRE(p.command() == "exptime"); REQUIRE(p.command() == "exptime");
} }
} // namespace sls

View File

@ -12,8 +12,8 @@
#include "test-CmdProxy-global.h" #include "test-CmdProxy-global.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -141,7 +141,7 @@ TEST_CASE("samples", "[.cmd]") {
if (det_type == defs::CHIPTESTBOARD || det_type == defs::MOENCH) { if (det_type == defs::CHIPTESTBOARD || det_type == defs::MOENCH) {
auto prev_asamples = det.getNumberOfAnalogSamples(); auto prev_asamples = det.getNumberOfAnalogSamples();
sls::Result<int> prev_dsamples = 0; Result<int> prev_dsamples = 0;
if (det_type == defs::CHIPTESTBOARD) { if (det_type == defs::CHIPTESTBOARD) {
prev_dsamples = det.getNumberOfDigitalSamples(); prev_dsamples = det.getNumberOfDigitalSamples();
} }
@ -865,4 +865,6 @@ TEST_CASE("led", "[.cmd]") {
} else { } else {
REQUIRE_THROWS(proxy.Call("led", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("led", {}, -1, GET));
} }
} }
} // namespace sls

View File

@ -12,8 +12,8 @@
#include "test-CmdProxy-global.h" #include "test-CmdProxy-global.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -657,4 +657,6 @@ TEST_CASE("top", "[.cmd]") {
REQUIRE_THROWS(proxy.Call("top", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("top", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("top", {"1"}, -1, PUT)); REQUIRE_THROWS(proxy.Call("top", {"1"}, -1, PUT));
} }
} }
} // namespace sls

View File

@ -6,8 +6,8 @@
#include "sls/Detector.h" #include "sls/Detector.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -52,7 +52,7 @@ void test_onchip_dac(defs::dacIndex index, const std::string &dacname,
int chipIndex = -1; // for now, it is -1 only int chipIndex = -1; // for now, it is -1 only
auto prev_val = det.getOnChipDAC(index, chipIndex); auto prev_val = det.getOnChipDAC(index, chipIndex);
auto dacValueStr = sls::ToStringHex(dacvalue); auto dacValueStr = ToStringHex(dacvalue);
auto chipIndexStr = std::to_string(chipIndex); auto chipIndexStr = std::to_string(chipIndex);
std::ostringstream oss_set, oss_get; std::ostringstream oss_set, oss_get;
proxy.Call(dacname, {chipIndexStr, dacValueStr}, -1, PUT, oss_set); proxy.Call(dacname, {chipIndexStr, dacValueStr}, -1, PUT, oss_set);
@ -66,4 +66,6 @@ void test_onchip_dac(defs::dacIndex index, const std::string &dacname,
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setOnChipDAC(index, chipIndex, prev_val[i], {i}); det.setOnChipDAC(index, chipIndex, prev_val[i], {i});
} }
} }
} // namespace sls

View File

@ -3,7 +3,12 @@
#pragma once #pragma once
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
namespace sls {
void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname,
int dacvalue); int dacvalue);
void test_onchip_dac(slsDetectorDefs::dacIndex index, void test_onchip_dac(slsDetectorDefs::dacIndex index,
const std::string &dacname, int dacvalue); const std::string &dacname, int dacvalue);
} // namespace sls

View File

@ -12,8 +12,8 @@
#include "test-CmdProxy-global.h" #include "test-CmdProxy-global.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -154,4 +154,6 @@ TEST_CASE("exptimel", "[.cmd]") {
} else { } else {
REQUIRE_THROWS(proxy.Call("exptimel", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("exptimel", {}, -1, GET));
} }
} }
} // namespace sls

View File

@ -12,8 +12,8 @@
#include "test-CmdProxy-global.h" #include "test-CmdProxy-global.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -467,7 +467,7 @@ TEST_CASE("burstmode", "[.cmd]") {
if (det_type == defs::GOTTHARD2) { if (det_type == defs::GOTTHARD2) {
auto burst = det.getBurstMode(); auto burst = det.getBurstMode();
auto burststr = sls::ToString(burst); auto burststr = ToString(burst);
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("burstmode", {"burst_internal"}, -1, PUT, oss); proxy.Call("burstmode", {"burst_internal"}, -1, PUT, oss);
@ -743,4 +743,6 @@ TEST_CASE("badchannels", "[.cmd]") {
} else { } else {
REQUIRE_THROWS(proxy.Call("badchannels", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("badchannels", {}, -1, GET));
} }
} }
} // namespace sls

View File

@ -10,8 +10,8 @@
#include "test-CmdProxy-global.h" #include "test-CmdProxy-global.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -538,3 +538,5 @@ TEST_CASE("filtercells", "[.cmd]") {
REQUIRE_THROWS(proxy.Call("filtercells", {"0"}, -1, PUT)); REQUIRE_THROWS(proxy.Call("filtercells", {"0"}, -1, PUT));
} }
} }
} // namespace sls

View File

@ -12,8 +12,8 @@
#include "test-CmdProxy-global.h" #include "test-CmdProxy-global.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -108,3 +108,5 @@ TEST_CASE("Setting and reading back MOENCH dacs", "[.cmd][.dacs]") {
REQUIRE_THROWS(proxy.Call("dac", {"vcom_adc2"}, -1, GET)); REQUIRE_THROWS(proxy.Call("dac", {"vcom_adc2"}, -1, GET));
} }
} }
} // namespace sls

View File

@ -12,8 +12,8 @@
#include "test-CmdProxy-global.h" #include "test-CmdProxy-global.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -216,9 +216,9 @@ TEST_CASE("counters", "[.cmd]") {
REQUIRE(oss_set2.str() == "counters [0, 2]\n"); REQUIRE(oss_set2.str() == "counters [0, 2]\n");
// put back old value // put back old value
proxy.Call("counters", list_str, -1, PUT, oss_set3); proxy.Call("counters", list_str, -1, PUT, oss_set3);
REQUIRE(oss_set3.str() == "counters " + sls::ToString(list_str) + "\n"); REQUIRE(oss_set3.str() == "counters " + ToString(list_str) + "\n");
proxy.Call("counters", {}, -1, GET, oss_get); proxy.Call("counters", {}, -1, GET, oss_get);
REQUIRE(oss_get.str() == "counters " + sls::ToString(list_str) + "\n"); REQUIRE(oss_get.str() == "counters " + ToString(list_str) + "\n");
} else { } else {
REQUIRE_THROWS(proxy.Call("counters", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("counters", {}, -1, GET));
} }
@ -349,7 +349,7 @@ TEST_CASE("gatedelay", "[.cmd]") {
auto prev_val = det.getExptimeForAllGates().tsquash( auto prev_val = det.getExptimeForAllGates().tsquash(
"inconsistent gatedelay to test"); "inconsistent gatedelay to test");
if (prev_val[0] != prev_val[1] || prev_val[1] != prev_val[2]) { if (prev_val[0] != prev_val[1] || prev_val[1] != prev_val[2]) {
throw sls::RuntimeError("inconsistent gatedelay for all gates"); throw RuntimeError("inconsistent gatedelay for all gates");
} }
{ {
std::ostringstream oss; std::ostringstream oss;
@ -496,32 +496,46 @@ TEST_CASE("interpolation", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
if (det.getDetectorType().squash() == defs::MYTHEN3) { if (det.getDetectorType().squash() == defs::MYTHEN3) {
auto prev_val = det.getInterpolation(); auto prev_interpolation = det.getInterpolation();
auto mask = det.getCounterMask(); auto prev_mask = det.getCounterMask();
{ auto prev_vth3DacVal = det.getDAC(defs::VTH3, 0, {});
proxy.Call("counters", {"0", "1"}, -1, PUT);
std::ostringstream oss; int disabledDacValue = 2800;
proxy.Call("interpolation", {"1"}, -1, PUT, oss); auto fixedVth3DacVal = 1000;
REQUIRE(oss.str() == "interpolation 1\n"); det.setDAC(defs::VTH3, fixedVth3DacVal, 0, {});
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") == // mask with counter 3 disabled and enabled(to test vth3)
7); uint32_t fixedMask[2] = {0x2, 0x4};
} for (int i = 0; i != 2; ++i) {
{ det.setCounterMask(fixedMask[i]);
proxy.Call("counters", {"0", "1"}, -1, PUT); {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("interpolation", {"0"}, -1, PUT, oss); proxy.Call("interpolation", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "interpolation 0\n"); REQUIRE(oss.str() == "interpolation 1\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") == REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
3); 7);
REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth3 dac value") == disabledDacValue);
}
{
std::ostringstream oss;
proxy.Call("interpolation", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "interpolation 0\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") ==
fixedMask[i]);
uint32_t expectedVth3DacVal = (fixedMask[i] & 0x4 ? fixedVth3DacVal : disabledDacValue);
REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth3 dac value") == expectedVth3DacVal);
}
} }
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("interpolation", {}, -1, GET, oss); proxy.Call("interpolation", {}, -1, GET, oss);
REQUIRE(oss.str() == "interpolation 0\n"); REQUIRE(oss.str() == "interpolation 0\n");
} }
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setCounterMask(mask[i], {i}); det.setCounterMask(prev_mask[i], {i});
det.setInterpolation(prev_val[i], {i}); det.setInterpolation(prev_interpolation[i], {i});
det.setDAC(defs::VTH3, prev_vth3DacVal[i], 0, {i});
} }
} else { } else {
REQUIRE_THROWS(proxy.Call("interpolation", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("interpolation", {}, -1, GET));
@ -533,15 +547,43 @@ TEST_CASE("pumpprobe", "[.cmd]") {
CmdProxy proxy(&det); CmdProxy proxy(&det);
if (det.getDetectorType().squash() == defs::MYTHEN3) { if (det.getDetectorType().squash() == defs::MYTHEN3) {
auto prev_val = det.getPumpProbe(); auto prev_val = det.getPumpProbe();
{ auto prev_interpolation = det.getInterpolation();
std::ostringstream oss; auto prev_mask = det.getCounterMask();
proxy.Call("pumpprobe", {"1"}, -1, PUT, oss); auto prev_vth1DacVal = det.getDAC(defs::VTH1, 0, {});
REQUIRE(oss.str() == "pumpprobe 1\n"); auto prev_vth2DacVal = det.getDAC(defs::VTH2, 0, {});
} auto prev_vth3DacVal = det.getDAC(defs::VTH3, 0, {});
{
std::ostringstream oss; int disabledDacValue = 2800;
proxy.Call("pumpprobe", {"0"}, -1, PUT, oss); auto fixedVthDacVal = 1000;
REQUIRE(oss.str() == "pumpprobe 0\n"); det.setDAC(defs::VTH1, fixedVthDacVal, 0, {});
det.setDAC(defs::VTH2, fixedVthDacVal, 0, {});
det.setDAC(defs::VTH3, fixedVthDacVal, 0, {});
// mask with counter 2 disabled and enabled(to test vth2)
uint32_t fixedMask[2] = {0x4, 0x3};
for (int i = 0; i != 2; ++i) {
det.setCounterMask(fixedMask[i]);
{
// pump probe
std::ostringstream oss;
proxy.Call("pumpprobe", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "pumpprobe 1\n");
REQUIRE(det.getDAC(defs::VTH1, 0, {0}).tsquash("inconsistent vth2 dac value") == disabledDacValue);
REQUIRE(det.getDAC(defs::VTH2, 0, {0}).tsquash("inconsistent vth2 dac value") == fixedVthDacVal);
REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth2 dac value") == disabledDacValue);
}
// interpolation and pump probe
REQUIRE_THROWS(proxy.Call("interpolation", {"1"}, -1, PUT));
{
// none
std::ostringstream oss;
proxy.Call("pumpprobe", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "pumpprobe 0\n");
REQUIRE(det.getCounterMask().tsquash("inconsistent counter mask") == 7);
REQUIRE(det.getDAC(defs::VTH1, 0, {0}).tsquash("inconsistent vth1 dac value") == (fixedMask[i] & 0x1 ? fixedVthDacVal : disabledDacValue));
REQUIRE(det.getDAC(defs::VTH2, 0, {0}).tsquash("inconsistent vth2 dac value") == (fixedMask[i] & 0x2 ? fixedVthDacVal : disabledDacValue));
REQUIRE(det.getDAC(defs::VTH3, 0, {0}).tsquash("inconsistent vth3 dac value") == (fixedMask[i] & 0x4 ? fixedVthDacVal : disabledDacValue));
}
} }
{ {
std::ostringstream oss; std::ostringstream oss;
@ -549,7 +591,12 @@ TEST_CASE("pumpprobe", "[.cmd]") {
REQUIRE(oss.str() == "pumpprobe 0\n"); REQUIRE(oss.str() == "pumpprobe 0\n");
} }
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setCounterMask(prev_mask[i], {i});
det.setPumpProbe(prev_val[i], {i}); det.setPumpProbe(prev_val[i], {i});
det.setInterpolation(prev_interpolation[i], {i});
det.setDAC(defs::VTH1, prev_vth1DacVal[i], 0, {i});
det.setDAC(defs::VTH2, prev_vth2DacVal[i], 0, {i});
det.setDAC(defs::VTH3, prev_vth3DacVal[i], 0, {i});
} }
} else { } else {
REQUIRE_THROWS(proxy.Call("pumpprobe", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("pumpprobe", {}, -1, GET));
@ -610,4 +657,6 @@ TEST_CASE("dpulse", "[.cmd]") {
} else { } else {
REQUIRE_THROWS(proxy.Call("dpulse", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("dpulse", {}, -1, GET));
} }
} }
} // namespace sls

View File

@ -12,8 +12,8 @@
#include "test-CmdProxy-global.h" #include "test-CmdProxy-global.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -99,7 +99,7 @@ TEST_CASE("patword", "[.cmd]") {
if (det_type == defs::CHIPTESTBOARD || det_type == defs::MOENCH || if (det_type == defs::CHIPTESTBOARD || det_type == defs::MOENCH ||
det_type == defs::MYTHEN3) { det_type == defs::MYTHEN3) {
int addr = 0x23; int addr = 0x23;
std::string saddr = sls::ToStringHex(addr, 4); std::string saddr = ToStringHex(addr, 4);
auto prev_val = det.getPatternWord(addr); auto prev_val = det.getPatternWord(addr);
{ {
std::ostringstream oss; std::ostringstream oss;
@ -528,4 +528,6 @@ TEST_CASE("patternstart", "[.cmd]") {
} else { } else {
REQUIRE_THROWS(proxy.Call("patternstart", {}, -1, PUT)); REQUIRE_THROWS(proxy.Call("patternstart", {}, -1, PUT));
} }
} }
} // namespace sls

View File

@ -9,8 +9,8 @@
#include "sls/versionAPI.h" #include "sls/versionAPI.h"
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -440,6 +440,79 @@ TEST_CASE("rx_arping", "[.cmd][.rx]") {
} }
} }
TEST_CASE("rx_roi", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD || det_type == defs::MOENCH) {
REQUIRE_THROWS(proxy.Call("rx_roi", {"5", "10"}, -1, PUT));
} else {
auto prev_val = det.getRxROI();
defs::xy detsize = det.getDetectorSize();
// 1d
if (det_type == defs::GOTTHARD || det_type == defs::GOTTHARD2 ||
det_type == defs::MYTHEN3) {
{
std::ostringstream oss;
proxy.Call("rx_roi", {"5", "10"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_roi [5, 10]\n");
}
{
std::ostringstream oss;
proxy.Call("rx_roi", {"10", "15"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_roi [10, 15]\n");
}
REQUIRE_THROWS(proxy.Call("rx_roi", {"-1", "-1"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("rx_roi", {"10", "15", "25", "30"}, -1, PUT));
}
// 2d
else {
{
std::ostringstream oss;
proxy.Call("rx_roi", {"10", "15", "1", "5"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_roi [10, 15, 1, 5]\n");
}
{
std::ostringstream oss;
proxy.Call("rx_roi", {"10", "22", "18", "19"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_roi [10, 22, 18, 19]\n");
}
{
std::ostringstream oss;
proxy.Call("rx_roi", {"1", std::to_string(detsize.x - 5), "1", std::to_string(detsize.y - 5)}, -1, PUT, oss);
REQUIRE(oss.str() == std::string("rx_roi [1, ") + std::to_string(detsize.x - 5) + std::string(", ") + std::to_string(detsize.y - 5) + std::string(", 1]\n"));
}
REQUIRE_THROWS(proxy.Call("rx_roi", {"-1", "-1", "-1", "-1"}, -1, PUT));
}
for (int i = 0; i != det.size(); ++i) {
det.setRxROI(prev_val);
}
}
}
TEST_CASE("rx_clearroi", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD || det_type == defs::MOENCH) {
REQUIRE_THROWS(proxy.Call("rx_clearroi", {}, -1, PUT));
} else {
auto prev_val = det.getRxROI();
{
std::ostringstream oss;
proxy.Call("rx_clearroi", {}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_clearroi successful\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setRxROI(prev_val);
}
}
}
/* File */ /* File */
TEST_CASE("fformat", "[.cmd]") { TEST_CASE("fformat", "[.cmd]") {
@ -499,6 +572,9 @@ TEST_CASE("fname", "[.cmd]") {
proxy.Call("fname", {"run"}, -1, PUT, oss); proxy.Call("fname", {"run"}, -1, PUT, oss);
REQUIRE(oss.str() == "fname run\n"); REQUIRE(oss.str() == "fname run\n");
} }
REQUIRE_THROWS(proxy.Call("fname", {"fdf/dfd"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("fname", {"fdf dfd"}, -1, PUT));
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setFileNamePrefix(prev_val[i], {i}); det.setFileNamePrefix(prev_val[i], {i});
} }
@ -915,3 +991,5 @@ TEST_CASE("rx_jsonpara", "[.cmd][.rx]") {
} }
/* Insignificant */ /* Insignificant */
} // namespace sls

View File

@ -11,8 +11,8 @@
#include "tests/globals.h" #include "tests/globals.h"
using sls::CmdProxy; namespace sls {
using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
@ -152,7 +152,7 @@ TEST_CASE("type", "[.cmd]") {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("type", {}, -1, GET, oss); proxy.Call("type", {}, -1, GET, oss);
auto ans = oss.str().erase(0, strlen("type ")); auto ans = oss.str().erase(0, strlen("type "));
REQUIRE(ans == sls::ToString(dt) + '\n'); REQUIRE(ans == ToString(dt) + '\n');
// REQUIRE(dt == test::type); // REQUIRE(dt == test::type);
} }
@ -339,7 +339,7 @@ TEST_CASE("threshold", "[.cmd]") {
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
if (prev_threshold[i][0] >= 0) { if (prev_threshold[i][0] >= 0) {
std::cout std::cout
<< "prev cvalues:" << sls::ToString(prev_threshold[i]) << "prev cvalues:" << ToString(prev_threshold[i])
<< std::endl; << std::endl;
det.setThresholdEnergy(prev_threshold[i], prev_settings, det.setThresholdEnergy(prev_threshold[i], prev_settings,
true, {i}); true, {i});
@ -684,7 +684,7 @@ TEST_CASE("exptime", "[.cmd][.time]") {
auto t = auto t =
det.getExptimeForAllGates().tsquash("inconsistent exptime to test"); det.getExptimeForAllGates().tsquash("inconsistent exptime to test");
if (t[0] != t[1] || t[1] != t[2]) { if (t[0] != t[1] || t[1] != t[2]) {
throw sls::RuntimeError("inconsistent exptime for all gates"); throw RuntimeError("inconsistent exptime for all gates");
} }
prev_val = t[0]; prev_val = t[0];
} }
@ -1867,7 +1867,7 @@ TEST_CASE("defaultdac", "[.cmd]") {
if (it == defs::VTHRESHOLD) { if (it == defs::VTHRESHOLD) {
continue; continue;
} }
auto dacname = sls::ToString(it); auto dacname = ToString(it);
auto prev_val = det.getDefaultDac(it); auto prev_val = det.getDefaultDac(it);
{ {
std::ostringstream oss; std::ostringstream oss;
@ -1889,7 +1889,7 @@ TEST_CASE("defaultdac", "[.cmd]") {
std::vector<defs::dacIndex> daclist = { std::vector<defs::dacIndex> daclist = {
defs::VREF_PRECH, defs::VREF_DS, defs::VREF_COMP}; defs::VREF_PRECH, defs::VREF_DS, defs::VREF_COMP};
for (auto it : daclist) { for (auto it : daclist) {
auto dacname = sls::ToString(it); auto dacname = ToString(it);
auto prev_val = det.getDefaultDac(it, defs::GAIN0); auto prev_val = det.getDefaultDac(it, defs::GAIN0);
{ {
std::ostringstream oss; std::ostringstream oss;
@ -2044,7 +2044,7 @@ TEST_CASE("start", "[.cmd]") {
auto t = auto t =
det.getExptimeForAllGates().tsquash("inconsistent exptime to test"); det.getExptimeForAllGates().tsquash("inconsistent exptime to test");
if (t[0] != t[1] || t[1] != t[2]) { if (t[0] != t[1] || t[1] != t[2]) {
throw sls::RuntimeError("inconsistent exptime for all gates"); throw RuntimeError("inconsistent exptime for all gates");
} }
prev_val = t[0]; prev_val = t[0];
} }
@ -2083,7 +2083,7 @@ TEST_CASE("stop", "[.cmd]") {
auto t = auto t =
det.getExptimeForAllGates().tsquash("inconsistent exptime to test"); det.getExptimeForAllGates().tsquash("inconsistent exptime to test");
if (t[0] != t[1] || t[1] != t[2]) { if (t[0] != t[1] || t[1] != t[2]) {
throw sls::RuntimeError("inconsistent exptime for all gates"); throw RuntimeError("inconsistent exptime for all gates");
} }
prev_val = t[0]; prev_val = t[0];
} }
@ -2126,7 +2126,7 @@ TEST_CASE("status", "[.cmd]") {
auto t = auto t =
det.getExptimeForAllGates().tsquash("inconsistent exptime to test"); det.getExptimeForAllGates().tsquash("inconsistent exptime to test");
if (t[0] != t[1] || t[1] != t[2]) { if (t[0] != t[1] || t[1] != t[2]) {
throw sls::RuntimeError("inconsistent exptime for all gates"); throw RuntimeError("inconsistent exptime for all gates");
} }
prev_val = t[0]; prev_val = t[0];
} }
@ -2265,29 +2265,29 @@ TEST_CASE("scan", "[.cmd]") {
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("scan", {sls::ToString(ind), "500", "1500", "500"}, -1, PUT, proxy.Call("scan", {ToString(ind), "500", "1500", "500"}, -1, PUT,
oss); oss);
CHECK(oss.str() == CHECK(oss.str() ==
"scan [" + sls::ToString(ind) + ", 500, 1500, 500]\n"); "scan [" + ToString(ind) + ", 500, 1500, 500]\n");
} }
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("scan", {}, -1, GET, oss); proxy.Call("scan", {}, -1, GET, oss);
CHECK(oss.str() == "scan [enabled\ndac " + sls::ToString(ind) + CHECK(oss.str() == "scan [enabled\ndac " + ToString(ind) +
"\nstart 500\nstop 1500\nstep " "\nstart 500\nstop 1500\nstep "
"500\nsettleTime 1ms\n]\n"); "500\nsettleTime 1ms\n]\n");
} }
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("scan", {sls::ToString(ind), "500", "1500", "500", "2s"}, -1, proxy.Call("scan", {ToString(ind), "500", "1500", "500", "2s"}, -1,
PUT, oss); PUT, oss);
CHECK(oss.str() == CHECK(oss.str() ==
"scan [" + sls::ToString(ind) + ", 500, 1500, 500, 2s]\n"); "scan [" + ToString(ind) + ", 500, 1500, 500, 2s]\n");
} }
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("scan", {}, -1, GET, oss); proxy.Call("scan", {}, -1, GET, oss);
CHECK(oss.str() == "scan [enabled\ndac " + sls::ToString(ind) + CHECK(oss.str() == "scan [enabled\ndac " + ToString(ind) +
"\nstart 500\nstop 1500\nstep " "\nstart 500\nstop 1500\nstep "
"500\nsettleTime 2s\n]\n"); "500\nsettleTime 2s\n]\n");
} }
@ -2303,17 +2303,17 @@ TEST_CASE("scan", "[.cmd]") {
} }
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("scan", {sls::ToString(ind), "1500", "500", "-500"}, -1, PUT, proxy.Call("scan", {ToString(ind), "1500", "500", "-500"}, -1, PUT,
oss); oss);
CHECK(oss.str() == CHECK(oss.str() ==
"scan [" + sls::ToString(ind) + ", 1500, 500, -500]\n"); "scan [" + ToString(ind) + ", 1500, 500, -500]\n");
} }
CHECK_THROWS(proxy.Call( CHECK_THROWS(proxy.Call(
"scan", {sls::ToString(notImplementedInd), "500", "1500", "500"}, -1, "scan", {ToString(notImplementedInd), "500", "1500", "500"}, -1,
PUT)); PUT));
CHECK_THROWS(proxy.Call("scan", {sls::ToString(ind), "500", "1500", "-500"}, CHECK_THROWS(proxy.Call("scan", {ToString(ind), "500", "1500", "-500"},
-1, PUT)); -1, PUT));
CHECK_THROWS(proxy.Call("scan", {sls::ToString(ind), "1500", "500", "500"}, CHECK_THROWS(proxy.Call("scan", {ToString(ind), "1500", "500", "500"},
-1, PUT)); -1, PUT));
if (det_type == defs::MYTHEN3 || defs::EIGER) { if (det_type == defs::MYTHEN3 || defs::EIGER) {
@ -2491,7 +2491,7 @@ TEST_CASE("udp_srcip2", "[.cmd]") {
REQUIRE(oss.str() == "udp_srcip2 129.129.205.12\n"); REQUIRE(oss.str() == "udp_srcip2 129.129.205.12\n");
} }
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
if (prev_val[i] != sls::IpAddr{"0.0.0.0"}) if (prev_val[i] != IpAddr{"0.0.0.0"})
det.setSourceUDPIP2(prev_val[i], {i}); det.setSourceUDPIP2(prev_val[i], {i});
} }
} else { } else {
@ -2846,7 +2846,7 @@ TEST_CASE("reg", "[.cmd]") {
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type != defs::EIGER) { if (det_type != defs::EIGER) {
uint32_t addr = 0x64; uint32_t addr = 0x64;
std::string saddr = sls::ToStringHex(addr); std::string saddr = ToStringHex(addr);
auto prev_val = det.readRegister(addr); auto prev_val = det.readRegister(addr);
{ {
std::ostringstream oss1, oss2; std::ostringstream oss1, oss2;
@ -2889,7 +2889,7 @@ TEST_CASE("setbit", "[.cmd]") {
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type != defs::EIGER) { if (det_type != defs::EIGER) {
uint32_t addr = 0x64; uint32_t addr = 0x64;
std::string saddr = sls::ToStringHex(addr); std::string saddr = ToStringHex(addr);
auto prev_val = det.readRegister(addr); auto prev_val = det.readRegister(addr);
{ {
std::ostringstream oss1, oss2; std::ostringstream oss1, oss2;
@ -2911,7 +2911,7 @@ TEST_CASE("clearbit", "[.cmd]") {
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type != defs::EIGER) { if (det_type != defs::EIGER) {
uint32_t addr = 0x64; uint32_t addr = 0x64;
std::string saddr = sls::ToStringHex(addr); std::string saddr = ToStringHex(addr);
auto prev_val = det.readRegister(addr); auto prev_val = det.readRegister(addr);
{ {
std::ostringstream oss1, oss2; std::ostringstream oss1, oss2;
@ -2933,7 +2933,7 @@ TEST_CASE("getbit", "[.cmd]") {
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type != defs::EIGER) { if (det_type != defs::EIGER) {
uint32_t addr = 0x64; uint32_t addr = 0x64;
std::string saddr = sls::ToStringHex(addr); std::string saddr = ToStringHex(addr);
auto prev_val = det.readRegister(addr); auto prev_val = det.readRegister(addr);
{ {
std::ostringstream oss1, oss2; std::ostringstream oss1, oss2;
@ -3162,3 +3162,5 @@ TEST_CASE("user", "[.cmd]") {
REQUIRE_THROWS(proxy.Call("user", {}, -1, PUT)); REQUIRE_THROWS(proxy.Call("user", {}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("user", {}, -1, GET)); REQUIRE_NOTHROW(proxy.Call("user", {}, -1, GET));
} }
} // namespace sls

View File

@ -5,9 +5,9 @@
#include "SharedMemory.h" #include "SharedMemory.h"
#include "CtbConfig.h" #include "CtbConfig.h"
using namespace sls;
#include <fstream> #include <fstream>
namespace sls {
TEST_CASE("Default construction"){ TEST_CASE("Default construction"){
static_assert(sizeof(CtbConfig) == 360); // 18*20 static_assert(sizeof(CtbConfig) == 360); // 18*20
@ -56,4 +56,6 @@ TEST_CASE("Move CtbConfig "){
c1.setDacName(3, "yetanothername"); c1.setDacName(3, "yetanothername");
CtbConfig c2(std::move(c1)); CtbConfig c2(std::move(c1));
REQUIRE(c2.getDacName(3) == "yetanothername"); REQUIRE(c2.getDacName(3) == "yetanothername");
} }
} // namespace sls

View File

@ -4,19 +4,21 @@
#include "SharedMemory.h" #include "SharedMemory.h"
#include "catch.hpp" #include "catch.hpp"
namespace sls {
using dt = slsDetectorDefs::detectorType; using dt = slsDetectorDefs::detectorType;
TEST_CASE("Construction with a defined detector type") { TEST_CASE("Construction with a defined detector type") {
sls::Module m(dt::EIGER); Module m(dt::EIGER);
REQUIRE(m.getDetectorType() == dt::EIGER); REQUIRE(m.getDetectorType() == dt::EIGER);
m.freeSharedMemory(); // clean up m.freeSharedMemory(); // clean up
} }
TEST_CASE("Read back detector type from shm") { TEST_CASE("Read back detector type from shm") {
// Create specific detector in order to create shm // Create specific detector in order to create shm
sls::Module m(dt::JUNGFRAU); Module m(dt::JUNGFRAU);
// New detector that reads type from shm // New detector that reads type from shm
sls::Module m2; Module m2;
REQUIRE(m2.getDetectorType() == dt::JUNGFRAU); REQUIRE(m2.getDetectorType() == dt::JUNGFRAU);
// Now both objects point to the same shm so we can only // Now both objects point to the same shm so we can only
@ -25,15 +27,15 @@ TEST_CASE("Read back detector type from shm") {
} }
TEST_CASE("Is shm fixed pattern shm compatible") { TEST_CASE("Is shm fixed pattern shm compatible") {
sls::Module m(dt::JUNGFRAU); Module m(dt::JUNGFRAU);
// Should be true since we just created the shm // Should be true since we just created the shm
REQUIRE(m.isFixedPatternSharedMemoryCompatible() == true); REQUIRE(m.isFixedPatternSharedMemoryCompatible() == true);
// Set shm version to 0 // Set shm version to 0
sls::SharedMemory<sls::sharedModule> shm(0, 0); SharedMemory<sharedModule> shm(0, 0);
REQUIRE(shm.exists() == true); REQUIRE(shm.exists() == true);
shm.openSharedMemory(); shm.openSharedMemory(true);
shm()->shmversion = 0; shm()->shmversion = 0;
// Should fail since version is set to 0 // Should fail since version is set to 0
@ -43,19 +45,21 @@ TEST_CASE("Is shm fixed pattern shm compatible") {
} }
TEST_CASE("Get default control port") { TEST_CASE("Get default control port") {
sls::Module m(dt::MYTHEN3); Module m(dt::MYTHEN3);
REQUIRE(m.getControlPort() == 1952); REQUIRE(m.getControlPort() == 1952);
m.freeSharedMemory(); m.freeSharedMemory();
} }
TEST_CASE("Get default stop port") { TEST_CASE("Get default stop port") {
sls::Module m(dt::GOTTHARD2); Module m(dt::GOTTHARD2);
REQUIRE(m.getStopPort() == 1953); REQUIRE(m.getStopPort() == 1953);
m.freeSharedMemory(); m.freeSharedMemory();
} }
TEST_CASE("Get default receiver TCP port") { TEST_CASE("Get default receiver TCP port") {
sls::Module m(dt::MYTHEN3); Module m(dt::MYTHEN3);
REQUIRE(m.getReceiverPort() == 1954); REQUIRE(m.getReceiverPort() == 1954);
m.freeSharedMemory(); m.freeSharedMemory();
} }
} // namespace sls

View File

@ -3,7 +3,7 @@
#include "catch.hpp" #include "catch.hpp"
#include "sls/Pattern.h" #include "sls/Pattern.h"
using sls::Pattern; namespace sls {
TEST_CASE("Pattern is default constructable and has zeroed fields") { TEST_CASE("Pattern is default constructable and has zeroed fields") {
Pattern p; Pattern p;
@ -27,3 +27,5 @@ TEST_CASE("Compare patterns") {
p1.data()->word[500] = 1; p1.data()->word[500] = 1;
REQUIRE_FALSE(p == p1); REQUIRE_FALSE(p == p1);
} }
} // namespace sls

View File

@ -6,10 +6,10 @@
#include "sls/TypeTraits.h" #include "sls/TypeTraits.h"
#include <string> #include <string>
using sls::Result; namespace sls {
TEST_CASE("Result looks and behaves like a standard container") { TEST_CASE("Result looks and behaves like a standard container") {
REQUIRE(sls::is_container<Result<int>>::value == true); REQUIRE(is_container<Result<int>>::value == true);
} }
TEST_CASE("Default construction is possible and gives an empty result") { TEST_CASE("Default construction is possible and gives an empty result") {
@ -195,3 +195,5 @@ TEST_CASE("String conversions") {
REQUIRE(ToString(res4) == REQUIRE(ToString(res4) ==
"[{one: 1}, {one: 1, three: 3, two: 2}, {one: 1}]"); "[{one: 1}, {one: 1, three: 3, two: 2}, {one: 1}]");
} }
} // namespace sls

View File

@ -7,14 +7,14 @@
#include <iostream> #include <iostream>
namespace sls {
struct Data { struct Data {
int x; int x;
double y; double y;
char mess[50]; char mess[50];
}; };
using namespace sls;
constexpr int shm_id = 10; constexpr int shm_id = 10;
TEST_CASE("Create SharedMemory read and write", "[detector]") { TEST_CASE("Create SharedMemory read and write", "[detector]") {
@ -26,7 +26,7 @@ TEST_CASE("Create SharedMemory read and write", "[detector]") {
shm()->x = 3; shm()->x = 3;
shm()->y = 5.7; shm()->y = 5.7;
sls::strcpy_safe(shm()->mess, "Some string"); strcpy_safe(shm()->mess, "Some string");
CHECK(shm()->x == 3); CHECK(shm()->x == 3);
CHECK(shm()->y == 5.7); CHECK(shm()->y == 5.7);
@ -47,7 +47,7 @@ TEST_CASE("Open existing SharedMemory and read", "[detector]") {
} }
SharedMemory<double> shm2(shm_id, -1); SharedMemory<double> shm2(shm_id, -1);
shm2.openSharedMemory(); shm2.openSharedMemory(true);
CHECK(*shm2() == 5.3); CHECK(*shm2() == 5.3);
shm2.removeSharedMemory(); shm2.removeSharedMemory();
@ -74,7 +74,7 @@ TEST_CASE("Open two shared memories to the same place", "[detector]") {
// Open the second shared memory with the same name // Open the second shared memory with the same name
SharedMemory<Data> shm2(shm_id, -1); SharedMemory<Data> shm2(shm_id, -1);
shm2.openSharedMemory(); shm2.openSharedMemory(true);
CHECK(shm2()->x == 5); CHECK(shm2()->x == 5);
CHECK(shm.getName() == shm2.getName()); CHECK(shm.getName() == shm2.getName());
@ -165,11 +165,9 @@ TEST_CASE("map int64 to int32 throws"){
*shm() = 7; *shm() = 7;
SharedMemory<int64_t> shm2(shm_id, -1); SharedMemory<int64_t> shm2(shm_id, -1);
REQUIRE_THROWS(shm2.openSharedMemory()); REQUIRE_THROWS(shm2.openSharedMemory(true));
shm.removeSharedMemory(); shm.removeSharedMemory();
}
} // namespace sls
}

View File

@ -238,7 +238,7 @@
// CHECK(d.getReceiverDbitList().size() == 10); // CHECK(d.getReceiverDbitList().size() == 10);
// list.push_back(64); // list.push_back(64);
// CHECK_THROWS_AS(d.setReceiverDbitList(list), sls::RuntimeError); // CHECK_THROWS_AS(d.setReceiverDbitList(list), RuntimeError);
// CHECK_THROWS_WITH(d.setReceiverDbitList(list), // CHECK_THROWS_WITH(d.setReceiverDbitList(list),
// Catch::Matchers::Contains("be between 0 and 63")); // Catch::Matchers::Contains("be between 0 and 63"));

View File

@ -4,10 +4,11 @@
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include <memory> #include <memory>
class ClientInterface;
namespace sls { namespace sls {
class ClientInterface;
class Receiver : private virtual slsDetectorDefs { class Receiver : private virtual slsDetectorDefs {
public: public:

View File

@ -6,6 +6,8 @@
#include <chrono> #include <chrono>
#include <unistd.h> #include <unistd.h>
namespace sls {
// gettid added in glibc 2.30 // gettid added in glibc 2.30
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30 #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
#include <sys/syscall.h> #include <sys/syscall.h>
@ -16,7 +18,7 @@ void Arping::SetInterfacesAndIps(const int index, const std::string &interface,
const std::string &ip) { const std::string &ip) {
if (interface.empty() || ip.empty()) { if (interface.empty() || ip.empty()) {
throw sls::RuntimeError("Could not arping. Interface name and ip not " throw RuntimeError("Could not arping. Interface name and ip not "
"set up for interface " + "set up for interface " +
std::to_string(index)); std::to_string(index));
} }
@ -38,7 +40,7 @@ void Arping::StartThread() {
try { try {
t = std::thread(&Arping::ThreadExecution, this); t = std::thread(&Arping::ThreadExecution, this);
} catch (...) { } catch (...) {
throw sls::RuntimeError("Could not start arping thread"); throw RuntimeError("Could not start arping thread");
} }
runningFlag = true; runningFlag = true;
} }
@ -74,13 +76,13 @@ void Arping::ThreadExecution() {
void Arping::TestCommands() { void Arping::TestCommands() {
// atleast one interface must be set up // atleast one interface must be set up
if (commands[0].empty()) { if (commands[0].empty()) {
throw sls::RuntimeError( throw RuntimeError(
"Could not arping. Interface not set up in apring thread"); "Could not arping. Interface not set up in apring thread");
} }
// test if arping commands throw an error // test if arping commands throw an error
std::string error = ExecuteCommands(); std::string error = ExecuteCommands();
if (!error.empty()) { if (!error.empty()) {
throw sls::RuntimeError(error); throw RuntimeError(error);
} }
} }
@ -117,4 +119,6 @@ std::string Arping::ExecuteCommands() {
} }
return std::string(); return std::string();
} }
} // namespace sls

View File

@ -12,6 +12,8 @@ is listening to.
#include <atomic> #include <atomic>
#include <thread> #include <thread>
namespace sls {
class Arping { class Arping {
public: public:
@ -33,3 +35,6 @@ class Arping {
std::thread t; std::thread t;
std::atomic<pid_t> threadId{0}; std::atomic<pid_t> threadId{0};
}; };
} // namespace sls

View File

@ -2,6 +2,8 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#include "BinaryDataFile.h" #include "BinaryDataFile.h"
namespace sls {
BinaryDataFile::BinaryDataFile(const int index) : File(BINARY), index_(index) {} BinaryDataFile::BinaryDataFile(const int index) : File(BINARY), index_(index) {}
BinaryDataFile::~BinaryDataFile() { CloseFile(); } BinaryDataFile::~BinaryDataFile() { CloseFile(); }
@ -47,12 +49,12 @@ void BinaryDataFile::CreateFile() {
if (!overWriteEnable_) { if (!overWriteEnable_) {
if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "wx"))) { if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "wx"))) {
fd_ = nullptr; fd_ = nullptr;
throw sls::RuntimeError("Could not create/overwrite file " + throw RuntimeError("Could not create/overwrite file " +
fileName_); fileName_);
} }
} else if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "w"))) { } else if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "w"))) {
fd_ = nullptr; fd_ = nullptr;
throw sls::RuntimeError("Could not create file " + fileName_); throw RuntimeError("Could not create file " + fileName_);
} }
// setting to no file buffering // setting to no file buffering
setvbuf(fd_, nullptr, _IONBF, 0); setvbuf(fd_, nullptr, _IONBF, 0);
@ -103,8 +105,10 @@ void BinaryDataFile::WriteToFile(char *buffer, const int buffersize,
// if write error // if write error
if (ret != buffersize) { if (ret != buffersize) {
throw sls::RuntimeError(std::to_string(index_) + throw RuntimeError(std::to_string(index_) +
" : Write to file failed for image number " + " : Write to file failed for image number " +
std::to_string(currentFrameNumber)); std::to_string(currentFrameNumber));
} }
} }
} // namespace sls

View File

@ -4,6 +4,8 @@
#include "File.h" #include "File.h"
namespace sls {
class BinaryDataFile : private virtual slsDetectorDefs, public File { class BinaryDataFile : private virtual slsDetectorDefs, public File {
public: public:
@ -42,4 +44,6 @@ class BinaryDataFile : private virtual slsDetectorDefs, public File {
int numUnitsPerReadout_{0}; int numUnitsPerReadout_{0};
uint32_t udpPortNumber_{0}; uint32_t udpPortNumber_{0};
uint32_t maxFramesPerFile_{0}; uint32_t maxFramesPerFile_{0};
}; };
} // namespace sls

View File

@ -22,10 +22,11 @@
#include <unistd.h> #include <unistd.h>
#include <vector> #include <vector>
namespace sls {
using ns = std::chrono::nanoseconds; using ns = std::chrono::nanoseconds;
using sls::RuntimeError; using Interface = ServerInterface;
using sls::SocketError;
using Interface = sls::ServerInterface;
// gettid added in glibc 2.30 // gettid added in glibc 2.30
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30 #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
@ -33,6 +34,7 @@ using Interface = sls::ServerInterface;
#define gettid() syscall(SYS_gettid) #define gettid() syscall(SYS_gettid)
#endif #endif
ClientInterface::~ClientInterface() { ClientInterface::~ClientInterface() {
killTcpThread = true; killTcpThread = true;
LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber; LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber;
@ -48,14 +50,15 @@ ClientInterface::ClientInterface(int portNumber)
functionTable(); functionTable();
parentThreadId = gettid(); parentThreadId = gettid();
tcpThread = tcpThread =
sls::make_unique<std::thread>(&ClientInterface::startTCPServer, this); make_unique<std::thread>(&ClientInterface::startTCPServer, this);
} }
int64_t ClientInterface::getReceiverVersion() { return APIRECEIVER; } int64_t ClientInterface::getReceiverVersion() { return APIRECEIVER; }
/***callback functions***/ /***callback functions***/
void ClientInterface::registerCallBackStartAcquisition( void ClientInterface::registerCallBackStartAcquisition(
int (*func)(const std::string &, const std::string &, uint64_t, size_t, void *), int (*func)(const std::string &, const std::string &, uint64_t, size_t,
void *),
void *arg) { void *arg) {
startAcquisitionCallBack = func; startAcquisitionCallBack = func;
pStartAcquisition = arg; pStartAcquisition = arg;
@ -97,7 +100,7 @@ void ClientInterface::startTCPServer() {
} catch (const RuntimeError &e) { } catch (const RuntimeError &e) {
// We had an error needs to be sent to client // We had an error needs to be sent to client
char mess[MAX_STR_LENGTH]{}; char mess[MAX_STR_LENGTH]{};
sls::strcpy_safe(mess, e.what()); strcpy_safe(mess, e.what());
socket.Send(FAIL); socket.Send(FAIL);
socket.Send(mess); socket.Send(mess);
} }
@ -122,7 +125,7 @@ int ClientInterface::functionTable(){
flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip; flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip;
flist[F_GET_RECEIVER_VERSION] = &ClientInterface::get_version; flist[F_GET_RECEIVER_VERSION] = &ClientInterface::get_version;
flist[F_SETUP_RECEIVER] = &ClientInterface::setup_receiver; flist[F_SETUP_RECEIVER] = &ClientInterface::setup_receiver;
flist[F_RECEIVER_SET_ROI] = &ClientInterface::set_roi; flist[F_RECEIVER_SET_DETECTOR_ROI] = &ClientInterface::set_detector_roi;
flist[F_RECEIVER_SET_NUM_FRAMES] = &ClientInterface::set_num_frames; flist[F_RECEIVER_SET_NUM_FRAMES] = &ClientInterface::set_num_frames;
flist[F_SET_RECEIVER_NUM_TRIGGERS] = &ClientInterface::set_num_triggers; flist[F_SET_RECEIVER_NUM_TRIGGERS] = &ClientInterface::set_num_triggers;
flist[F_SET_RECEIVER_NUM_BURSTS] = &ClientInterface::set_num_bursts; flist[F_SET_RECEIVER_NUM_BURSTS] = &ClientInterface::set_num_bursts;
@ -217,6 +220,9 @@ int ClientInterface::functionTable(){
flist[F_RECEIVER_SET_DATASTREAM] = &ClientInterface::set_detector_datastream; flist[F_RECEIVER_SET_DATASTREAM] = &ClientInterface::set_detector_datastream;
flist[F_GET_RECEIVER_ARPING] = &ClientInterface::get_arping; flist[F_GET_RECEIVER_ARPING] = &ClientInterface::get_arping;
flist[F_SET_RECEIVER_ARPING] = &ClientInterface::set_arping; flist[F_SET_RECEIVER_ARPING] = &ClientInterface::set_arping;
flist[F_RECEIVER_GET_RECEIVER_ROI] = &ClientInterface::get_receiver_roi;
flist[F_RECEIVER_SET_RECEIVER_ROI] = &ClientInterface::set_receiver_roi;
flist[F_RECEIVER_SET_RECEIVER_ROI_METADATA] = &ClientInterface::set_receiver_roi_metadata;
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" << LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@ -247,7 +253,7 @@ int ClientInterface::decodeFunction(Interface &socket) {
void ClientInterface::functionNotImplemented() { void ClientInterface::functionNotImplemented() {
std::ostringstream os; std::ostringstream os;
os << "Function: " << getFunctionNameFromEnum((enum detFuncs)fnum) os << "Function: " << getFunctionNameFromEnum((enum detFuncs)fnum)
<< ", is is not implemented for this detector"; << " is not implemented for this detector";
throw RuntimeError(os.str()); throw RuntimeError(os.str());
} }
@ -273,7 +279,7 @@ void ClientInterface::validate(T arg, T retval, const std::string &modename,
void ClientInterface::verifyLock() { void ClientInterface::verifyLock() {
if (lockedByClient && server.getThisClient() != server.getLockedBy()) { if (lockedByClient && server.getThisClient() != server.getLockedBy()) {
throw sls::SocketError("Receiver locked\n"); throw SocketError("Receiver locked\n");
} }
} }
@ -283,7 +289,7 @@ void ClientInterface::verifyIdle(Interface &socket) {
oss << "Can not execute " oss << "Can not execute "
<< getFunctionNameFromEnum((enum detFuncs)fnum) << getFunctionNameFromEnum((enum detFuncs)fnum)
<< " when receiver is not idle"; << " when receiver is not idle";
throw sls::SocketError(oss.str()); throw SocketError(oss.str());
} }
} }
@ -295,7 +301,7 @@ int ClientInterface::lock_receiver(Interface &socket) {
(server.getLockedBy() == server.getThisClient())) { (server.getLockedBy() == server.getThisClient())) {
lockedByClient = lock; lockedByClient = lock;
lock ? server.setLockedBy(server.getThisClient()) lock ? server.setLockedBy(server.getThisClient())
: server.setLockedBy(sls::IpAddr{}); : server.setLockedBy(IpAddr{});
} else { } else {
throw RuntimeError("Receiver locked\n"); throw RuntimeError("Receiver locked\n");
} }
@ -313,7 +319,7 @@ int ClientInterface::get_version(Interface &socket) {
int ClientInterface::setup_receiver(Interface &socket) { int ClientInterface::setup_receiver(Interface &socket) {
auto arg = socket.Receive<rxParameters>(); auto arg = socket.Receive<rxParameters>();
LOG(logDEBUG) << sls::ToString(arg); LOG(logDEBUG) << ToString(arg);
// if object exists, verify unlocked and idle, else only verify lock // if object exists, verify unlocked and idle, else only verify lock
// (connecting first time) // (connecting first time)
@ -329,17 +335,17 @@ int ClientInterface::setup_receiver(Interface &socket) {
// udp setup // udp setup
// update retvals only if detmac is not the same as in detector // update retvals only if detmac is not the same as in detector
sls::MacAddr retvals[2]; MacAddr retvals[2];
if (arg.udp_dstip != 0) { if (arg.udp_dstip != 0) {
sls::MacAddr r = setUdpIp(sls::IpAddr(arg.udp_dstip)); MacAddr r = setUdpIp(IpAddr(arg.udp_dstip));
sls::MacAddr detMac{arg.udp_dstmac}; MacAddr detMac{arg.udp_dstmac};
if (detMac != r) { if (detMac != r) {
retvals[0] = r; retvals[0] = r;
} }
} }
if (arg.udp_dstip2 != 0) { if (arg.udp_dstip2 != 0) {
sls::MacAddr r = setUdpIp2(sls::IpAddr(arg.udp_dstip2)); MacAddr r = setUdpIp2(IpAddr(arg.udp_dstip2));
sls::MacAddr detMac{arg.udp_dstmac2}; MacAddr detMac{arg.udp_dstmac2};
if (detMac != r) { if (detMac != r) {
retvals[1] = r; retvals[1] = r;
} }
@ -455,7 +461,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
} }
if (detType == GOTTHARD) { if (detType == GOTTHARD) {
try { try {
impl()->setROI(arg.roi); impl()->setDetectorROI(arg.roi);
} catch (const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set ROI"); throw RuntimeError("Could not set ROI");
} }
@ -495,10 +501,13 @@ void ClientInterface::setDetectorType(detectorType arg) {
try { try {
detType = GENERIC; detType = GENERIC;
receiver = sls::make_unique<Implementation>(arg); receiver = make_unique<Implementation>(arg);
detType = arg; detType = arg;
} catch (...) { } catch (std::exception &e) {
throw RuntimeError("Could not set detector type"); std::ostringstream os;
os << "Could not set detector type in the receiver. ";
os << e.what();
throw RuntimeError(os.str());
} }
// callbacks after (in setdetectortype, the object is reinitialized) // callbacks after (in setdetectortype, the object is reinitialized)
@ -518,16 +527,16 @@ void ClientInterface::setDetectorType(detectorType arg) {
impl()->setThreadIds(parentThreadId, tcpThreadId); impl()->setThreadIds(parentThreadId, tcpThreadId);
} }
int ClientInterface::set_roi(Interface &socket) { int ClientInterface::set_detector_roi(Interface &socket) {
auto arg = socket.Receive<ROI>(); auto arg = socket.Receive<ROI>();
LOG(logDEBUG1) << "Set ROI: [" << arg.xmin << ", " << arg.xmax << "]"; LOG(logDEBUG1) << "Set Detector ROI: " << ToString(arg);
if (detType != GOTTHARD) if (detType != GOTTHARD)
functionNotImplemented(); functionNotImplemented();
verifyIdle(socket); verifyIdle(socket);
try { try {
impl()->setROI(arg); impl()->setDetectorROI(arg);
} catch (const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set ROI"); throw RuntimeError("Could not set ROI");
} }
@ -637,7 +646,7 @@ int ClientInterface::set_exptime(Interface &socket) {
socket.Receive(args); socket.Receive(args);
int gateIndex = static_cast<int>(args[0]); int gateIndex = static_cast<int>(args[0]);
ns value = std::chrono::nanoseconds(args[1]); ns value = std::chrono::nanoseconds(args[1]);
LOG(logDEBUG1) << "Setting exptime to " << sls::ToString(value) LOG(logDEBUG1) << "Setting exptime to " << ToString(value)
<< " (gateIndex: " << gateIndex << ")"; << " (gateIndex: " << gateIndex << ")";
switch (gateIndex) { switch (gateIndex) {
case -1: case -1:
@ -676,14 +685,14 @@ int ClientInterface::set_exptime(Interface &socket) {
int ClientInterface::set_period(Interface &socket) { int ClientInterface::set_period(Interface &socket) {
auto value = std::chrono::nanoseconds(socket.Receive<int64_t>()); auto value = std::chrono::nanoseconds(socket.Receive<int64_t>());
LOG(logDEBUG1) << "Setting period to " << sls::ToString(value); LOG(logDEBUG1) << "Setting period to " << ToString(value);
impl()->setAcquisitionPeriod(value); impl()->setAcquisitionPeriod(value);
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::set_subexptime(Interface &socket) { int ClientInterface::set_subexptime(Interface &socket) {
auto value = std::chrono::nanoseconds(socket.Receive<int64_t>()); auto value = std::chrono::nanoseconds(socket.Receive<int64_t>());
LOG(logDEBUG1) << "Setting period to " << sls::ToString(value); LOG(logDEBUG1) << "Setting period to " << ToString(value);
ns subdeadtime = impl()->getSubPeriod() - impl()->getSubExpTime(); ns subdeadtime = impl()->getSubPeriod() - impl()->getSubExpTime();
impl()->setSubExpTime(value); impl()->setSubExpTime(value);
impl()->setSubPeriod(impl()->getSubExpTime() + subdeadtime); impl()->setSubPeriod(impl()->getSubExpTime() + subdeadtime);
@ -692,10 +701,10 @@ int ClientInterface::set_subexptime(Interface &socket) {
int ClientInterface::set_subdeadtime(Interface &socket) { int ClientInterface::set_subdeadtime(Interface &socket) {
auto value = std::chrono::nanoseconds(socket.Receive<int64_t>()); auto value = std::chrono::nanoseconds(socket.Receive<int64_t>());
LOG(logDEBUG1) << "Setting sub deadtime to " << sls::ToString(value); LOG(logDEBUG1) << "Setting sub deadtime to " << ToString(value);
impl()->setSubPeriod(value + impl()->getSubExpTime()); impl()->setSubPeriod(value + impl()->getSubExpTime());
LOG(logDEBUG1) << "Setting sub period to " LOG(logDEBUG1) << "Setting sub period to "
<< sls::ToString(impl()->getSubPeriod()); << ToString(impl()->getSubPeriod());
return socket.Send(OK); return socket.Send(OK);
} }
@ -766,7 +775,7 @@ int ClientInterface::get_streaming_frequency(Interface &socket) {
int ClientInterface::get_status(Interface &socket) { int ClientInterface::get_status(Interface &socket) {
auto retval = impl()->getStatus(); auto retval = impl()->getStatus();
LOG(logDEBUG1) << "Status:" << sls::ToString(retval); LOG(logDEBUG1) << "Status:" << ToString(retval);
return socket.sendResult(retval); return socket.sendResult(retval);
} }
@ -788,7 +797,7 @@ int ClientInterface::stop_receiver(Interface &socket) {
auto s = impl()->getStatus(); auto s = impl()->getStatus();
if (s != IDLE) if (s != IDLE)
throw RuntimeError("Could not stop receiver. It as it is: " + throw RuntimeError("Could not stop receiver. It as it is: " +
sls::ToString(s)); ToString(s));
return socket.Send(OK); return socket.Send(OK);
} }
@ -849,7 +858,7 @@ int ClientInterface::get_file_index(Interface &socket) {
int ClientInterface::get_frame_index(Interface &socket) { int ClientInterface::get_frame_index(Interface &socket) {
auto retval = impl()->getCurrentFrameIndex(); auto retval = impl()->getCurrentFrameIndex();
LOG(logDEBUG1) << "frames index:" << sls::ToString(retval); LOG(logDEBUG1) << "frames index:" << ToString(retval);
auto size = static_cast<int>(retval.size()); auto size = static_cast<int>(retval.size());
socket.Send(OK); socket.Send(OK);
socket.Send(size); socket.Send(size);
@ -859,7 +868,7 @@ int ClientInterface::get_frame_index(Interface &socket) {
int ClientInterface::get_missing_packets(Interface &socket) { int ClientInterface::get_missing_packets(Interface &socket) {
auto missing_packets = impl()->getNumMissingPackets(); auto missing_packets = impl()->getNumMissingPackets();
LOG(logDEBUG1) << "missing packets:" << sls::ToString(missing_packets); LOG(logDEBUG1) << "missing packets:" << ToString(missing_packets);
auto size = static_cast<int>(missing_packets.size()); auto size = static_cast<int>(missing_packets.size());
socket.Send(OK); socket.Send(OK);
socket.Send(size); socket.Send(size);
@ -869,7 +878,7 @@ int ClientInterface::get_missing_packets(Interface &socket) {
int ClientInterface::get_frames_caught(Interface &socket) { int ClientInterface::get_frames_caught(Interface &socket) {
auto retval = impl()->getFramesCaught(); auto retval = impl()->getFramesCaught();
LOG(logDEBUG1) << "frames caught:" << sls::ToString(retval); LOG(logDEBUG1) << "frames caught:" << ToString(retval);
auto size = static_cast<int>(retval.size()); auto size = static_cast<int>(retval.size());
socket.Send(OK); socket.Send(OK);
socket.Send(size); socket.Send(size);
@ -1087,7 +1096,7 @@ int ClientInterface::get_streaming_port(Interface &socket) {
} }
int ClientInterface::set_streaming_source_ip(Interface &socket) { int ClientInterface::set_streaming_source_ip(Interface &socket) {
auto ip = socket.Receive<sls::IpAddr>(); auto ip = socket.Receive<IpAddr>();
if (ip == 0) if (ip == 0)
throw RuntimeError("Invalid zmq ip " + ip.str()); throw RuntimeError("Invalid zmq ip " + ip.str());
verifyIdle(socket); verifyIdle(socket);
@ -1096,7 +1105,7 @@ int ClientInterface::set_streaming_source_ip(Interface &socket) {
} }
int ClientInterface::get_streaming_source_ip(Interface &socket) { int ClientInterface::get_streaming_source_ip(Interface &socket) {
sls::IpAddr retval = impl()->getStreamingSourceIP(); IpAddr retval = impl()->getStreamingSourceIP();
LOG(logDEBUG1) << "streaming IP:" << retval; LOG(logDEBUG1) << "streaming IP:" << retval;
return socket.sendResult(retval); return socket.sendResult(retval);
} }
@ -1144,14 +1153,14 @@ int ClientInterface::set_additional_json_header(Interface &socket) {
} }
} }
// verifyIdle(socket); allowing it to be set on the fly // verifyIdle(socket); allowing it to be set on the fly
LOG(logDEBUG1) << "Setting additional json header: " << sls::ToString(json); LOG(logDEBUG1) << "Setting additional json header: " << ToString(json);
impl()->setAdditionalJsonHeader(json); impl()->setAdditionalJsonHeader(json);
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::get_additional_json_header(Interface &socket) { int ClientInterface::get_additional_json_header(Interface &socket) {
std::map<std::string, std::string> json = impl()->getAdditionalJsonHeader(); std::map<std::string, std::string> json = impl()->getAdditionalJsonHeader();
LOG(logDEBUG1) << "additional json header:" << sls::ToString(json); LOG(logDEBUG1) << "additional json header:" << ToString(json);
std::ostringstream oss; std::ostringstream oss;
for (auto &it : json) { for (auto &it : json) {
oss << it.first << ' ' << it.second << ' '; oss << it.first << ' ' << it.second << ' ';
@ -1316,7 +1325,7 @@ int ClientInterface::set_adc_mask(Interface &socket) {
} }
int ClientInterface::set_dbit_list(Interface &socket) { int ClientInterface::set_dbit_list(Interface &socket) {
sls::StaticVector<int, MAX_RX_DBIT> args; StaticVector<int, MAX_RX_DBIT> args;
socket.Receive(args); socket.Receive(args);
if (detType != CHIPTESTBOARD) if (detType != CHIPTESTBOARD)
functionNotImplemented(); functionNotImplemented();
@ -1333,7 +1342,7 @@ int ClientInterface::set_dbit_list(Interface &socket) {
int ClientInterface::get_dbit_list(Interface &socket) { int ClientInterface::get_dbit_list(Interface &socket) {
if (detType != CHIPTESTBOARD) if (detType != CHIPTESTBOARD)
functionNotImplemented(); functionNotImplemented();
sls::StaticVector<int, MAX_RX_DBIT> retval; StaticVector<int, MAX_RX_DBIT> retval;
retval = impl()->getDbitList(); retval = impl()->getDbitList();
LOG(logDEBUG1) << "Dbit list size retval:" << retval.size(); LOG(logDEBUG1) << "Dbit list size retval:" << retval.size();
return socket.sendResult(retval); return socket.sendResult(retval);
@ -1396,10 +1405,10 @@ int ClientInterface::set_read_n_rows(Interface &socket) {
return socket.Send(OK); return socket.Send(OK);
} }
sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) { MacAddr ClientInterface::setUdpIp(IpAddr arg) {
LOG(logINFO) << "Received UDP IP: " << arg; LOG(logINFO) << "Received UDP IP: " << arg;
// getting eth // getting eth
std::string eth = sls::IpToInterfaceName(arg.str()); std::string eth = IpToInterfaceName(arg.str());
if (eth == "none") { if (eth == "none") {
throw RuntimeError("Failed to get udp ethernet interface from IP " + throw RuntimeError("Failed to get udp ethernet interface from IP " +
arg.str()); arg.str());
@ -1418,7 +1427,7 @@ sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
udpips[0] = arg.str(); udpips[0] = arg.str();
// get mac address // get mac address
auto retval = sls::InterfaceNameToMac(eth); auto retval = InterfaceNameToMac(eth);
if (retval == 0 && arg.str() != LOCALHOST_IP) { if (retval == 0 && arg.str() != LOCALHOST_IP) {
throw RuntimeError("Failed to get udp mac adddress to listen to (eth:" + throw RuntimeError("Failed to get udp mac adddress to listen to (eth:" +
eth + ", ip:" + arg.str() + ")\n"); eth + ", ip:" + arg.str() + ")\n");
@ -1428,16 +1437,16 @@ sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
} }
int ClientInterface::set_udp_ip(Interface &socket) { int ClientInterface::set_udp_ip(Interface &socket) {
auto arg = socket.Receive<sls::IpAddr>(); auto arg = socket.Receive<IpAddr>();
verifyIdle(socket); verifyIdle(socket);
auto retval = setUdpIp(arg); auto retval = setUdpIp(arg);
return socket.sendResult(retval); return socket.sendResult(retval);
} }
sls::MacAddr ClientInterface::setUdpIp2(sls::IpAddr arg) { MacAddr ClientInterface::setUdpIp2(IpAddr arg) {
LOG(logINFO) << "Received UDP IP2: " << arg; LOG(logINFO) << "Received UDP IP2: " << arg;
// getting eth // getting eth
std::string eth = sls::IpToInterfaceName(arg.str()); std::string eth = IpToInterfaceName(arg.str());
if (eth == "none") { if (eth == "none") {
throw RuntimeError("Failed to get udp ethernet interface2 from IP " + throw RuntimeError("Failed to get udp ethernet interface2 from IP " +
arg.str()); arg.str());
@ -1453,7 +1462,7 @@ sls::MacAddr ClientInterface::setUdpIp2(sls::IpAddr arg) {
udpips[1] = arg.str(); udpips[1] = arg.str();
// get mac address // get mac address
auto retval = sls::InterfaceNameToMac(eth); auto retval = InterfaceNameToMac(eth);
if (retval == 0 && arg.str() != LOCALHOST_IP) { if (retval == 0 && arg.str() != LOCALHOST_IP) {
throw RuntimeError( throw RuntimeError(
"Failed to get udp mac adddress2 to listen to (eth:" + eth + "Failed to get udp mac adddress2 to listen to (eth:" + eth +
@ -1464,7 +1473,7 @@ sls::MacAddr ClientInterface::setUdpIp2(sls::IpAddr arg) {
} }
int ClientInterface::set_udp_ip2(Interface &socket) { int ClientInterface::set_udp_ip2(Interface &socket) {
auto arg = socket.Receive<sls::IpAddr>(); auto arg = socket.Receive<IpAddr>();
verifyIdle(socket); verifyIdle(socket);
if (detType != JUNGFRAU && detType != GOTTHARD2) { if (detType != JUNGFRAU && detType != GOTTHARD2) {
throw RuntimeError( throw RuntimeError(
@ -1588,7 +1597,7 @@ int ClientInterface::set_gate_delay(Interface &socket) {
socket.Receive(args); socket.Receive(args);
int gateIndex = static_cast<int>(args[0]); int gateIndex = static_cast<int>(args[0]);
auto value = std::chrono::nanoseconds(args[1]); auto value = std::chrono::nanoseconds(args[1]);
LOG(logDEBUG1) << "Setting gate delay to " << sls::ToString(value) LOG(logDEBUG1) << "Setting gate delay to " << ToString(value)
<< " (gateIndex: " << gateIndex << ")"; << " (gateIndex: " << gateIndex << ")";
if (detType != MYTHEN3) { if (detType != MYTHEN3) {
functionNotImplemented(); functionNotImplemented();
@ -1617,7 +1626,7 @@ int ClientInterface::set_gate_delay(Interface &socket) {
int ClientInterface::get_thread_ids(Interface &socket) { int ClientInterface::get_thread_ids(Interface &socket) {
auto retval = impl()->getThreadIds(); auto retval = impl()->getThreadIds();
LOG(logDEBUG1) << "thread ids retval: " << sls::ToString(retval); LOG(logDEBUG1) << "thread ids retval: " << ToString(retval);
return socket.sendResult(retval); return socket.sendResult(retval);
} }
@ -1656,7 +1665,7 @@ int ClientInterface::set_rate_correct(Interface &socket) {
int ClientInterface::set_scan(Interface &socket) { int ClientInterface::set_scan(Interface &socket) {
auto arg = socket.Receive<scanParameters>(); auto arg = socket.Receive<scanParameters>();
LOG(logDEBUG) << "Scan Mode: " << sls::ToString(arg); LOG(logDEBUG) << "Scan Mode: " << ToString(arg);
verifyIdle(socket); verifyIdle(socket);
impl()->setScan(arg); impl()->setScan(arg);
return socket.Send(OK); return socket.Send(OK);
@ -1691,7 +1700,7 @@ int ClientInterface::set_streaming_hwm(Interface &socket) {
int ClientInterface::set_all_threshold(Interface &socket) { int ClientInterface::set_all_threshold(Interface &socket) {
auto eVs = socket.Receive<std::array<int, 3>>(); auto eVs = socket.Receive<std::array<int, 3>>();
LOG(logDEBUG) << "Threshold:" << sls::ToString(eVs); LOG(logDEBUG) << "Threshold:" << ToString(eVs);
if (detType != MYTHEN3) if (detType != MYTHEN3)
functionNotImplemented(); functionNotImplemented();
verifyIdle(socket); verifyIdle(socket);
@ -1711,8 +1720,8 @@ int ClientInterface::set_detector_datastream(Interface &socket) {
throw RuntimeError("Invalid port type"); throw RuntimeError("Invalid port type");
} }
bool enable = static_cast<int>(args[1]); bool enable = static_cast<int>(args[1]);
LOG(logDEBUG1) << "Setting datastream (" << sls::ToString(port) << ") to " LOG(logDEBUG1) << "Setting datastream (" << ToString(port) << ") to "
<< sls::ToString(enable); << ToString(enable);
if (detType != EIGER) if (detType != EIGER)
functionNotImplemented(); functionNotImplemented();
verifyIdle(socket); verifyIdle(socket);
@ -1736,3 +1745,39 @@ int ClientInterface::set_arping(Interface &socket) {
impl()->setArping(value, udpips); impl()->setArping(value, udpips);
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::get_receiver_roi(Interface &socket) {
auto retval = impl()->getReceiverROI();
LOG(logDEBUG1) << "Receiver roi retval:" << ToString(retval);
return socket.sendResult(retval);
}
int ClientInterface::set_receiver_roi(Interface &socket) {
auto arg = socket.Receive<ROI>();
if (detType == CHIPTESTBOARD || detType == MOENCH)
functionNotImplemented();
LOG(logDEBUG1) << "Set Receiver ROI: " << ToString(arg);
verifyIdle(socket);
try {
impl()->setReceiverROI(arg);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set ReceiverROI");
}
return socket.Send(OK);
}
int ClientInterface::set_receiver_roi_metadata(Interface &socket) {
auto arg = socket.Receive<ROI>();
if (detType == CHIPTESTBOARD || detType == MOENCH)
functionNotImplemented();
LOG(logDEBUG1) << "Set Receiver ROI Metadata: " << ToString(arg);
verifyIdle(socket);
try {
impl()->setReceiverROIMetadata(arg);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set ReceiverROI metadata");
}
return socket.Send(OK);
}
} // namespace sls

Some files were not shown because too many files have changed in this diff Show More