From 2c1fddee8479f5d87fdafd258e17536146958259 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil <33750417+thattil@users.noreply.github.com> Date: Thu, 24 Sep 2020 17:16:34 +0200 Subject: [PATCH] Cmddacs (#189) Moved dacs to it's own command for command line. Co-authored-by: Erik Frojdh --- python/slsdet/detector.py | 16 +- python/src/detector.cpp | 4 + .../bin/gotthard2DetectorServer_developer | Bin 220208 -> 220272 bytes .../slsDetectorFunctionList.c | 23 +- .../include/slsDetectorFunctionList.h | 3 + .../include/slsDetectorServer_funcs.h | 3 +- .../src/slsDetectorServer_funcs.c | 16 + slsDetectorSoftware/include/Detector.h | 7 +- slsDetectorSoftware/src/CmdProxy.cpp | 65 ++- slsDetectorSoftware/src/CmdProxy.h | 444 +++--------------- slsDetectorSoftware/src/Detector.cpp | 4 + slsDetectorSoftware/src/HelpDacs.h | 302 ++++++++++++ slsDetectorSoftware/src/Module.cpp | 4 + slsDetectorSoftware/src/Module.h | 1 + .../tests/test-CmdProxy-gotthard2.cpp | 11 + slsSupportLib/include/sls_detector_funcs.h | 4 +- slsSupportLib/include/string_utils.h | 3 + slsSupportLib/include/versionAPI.h | 3 +- slsSupportLib/src/ToString.cpp | 36 +- slsSupportLib/src/string_utils.cpp | 6 + slsSupportLib/tests/test-string_utils.cpp | 10 + 21 files changed, 545 insertions(+), 420 deletions(-) create mode 100644 slsDetectorSoftware/src/HelpDacs.h diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 30dde7d73..ba3368989 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -342,7 +342,7 @@ class Detector(CppDetectorApi): def framesl(self): """ [Gotthard][Jungfrau][Mythen3][Gotthard2][CTB][Moench] Number of frames left in acquisition.\n - [Gotthard2] only in continuous mode. + [Gotthard2] only in continuous auto mode. :setter: Not Implemented """ return self.getNumberOfFramesLeft() @@ -1492,7 +1492,7 @@ class Detector(CppDetectorApi): [Gotthard][Jungfrau][Mythen3][Gotthard2][CTB][Moench] Number of triggers left in acquisition.\n Note ---- - [Gotthard2] only in continuous mode. + Only when external trigger used. :setter: Not Implemented """ return self.getNumberOfTriggersLeft() @@ -2119,6 +2119,18 @@ class Detector(CppDetectorApi): def bursts(self, value): self.setNumberOfBursts(value) + @property + @element + def burstsl(self): + """ + [Gotthard2] Number of bursts left in acquisition.\n + Note + ---- + Only in burst auto mode. + :setter: Not Implemented + """ + return self.getNumberOfBurstsLeft() + @property @element def filter(self): diff --git a/python/src/detector.cpp b/python/src/detector.cpp index e28689554..67976f21a 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -965,6 +965,10 @@ void init_det(py::module &m) { (void (Detector::*)(sls::ns, sls::Positions)) & Detector::setBurstPeriod, py::arg(), py::arg() = Positions{}) + .def("getNumberOfBurstsLeft", + (Result(Detector::*)(sls::Positions) const) & + Detector::getNumberOfBurstsLeft, + py::arg() = Positions{}) .def("getInjectChannel", (Result>(Detector::*)(sls::Positions)) & Detector::getInjectChannel, diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index f91fec01d7cc3333edef51fb4b3e556e2efb7b2c..3b433e5cf59e9c2abc745c3875ff17e3bf8a7ce2 100755 GIT binary patch delta 55672 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 RECEIVER_ENUM_START) { @@ -8067,4 +8068,19 @@ int validate_udp_configuration(int file_des) { } return Server_SendResult(file_des, INT32, NULL, 0); +} + +int get_bursts_left(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int64_t retval = -1; + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // get only + retval = getNumBurstsLeft(); + LOG(logDEBUG1, ("retval num bursts left %lld\n", (long long int)retval)); +#endif + return Server_SendResult(file_des, INT64, &retval, sizeof(retval)); } \ No newline at end of file diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index bc1842e33..100e3e706 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -214,11 +214,11 @@ class Detector { void setDelayAfterTrigger(ns value, Positions pos = {}); /** [Gotthard][Jungfrau][CTB][Moench][Mythen3] - * [Gotthard2] only in continuous mode */ + * [Gotthard2] only in continuous auto mode */ Result getNumberOfFramesLeft(Positions pos = {}) const; /** [Gotthard][Jungfrau][CTB][Moench][Mythen3] - * [Gotthard2] only in continuous mode */ + * Only when external trigger used */ Result getNumberOfTriggersLeft(Positions pos = {}) const; /** [Gotthard][Jungfrau][CTB][Moench][Mythen3][Gotthard2] @@ -1140,6 +1140,9 @@ class Detector { * mode */ void setBurstPeriod(ns value, Positions pos = {}); + /** [Gotthard2] only in burst auto mode */ + Result getNumberOfBurstsLeft(Positions pos = {}) const; + /** [Gotthard2] offset channel, increment channel */ Result> getInjectChannel(Positions pos = {}); diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index e59c05756..7b05a8e2b 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1,4 +1,5 @@ #include "CmdProxy.h" +#include "HelpDacs.h" #include "TimeHelper.h" #include "ToString.h" #include "bit_utils.h" @@ -33,7 +34,11 @@ void CmdProxy::Call(const std::string &command, args = arguments; det_id = detector_id; - ReplaceIfDepreciated(cmd); + std::string temp; + while (temp != cmd) { + temp = cmd; + ReplaceIfDepreciated(cmd); + } auto it = functions.find(cmd); if (it != functions.end()) { @@ -51,6 +56,10 @@ bool CmdProxy::ReplaceIfDepreciated(std::string &command) { << command << " is depreciated and will be removed. Please migrate to: " << d_it->second; + // insert old command into arguments (for dacs) + if (d_it->second == "dac") { + args.insert(args.begin(), command); + } command = d_it->second; return true; } @@ -905,45 +914,59 @@ std::string CmdProxy::TemperatureValues(int action) { std::string CmdProxy::Dac(int action) { std::ostringstream os; os << cmd << ' '; + + // dac indices only for ctb + if (args.size() > 0 && action != defs::HELP_ACTION) { + if (is_int(args[0]) && + det->getDetectorType().squash() != defs::CHIPTESTBOARD) { + throw sls::RuntimeError( + "Dac indices can only be used for chip test board. Use daclist " + "to get list of dac names for current detector."); + } + } + if (action == defs::HELP_ACTION) { - os << "[dac index] [dac or mV value] [(optional unit) mV] " - "\n\t[Ctb] Dac." - << '\n'; - } else if (det->getDetectorType().squash(defs::GENERIC) != - defs::CHIPTESTBOARD) { - throw sls::RuntimeError( - "Dac command can only be used for chip test board. Use daclist to " - "get list of dac commands for current detector."); + if (args.size() == 0) { + os << GetHelpDac(std::to_string(0)) << '\n'; + } else { + os << args[0] << ' ' << GetHelpDac(args[0]) << '\n'; + } } else if (action == defs::GET_ACTION) { - bool mv = false; + if (args.empty()) + WrongNumberOfParameters(1); // This prints slightly wrong + + defs::dacIndex dacIndex = StringTo(args[0]); + bool mV = false; + if (args.size() == 2) { if ((args[1] != "mv") && (args[1] != "mV")) { throw sls::RuntimeError("Unknown argument " + args[1] + ". Did you mean mV?"); } - mv = true; + mV = true; } else if (args.size() > 2) { WrongNumberOfParameters(1); } - auto t = - det->getDAC(static_cast(StringTo(args[0])), mv, - std::vector{det_id}); - os << args[0] << ' ' << OutString(t) - << (args.size() > 1 ? " mV\n" : "\n"); + auto t = det->getDAC(dacIndex, mV, std::vector{det_id}); + os << args[0] << ' ' << OutString(t) << (mV ? " mV\n" : "\n"); } else if (action == defs::PUT_ACTION) { - bool mv = false; + if (args.empty()) + WrongNumberOfParameters(1); // This prints slightly wrong + + defs::dacIndex dacIndex = StringTo(args[0]); + bool mV = false; if (args.size() == 3) { if ((args[2] != "mv") && (args[2] != "mV")) { throw sls::RuntimeError("Unknown argument " + args[2] + ". Did you mean mV?"); } - mv = true; + mV = true; } else if (args.size() > 3 || args.size() < 2) { WrongNumberOfParameters(2); } - det->setDAC(static_cast(StringTo(args[0])), - StringTo(args[1]), mv, std::vector{det_id}); - os << args[0] << ' ' << args[1] << (args.size() > 2 ? " mV\n" : "\n"); + det->setDAC(dacIndex, StringTo(args[1]), mV, + std::vector{det_id}); + os << args[0] << ' ' << args[1] << (mV ? " mV\n" : "\n"); } else { throw sls::RuntimeError("Unknown action"); } diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 2218ff4a7..89929f5b7 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -318,46 +318,6 @@ return os.str(); \ } -/** dac */ -#define DAC_COMMAND(CMDNAME, GETFCN, SETFCN, DAC_INDEX, HLPSTR) \ - std::string CMDNAME(const int action) { \ - std::ostringstream os; \ - os << cmd << ' '; \ - if (action == slsDetectorDefs::HELP_ACTION) \ - os << HLPSTR << '\n'; \ - else if (action == slsDetectorDefs::GET_ACTION) { \ - bool mv = false; \ - if (args.size() == 1) { \ - if ((args[0] != "mv") && (args[0] != "mV")) { \ - throw sls::RuntimeError("Unknown argument " + args[0] + \ - ". Did you mean mV?"); \ - } \ - mv = true; \ - } else if (args.size() > 1) { \ - WrongNumberOfParameters(0); \ - } \ - auto t = det->GETFCN(DAC_INDEX, mv, std::vector{det_id}); \ - os << OutString(t) << (!args.empty() ? " mV\n" : "\n"); \ - } else if (action == slsDetectorDefs::PUT_ACTION) { \ - bool mv = false; \ - if (args.size() == 2) { \ - if ((args[1] != "mv") && (args[1] != "mV")) { \ - throw sls::RuntimeError("Unknown argument " + args[1] + \ - ". Did you mean mV?"); \ - } \ - mv = true; \ - } else if (args.size() > 2 || args.empty()) { \ - WrongNumberOfParameters(1); \ - } \ - det->SETFCN(DAC_INDEX, StringTo(args[0]), mv, \ - std::vector{det_id}); \ - os << args.front() << (args.size() > 1 ? " mV\n" : "\n"); \ - } else { \ - throw sls::RuntimeError("Unknown action"); \ - } \ - return os.str(); \ - } - /** set only, no arguments, no id */ #define EXECUTE_SET_COMMAND_NOID(CMDNAME, SETFCN, HLPSTR) \ std::string CMDNAME(const int action) { \ @@ -615,7 +575,7 @@ class CmdProxy { /** temperature */ - /** dacs */ + /** super old dacs */ {"vtr", "vtrim"}, {"vrf", "vrpreamp"}, {"vrs", "vrshaper"}, @@ -627,6 +587,70 @@ class CmdProxy { {"viinsh", "vishaper"}, {"vpl", "vcal_n"}, {"vph", "vcal_p"}, + /** dacs */ + {"vthreshold", "dac"}, + {"vsvp", "dac"}, + {"vsvn", "dac"}, + {"vtrim", "dac"}, + {"vrpreamp", "dac"}, + {"vrshaper", "dac"}, + {"vtgstv", "dac"}, + {"vcmp_ll", "dac"}, + {"vcmp_lr", "dac"}, + {"vcal", "dac"}, + {"vcmp_rl", "dac"}, + {"vcmp_rr", "dac"}, + {"rxb_rb", "dac"}, + {"rxb_lb", "dac"}, + {"vcp", "dac"}, + {"vcn", "dac"}, + {"vishaper", "dac"}, + {"iodelay", "dac"}, + {"vref_ds", "dac"}, + {"vcascn_pb", "dac"}, + {"vcascp_pb", "dac"}, + {"vout_cm", "dac"}, + {"vcasc_out", "dac"}, + {"vin_cm", "dac"}, + {"vref_comp", "dac"}, + {"ib_test_c", "dac"}, + {"vrshaper_n", "dac"}, + {"vipre", "dac"}, + {"vdcsh", "dac"}, + {"vth1", "dac"}, + {"vth2", "dac"}, + {"vth3", "dac"}, + {"vcal_n", "dac"}, + {"vcal_p", "dac"}, + {"vcassh", "dac"}, + {"vcas", "dac"}, + {"vicin", "dac"}, + {"vipre_out", "dac"}, + {"vref_h_adc", "dac"}, + {"vb_comp_fe", "dac"}, + {"vb_comp_adc", "dac"}, + {"vcom_cds", "dac"}, + {"vref_rstore", "dac"}, + {"vb_opa_1st", "dac"}, + {"vref_comp_fe", "dac"}, + {"vcom_adc1", "dac"}, + {"vref_prech", "dac"}, + {"vref_l_adc", "dac"}, + {"vref_cds", "dac"}, + {"vb_cs", "dac"}, + {"vb_opa_fd", "dac"}, + {"vcom_adc2", "dac"}, + {"adcvpp", "dac"}, + {"vb_ds", "dac"}, + {"vb_comp", "dac"}, + {"vb_pixbuf", "dac"}, + {"vin_com", "dac"}, + {"vdd_prot", "dac"}, + {"vbp_colbuf", "dac"}, + {"vb_sda", "dac"}, + {"vcasc_sfp", "dac"}, + {"vipre_cds", "dac"}, + {"ibias_sfp", "dac"}, /* acquisition */ {"busy", "clearbusy"}, @@ -764,70 +788,6 @@ class CmdProxy { {"temp_slowadc", &CmdProxy::temp_slowadc}, /* dacs */ - {"vthreshold", &CmdProxy::vthreshold}, - {"vsvp", &CmdProxy::vsvp}, - {"vsvn", &CmdProxy::vsvn}, - {"vtrim", &CmdProxy::vtrim}, - {"vrpreamp", &CmdProxy::vrpreamp}, - {"vrshaper", &CmdProxy::vrshaper}, - {"vtgstv", &CmdProxy::vtgstv}, - {"vcmp_ll", &CmdProxy::vcmp_ll}, - {"vcmp_lr", &CmdProxy::vcmp_lr}, - {"vcal", &CmdProxy::vcal}, - {"vcmp_rl", &CmdProxy::vcmp_rl}, - {"vcmp_rr", &CmdProxy::vcmp_rr}, - {"rxb_rb", &CmdProxy::rxb_rb}, - {"rxb_lb", &CmdProxy::rxb_lb}, - {"vcp", &CmdProxy::vcp}, - {"vcn", &CmdProxy::vcn}, - {"vishaper", &CmdProxy::vishaper}, - {"iodelay", &CmdProxy::iodelay}, - {"vref_ds", &CmdProxy::vref_ds}, - {"vcascn_pb", &CmdProxy::vcascn_pb}, - {"vcascp_pb", &CmdProxy::vcascp_pb}, - {"vout_cm", &CmdProxy::vout_cm}, - {"vcasc_out", &CmdProxy::vcasc_out}, - {"vin_cm", &CmdProxy::vin_cm}, - {"vref_comp", &CmdProxy::vref_comp}, - {"ib_test_c", &CmdProxy::ib_test_c}, - {"vrshaper_n", &CmdProxy::vrshaper_n}, - {"vipre", &CmdProxy::vipre}, - {"vdcsh", &CmdProxy::vdcsh}, - {"vth1", &CmdProxy::vth1}, - {"vth2", &CmdProxy::vth2}, - {"vth3", &CmdProxy::vth3}, - {"vcal_n", &CmdProxy::vcal_n}, - {"vcal_p", &CmdProxy::vcal_p}, - {"vcassh", &CmdProxy::vcassh}, - {"vcas", &CmdProxy::vcas}, - {"vicin", &CmdProxy::vicin}, - {"vipre_out", &CmdProxy::vipre_out}, - {"vref_h_adc", &CmdProxy::vref_h_adc}, - {"vb_comp_fe", &CmdProxy::vb_comp_fe}, - {"vb_comp_adc", &CmdProxy::vb_comp_adc}, - {"vcom_cds", &CmdProxy::vcom_cds}, - {"vref_rstore", &CmdProxy::vref_rstore}, - {"vb_opa_1st", &CmdProxy::vb_opa_1st}, - {"vref_comp_fe", &CmdProxy::vref_comp_fe}, - {"vcom_adc1", &CmdProxy::vcom_adc1}, - {"vref_prech", &CmdProxy::vref_prech}, - {"vref_l_adc", &CmdProxy::vref_l_adc}, - {"vref_cds", &CmdProxy::vref_cds}, - {"vb_cs", &CmdProxy::vb_cs}, - {"vb_opa_fd", &CmdProxy::vb_opa_fd}, - {"vcom_adc2", &CmdProxy::vcom_adc2}, - {"adcvpp", &CmdProxy::adcvpp}, - {"vb_ds", &CmdProxy::vb_ds}, - {"vb_comp", &CmdProxy::vb_comp}, - {"vb_pixbuf", &CmdProxy::vb_pixbuf}, - {"vin_com", &CmdProxy::vin_com}, - {"vdd_prot", &CmdProxy::vdd_prot}, - {"vbp_colbuf", &CmdProxy::vbp_colbuf}, - {"vb_sda", &CmdProxy::vb_sda}, - {"vcasc_sfp", &CmdProxy::vcasc_sfp}, - {"vipre_cds", &CmdProxy::vipre_cds}, - {"ibias_sfp", &CmdProxy::ibias_sfp}, - {"dac", &CmdProxy::Dac}, {"daclist", &CmdProxy::daclist}, {"dacvalues", &CmdProxy::DacValues}, @@ -947,6 +907,7 @@ class CmdProxy { /* Gotthard2 Specific */ {"bursts", &CmdProxy::bursts}, {"burstperiod", &CmdProxy::burstperiod}, + {"burstsl", &CmdProxy::burstsl}, {"inj_ch", &CmdProxy::InjectChannel}, {"vetophoton", &CmdProxy::VetoPhoton}, {"vetoref", &CmdProxy::VetoReference}, @@ -1249,12 +1210,12 @@ class CmdProxy { GET_COMMAND(framesl, getNumberOfFramesLeft, "\n\t[Gotthard][Jungfrau][Mythen3][Gotthard2][CTB][Moench] " "Number of frames left in acquisition." - "\n\t[Gotthard2] only in continuous mode."); + "\n\t[Gotthard2] only in continuous auto mode."); GET_COMMAND(triggersl, getNumberOfTriggersLeft, "\n\t[Gotthard][Jungfrau][Mythen3][Gotthard2][CTB][Moench] " - "Number of triggers left in acquisition." - "\n\t[Gotthard2] only in continuous mode."); + "Number of triggers left in acquisition. Only when external " + "trigger used."); TIME_GET_COMMAND(delayl, getDelayAfterTriggerLeft, "\n\t[Gotthard][Jungfrau][Mythen3][Gotthard2][CTB][Moench]" @@ -1365,269 +1326,6 @@ class CmdProxy { /* dacs */ - DAC_COMMAND( - vthreshold, getDAC, setDAC, defs::VTHRESHOLD, - "[dac or mV value][(optional unit) mV] \n\t[Eiger][Mythen3] " - "Detector threshold voltage for single photon counters.\n\t[Eiger] " - "Sets vcmp_ll, vcmp_lr, vcmp_rl, vcmp_rr and vcp to the same value. " - "\n\t[Mythen3] Sets vth1, vth2 and vth3 to the same value."); - - DAC_COMMAND(vsvp, getDAC, setDAC, defs::VSVP, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vsvn, getDAC, setDAC, defs::VSVN, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? \n\t[Mythen3] voltage " - "to define feedback resistance of the first shaper"); // TODO - - DAC_COMMAND(vtrim, getDAC, setDAC, defs::VTRIM, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? \n\t[Mythen3] Dac for " - "the voltage defining the trim bit size."); // TODO - - DAC_COMMAND(vrpreamp, getDAC, setDAC, defs::VRPREAMP, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? \n\t[Mythen3] voltage " - "to define the preamplifier feedback resistance."); // TODO - - DAC_COMMAND(vrshaper, getDAC, setDAC, defs::VRSHAPER, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? \n\t[Mythen3] voltage to define feedback resistance of " - "the first shaper"); // TODO - - DAC_COMMAND(vtgstv, getDAC, setDAC, defs::VTGSTV, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vcmp_ll, getDAC, setDAC, defs::VCMP_LL, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vcmp_lr, getDAC, setDAC, defs::VCMP_LR, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vcal, getDAC, setDAC, defs::VCAL, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vcmp_rl, getDAC, setDAC, defs::VCMP_RL, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vcmp_rr, getDAC, setDAC, defs::VCMP_RR, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(rxb_rb, getDAC, setDAC, defs::RXB_RB, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(rxb_lb, getDAC, setDAC, defs::RXB_LB, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vcp, getDAC, setDAC, defs::VCP, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vcn, getDAC, setDAC, defs::VCN, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vishaper, getDAC, setDAC, defs::VISHAPER, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? \n\t[Mythen3] Dac for " - "the bias current for the shaper."); // TODO - - DAC_COMMAND(iodelay, getDAC, setDAC, defs::IO_DELAY, - "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for " - "?? "); // TODO - - DAC_COMMAND(vref_ds, getDAC, setDAC, defs::VREF_DS, - "[dac or mV value][(optional unit) mV] " - "\n\t[Gotthard][Jungfrau] Dac for ?? "); // TODO - - DAC_COMMAND(vcascn_pb, getDAC, setDAC, defs::VCASCN_PB, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for " - "?? "); // TODO - - DAC_COMMAND(vcascp_pb, getDAC, setDAC, defs::VCASCP_PB, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for " - "?? "); // TODO - - DAC_COMMAND(vout_cm, getDAC, setDAC, defs::VOUT_CM, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for " - "?? \n\t[Moench] Dac for 5"); // TODO - - DAC_COMMAND(vcasc_out, getDAC, setDAC, defs::VCASC_OUT, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for " - "?? "); // TODO - - DAC_COMMAND(vin_cm, getDAC, setDAC, defs::VIN_CM, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for " - "?? \n\t[Moench] Dac for 2"); // TODO - - DAC_COMMAND(vref_comp, getDAC, setDAC, defs::VREF_COMP, - "[dac or mV value][(optional unit) mV] " - "\n\t[Gotthard][Jungfrau] Dac for ?? "); // TODO - - DAC_COMMAND(ib_test_c, getDAC, setDAC, defs::IB_TESTC, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for " - "?? "); // TODO - - DAC_COMMAND(vrshaper_n, getDAC, setDAC, defs::VRSHAPER_N, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] voltage " - "to define feedback resistance of the second shaper."); - - DAC_COMMAND( - vipre, getDAC, setDAC, defs::VIPRE, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for the " - "preamplifier's input transistor current.\n\t[Moench] Dac for 1"); - - DAC_COMMAND(vdcsh, getDAC, setDAC, defs::VDCSH, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "the reference (DC) voltage for the shaper."); - - DAC_COMMAND(vth1, getDAC, setDAC, defs::VTH1, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "first detector threshold voltage."); - - DAC_COMMAND(vth2, getDAC, setDAC, defs::VTH2, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "second detector threshold voltage."); - - DAC_COMMAND(vth3, getDAC, setDAC, defs::VTH3, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "third detector threshold voltage."); - - DAC_COMMAND(vcal_n, getDAC, setDAC, defs::VCAL_N, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "the low voltage for analog pulsing."); - - DAC_COMMAND(vcal_p, getDAC, setDAC, defs::VCAL_P, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "the high voltage for analog pulsing."); - - DAC_COMMAND(vcassh, getDAC, setDAC, defs::VCASSH, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "the shaper's cascode voltage."); - - DAC_COMMAND(vcas, getDAC, setDAC, defs::VCAS, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "the preamplifier's cascode voltage."); - - DAC_COMMAND(vicin, getDAC, setDAC, defs::VICIN, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "the bias current for the comparator."); - - DAC_COMMAND(vipre_out, getDAC, setDAC, defs::VIPRE_OUT, - "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " - "preamplifier's output transistor current."); // TODO - - DAC_COMMAND(vref_h_adc, getDAC, setDAC, defs::VREF_H_ADC, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "reference voltage high of ADC."); - - DAC_COMMAND(vb_comp_fe, getDAC, setDAC, defs::VB_COMP_FE, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "comparator current of analogue front end."); - - DAC_COMMAND(vb_comp_adc, getDAC, setDAC, defs::VB_COMP_ADC, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "comparator current of ADC."); - - DAC_COMMAND(vcom_cds, getDAC, setDAC, defs::VCOM_CDS, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "common mode voltage of CDS stage."); - - DAC_COMMAND( - vref_rstore, getDAC, setDAC, defs::VREF_RSTORE, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "reference charging voltage of temparory storage cell in high gain."); - - DAC_COMMAND(vb_opa_1st, getDAC, setDAC, defs::VB_OPA_1ST, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] dac dac " - "for opa current for driving the other DACs in chip."); - - DAC_COMMAND(vref_comp_fe, getDAC, setDAC, defs::VREF_COMP_FE, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "reference voltage of the comparator of analogue front end."); - - DAC_COMMAND(vcom_adc1, getDAC, setDAC, defs::VCOM_ADC1, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "common mode voltage of ADC DAC bank 1."); - - DAC_COMMAND( - vref_prech, getDAC, setDAC, defs::VREF_PRECH, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2][Jungfrau] Dac " - "for reference votlage for precharing the preamplifier."); // TODO also - // for - // jungfrau? - - DAC_COMMAND(vref_l_adc, getDAC, setDAC, defs::VREF_L_ADC, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "reference voltage low for ADC."); - - DAC_COMMAND(vref_cds, getDAC, setDAC, defs::VREF_CDS, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "reference voltage of CDS applied to the temporary storage " - "cell in medium and low gain."); - - DAC_COMMAND(vb_cs, getDAC, setDAC, defs::VB_CS, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "current injection into preamplifier."); - - DAC_COMMAND(vb_opa_fd, getDAC, setDAC, defs::VB_OPA_FD, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "current for CDS opa stage."); - - DAC_COMMAND(vcom_adc2, getDAC, setDAC, defs::VCOM_ADC2, - "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " - "common mode voltage of ADC DAC bank 2."); - - DAC_COMMAND( - adcvpp, getDAC, setDAC, defs::ADC_VPP, - "[dac or mV value][(optional unit) mV] \n\t[Ctb][Moench] Vpp of " - "ADC.\n\t 0 -> 1V ; 1 -> 1.14V ; 2 -> 1.33V ; 3 -> 1.6V ; 4 -> 2V. " - "\n\tAdvanced User function! "); - - DAC_COMMAND(vb_ds, getDAC, setDAC, defs::VB_DS, - "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for " - "??"); // TODO - - DAC_COMMAND(vb_comp, getDAC, setDAC, defs::VB_COMP, - "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for " - "??"); // TODO - - DAC_COMMAND(vb_pixbuf, getDAC, setDAC, defs::VB_PIXBUF, - "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for " - "??"); // TODO - - DAC_COMMAND(vin_com, getDAC, setDAC, defs::VIN_COM, - "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for " - "??"); // TODO - - DAC_COMMAND(vdd_prot, getDAC, setDAC, defs::VDD_PROT, - "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for " - "??"); // TODO - - DAC_COMMAND(vbp_colbuf, getDAC, setDAC, defs::VBP_COLBUF, - "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 0"); - - DAC_COMMAND(vb_sda, getDAC, setDAC, defs::VB_SDA, - "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 3"); - - DAC_COMMAND(vcasc_sfp, getDAC, setDAC, defs::VCASC_SFP, - "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 4"); - - DAC_COMMAND(vipre_cds, getDAC, setDAC, defs::VIPRE_CDS, - "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 6"); - - DAC_COMMAND(ibias_sfp, getDAC, setDAC, defs::IBIAS_SFP, - "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 7"); - GET_COMMAND_NOID( daclist, getDacList, "\n\tGets the list of commands for every dac for this detector."); @@ -2116,6 +1814,10 @@ class CmdProxy { "[duration] [(optional unit) ns|us|ms|s]\n\t[Gotthard2] " "Period between 2 bursts. Only in burst mode and auto timing mode."); + GET_COMMAND(burstsl, getNumberOfBurstsLeft, + "\n\t[Gotthard2] Number of bursts left in acquisition. Only in " + "burst auto mode."); + INTEGER_COMMAND_VEC_ID( cdsgain, getCDSGain, setCDSGain, StringTo, "[0, 1]\n\t[Gotthard2] Enable or disable CDS gain. Default " diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 31383662a..ee47cf05e 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1353,6 +1353,10 @@ void Detector::setBurstPeriod(ns value, Positions pos) { pimpl->Parallel(&Module::setBurstPeriod, pos, value.count()); } +Result Detector::getNumberOfBurstsLeft(Positions pos) const { + return pimpl->Parallel(&Module::getNumberOfBurstsLeft, pos); +} + Result> Detector::getInjectChannel(Positions pos) { return pimpl->Parallel(&Module::getInjectChannel, pos); } diff --git a/slsDetectorSoftware/src/HelpDacs.h b/slsDetectorSoftware/src/HelpDacs.h new file mode 100644 index 000000000..75d108c61 --- /dev/null +++ b/slsDetectorSoftware/src/HelpDacs.h @@ -0,0 +1,302 @@ +#include "string_utils.h" + +std::string GetHelpDac(std::string dac) { + if (sls::is_int(dac)) { + return std::string("[dac name] [dac or mV value] [(optional unit) mV] " + "\n\t[Ctb] Use dac index for dac name."); + } + if (dac == "vthreshold") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger][Mythen3] " + "Detector threshold voltage for single photon counters.\n\t[Eiger] " + "Sets vcmp_ll, vcmp_lr, vcmp_rl, vcmp_rr and vcp to the same " + "value. \n\t[Mythen3] Sets vth1, vth2 and vth3 to the same value."); + } + if (dac == "vsvp") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ?? "); + } + if (dac == "vsvn") { + return std::string("[dac or mV value][(optional unit) mV] \n\t[Eiger] " + "Dac for ?? \n\t[Mythen3] voltage to define " + "feedback resistance of the first shaper"); + } + if (dac == "vtrim") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ?? " + "\n\t[Mythen3] Dac for the voltage defining the trim bit size."); + } + if (dac == "vrpreamp") { + return std::string("[dac or mV value][(optional unit) mV] \n\t[Eiger] " + "Dac for ?? \n\t[Mythen3] voltage to define the " + "preamplifier feedback resistance."); + } + if (dac == "vrshaper") { + return std::string("[dac or mV value][(optional unit) mV] \n\t[Eiger] " + "Dac for ?? \n\t[Mythen3] voltage to define " + "feedback resistance of the first shaper"); + } + if (dac == "vtgstv") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "vcmp_ll") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "vcmp_lr") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "vcal") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "vcmp_rl") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "vcmp_rr") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "rxb_rb") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "rxb_lb") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "vcp") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "vcn") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "vishaper") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "iodelay") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Eiger] Dac for ??"); + } + if (dac == "vref_ds") { + return std::string("[dac or mV value][(optional unit) mV] " + "\n\t[Gotthard][Jungfrau] Dac for ??"); + } + if (dac == "vcascn_pb") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for ??"); + } + if (dac == "vcascp_pb") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for ??"); + } + if (dac == "vout_cm") { + return std::string("[dac or mV value][(optional unit) mV] " + "\n\t[Gotthard] Dac for ??\n\t[Moench] Dac for 5"); + } + if (dac == "vcasc_out") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for ??"); + } + if (dac == "vin_cm") { + return std::string("[dac or mV value][(optional unit) mV] " + "\n\t[Gotthard] Dac for ??\n\t[Moench] Dac for 2"); + } + if (dac == "vref_comp") { + return std::string("[dac or mV value][(optional unit) mV] " + "\n\t[Gotthard][Jungfrau] Dac for ??"); + } + if (dac == "ib_test_c") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard] Dac for ??"); + } + if (dac == "vrshaper_n") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] voltage to " + "define feedback resistance of the second shaper."); + } + if (dac == "vipre") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for the " + "preamplifier's input transistor current.\n\t[Moench] Dac for 1"); + } + if (dac == "vdcsh") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for the " + "reference (DC) voltage for the shaper."); + } + if (dac == "vth1") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for first " + "detector threshold voltage."); + } + if (dac == "vth2") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " + "second detector threshold voltage."); + } + if (dac == "vth3") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for third " + "detector threshold voltage."); + } + if (dac == "vcal_n") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for the " + "low voltage for analog pulsing."); + } + if (dac == "vcal_p") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for the " + "high voltage for analog pulsing."); + } + if (dac == "vcassh") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for the " + "shaper's cascode voltage."); + } + if (dac == "vcas") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for the " + "preamplifier's cascode voltage."); + } + if (dac == "vicin") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for the " + "bias current for the comparator."); + } + if (dac == "vipre_out") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Mythen3] Dac for " + "preamplifier's output transistor current."); + } + if (dac == "vref_h_adc") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "reference voltage high of ADC."); + } + if (dac == "vb_comp_fe") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "comparator current of analogue front end."); + } + if (dac == "vb_comp_adc") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "comparator current of ADC."); + } + if (dac == "vcom_cds") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "common mode voltage of CDS stage."); + } + if (dac == "vref_rstore") { + return std::string("[dac or mV value][(optional unit) mV] " + "\n\t[Gotthard2] Dac for reference charging voltage " + "of temparory storage cell in high gain."); + } + if (dac == "vb_opa_1st") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] dac dac for " + "opa current for driving the other DACs in chip."); + } + if (dac == "vref_comp_fe") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "reference voltage of the comparator of analogue front end."); + } + if (dac == "vcom_adc1") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "common mode voltage of ADC DAC bank 1."); + } + if (dac == "vref_prech") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2][Jungfrau] " + "Dac for reference votlage for precharing the preamplifier."); + } + if (dac == "vref_l_adc") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "reference voltage low for ADC."); + } + if (dac == "vref_cds") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "reference voltage of CDS applied to the temporary storage cell in " + "medium and low gain."); + } + if (dac == "vb_cs") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "current injection into preamplifier."); + } + if (dac == "vb_opa_fd") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "current for CDS opa stage."); + } + if (dac == "vcom_adc2") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Gotthard2] Dac for " + "common mode voltage of ADC DAC bank 2."); + } + if (dac == "adcvpp") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Ctb][Moench] Vpp of " + "ADC.\n\t 0 -> 1V ; 1 -> 1.14V ; 2 -> 1.33V ; 3 -> 1.6V ; 4 -> 2V. " + "\n\tAdvanced User function! "); + } + if (dac == "vb_ds") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for ??"); + } + if (dac == "vb_comp") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for ??"); + } + if (dac == "vb_pixbuf") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for ??"); + } + if (dac == "vin_com") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for ??"); + } + if (dac == "vdd_prot") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Jungfrau] Dac for ??"); + } + if (dac == "vbp_colbuf") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 0"); + } + if (dac == "vb_sda") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 3"); + } + if (dac == "vcasc_sfp") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 4"); + } + if (dac == "vipre_cds") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 6"); + } + if (dac == "ibias_sfp") { + return std::string( + "[dac or mV value][(optional unit) mV] \n\t[Moench] Dac for 7"); + } + + // clang-format off + if (dac == "vtgstv") { return std::string(""); } + // clang-format on + + throw sls::RuntimeError("Unknown dac command"); +} \ No newline at end of file diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 10002f113..9d54457cd 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1355,6 +1355,10 @@ void Module::setBurstPeriod(int64_t value) { sendToDetector(F_SET_BURST_PERIOD, value, nullptr); } +int64_t Module::getNumberOfBurstsLeft() const { + return sendToDetectorStop(F_GET_BURSTS_LEFT); +} + std::array Module::getInjectChannel() const { return sendToDetector>(F_GET_INJECT_CHANNEL); } diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 4303ce1fe..4ce63ec1a 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -372,6 +372,7 @@ class Module : public virtual slsDetectorDefs { void setNumberOfBursts(int64_t value); int64_t getBurstPeriod() const; void setBurstPeriod(int64_t value); + int64_t getNumberOfBurstsLeft() const; std::array getInjectChannel() const; void setInjectChannel(const int offsetChannel, const int incrementChannel); void sendVetoPhoton(const int chipIndex, diff --git a/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp index b78338d23..78825a812 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp @@ -284,6 +284,17 @@ TEST_CASE("burstperiod", "[.cmd][.new]") { } } +TEST_CASE("burstsl", "[.cmd][.new]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + REQUIRE_NOTHROW(proxy.Call("burstsl", {}, -1, GET)); + } else { + REQUIRE_THROWS(proxy.Call("burstsl", {}, -1, GET)); + } +} + TEST_CASE("inj_ch", "[.cmd][.new]") { Detector det; CmdProxy proxy(&det); diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index a0f1d293e..8ba7fa39e 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -213,6 +213,7 @@ enum detFuncs { F_SET_BAD_CHANNELS, F_RECONFIGURE_UDP, F_VALIDATE_UDP_CONFIG, + F_GET_BURSTS_LEFT, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -529,7 +530,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_SET_BAD_CHANNELS: return "F_SET_BAD_CHANNELS"; case F_RECONFIGURE_UDP: return "F_RECONFIGURE_UDP"; case F_VALIDATE_UDP_CONFIG: return "F_VALIDATE_UDP_CONFIG"; - + case F_GET_BURSTS_LEFT: return "F_GET_BURSTS_LEFT"; + case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; diff --git a/slsSupportLib/include/string_utils.h b/slsSupportLib/include/string_utils.h index b11877ccd..7f287fc5b 100755 --- a/slsSupportLib/include/string_utils.h +++ b/slsSupportLib/include/string_utils.h @@ -51,4 +51,7 @@ implementation should not be used in a performance critical place. std::vector split(const std::string &strToSplit, char delimeter); std::string RemoveUnit(std::string &str); + +bool is_int(const std::string& s); } // namespace sls + diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index ae011b616..dba592076 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -3,11 +3,10 @@ #define APILIB 0x200810 #define APIRECEIVER 0x200810 #define APIGUI 0x200804 - #define APICTB 0x200910 #define APIMOENCH 0x200910 +#define APIMYTHEN3 0x200923 #define APIGOTTHARD 0x200917 #define APIJUNGFRAU 0x200917 #define APIEIGER 0x200918 -#define APIMYTHEN3 0x200923 #define APIGOTTHARD2 0x200924 diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index c0ea67752..a5b42cb3b 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -686,41 +686,41 @@ template <> defs::readoutMode StringTo(const std::string &s) { } template <> defs::dacIndex StringTo(const std::string &s) { - if (s == "dac 0") + if (s == "dac 0" || s == "0") return defs::DAC_0; - if (s == "dac 1") + if (s == "dac 1" || s == "1") return defs::DAC_1; - if (s == "dac 2") + if (s == "dac 2" || s == "2") return defs::DAC_2; - if (s == "dac 3") + if (s == "dac 3" || s == "3") return defs::DAC_3; - if (s == "dac 4") + if (s == "dac 4" || s == "4") return defs::DAC_4; - if (s == "dac 5") + if (s == "dac 5"|| s == "5") return defs::DAC_5; - if (s == "dac 6") + if (s == "dac 6"|| s == "6") return defs::DAC_6; - if (s == "dac 7") + if (s == "dac 7"|| s == "7") return defs::DAC_7; - if (s == "dac 8") + if (s == "dac 8"|| s == "8") return defs::DAC_8; - if (s == "dac 9") + if (s == "dac 9"|| s == "9") return defs::DAC_9; - if (s == "dac 10") + if (s == "dac 10"|| s == "10") return defs::DAC_10; - if (s == "dac 11") + if (s == "dac 11"|| s == "11") return defs::DAC_11; - if (s == "dac 12") + if (s == "dac 12"|| s == "12") return defs::DAC_12; - if (s == "dac 13") + if (s == "dac 13"|| s == "13") return defs::DAC_13; - if (s == "dac 14") + if (s == "dac 14"|| s == "14") return defs::DAC_14; - if (s == "dac 15") + if (s == "dac 15"|| s == "15") return defs::DAC_15; - if (s == "dac 16") + if (s == "dac 16"|| s == "16") return defs::DAC_16; - if (s == "dac 17") + if (s == "dac 17"|| s == "17") return defs::DAC_17; if (s == "vsvp") return defs::VSVP; diff --git a/slsSupportLib/src/string_utils.cpp b/slsSupportLib/src/string_utils.cpp index 145f5936e..1846fccf8 100755 --- a/slsSupportLib/src/string_utils.cpp +++ b/slsSupportLib/src/string_utils.cpp @@ -30,4 +30,10 @@ std::string RemoveUnit(std::string &str) { return unit; } +bool is_int(const std::string &s) { + return !s.empty() && std::find_if(s.begin(), s.end(), [](unsigned char c) { + return !std::isdigit(c); + }) == s.end(); +} + }; // namespace sls \ No newline at end of file diff --git a/slsSupportLib/tests/test-string_utils.cpp b/slsSupportLib/tests/test-string_utils.cpp index 97d52d7c7..ef69f96bc 100644 --- a/slsSupportLib/tests/test-string_utils.cpp +++ b/slsSupportLib/tests/test-string_utils.cpp @@ -66,4 +66,14 @@ TEST_CASE("Many characters in a row") { REQUIRE(std::string(str) == "someeequite::ongstring"); } +TEST_CASE("Check is string is integer"){ + + REQUIRE(sls::is_int("75")); + REQUIRE(sls::is_int("11675")); + REQUIRE_FALSE(sls::is_int("7.5")); + REQUIRE_FALSE(sls::is_int("hej")); + REQUIRE_FALSE(sls::is_int("7a")); + REQUIRE_FALSE(sls::is_int("")); +} + // TEST_CASE("concat things not being strings") \ No newline at end of file