From 3ddeea3c2ba62414c2d563944993e6af440510d3 Mon Sep 17 00:00:00 2001 From: Erik Frojdh Date: Wed, 2 Sep 2020 11:44:13 +0200 Subject: [PATCH 01/10] minor fix docs --- docs/src/pyexamples.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/pyexamples.rst b/docs/src/pyexamples.rst index 6da3ca391..8281f312a 100755 --- a/docs/src/pyexamples.rst +++ b/docs/src/pyexamples.rst @@ -17,13 +17,13 @@ using the built in hex() function. .. code-block :: python from slsdet import Detector - d = Detector() + >>> d = Detector() >>> d.patwait0 = 0xaa >>> d.patwait0 170 # Convert to string - >>> (d.patwait0) + >>> hex(d.patwait0) '0xaa' For multiple values one can use a list comprehension to loop over the values. From b8350b070ea97c1ad76927c4dcfee92b328751cd Mon Sep 17 00:00:00 2001 From: Erik Frojdh Date: Wed, 2 Sep 2020 11:55:27 +0200 Subject: [PATCH 02/10] rx_zmqip fix --- python/slsdet/detector.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 69ad0311c..e51e94cb0 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -709,7 +709,7 @@ class Detector(CppDetectorApi): @rx_zmqip.setter def rx_zmqip(self, ip): - self.setRxZmqIP(ip) + self.setRxZmqIP(IpAddr(ip)) @property def zmqip(self): @@ -717,7 +717,7 @@ class Detector(CppDetectorApi): @zmqip.setter def zmqip(self, ip): - self.setClientZmqIp(ip) + self.setClientZmqIp(IpAddr(ip)) @property def udp_dstip(self): @@ -769,7 +769,7 @@ class Detector(CppDetectorApi): @udp_srcip2.setter def udp_srcip2(self, ip): - self.setSourceUDPIP2(ip) + self.setSourceUDPIP2(IpAddr(ip)) @property def udp_dstport(self): From e192cad1f28c0494e1917e538e85b6204ffa3584 Mon Sep 17 00:00:00 2001 From: Erik Frojdh Date: Wed, 2 Sep 2020 12:07:47 +0200 Subject: [PATCH 03/10] zmqport fix --- python/slsdet/detector.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index e51e94cb0..8c24a1779 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -679,7 +679,13 @@ class Detector(CppDetectorApi): @rx_zmqport.setter def rx_zmqport(self, port): - self.setRxZmqPort(port) + if isinstance(port, int) and self.size() == 1: + self.setRxZmqPort(port, 0) + elif is_iterable(port): + for i, p in enumerate(port): + self.setRxZmqPort(p, i) + else: + raise ValueError("Unknown argument type") @property def zmqport(self): @@ -687,7 +693,13 @@ class Detector(CppDetectorApi): @zmqport.setter def zmqport(self, port): - self.setClientZmqPort(port) + if isinstance(port, int) and self.size() == 1: + self.setClientZmqPort(port, 0) + elif is_iterable(port): + for i, p in enumerate(port): + self.setClientZmqPort(p, i) + else: + raise ValueError("Unknown argument type") @property def rx_zmqip(self): From 38e03510681f94c5cd23912592f20c21cfd82aa5 Mon Sep 17 00:00:00 2001 From: Erik Frojdh Date: Wed, 2 Sep 2020 12:20:08 +0200 Subject: [PATCH 04/10] zmqports work like command line --- python/slsdet/detector.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 8c24a1779..b1a7adc82 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -669,18 +669,22 @@ class Detector(CppDetectorApi): Modified only when using an intermediate process after receiver. \n Must be different for every detector (and udp port). \n Multi command will automatically increment for individual modules, use setRxZmqPort. - Exmaples + + Examples -------- + >>> d.rx_zmqport [30001, 30002, 30003, 300004] - >>> d.rx_zmqport = ????? + >>> d.rx_zmqport = 30001 + >>> d.rx_zmqport = [30001, 30005] #Set ports for the two first detectors + """ return element_if_equal(self.getRxZmqPort()) @rx_zmqport.setter def rx_zmqport(self, port): - if isinstance(port, int) and self.size() == 1: - self.setRxZmqPort(port, 0) + if isinstance(port, int): + self.setRxZmqPort(port, -1) elif is_iterable(port): for i, p in enumerate(port): self.setRxZmqPort(p, i) @@ -693,8 +697,8 @@ class Detector(CppDetectorApi): @zmqport.setter def zmqport(self, port): - if isinstance(port, int) and self.size() == 1: - self.setClientZmqPort(port, 0) + if isinstance(port, int): + self.setClientZmqPort(port, -1) elif is_iterable(port): for i, p in enumerate(port): self.setClientZmqPort(p, i) From 05d565253221d494d874174955592cd07e8f944b Mon Sep 17 00:00:00 2001 From: Erik Frojdh Date: Wed, 2 Sep 2020 12:32:14 +0200 Subject: [PATCH 05/10] exptime example --- docs/src/pyexamples.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/src/pyexamples.rst b/docs/src/pyexamples.rst index 8281f312a..f432541da 100755 --- a/docs/src/pyexamples.rst +++ b/docs/src/pyexamples.rst @@ -6,6 +6,33 @@ open an issue in our our `github repo `_. +------------------------------------ +Setting exposure time +------------------------------------ + +Setting and reading back exposure time can be done either using a Python datetime.timedelta +or by setting the time in seconds. + +:: + + # Set exposure time to 1.2 seconds + >>> d.exptime = 1.2 + + # Setting exposure time using timedelta + import datetime as dt + >>> d.exptime = dt.timedelta(seconds = 1.2) + + # With timedelta any arbitrary combination of units can be used + >>> t = dt.timedelta(microseconds = 100, seconds = 5.3, minutes = .3) + + # To set exposure time for individual detector one have to resort + # to the C++ style API. + # Sets exposure time to 1.2 seconds for module 0, 6 and 12 + >>> d.setExptime(1.2, [0, 6, 12]) + >>> d.setExptime(dt.timedelta(seconds = 1.2), [0, 6, 12]) + + + ------------------------------------ Converting numbers to hex ------------------------------------ From 73530ddd6ffe6ceb3621b79ccf56396f6f54775f Mon Sep 17 00:00:00 2001 From: Erik Frojdh Date: Wed, 2 Sep 2020 16:48:51 +0200 Subject: [PATCH 06/10] python udp_srcmac --- python/slsdet/detector.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index b1a7adc82..e258e6f4c 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -771,6 +771,30 @@ class Detector(CppDetectorApi): def udp_dstmac2(self, mac): self.setDestinationUDPMAC2(MacAddr(mac)) + @property + def udp_srcmac(self): + return element_if_equal(self.getSourceUDPMAC()) + + @udp_srcmac.setter + def udp_srcmac(self, mac): + if isinstance(mac, (list, tuple)): + for i, m in enumerate(mac): + self.setSourceUDPMAC(MacAddr(m), [i]) + else: + self.setSourceUDPMAC(MacAddr(mac)) + + @property + def udp_srcmac2(self): + return element_if_equal(self.getSourceUDPMAC2()) + + @udp_srcmac2.setter + def udp_srcmac2(self, mac): + if isinstance(mac, (list, tuple)): + for i, m in enumerate(mac): + self.setSourceUDPMAC2(MacAddr(m), [i]) + else: + self.setSourceUDPMAC2(MacAddr(mac)) + @property def udp_srcip(self): return element_if_equal(self.getSourceUDPIP()) From 658a804cca13df27c43149c6212ec2c6e6107ce8 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 2 Sep 2020 16:48:58 +0200 Subject: [PATCH 07/10] gotthard2: change default clock divider of readout clocks 1 and 2 from 8 to 6 --- .../bin/gotthard2DetectorServer_developer | Bin 211388 -> 211388 bytes .../slsDetectorServer_defs.h | 4 ++-- slsSupportLib/include/versionAPI.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index a2cb8e6e8a1829d250cff5a1605c88937832d87e..13d74ce56a521951a9401d481b3845794bf979cd 100755 GIT binary patch delta 73 zcmdnDxQ0milpD=Py=CKml9HAJ%BGkfofI*bufWQ}q1_qXO Y8wFYzn|GDxQ0milpD=Py=CKml9HAJ%BE-UUfI*bufWQ}q1_qXO Y8wFUHns=$T?^0z1Vy5l8RGFDX0G{?2RR910 diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index 330e53b04..439817a66 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -46,8 +46,8 @@ #define DEFAULT_CURRENT_SOURCE (0) #define DEFAULT_TIMING_SOURCE (TIMING_INTERNAL) -#define DEFAULT_READOUT_C0 (8) //(108333336) // rdo_clk, 108 MHz -#define DEFAULT_READOUT_C1 (8) //(108333336) // rdo_x2_clk, 108 MHz +#define DEFAULT_READOUT_C0 (6) //(144444448) // rdo_clk, 144 MHz +#define DEFAULT_READOUT_C1 (6) //(144444448) // rdo_x2_clk, 144 MHz #define DEFAULT_SYSTEM_C0 (5) //(144444448) // run_clk, 144 MHz #define DEFAULT_SYSTEM_C1 (10) //(72222224) // chip_clk, 72 MHz #define DEFAULT_SYSTEM_C2 (5) //(144444448) // sync_clk, 144 MHz diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 4637973d3..f45cf6141 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -5,8 +5,8 @@ #define APIGUI 0x200804 #define APICTB 0x200810 #define APIGOTTHARD 0x200810 -#define APIGOTTHARD2 0x200810 #define APIJUNGFRAU 0x200810 #define APIMOENCH 0x200810 #define APIEIGER 0x200831 #define APIMYTHEN3 0x200901 +#define APIGOTTHARD2 0x200902 From 180c7b719180fc25a061be11b4fd3ab5b25984b2 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil <33750417+thattil@users.noreply.github.com> Date: Wed, 2 Sep 2020 16:56:57 +0200 Subject: [PATCH 08/10] Gui slot call focus fix (#150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix for editingFinished for qlineedit using isModified() * spinbox disable keyboard tracking to use valuechanged so slot called only after editing finished, focus fix * return pressed forces qtextfield to be set (slot for tab checks for modification flag due to avoid unnecessary set when focus). This is to remove inconsistencies from command line. A return should set even if it looks like no modification in gui Co-authored-by: Erik Fröjdh --- slsDetectorGui/forms/form_dac.ui | 3 + slsDetectorGui/forms/form_tab_advanced.ui | 3 + slsDetectorGui/forms/form_tab_dataoutput.ui | 3 + slsDetectorGui/forms/form_tab_developer.ui | 3 + slsDetectorGui/forms/form_tab_plot.ui | 8 +- slsDetectorGui/include/qTabAdvanced.h | 21 ++- slsDetectorGui/include/qTabDataOutput.h | 3 +- slsDetectorGui/include/qTabMeasurement.h | 3 +- slsDetectorGui/include/qTabPlot.h | 6 + slsDetectorGui/src/qDacWidget.cpp | 6 +- slsDetectorGui/src/qTabAdvanced.cpp | 183 +++++++++++++------- slsDetectorGui/src/qTabDataOutput.cpp | 60 ++++--- slsDetectorGui/src/qTabDeveloper.cpp | 6 +- slsDetectorGui/src/qTabMeasurement.cpp | 29 ++-- slsDetectorGui/src/qTabPlot.cpp | 86 ++++++--- 15 files changed, 290 insertions(+), 133 deletions(-) diff --git a/slsDetectorGui/forms/form_dac.ui b/slsDetectorGui/forms/form_dac.ui index 25e512d1d..83e0d7c56 100755 --- a/slsDetectorGui/forms/form_dac.ui +++ b/slsDetectorGui/forms/form_dac.ui @@ -52,6 +52,9 @@ 25 + + false + -1.000000000000000 diff --git a/slsDetectorGui/forms/form_tab_advanced.ui b/slsDetectorGui/forms/form_tab_advanced.ui index ea19dab8a..0adf847a9 100755 --- a/slsDetectorGui/forms/form_tab_advanced.ui +++ b/slsDetectorGui/forms/form_tab_advanced.ui @@ -98,6 +98,9 @@ 25 + + false + -1 diff --git a/slsDetectorGui/forms/form_tab_dataoutput.ui b/slsDetectorGui/forms/form_tab_dataoutput.ui index ea7f80c65..d6f8d5225 100755 --- a/slsDetectorGui/forms/form_tab_dataoutput.ui +++ b/slsDetectorGui/forms/form_tab_dataoutput.ui @@ -463,6 +463,9 @@ Compression using Root. Available only for Gotthard in Expert Mode. 25 + + false + ns diff --git a/slsDetectorGui/forms/form_tab_developer.ui b/slsDetectorGui/forms/form_tab_developer.ui index 8cf71fea6..e16e86287 100755 --- a/slsDetectorGui/forms/form_tab_developer.ui +++ b/slsDetectorGui/forms/form_tab_developer.ui @@ -180,6 +180,9 @@ <html><head/><body><p>High Voltage. Range: 60 - 200V. Swich off high voltage by setting to 0.</p><p>-1 corresponds to different values from detectors.</p><p>#highvoltage#</p></body></html> + + false + -1 diff --git a/slsDetectorGui/forms/form_tab_plot.ui b/slsDetectorGui/forms/form_tab_plot.ui index 22be36a18..9d3ee2616 100755 --- a/slsDetectorGui/forms/form_tab_plot.ui +++ b/slsDetectorGui/forms/form_tab_plot.ui @@ -2169,7 +2169,7 @@ Displays minimum, maximum and sum of values for each plot. - 0 + 1 @@ -2181,6 +2181,9 @@ Displays minimum, maximum and sum of values for each plot. 0 + + false + 3 @@ -2249,6 +2252,9 @@ Displays minimum, maximum and sum of values for each plot. 0 + + false + 1 diff --git a/slsDetectorGui/include/qTabAdvanced.h b/slsDetectorGui/include/qTabAdvanced.h index 7165eeb2f..ba4ff2a0e 100644 --- a/slsDetectorGui/include/qTabAdvanced.h +++ b/slsDetectorGui/include/qTabAdvanced.h @@ -18,17 +18,24 @@ class qTabAdvanced : public QWidget, private Ui::TabAdvancedObject { void SetDetector(); void SetControlPort(int port); void SetStopPort(int port); - void SetDetectorUDPIP(); - void SetDetectorUDPMAC(); + void SetDetectorUDPIP(bool force = false); + void ForceSetDetectorUDPIP(); + void SetDetectorUDPMAC(bool force = false); + void ForceSetDetectorUDPMAC(); void SetCltZMQPort(int port); - void SetCltZMQIP(); - void SetRxrHostname(); + void SetCltZMQIP(bool force = false); + void ForceSetCltZMQIP(); + void SetRxrHostname(bool force = false); + void ForceSetRxrHostname(); void SetRxrTCPPort(int port); void SetRxrUDPPort(int port); - void SetRxrUDPIP(); - void SetRxrUDPMAC(); + void SetRxrUDPIP(bool force = false); + void ForceSetRxrUDPIP(); + void SetRxrUDPMAC(bool force = false); + void ForceSetRxrUDPMAC(); void SetRxrZMQPort(int port); - void SetRxrZMQIP(); + void SetRxrZMQIP(bool force = false); + void ForceSetRxrZMQIP(); void GetROI(); void ClearROI(); void SetROI(); diff --git a/slsDetectorGui/include/qTabDataOutput.h b/slsDetectorGui/include/qTabDataOutput.h index 0df374e57..e1cdf5fcb 100644 --- a/slsDetectorGui/include/qTabDataOutput.h +++ b/slsDetectorGui/include/qTabDataOutput.h @@ -13,7 +13,8 @@ class qTabDataOutput : public QWidget, private Ui::TabDataOutputObject { private slots: void GetOutputDir(); void BrowseOutputDir(); - void SetOutputDir(); + void SetOutputDir(bool force = false); + void ForceSetOutputDir(); void SetFileFormat(int format); void SetOverwriteEnable(bool enable); void SetTenGigaEnable(bool enable); diff --git a/slsDetectorGui/include/qTabMeasurement.h b/slsDetectorGui/include/qTabMeasurement.h index b38148188..091936ecc 100644 --- a/slsDetectorGui/include/qTabMeasurement.h +++ b/slsDetectorGui/include/qTabMeasurement.h @@ -31,7 +31,8 @@ class qTabMeasurement : public QWidget, private Ui::TabMeasurementObject { void SetDelay(); void SetBurstPeriod(); void SetFileWrite(bool val); - void SetFileName(); + void SetFileName(bool force = false); + void ForceSetFileName(); void SetRunIndex(int val); void SetStartingFrameNumber(int val); void UpdateProgress(); diff --git a/slsDetectorGui/include/qTabPlot.h b/slsDetectorGui/include/qTabPlot.h index 879e6f259..5bca30acd 100644 --- a/slsDetectorGui/include/qTabPlot.h +++ b/slsDetectorGui/include/qTabPlot.h @@ -24,6 +24,12 @@ class qTabPlot : public QWidget, private Ui::TabPlotObject { void SetBinary(); void SetGapPixels(bool enable); void SetTitles(); + void isXMinModified(); + void isXMaxModified(); + void isYMinModified(); + void isYMaxModified(); + void isZMinModified(); + void isZMaxModified(); void SetXRange(); void SetYRange(); void CheckAspectRatio(); diff --git a/slsDetectorGui/src/qDacWidget.cpp b/slsDetectorGui/src/qDacWidget.cpp index 045bf5e75..5db875e4f 100644 --- a/slsDetectorGui/src/qDacWidget.cpp +++ b/slsDetectorGui/src/qDacWidget.cpp @@ -26,7 +26,7 @@ void qDacWidget::SetupWidgetWindow(std::string name) { void qDacWidget::Initialization() { if (isDac) { - connect(spinDac, SIGNAL(editingFinished()), this, SLOT(SetDac())); + connect(spinDac, SIGNAL(valueChanged(double)), this, SLOT(SetDac())); } } @@ -38,7 +38,7 @@ void qDacWidget::SetDetectorIndex(int id) { void qDacWidget::GetDac() { LOG(logDEBUG) << "Getting Dac " << index; - disconnect(spinDac, SIGNAL(editingFinished()), this, SLOT(SetDac())); + disconnect(spinDac, SIGNAL(valueChanged(double)), this, SLOT(SetDac())); try { // dac units auto retval = det->getDAC(index, 0, {detectorIndex}).squash(-1); @@ -52,7 +52,7 @@ void qDacWidget::GetDac() { CATCH_DISPLAY(std::string("Could not get dac ") + std::to_string(index), "qDacWidget::GetDac") - connect(spinDac, SIGNAL(editingFinished()), this, SLOT(SetDac())); + connect(spinDac, SIGNAL(valueChanged(double)), this, SLOT(SetDac())); } void qDacWidget::SetDac() { diff --git a/slsDetectorGui/src/qTabAdvanced.cpp b/slsDetectorGui/src/qTabAdvanced.cpp index e5ad30cab..85f7c42a3 100644 --- a/slsDetectorGui/src/qTabAdvanced.cpp +++ b/slsDetectorGui/src/qTabAdvanced.cpp @@ -65,8 +65,7 @@ void qTabAdvanced::Initialization() { // trimming if (tab_trimming->isEnabled()) { - // editingFinished to not set trimbits for every character input - connect(spinSetAllTrimbits, SIGNAL(editingFinished()), this, + connect(spinSetAllTrimbits, SIGNAL(valueChanged(int)), this, SLOT(SetAllTrimbits())); } @@ -79,23 +78,36 @@ void qTabAdvanced::Initialization() { SLOT(SetStopPort(int))); connect(dispDetectorUDPIP, SIGNAL(editingFinished()), this, SLOT(SetDetectorUDPIP())); + connect(dispDetectorUDPIP, SIGNAL(returnPressed()), this, + SLOT(ForceSetDetectorUDPIP())); connect(dispDetectorUDPMAC, SIGNAL(editingFinished()), this, SLOT(SetDetectorUDPMAC())); + connect(dispDetectorUDPMAC, SIGNAL(returnPressed()), this, + SLOT(ForceSetDetectorUDPMAC())); connect(spinZMQPort, SIGNAL(valueChanged(int)), this, SLOT(SetCltZMQPort(int))); connect(dispZMQIP, SIGNAL(editingFinished()), this, SLOT(SetCltZMQIP())); + connect(dispZMQIP, SIGNAL(returnPressed()), this, SLOT(ForceSetCltZMQIP())); connect(dispRxrHostname, SIGNAL(editingFinished()), this, SLOT(SetRxrHostname())); + connect(dispRxrHostname, SIGNAL(returnPressed()), this, + SLOT(ForceSetRxrHostname())); connect(spinRxrTCPPort, SIGNAL(valueChanged(int)), this, SLOT(SetRxrTCPPort(int))); connect(spinRxrUDPPort, SIGNAL(valueChanged(int)), this, SLOT(SetRxrUDPPort(int))); connect(dispRxrUDPIP, SIGNAL(editingFinished()), this, SLOT(SetRxrUDPIP())); + connect(dispRxrUDPIP, SIGNAL(returnPressed()), this, + SLOT(ForceSetRxrUDPIP())); connect(dispRxrUDPMAC, SIGNAL(editingFinished()), this, SLOT(SetRxrUDPMAC())); + connect(dispRxrUDPMAC, SIGNAL(returnPressed()), this, + SLOT(ForceSetRxrUDPMAC())); connect(spinRxrZMQPort, SIGNAL(valueChanged(int)), this, SLOT(SetRxrZMQPort(int))); connect(dispRxrZMQIP, SIGNAL(editingFinished()), this, SLOT(SetRxrZMQIP())); + connect(dispRxrZMQIP, SIGNAL(returnPressed()), this, + SLOT(ForceSetRxrZMQIP())); // roi if (tab_roi->isEnabled()) { @@ -421,28 +433,42 @@ void qTabAdvanced::SetStopPort(int port) { &qTabAdvanced::GetStopPort) } -void qTabAdvanced::SetDetectorUDPIP() { - std::string s = dispDetectorUDPIP->text().toAscii().constData(); - LOG(logINFO) << "Setting Detector UDP IP:" << s; - try { - det->setSourceUDPIP(sls::IpAddr{s}, {comboDetector->currentIndex()}); +void qTabAdvanced::SetDetectorUDPIP(bool force) { + // return forces modification (inconsistency from command line) + if (dispDetectorUDPIP->isModified() || force) { + dispDetectorUDPIP->setModified(false); + std::string s = dispDetectorUDPIP->text().toAscii().constData(); + LOG(logINFO) << "Setting Detector UDP IP:" << s; + try { + det->setSourceUDPIP(sls::IpAddr{s}, + {comboDetector->currentIndex()}); + } + CATCH_HANDLE("Could not set Detector UDP IP.", + "qTabAdvanced::SetDetectorUDPIP", this, + &qTabAdvanced::GetDetectorUDPIP) } - CATCH_HANDLE("Could not set Detector UDP IP.", - "qTabAdvanced::SetDetectorUDPIP", this, - &qTabAdvanced::GetDetectorUDPIP) } -void qTabAdvanced::SetDetectorUDPMAC() { - std::string s = dispDetectorUDPMAC->text().toAscii().constData(); - LOG(logINFO) << "Setting Detector UDP MAC:" << s; - try { - det->setSourceUDPMAC(sls::MacAddr{s}, {comboDetector->currentIndex()}); +void qTabAdvanced::ForceSetDetectorUDPIP() { SetDetectorUDPIP(true); }; + +void qTabAdvanced::SetDetectorUDPMAC(bool force) { + // return forces modification (inconsistency from command line) + if (dispDetectorUDPMAC->isModified() || force) { + dispDetectorUDPMAC->setModified(false); + std::string s = dispDetectorUDPMAC->text().toAscii().constData(); + LOG(logINFO) << "Setting Detector UDP MAC:" << s; + try { + det->setSourceUDPMAC(sls::MacAddr{s}, + {comboDetector->currentIndex()}); + } + CATCH_HANDLE("Could not set Detector UDP MAC.", + "qTabAdvanced::SetDetectorUDPMAC", this, + &qTabAdvanced::GetDetectorUDPMAC) } - CATCH_HANDLE("Could not set Detector UDP MAC.", - "qTabAdvanced::SetDetectorUDPMAC", this, - &qTabAdvanced::GetDetectorUDPMAC) } +void qTabAdvanced::ForceSetDetectorUDPMAC() { SetDetectorUDPMAC(true); } + void qTabAdvanced::SetCltZMQPort(int port) { LOG(logINFO) << "Setting Client ZMQ Port:" << port; try { @@ -453,29 +479,44 @@ void qTabAdvanced::SetCltZMQPort(int port) { &qTabAdvanced::GetCltZMQPort) } -void qTabAdvanced::SetCltZMQIP() { - std::string s = dispZMQIP->text().toAscii().constData(); - LOG(logINFO) << "Setting Client ZMQ IP:" << s; - try { - det->setClientZmqIp(sls::IpAddr{s}, {comboDetector->currentIndex()}); +void qTabAdvanced::SetCltZMQIP(bool force) { + // return forces modification (inconsistency from command line) + if (dispZMQIP->isModified() || force) { + dispZMQIP->setModified(false); + std::string s = dispZMQIP->text().toAscii().constData(); + LOG(logINFO) << "Setting Client ZMQ IP:" << s; + try { + det->setClientZmqIp(sls::IpAddr{s}, + {comboDetector->currentIndex()}); + } + CATCH_HANDLE("Could not set Client ZMQ IP.", + "qTabAdvanced::SetCltZMQIP", this, + &qTabAdvanced::GetCltZMQIP) } - CATCH_HANDLE("Could not set Client ZMQ IP.", "qTabAdvanced::SetCltZMQIP", - this, &qTabAdvanced::GetCltZMQIP) } -void qTabAdvanced::SetRxrHostname() { - std::string s = dispZMQIP->text().toAscii().constData(); - LOG(logINFO) << "Setting Receiver Hostname:" << s; - try { - det->setRxHostname(s, {comboDetector->currentIndex()}); - } - CATCH_HANDLE("Could not set Client ZMQ IP.", "qTabAdvanced::SetRxrHostname", - this, &qTabAdvanced::GetRxrHostname) +void qTabAdvanced::ForceSetCltZMQIP() { SetCltZMQIP(true); } - // update all network widgets (receiver mainly) - SetDetector(); +void qTabAdvanced::SetRxrHostname(bool force) { + // return forces modification (inconsistency from command line) + if (dispRxrHostname->isModified() || force) { + dispRxrHostname->setModified(false); + std::string s = dispRxrHostname->text().toAscii().constData(); + LOG(logINFO) << "Setting Receiver Hostname:" << s; + try { + det->setRxHostname(s, {comboDetector->currentIndex()}); + } + CATCH_HANDLE("Could not set Client ZMQ IP.", + "qTabAdvanced::SetRxrHostname", this, + &qTabAdvanced::GetRxrHostname) + + // update all network widgets (receiver mainly) + SetDetector(); + } } +void qTabAdvanced::ForceSetRxrHostname() { SetRxrHostname(true); } + void qTabAdvanced::SetRxrTCPPort(int port) { LOG(logINFO) << "Setting Receiver TCP Port:" << port; try { @@ -496,29 +537,42 @@ void qTabAdvanced::SetRxrUDPPort(int port) { &qTabAdvanced::GetRxrUDPPort) } -void qTabAdvanced::SetRxrUDPIP() { - std::string s = dispRxrUDPIP->text().toAscii().constData(); - LOG(logINFO) << "Setting Receiver UDP IP:" << s; - try { - det->setDestinationUDPIP(sls::IpAddr{s}, - {comboDetector->currentIndex()}); +void qTabAdvanced::SetRxrUDPIP(bool force) { + // return forces modification (inconsistency from command line) + if (dispRxrUDPIP->isModified() || force) { + dispRxrUDPIP->setModified(false); + std::string s = dispRxrUDPIP->text().toAscii().constData(); + LOG(logINFO) << "Setting Receiver UDP IP:" << s; + try { + det->setDestinationUDPIP(sls::IpAddr{s}, + {comboDetector->currentIndex()}); + } + CATCH_HANDLE("Could not set Receiver UDP IP.", + "qTabAdvanced::SetRxrUDPIP", this, + &qTabAdvanced::GetRxrUDPIP) } - CATCH_HANDLE("Could not set Receiver UDP IP.", "qTabAdvanced::SetRxrUDPIP", - this, &qTabAdvanced::GetRxrUDPIP) } -void qTabAdvanced::SetRxrUDPMAC() { - std::string s = dispRxrUDPMAC->text().toAscii().constData(); - LOG(logINFO) << "Setting Receiver UDP MAC:" << s; - try { - det->setDestinationUDPMAC(sls::MacAddr{s}, - {comboDetector->currentIndex()}); +void qTabAdvanced::ForceSetRxrUDPIP() { SetRxrUDPIP(true); } + +void qTabAdvanced::SetRxrUDPMAC(bool force) { + // return forces modification (inconsistency from command line) + if (dispRxrUDPMAC->isModified() || force) { + dispRxrUDPMAC->setModified(false); + std::string s = dispRxrUDPMAC->text().toAscii().constData(); + LOG(logINFO) << "Setting Receiver UDP MAC:" << s; + try { + det->setDestinationUDPMAC(sls::MacAddr{s}, + {comboDetector->currentIndex()}); + } + CATCH_HANDLE("Could not set Receiver UDP MAC.", + "qTabAdvanced::SetRxrUDPMAC", this, + &qTabAdvanced::GetRxrUDPMAC) } - CATCH_HANDLE("Could not set Receiver UDP MAC.", - "qTabAdvanced::SetRxrUDPMAC", this, - &qTabAdvanced::GetRxrUDPMAC) } +void qTabAdvanced::ForceSetRxrUDPMAC() { SetRxrUDPMAC(true); } + void qTabAdvanced::SetRxrZMQPort(int port) { LOG(logINFO) << "Setting Receiver ZMQ Port:" << port; try { @@ -529,16 +583,23 @@ void qTabAdvanced::SetRxrZMQPort(int port) { &qTabAdvanced::GetRxrZMQPort) } -void qTabAdvanced::SetRxrZMQIP() { - std::string s = dispRxrZMQIP->text().toAscii().constData(); - LOG(logINFO) << "Setting Receiver ZMQ IP:" << s; - try { - det->setRxZmqIP(sls::IpAddr{s}, {comboDetector->currentIndex()}); +void qTabAdvanced::SetRxrZMQIP(bool force) { + // return forces modification (inconsistency from command line) + if (dispRxrZMQIP->isModified() || force) { + dispRxrZMQIP->setModified(false); + std::string s = dispRxrZMQIP->text().toAscii().constData(); + LOG(logINFO) << "Setting Receiver ZMQ IP:" << s; + try { + det->setRxZmqIP(sls::IpAddr{s}, {comboDetector->currentIndex()}); + } + CATCH_HANDLE("Could not set Receiver ZMQ IP.", + "qTabAdvanced::SetRxrZMQIP", this, + &qTabAdvanced::GetRxrZMQIP) } - CATCH_HANDLE("Could not set Receiver ZMQ IP.", "qTabAdvanced::SetRxrZMQIP", - this, &qTabAdvanced::GetRxrZMQIP) } +void qTabAdvanced::ForceSetRxrZMQIP() { SetRxrZMQIP(true); } + void qTabAdvanced::GetROI() { LOG(logDEBUG) << "Getting ROI"; try { @@ -575,7 +636,7 @@ void qTabAdvanced::SetROI() { void qTabAdvanced::GetAllTrimbits() { LOG(logDEBUG) << "Getting all trimbits value"; - disconnect(spinSetAllTrimbits, SIGNAL(editingFinished()), this, + disconnect(spinSetAllTrimbits, SIGNAL(valueChanged(int)), this, SLOT(SetAllTrimbits())); try { @@ -584,7 +645,7 @@ void qTabAdvanced::GetAllTrimbits() { } CATCH_DISPLAY("Could not get all trimbits.", "qTabAdvanced::GetAllTrimbits") - connect(spinSetAllTrimbits, SIGNAL(editingFinished()), this, + connect(spinSetAllTrimbits, SIGNAL(valueChanged(int)), this, SLOT(SetAllTrimbits())); } diff --git a/slsDetectorGui/src/qTabDataOutput.cpp b/slsDetectorGui/src/qTabDataOutput.cpp index 590477855..9767e519a 100644 --- a/slsDetectorGui/src/qTabDataOutput.cpp +++ b/slsDetectorGui/src/qTabDataOutput.cpp @@ -54,6 +54,8 @@ void qTabDataOutput::Initialization() { SLOT(GetOutputDir())); connect(dispOutputDir, SIGNAL(editingFinished()), this, SLOT(SetOutputDir())); + connect(dispOutputDir, SIGNAL(returnPressed()), this, + SLOT(ForceSetOutputDir())); connect(btnOutputBrowse, SIGNAL(clicked()), this, SLOT(BrowseOutputDir())); connect(comboFileFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(SetFileFormat(int))); @@ -69,7 +71,7 @@ void qTabDataOutput::Initialization() { SLOT(EnableRateCorrection())); connect(btnGroupRate, SIGNAL(buttonClicked(int)), this, SLOT(SetRateCorrection())); - connect(spinCustomDeadTime, SIGNAL(editingFinished()), this, + connect(spinCustomDeadTime, SIGNAL(valueChanged(int)), this, SLOT(SetRateCorrection())); } // flags, speed @@ -169,35 +171,41 @@ void qTabDataOutput::BrowseOutputDir() { dispOutputDir->setText(directory); } -void qTabDataOutput::SetOutputDir() { - QString path = dispOutputDir->text(); - LOG(logDEBUG) << "Setting output directory to " - << path.toAscii().constData(); +void qTabDataOutput::SetOutputDir(bool force) { + // return forces modification (inconsistency from command line) + if (dispOutputDir->isModified() || force) { + dispOutputDir->setModified(false); + QString path = dispOutputDir->text(); + LOG(logDEBUG) << "Setting output directory to " + << path.toAscii().constData(); - // empty - if (path.isEmpty()) { - qDefs::Message(qDefs::WARNING, - "Invalid Output Path. Must not be empty.", - "qTabDataOutput::SetOutputDir"); - LOG(logWARNING) << "Invalid Output Path. Must not be empty."; - GetOutputDir(); - } else { - // chop off trailing '/' - if (path.endsWith('/')) { - while (path.endsWith('/')) { - path.chop(1); + // empty + if (path.isEmpty()) { + qDefs::Message(qDefs::WARNING, + "Invalid Output Path. Must not be empty.", + "qTabDataOutput::SetOutputDir"); + LOG(logWARNING) << "Invalid Output Path. Must not be empty."; + GetOutputDir(); + } else { + // chop off trailing '/' + if (path.endsWith('/')) { + while (path.endsWith('/')) { + path.chop(1); + } } + std::string spath = std::string(path.toAscii().constData()); + try { + det->setFilePath(spath, {comboDetector->currentIndex() - 1}); + } + CATCH_HANDLE("Could not set output file path.", + "qTabDataOutput::SetOutputDir", this, + &qTabDataOutput::GetOutputDir) } - std::string spath = std::string(path.toAscii().constData()); - try { - det->setFilePath(spath, {comboDetector->currentIndex() - 1}); - } - CATCH_HANDLE("Could not set output file path.", - "qTabDataOutput::SetOutputDir", this, - &qTabDataOutput::GetOutputDir) } } +void qTabDataOutput::ForceSetOutputDir() { SetOutputDir(true); }; + void qTabDataOutput::GetFileFormat() { LOG(logDEBUG) << "Getting File Format"; disconnect(comboFileFormat, SIGNAL(currentIndexChanged(int)), this, @@ -288,7 +296,7 @@ void qTabDataOutput::GetRateCorrection() { SLOT(EnableRateCorrection())); disconnect(btnGroupRate, SIGNAL(buttonClicked(int)), this, SLOT(SetRateCorrection())); - disconnect(spinCustomDeadTime, SIGNAL(editingFinished()), this, + disconnect(spinCustomDeadTime, SIGNAL(valueChanged(int)), this, SLOT(SetRateCorrection())); try { spinCustomDeadTime->setValue(-1); @@ -305,7 +313,7 @@ void qTabDataOutput::GetRateCorrection() { connect(chkRate, SIGNAL(toggled(bool)), this, SLOT(EnableRateCorrection())); connect(btnGroupRate, SIGNAL(buttonClicked(int)), this, SLOT(SetRateCorrection())); - connect(spinCustomDeadTime, SIGNAL(editingFinished()), this, + connect(spinCustomDeadTime, SIGNAL(valueChanged(int)), this, SLOT(SetRateCorrection())); } diff --git a/slsDetectorGui/src/qTabDeveloper.cpp b/slsDetectorGui/src/qTabDeveloper.cpp index 3e3742f7d..8d0084719 100644 --- a/slsDetectorGui/src/qTabDeveloper.cpp +++ b/slsDetectorGui/src/qTabDeveloper.cpp @@ -290,7 +290,7 @@ void qTabDeveloper::Initialization() { SLOT(Refresh())); connect(comboHV, SIGNAL(currentIndexChanged(int)), this, SLOT(SetHighVoltage())); - connect(spinHV, SIGNAL(editingFinished()), this, SLOT(SetHighVoltage())); + connect(spinHV, SIGNAL(valueChanged(int)), this, SLOT(SetHighVoltage())); } void qTabDeveloper::PopulateDetectors() { @@ -312,7 +312,7 @@ void qTabDeveloper::GetHighVoltage() { if (!comboHV->isVisible() && !spinHV->isVisible()) return; LOG(logDEBUG) << "Getting High Voltage"; - disconnect(spinHV, SIGNAL(editingFinished()), this, SLOT(SetHighVoltage())); + disconnect(spinHV, SIGNAL(valueChanged(int)), this, SLOT(SetHighVoltage())); disconnect(comboHV, SIGNAL(currentIndexChanged(int)), this, SLOT(SetHighVoltage())); try { @@ -359,7 +359,7 @@ void qTabDeveloper::GetHighVoltage() { } CATCH_DISPLAY("Could not get high voltage.", "qTabDeveloper::GetHighVoltage") - connect(spinHV, SIGNAL(editingFinished()), this, SLOT(SetHighVoltage())); + connect(spinHV, SIGNAL(valueChanged(int)), this, SLOT(SetHighVoltage())); connect(comboHV, SIGNAL(currentIndexChanged(int)), this, SLOT(SetHighVoltage())); } diff --git a/slsDetectorGui/src/qTabMeasurement.cpp b/slsDetectorGui/src/qTabMeasurement.cpp index 4af9b9053..06d283f15 100644 --- a/slsDetectorGui/src/qTabMeasurement.cpp +++ b/slsDetectorGui/src/qTabMeasurement.cpp @@ -129,6 +129,8 @@ void qTabMeasurement::Initialization() { } connect(chkFile, SIGNAL(toggled(bool)), this, SLOT(SetFileWrite(bool))); connect(dispFileName, SIGNAL(editingFinished()), this, SLOT(SetFileName())); + connect(dispFileName, SIGNAL(returnPressed()), this, + SLOT(ForceSetFileName())); connect(spinIndex, SIGNAL(valueChanged(int)), this, SLOT(SetRunIndex(int))); if (startingFnumImplemented) { connect(spinStartingFrameNumber, SIGNAL(valueChanged(int)), this, @@ -723,19 +725,26 @@ void qTabMeasurement::GetFileName() { connect(dispFileName, SIGNAL(editingFinished()), this, SLOT(SetFileName())); } -void qTabMeasurement::SetFileName() { - std::string val = std::string(dispFileName->text().toAscii().constData()); - LOG(logINFO) << "Setting File Name Prefix:" << val; - try { - det->setFileNamePrefix(val); - } - CATCH_HANDLE("Could not set file name prefix.", - "qTabMeasurement::SetFileName", this, - &qTabMeasurement::GetFileName) +void qTabMeasurement::SetFileName(bool force) { + // return forces modification (inconsistency from command line) + if (dispFileName->isModified() || force) { + dispFileName->setModified(false); + std::string val = + std::string(dispFileName->text().toAscii().constData()); + LOG(logINFO) << "Setting File Name Prefix:" << val; + try { + det->setFileNamePrefix(val); + } + CATCH_HANDLE("Could not set file name prefix.", + "qTabMeasurement::SetFileName", this, + &qTabMeasurement::GetFileName) - emit FileNameChangedSignal(dispFileName->text()); + emit FileNameChangedSignal(dispFileName->text()); + } } +void qTabMeasurement::ForceSetFileName() { SetFileName(true); } + void qTabMeasurement::GetRunIndex() { LOG(logDEBUG) << "Getting Acquisition File index"; disconnect(spinIndex, SIGNAL(valueChanged(int)), this, diff --git a/slsDetectorGui/src/qTabPlot.cpp b/slsDetectorGui/src/qTabPlot.cpp index 31eca3458..5a0a9e9fc 100644 --- a/slsDetectorGui/src/qTabPlot.cpp +++ b/slsDetectorGui/src/qTabPlot.cpp @@ -87,9 +87,9 @@ void qTabPlot::Initialization() { SLOT(SetStreamingFrequency())); connect(comboTimeGapUnit, SIGNAL(currentIndexChanged(int)), this, SLOT(SetStreamingFrequency())); - connect(spinTimeGap, SIGNAL(editingFinished()), this, + connect(spinTimeGap, SIGNAL(valueChanged(double)), this, SLOT(SetStreamingFrequency())); - connect(spinNthFrame, SIGNAL(editingFinished()), this, + connect(spinNthFrame, SIGNAL(valueChanged(int)), this, SLOT(SetStreamingFrequency())); // navigation buttons for options @@ -174,17 +174,17 @@ void qTabPlot::Initialization() { connect(chkXMax, SIGNAL(toggled(bool)), this, SLOT(SetXRange())); connect(chkYMin, SIGNAL(toggled(bool)), this, SLOT(SetYRange())); connect(chkYMax, SIGNAL(toggled(bool)), this, SLOT(SetYRange())); - connect(dispXMin, SIGNAL(editingFinished()), this, SLOT(SetXRange())); - connect(dispXMax, SIGNAL(editingFinished()), this, SLOT(SetXRange())); - connect(dispYMin, SIGNAL(editingFinished()), this, SLOT(SetYRange())); - connect(dispYMax, SIGNAL(editingFinished()), this, SLOT(SetYRange())); + connect(dispXMin, SIGNAL(editingFinished()), this, SLOT(isXMinModified())); + connect(dispXMax, SIGNAL(editingFinished()), this, SLOT(isXMaxModified())); + connect(dispYMin, SIGNAL(editingFinished()), this, SLOT(isYMinModified())); + connect(dispYMax, SIGNAL(editingFinished()), this, SLOT(isYMaxModified())); connect(chkAspectRatio, SIGNAL(toggled(bool)), this, SLOT(CheckAspectRatio())); connect(chkZMin, SIGNAL(toggled(bool)), this, SLOT(SetZRange())); connect(chkZMax, SIGNAL(toggled(bool)), this, SLOT(SetZRange())); - connect(dispZMin, SIGNAL(editingFinished()), this, SLOT(SetZRange())); - connect(dispZMax, SIGNAL(editingFinished()), this, SLOT(SetZRange())); + connect(dispZMin, SIGNAL(editingFinished()), this, SLOT(isZMinModified())); + connect(dispZMax, SIGNAL(editingFinished()), this, SLOT(isZMaxModified())); } void qTabPlot::Select1DPlot(bool enable) { @@ -389,6 +389,48 @@ void qTabPlot::SetTitles() { SLOT(SetTitles())); } +void qTabPlot::isXMinModified() { + if (dispXMin->isModified()) { + dispXMin->setModified(false); + SetXRange(); + } +} + +void qTabPlot::isXMaxModified() { + if (dispXMax->isModified()) { + dispXMax->setModified(false); + SetXRange(); + } +} + +void qTabPlot::isYMinModified() { + if (dispYMin->isModified()) { + dispYMin->setModified(false); + SetYRange(); + } +} + +void qTabPlot::isYMaxModified() { + if (dispYMax->isModified()) { + dispYMax->setModified(false); + SetYRange(); + } +} + +void qTabPlot::isZMinModified() { + if (dispZMin->isModified()) { + dispZMin->setModified(false); + SetZRange(); + } +} + +void qTabPlot::isZMaxModified() { + if (dispZMax->isModified()) { + dispZMax->setModified(false); + SetZRange(); + } +} + void qTabPlot::SetXRange() { LOG(logDEBUG) << "Enable X axis range"; @@ -452,10 +494,14 @@ void qTabPlot::MaintainAspectRatio(int dimension) { disconnect(chkXMax, SIGNAL(toggled(bool)), this, SLOT(SetXRange())); disconnect(chkYMin, SIGNAL(toggled(bool)), this, SLOT(SetYRange())); disconnect(chkYMax, SIGNAL(toggled(bool)), this, SLOT(SetYRange())); - disconnect(dispXMin, SIGNAL(editingFinished()), this, SLOT(SetXRange())); - disconnect(dispXMax, SIGNAL(editingFinished()), this, SLOT(SetXRange())); - disconnect(dispYMin, SIGNAL(editingFinished()), this, SLOT(SetYRange())); - disconnect(dispYMax, SIGNAL(editingFinished()), this, SLOT(SetYRange())); + disconnect(dispXMin, SIGNAL(editingFinished()), this, + SLOT(isXMinModified())); + disconnect(dispXMax, SIGNAL(editingFinished()), this, + SLOT(isXMaxModified())); + disconnect(dispYMin, SIGNAL(editingFinished()), this, + SLOT(isYMinModified())); + disconnect(dispYMax, SIGNAL(editingFinished()), this, + SLOT(isYMaxModified())); // check all, fill all chkXMin->setChecked(true); @@ -550,10 +596,10 @@ void qTabPlot::MaintainAspectRatio(int dimension) { connect(chkXMax, SIGNAL(toggled(bool)), this, SLOT(SetXRange())); connect(chkYMin, SIGNAL(toggled(bool)), this, SLOT(SetYRange())); connect(chkYMax, SIGNAL(toggled(bool)), this, SLOT(SetYRange())); - connect(dispXMin, SIGNAL(editingFinished()), this, SLOT(SetXRange())); - connect(dispXMax, SIGNAL(editingFinished()), this, SLOT(SetXRange())); - connect(dispYMin, SIGNAL(editingFinished()), this, SLOT(SetYRange())); - connect(dispYMax, SIGNAL(editingFinished()), this, SLOT(SetYRange())); + connect(dispXMin, SIGNAL(editingFinished()), this, SLOT(isXMinModified())); + connect(dispXMax, SIGNAL(editingFinished()), this, SLOT(isXMaxModified())); + connect(dispYMin, SIGNAL(editingFinished()), this, SLOT(isYMinModified())); + connect(dispYMax, SIGNAL(editingFinished()), this, SLOT(isYMaxModified())); bool isRange[4]{true, true, true, true}; plot->SetXYRangeChanged(true, ranges, isRange); @@ -583,9 +629,9 @@ void qTabPlot::GetStreamingFrequency() { SLOT(SetStreamingFrequency())); disconnect(comboTimeGapUnit, SIGNAL(currentIndexChanged(int)), this, SLOT(SetStreamingFrequency())); - disconnect(spinTimeGap, SIGNAL(editingFinished()), this, + disconnect(spinTimeGap, SIGNAL(valueChanged(double)), this, SLOT(SetStreamingFrequency())); - disconnect(spinNthFrame, SIGNAL(editingFinished()), this, + disconnect(spinNthFrame, SIGNAL(valueChanged(int)), this, SLOT(SetStreamingFrequency())); try { int freq = det->getRxZmqFrequency().tsquash( @@ -621,9 +667,9 @@ void qTabPlot::GetStreamingFrequency() { SLOT(SetStreamingFrequency())); connect(comboTimeGapUnit, SIGNAL(currentIndexChanged(int)), this, SLOT(SetStreamingFrequency())); - connect(spinTimeGap, SIGNAL(editingFinished()), this, + connect(spinTimeGap, SIGNAL(valueChanged(double)), this, SLOT(SetStreamingFrequency())); - connect(spinNthFrame, SIGNAL(editingFinished()), this, + connect(spinNthFrame, SIGNAL(valueChanged(int)), this, SLOT(SetStreamingFrequency())); } From dbaab61ea2fc965b16121b66d5ce92ccf76fd8c6 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 2 Sep 2020 17:02:12 +0200 Subject: [PATCH 09/10] g2: print ns in server before converting to freq --- .../gotthard2DetectorServer/slsDetectorFunctionList.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index 2fe739003..90c4971ec 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -901,12 +901,13 @@ int setPeriod(int64_t val) { LOG(logERROR, ("Invalid period: %lld ns\n", val)); return FAIL; } - val *= (1E-9 * systemFrequency); if (burstMode == BURST_OFF) { LOG(logINFO, ("Setting period %lld ns [Continuous mode]\n", val)); + val *= (1E-9 * systemFrequency); set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG); } else { LOG(logINFO, ("Setting period %lld ns [Burst mode]\n", val)); + val *= (1E-9 * systemFrequency); set64BitReg(val, ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG); } // validate for tolerance From d62d5ef80471454d73d679e7bd9343feb8f556cb Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 2 Sep 2020 17:03:19 +0200 Subject: [PATCH 10/10] binaries in --- .../bin/gotthard2DetectorServer_developer | Bin 211388 -> 211388 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index 13d74ce56a521951a9401d481b3845794bf979cd..a83ae9f9dd57c79cc1a205abf96b43421e567ad6 100755 GIT binary patch delta 47471 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 XUf`Q<24u4etOSmHZ;v%&j%Nk{QL?>q