* 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
This commit is contained in:
Dhanya Thattil 2022-05-16 12:35:06 +02:00 committed by GitHub
parent 9808376207
commit fcc7f7aef8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 1713 additions and 859 deletions

View File

@ -59,6 +59,7 @@ 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)
- 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
- rx_roi
- m3 polarity, interpolation (enables all counters when enabled), pump probe, analog pulsing, digital pulsing
- updatedetectorserver - removes old server current binary pointing to for blackfin
- removing copydetectorserver using tftp
@ -69,6 +70,7 @@ This document describes the differences between v7.0.0 and v6.x.x
- fixed row column indexing (mainly for multi module Jungfrau 2 interfaces )
- 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
2. Resolved Issues

View File

@ -786,6 +786,15 @@ void init_det(py::module &m) {
.def("setRxArping",
(void (Detector::*)(bool, sls::Positions)) & Detector::setRxArping,
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",
(Result<defs::fileFormat>(Detector::*)(sls::Positions) const) &
Detector::getFileFormat,
@ -1602,11 +1611,6 @@ void init_det(py::module &m) {
.def("rebootController",
(void (Detector::*)(sls::Positions)) & Detector::rebootController,
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",
(void (Detector::*)(const std::string &, const std::string &,
sls::Positions)) &

View File

@ -20,7 +20,105 @@
<string>Form</string>
</property>
<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">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -212,104 +310,6 @@
</property>
</spacer>
</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">
<widget class="QLabel" name="lblCompleteImage">
<property name="sizePolicy">
@ -320,7 +320,7 @@
</property>
<property name="minimumSize">
<size>
<width>40</width>
<width>120</width>
<height>0</height>
</size>
</property>
@ -375,6 +375,71 @@
</property>
</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>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>
</widget>
<resources/>

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>775</width>
<height>380</height>
<height>385</height>
</rect>
</property>
<property name="sizePolicy">
@ -32,22 +32,25 @@
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="4" column="3">
<widget class="QCheckBox" name="chkCounter2">
<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>50</width>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>2</string>
</property>
<property name="checked">
<bool>true</bool>
<string>Threshold:</string>
</property>
</widget>
</item>
@ -70,237 +73,22 @@
</property>
</widget>
</item>
<item row="3" column="2" colspan="3">
<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="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">
<item row="2" column="14">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>190</height>
<height>20</height>
</size>
</property>
</spacer>
</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">
<widget class="QLabel" name="lblSettings">
<property name="enabled">
@ -323,119 +111,6 @@
</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="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">
<widget class="QCheckBox" name="chkCounter1">
<property name="enabled">
@ -455,7 +130,7 @@
</property>
</widget>
</item>
<item row="0" column="2" colspan="3">
<item row="0" column="2" colspan="9">
<widget class="QComboBox" name="comboSettings">
<property name="enabled">
<bool>true</bool>
@ -594,6 +269,268 @@
</item>
</widget>
</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">
<widget class="QLabel" name="lblGainMode">
<property name="enabled">
@ -616,7 +553,70 @@
</property>
</widget>
</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">
<property name="enabled">
<bool>false</bool>

View File

@ -55,6 +55,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
void EnableGainPlot(bool enable);
void ClonePlot();
void SavePlot();
void SetGapPixels(bool enable);
protected:
void resizeEvent(QResizeEvent *event);
@ -160,6 +161,9 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
int64_t currentFrame{0};
mutable std::mutex mPlots;
int64_t currentAcqIndex{0};
slsDetectorDefs::ROI rxRoi{};
bool isRxRoiDisplayed{false};
bool isGapPixels{false};
unsigned int nPixelsX{0};
unsigned int nPixelsY{0};

View File

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

View File

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

View File

@ -442,6 +442,28 @@ void SlsQt1DPlot::SetLog(int axisId, bool yes) {
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() {
setAxisScale(QwtPlot::xBottom, zoomer->x(), zoomer->x() + zoomer->w());
setAxisScale(QwtPlot::yLeft, zoomer->y(), zoomer->y() + zoomer->h());

View File

@ -290,3 +290,25 @@ void SlsQt2DPlot::showSpectrogram(bool on) {
d_spectrogram->setDefaultContourPen(on ? QPen() : QPen(Qt::NoPen));
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();
}
}

View File

@ -278,11 +278,13 @@ void qDrawPlot::Select1dPlot(bool enable) {
}
void qDrawPlot::SetPlotTitlePrefix(QString title) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting Title to " << title.toAscii().constData();
plotTitlePrefix = title;
}
void qDrawPlot::SetXAxisTitle(QString title) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting X Axis Title to " << title.toAscii().constData();
if (is1d) {
xTitle1d = title;
@ -292,6 +294,7 @@ void qDrawPlot::SetXAxisTitle(QString title) {
}
void qDrawPlot::SetYAxisTitle(QString title) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting Y Axis Title to " << title.toAscii().constData();
if (is1d) {
yTitle1d = title;
@ -301,6 +304,7 @@ void qDrawPlot::SetYAxisTitle(QString title) {
}
void qDrawPlot::SetZAxisTitle(QString title) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting Z Axis Title to " << title.toAscii().constData();
zTitle2d = title;
}
@ -318,6 +322,7 @@ void qDrawPlot::SetXYRangeChanged(bool disable, double *xy, bool *isXY) {
}
void qDrawPlot::SetZRange(double *z, bool *isZ) {
std::lock_guard<std::mutex> lock(mPlots);
std::copy(z, z + 2, zRange);
std::copy(isZ, isZ + 2, isZRange);
}
@ -351,6 +356,7 @@ double qDrawPlot::GetYMaximum() {
}
void qDrawPlot::SetDataCallBack(bool enable) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting data call back to " << std::boolalpha << enable
<< std::noboolalpha;
try {
@ -369,6 +375,7 @@ void qDrawPlot::SetDataCallBack(bool enable) {
}
void qDrawPlot::SetBinary(bool enable, int from, int to) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << (enable ? "Enabling" : "Disabling")
<< " Binary output from " << from << " to " << to;
binaryFrom = from;
@ -377,6 +384,7 @@ void qDrawPlot::SetBinary(bool enable, int from, int to) {
}
void qDrawPlot::SetPersistency(int val) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting Persistency to " << val;
persistency = val;
}
@ -458,17 +466,20 @@ void qDrawPlot::ResetAccumulate() {
}
void qDrawPlot::DisplayStatistics(bool enable) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << (enable ? "Enabling" : "Disabling")
<< " Statistics Display";
displayStatistics = enable;
}
void qDrawPlot::SetNumDiscardBits(int value) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << "Setting number of bits to discard: " << value;
numDiscardBits = value;
}
void qDrawPlot::EnableGainPlot(bool enable) {
std::lock_guard<std::mutex> lock(mPlots);
LOG(logINFO) << (enable ? "Enabling" : "Disabling") << " Gain Plot";
hasGainData = enable;
}
@ -609,6 +620,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) {
LOG(logDEBUG) << "Calculating Statistics";
double *array = data2d;
@ -642,6 +660,7 @@ void qDrawPlot::StartAcquisition() {
currentFrame = 0;
boxPlot->setTitle("Old Plot");
det->clearAcquiringFlag(); // (from previous exit) or if running
isRxRoiDisplayed = false;
// ensure data streaming in receiver (if plot enabled)
if (isPlot) {
@ -742,6 +761,7 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
<< " \t dynamic range: " << data->dynamicRange << std::endl
<< " \t file index: " << data->fileIndex << std::endl
<< " \t complete image: " << data->completeImage << std::endl
<< " \t rx Roi: " << sls::ToString(data->rxRoi) << std::endl
<< " ]";
progress = data->progressIndex;
@ -749,6 +769,22 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
currentFrame = frameIndex;
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: " << sls::ToString(rxRoi);
}
LOG(logDEBUG) << "Rx_roi: " << sls::ToString(rxRoi);
}
// 1d check if npixelX has changed (m3 for different counters enabled)
if (is1d && static_cast<int>(nPixelsX) != data->nx) {
@ -987,6 +1023,26 @@ void qDrawPlot::Update1dPlot() {
xyRangeChanged = false;
}
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() {
@ -1015,6 +1071,22 @@ void qDrawPlot::Update2dPlot() {
}
plot2d->DisableZoom(disableZoom);
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() {

View File

@ -331,6 +331,7 @@ void qTabPlot::SetGapPixels(bool enable) {
LOG(logINFO) << "Setting Gap Pixels Enable to " << enable;
try {
det->setGapPixelsinCallback(enable);
plot->SetGapPixels(enable);
}
CATCH_HANDLE("Could not set gap pixels enable.", "qTabPlot::SetGapPixels",
this, &qTabPlot::GetGapPixels)

View File

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

View File

@ -25,7 +25,7 @@ target_include_directories(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

View File

@ -2317,6 +2317,7 @@ void *start_timer(void *arg) {
if (dr == 32 && ncounters > 1) {
packetsPerFrame = 2;
}
dataSize = imageSize / packetsPerFrame;
}
// 1g
else {
@ -2338,29 +2339,24 @@ void *start_timer(void *arg) {
{
const int nchannels = NCHAN_1_COUNTER * NCHIP * ncounters;
switch (dr) {
/*case 1: // TODO: Not implemented in firmware yet
break;*/
case 8:
for (int i = 0; i < nchannels; ++i) {
switch (dr) {
//case 1: // TODO: Not implemented in firmware yet
// break;
case 8:
*((uint8_t *)(imageData + i)) = (uint8_t)i;
}
break;
case 16:
for (int i = 0; i < nchannels; ++i) {
*((uint16_t *)(imageData + i * sizeof(uint16_t))) = (uint16_t)i;
}
break;
case 32:
for (int i = 0; i < nchannels; ++i) {
*((uint32_t *)(imageData + i * sizeof(uint32_t))) =
((uint32_t)i & 0xFFFFFF); // 24 bit
}
*((uint32_t *)(imageData + i * sizeof(uint32_t))) = ((uint32_t)i & 0xFFFFFF); // 24 bit
break;
default:
break;
}
}
}
// Send data
// loop over number of frames
@ -2376,6 +2372,7 @@ void *start_timer(void *arg) {
clock_gettime(CLOCK_REALTIME, &begin);
usleep(expUs);
int srcOffset = 0;
// loop packet
for (int i = 0; i != packetsPerFrame; ++i) {
@ -2396,7 +2393,6 @@ void *start_timer(void *arg) {
memcpy(packetData + sizeof(sls_detector_header),
imageData + srcOffset, dataSize);
srcOffset += dataSize;
sendUDPPacket(0, 0, packetData, packetSize);
}
LOG(logINFO, ("Sent frame: %d [%lld]\n", frameNr,

View File

@ -2045,7 +2045,7 @@ int set_num_frames(int file_des) {
arg > MAX_FRAMES_IN_BURST_MODE) {
ret = FAIL;
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",
(long long unsigned int)arg, MAX_FRAMES_IN_BURST_MODE);
LOG(logERROR, (mess));
@ -2863,7 +2863,12 @@ int set_roi(int file_des) {
return printSocketReadError();
if (receiveData(file_des, &arg.xmax, sizeof(int), INT32) < 0)
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
functionNotImplemented();
@ -2895,13 +2900,16 @@ int get_roi(int file_des) {
#else
// only get
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
Server_SendResult(file_des, INT32, NULL, 0);
if (ret != FAIL) {
sendData(file_des, &retval.xmin, 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;
}
@ -7134,6 +7142,8 @@ int get_receiver_parameters(int file_des) {
#else
roi.xmin = -1;
roi.xmax = -1;
roi.ymin = -1;
roi.ymax = -1;
#endif
n += sendData(file_des, &roi.xmin, sizeof(int), INT32);
if (n < 0)
@ -7141,6 +7151,12 @@ int get_receiver_parameters(int file_des) {
n += sendData(file_des, &roi.xmax, sizeof(int), INT32);
if (n < 0)
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

View File

@ -899,6 +899,16 @@ class Detector {
* every minute. Useful in 10G mode. */
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 */

View File

@ -9,27 +9,12 @@
*/
class detectorData {
public:
/**
* Constructor
* @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)
: progressIndex(progressIndex), fileName(fileName), fileIndex(fileIndex), nx(nx), ny(ny), data(data), databytes(databytes), dynamicRange(dynamicRange), completeImage(completeImage){};
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
*/
~detectorData(){};
@ -60,8 +45,9 @@ class detectorData {
uint64_t fileIndex;
int nx;
int ny;
char *data;
char *data{nullptr};
int databytes;
int dynamicRange;
bool completeImage;
std::array<int,4> rxRoi{{-1, -1, -1, -1}};
};

View File

@ -354,7 +354,7 @@ std::string CmdProxy::DetectorSize(int action) {
WrongNumberOfParameters(0);
}
auto t = det->getDetectorSize();
os << "[" << t.x << ", " << t.y << "]\n";
os << t << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() != 2) {
WrongNumberOfParameters(2);
@ -1152,7 +1152,8 @@ std::string CmdProxy::DacList(const int action) {
"names. Cannot change them.");
}
if (det_id != -1) {
throw sls::RuntimeError("Cannot configure dacnames at module level");
throw sls::RuntimeError(
"Cannot configure dacnames at module level");
}
if (args.size() != 18) {
WrongNumberOfParameters(18);
@ -1646,6 +1647,51 @@ std::string CmdProxy::ReceiverHostname(int action) {
}
return os.str();
}
std::string CmdProxy::Rx_ROI(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[xmin] [xmax] [ymin] [ymax]\n\tRegion of interest in "
"receiver.\n\tOnly allowed at multi module level and without gap pixels."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
if (det_id == -1) {
auto t = det->getRxROI();
os << t << '\n';
} else {
auto t = det->getIndividualRxROIs(std::vector<int>{det_id});
os << t << '\n';
}
} else if (action == defs::PUT_ACTION) {
defs::ROI t;
// 2 or 4 arguments
if (args.size() != 2 && args.size() != 4) {
WrongNumberOfParameters(2);
}
if (args.size() == 2 || args.size() == 4) {
t.xmin = StringTo<int>(args[0]);
t.xmax = StringTo<int>(args[1]);
}
if (args.size() == 4) {
t.ymin = StringTo<int>(args[2]);
t.ymax = StringTo<int>(args[3]);
}
// only multi level
if (det_id != -1) {
throw RuntimeError("Cannot execute receiver ROI at module level");
}
det->setRxROI(t);
os << t << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
/* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */
@ -1898,9 +1944,7 @@ std::string CmdProxy::ROI(int action) {
WrongNumberOfParameters(0);
}
auto t = det->getROI(std::vector<int>{det_id});
for (auto &it : t) {
os << '[' << it.xmin << ", " << it.xmax << "] \n";
}
os << t << '\n';
} else if (action == defs::PUT_ACTION) {
if (det_id == -1 && det->size() > 1) {
throw sls::RuntimeError("Cannot execute ROI at multi module level");
@ -1910,28 +1954,7 @@ std::string CmdProxy::ROI(int action) {
}
defs::ROI t(StringTo<int>(args[0]), StringTo<int>(args[1]));
det->setROI(t, det_id);
os << '[' << t.xmin << ", " << t.xmax << "]\n";
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::ClearROI(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "\n\t[Gotthard] Resets Region of interest in detector. All "
"channels enabled. Default is all channels enabled."
<< '\n';
} else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("Cannot get");
} else if (action == defs::PUT_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
det->clearROI(std::vector<int>{det_id});
os << "[-1, -1]\n";
os << t << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
@ -2101,9 +2124,8 @@ std::string CmdProxy::VetoStreaming(int action) {
os << "[none|lll|10gbe|...]\n\t[Gotthard2] Enable or disable the 2 "
"veto streaming interfaces available. Can include more than one "
"interface. \n\tDefault: none. lll (low latency link) is the "
"default "
"interface to work with. \n\t10GbE is for debugging and also "
"enables second interface in receiver for listening to veto "
"default interface to work with. \n\t10GbE is for debugging and "
"also enables second interface in receiver for listening to veto "
"packets (writes a separate file if writing enabled). Also "
"restarts client and receiver zmq sockets if zmq streaming "
"enabled."
@ -2294,9 +2316,9 @@ std::string CmdProxy::GateDelay(int action) {
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
if (cmd == "gatedelay") {
os << "[duration] [(optional unit) "
"ns|us|ms|s]\n\t[Mythen3] Gate Delay of all gate signals in "
"auto and trigger mode (internal gating)."
os << "[duration] [(optional unit) ns|us|ms|s]\n\t[Mythen3] Gate "
"Delay of all gate signals in auto and trigger mode "
"(internal gating)."
<< '\n';
} else if (cmd == "gatedelay1") {
os << "[n_value]\n\t[Mythen3] Gate Delay of gate signal 1 in auto "
@ -2807,11 +2829,11 @@ std::string CmdProxy::AdditionalJsonHeader(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[key1] [value1] [key2] [value2]...[keyn] [valuen]"
"\n\tAdditional json header to be streamed out from receiver via "
"zmq. Default is empty. Max 20 characters for each key/value. "
"Use only if to be processed by an intermediate user process "
"listening to receiver zmq packets. Empty value deletes header. "
os << "[key1] [value1] [key2] [value2]...[keyn] [valuen]\n\tAdditional "
"json header to be streamed out from receiver via zmq. Default "
"is empty. Max 20 characters for each key/value. Use only if to "
"be processed by an intermediate user process listening to "
"receiver zmq packets. Empty value deletes header. "
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
@ -2921,10 +2943,10 @@ std::string CmdProxy::UpdateDetectorServer(int action) {
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[server_name with full "
"path]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3]["
"Gotthard2] Copies detector server via TCP (without tftp). Makes "
"a symbolic link with a shorter name (without vx.x.x). Then, "
"detector controller reboots (except "
"path]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3][Gotthard2] "
"Copies detector server via TCP (without tftp). Makes a symbolic "
"link with a shorter name (without vx.x.x). Then, detector "
"controller reboots (except "
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
"to the link, which is effective after a reboot."
<< '\n';
@ -2947,11 +2969,9 @@ std::string CmdProxy::UpdateKernel(int action) {
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[kernel_name with full "
"path]\n\t[Jungfrau][Ctb][Moench][Mythen3]["
"Gotthard2] Advanced Command!! You could damage the detector. "
"Please use"
" with caution.\n\tUpdates the kernel image. Then, detector "
"controller "
"path]\n\t[Jungfrau][Ctb][Moench][Mythen3][Gotthard2] Advanced "
"Command!! You could damage the detector. Please use with "
"caution.\n\tUpdates the kernel image. Then, detector controller "
"reboots with new kernel."
<< '\n';
} else if (action == defs::GET_ACTION) {
@ -2972,16 +2992,15 @@ std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "\n\tWithout tftp: [server_name (incl fullpath)] "
"[fname.pof (incl full path)] "
"This does not use tftp."
"\n\t\t[Jungfrau][Gotthard][CTB][Moench] Updates the "
"firmware, detector server, deletes old server, creates the symbolic link and then "
"reboots detector controller. \n\t\t[Mythen3][Gotthard2] will "
"require a script to start up the shorter named server link at "
"start up. \n\t\tserver_name is full path name of detector server "
"binary"
"\n\t\tfname is full path of programming file"
os << "\n\tWithout tftp: [server_name (incl fullpath)] [fname.pof "
"(incl full path)] This does not use "
"tftp.\n\t\t[Jungfrau][Gotthard][CTB][Moench] Updates the "
"firmware, detector server, deletes old server, creates the "
"symbolic link and then reboots detector controller. "
"\n\t\t[Mythen3][Gotthard2] will require a script to start up "
"the shorter named server link at start up. \n\t\tserver_name is "
"full path name of detector server binary\n\t\tfname is full "
"path of programming file"
<< '\n';
} else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("Cannot get");
@ -2989,7 +3008,6 @@ std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
if (args.size() != 2) {
WrongNumberOfParameters(2);
}
int fpos = args.size() - 1;
if (args[fpos].find(".pof") == std::string::npos &&
args[fpos].find(".rbf") == std::string::npos) {
@ -3039,8 +3057,7 @@ std::string CmdProxy::AdcRegister(int action) {
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[address] [value]\n\t[Jungfrau][Ctb][Moench][Gotthard] Writes "
"to an adc "
"register in hex. Advanced user Function!"
"to an adc register in hex. Advanced user Function!"
<< '\n';
} else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("Cannot get.");

View File

@ -747,7 +747,6 @@ class CmdProxy {
/* Advanced */
{"copydetectorserver", "updatedetectorserver"},
/* Insignificant */
{"nframes", "framecounter"},
{"now", "runtime"},
@ -910,6 +909,8 @@ class CmdProxy {
{"rx_lastclient", &CmdProxy::rx_lastclient},
{"rx_threads", &CmdProxy::rx_threads},
{"rx_arping", &CmdProxy::rx_arping},
{"rx_roi", &CmdProxy::Rx_ROI},
{"rx_clearroi", &CmdProxy::rx_clearroi},
/* File */
{"fformat", &CmdProxy::fformat},
@ -965,7 +966,7 @@ class CmdProxy {
/* Gotthard Specific */
{"roi", &CmdProxy::ROI},
{"clearroi", &CmdProxy::ClearROI},
{"clearroi", &CmdProxy::clearroi},
{"exptimel", &CmdProxy::exptimel},
/* Gotthard2 Specific */
@ -1150,6 +1151,7 @@ class CmdProxy {
std::string UDPDestinationIP2(int action);
/* Receiver Config */
std::string ReceiverHostname(int action);
std::string Rx_ROI(int action);
/* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */
std::string ZMQHWM(int action);
@ -1164,7 +1166,6 @@ class CmdProxy {
std::string TemperatureEvent(int action);
/* Gotthard Specific */
std::string ROI(int action);
std::string ClearROI(int action);
/* Gotthard2 Specific */
std::string InjectChannel(int action);
std::string VetoPhoton(int action);
@ -1766,6 +1767,11 @@ class CmdProxy {
"the interface it is "
"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 */
INTEGER_COMMAND_VEC_ID(
@ -2001,6 +2007,10 @@ class CmdProxy {
"[(optional unit) ns|us|ms|s]\n\t[Gotthard] Exposure time "
"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 */
INTEGER_COMMAND_SET_NOID_GET_ID(
bursts, getNumberOfBursts, setNumberOfBursts, StringTo<int64_t>,

View File

@ -38,7 +38,7 @@ void freeSharedMemory(int detectorIndex, int moduleIndex) {
if (detectorShm.exists()) {
detectorShm.openSharedMemory(false);
numDetectors = detectorShm()->numberOfModules;
numDetectors = detectorShm()->totalNumberOfModules;
detectorShm.removeSharedMemory();
}
@ -1211,6 +1211,16 @@ void Detector::setRxArping(bool value, Positions pos) {
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
Result<defs::fileFormat> Detector::getFileFormat(Positions pos) const {
@ -1777,7 +1787,7 @@ Detector::getVetoAlgorithm(const defs::streamingInterface interface,
void Detector::setVetoAlgorithm(const defs::vetoAlgorithm alg,
defs::streamingInterface interface,
Positions pos) {
LOG(logINFOBLUE) << "alg:" << ToString(alg)
LOG(logDEBUG) << "alg:" << ToString(alg)
<< " interface:" << ToString(interface);
pimpl->Parallel(&Module::setVetoAlgorithm, pos, alg, interface);
}

View File

@ -70,7 +70,7 @@ void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
if (detectorShm.exists()) {
detectorShm.openSharedMemory(false);
numModules = detectorShm()->numberOfModules;
numModules = detectorShm()->totalNumberOfModules;
detectorShm.removeSharedMemory();
}
@ -161,10 +161,10 @@ void DetectorImpl::initSharedMemory(bool verify) {
void DetectorImpl::initializeDetectorStructure() {
shm()->shmversion = DETECTOR_SHMVERSION;
shm()->numberOfModules = 0;
shm()->totalNumberOfModules = 0;
shm()->detType = GENERIC;
shm()->numberOfModule.x = 0;
shm()->numberOfModule.y = 0;
shm()->numberOfModules.x = 0;
shm()->numberOfModules.y = 0;
shm()->numberOfChannels.x = 0;
shm()->numberOfChannels.y = 0;
shm()->acquiringFlag = false;
@ -172,6 +172,10 @@ void DetectorImpl::initializeDetectorStructure() {
shm()->gapPixels = false;
// zmqlib default
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) {
@ -179,7 +183,7 @@ void DetectorImpl::initializeMembers(bool verify) {
zmqSocket.clear();
// 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 {
modules.push_back(
sls::make_unique<Module>(detectorIndex, i, verify));
@ -246,7 +250,7 @@ void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) {
void DetectorImpl::setHostname(const std::vector<std::string> &name) {
// 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."
"Freeing Shared memory now.";
bool initialChecks = shm()->initialChecks;
@ -305,7 +309,7 @@ void DetectorImpl::addModule(const std::string &hostname) {
auto pos = modules.size();
modules.emplace_back(
sls::make_unique<Module>(type, detectorIndex, pos, false));
shm()->numberOfModules = modules.size();
shm()->totalNumberOfModules = modules.size();
modules[pos]->setControlPort(port);
modules[pos]->setStopPort(port + 1);
modules[pos]->setHostname(host, shm()->initialChecks);
@ -328,9 +332,8 @@ void DetectorImpl::addModule(const std::string &hostname) {
void DetectorImpl::updateDetectorSize() {
LOG(logDEBUG) << "Updating Detector Size: " << size();
const slsDetectorDefs::xy det_size = modules[0]->getNumberOfChannels();
if (det_size.x == 0 || det_size.y == 0) {
const slsDetectorDefs::xy modSize = modules[0]->getNumberOfChannels();
if (modSize.x == 0 || modSize.y == 0) {
throw sls::RuntimeError(
"Module size for x or y dimensions is 0. Unable to proceed in "
"updating detector size. ");
@ -338,39 +341,39 @@ void DetectorImpl::updateDetectorSize() {
int maxx = shm()->numberOfChannels.x;
int maxy = shm()->numberOfChannels.y;
int ndetx = 0, ndety = 0;
int nModx = 0, nMody = 0;
// 1d, add modules along x axis
if (det_size.y == 1) {
if (modSize.y == 1) {
if (maxx == 0) {
maxx = det_size.x * size();
maxx = modSize.x * size();
}
ndetx = maxx / det_size.x;
ndety = size() / ndetx;
if ((maxx % det_size.x) > 0) {
++ndety;
nModx = maxx / modSize.x;
nMody = size() / nModx;
if ((maxx % modSize.x) > 0) {
++nMody;
}
}
// 2d, add modules along y axis (due to eiger top/bottom)
else {
if (maxy == 0) {
maxy = det_size.y * size();
maxy = modSize.y * size();
}
ndety = maxy / det_size.y;
ndetx = size() / ndety;
if ((maxy % det_size.y) > 0) {
++ndetx;
nMody = maxy / modSize.y;
nModx = size() / nMody;
if ((maxy % modSize.y) > 0) {
++nModx;
}
}
shm()->numberOfModule.x = ndetx;
shm()->numberOfModule.y = ndety;
shm()->numberOfChannels.x = det_size.x * ndetx;
shm()->numberOfChannels.y = det_size.y * ndety;
shm()->numberOfModules.x = nModx;
shm()->numberOfModules.y = nMody;
shm()->numberOfChannels.x = modSize.x * nModx;
shm()->numberOfChannels.y = modSize.y * nMody;
LOG(logDEBUG) << "\n\tNumber of Modules in X direction:"
<< shm()->numberOfModule.x
<< shm()->numberOfModules.x
<< "\n\tNumber of Modules in Y direction:"
<< shm()->numberOfModule.y
<< shm()->numberOfModules.y
<< "\n\tNumber of Channels in X direction:"
<< shm()->numberOfChannels.x
<< "\n\tNumber of Channels in Y direction:"
@ -378,7 +381,7 @@ void DetectorImpl::updateDetectorSize() {
for (auto &module : modules) {
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(); }
slsDetectorDefs::xy DetectorImpl::getNumberOfModules() const {
return shm()->numberOfModule;
return shm()->numberOfModules;
}
slsDetectorDefs::xy DetectorImpl::getNumberOfChannels() const {
@ -412,7 +415,7 @@ void DetectorImpl::setGapPixelsinCallback(const bool enable) {
if (size() && modules[0]->getQuad()) {
break;
}
if (shm()->numberOfModule.y % 2 != 0) {
if (shm()->numberOfModules.y % 2 != 0) {
throw RuntimeError("Gap pixels can only be used "
"for full modules.");
}
@ -495,6 +498,7 @@ void DetectorImpl::readFrameFromReceiver() {
bool quadEnable = false;
// to flip image
bool eiger = false;
std::array<int, 4> rxRoi = shm()->rx_roi.getIntArray();
std::vector<bool> runningList(zmqSocket.size());
std::vector<bool> connectList(zmqSocket.size());
@ -571,7 +575,7 @@ void DetectorImpl::readFrameFromReceiver() {
// shape
nPixelsX = zHeader.npixelsx;
nPixelsY = zHeader.npixelsy;
// module shape (port)
// port geometry
nX = zHeader.ndetx;
nY = zHeader.ndety;
nDetPixelsX = nX * nPixelsX;
@ -668,6 +672,7 @@ void DetectorImpl::readFrameFromReceiver() {
<< "\n\t databytes: " << multisize
<< "\n\t dynamicRange: " << dynamicRange;
// send data to callback
if (data) {
char *callbackImage = multiframe.get();
@ -691,7 +696,7 @@ void DetectorImpl::readFrameFromReceiver() {
thisData = new detectorData(currentProgress, currentFileName,
nDetActualPixelsX, nDetActualPixelsY,
callbackImage, imagesize, dynamicRange,
currentFileIndex, completeImage);
currentFileIndex, completeImage, rxRoi);
try {
dataReady(
thisData, currentFrameIndex,
@ -1094,9 +1099,6 @@ int DetectorImpl::acquire() {
return FAIL;
}
// We need this to handle Mythen3 synchronization
auto detector_type = Parallel(&Module::getDetectorType, {}).squash();
try {
struct timespec begin, end;
clock_gettime(CLOCK_REALTIME, &begin);
@ -1174,6 +1176,7 @@ int DetectorImpl::acquire() {
}
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;
@ -1425,6 +1428,218 @@ void DetectorImpl::setDefaultDac(defs::dacIndex index, int defaultValue,
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 {
return ctb_shm()->getDacNames();
}

View File

@ -7,7 +7,6 @@
#include "sls/logger.h"
#include "sls/sls_detector_defs.h"
#include "CtbConfig.h"
class ZmqSocket;
class detectorData;
@ -20,7 +19,7 @@ class detectorData;
#include <vector>
#define DETECTOR_SHMAPIVERSION 0x190809
#define DETECTOR_SHMVERSION 0x201007
#define DETECTOR_SHMVERSION 0x220505
#define SHORT_STRING_LENGTH 50
#include <future>
@ -51,14 +50,14 @@ struct sharedDetector {
/** last time stamp when accessing the shared memory */
char lastDate[SHORT_STRING_LENGTH];
int numberOfModules;
int totalNumberOfModules;
slsDetectorDefs::detectorType detType;
/** END OF FIXED PATTERN
* -----------------------------------------------*/
/** Number of modules operated at once */
slsDetectorDefs::xy numberOfModule;
slsDetectorDefs::xy numberOfModules;
/** max number of channels for complete detector*/
slsDetectorDefs::xy numberOfChannels;
@ -68,6 +67,8 @@ struct sharedDetector {
bool gapPixels;
/** high water mark of listening tcp port (only data) */
int zmqHwm;
/** in shm for gui purposes */
defs::ROI rx_roi{};
};
class DetectorImpl : public virtual slsDetectorDefs {
@ -302,7 +303,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
Positions pos = {});
void setDefaultDac(defs::dacIndex index, int defaultValue,
defs::detectorSettings sett, Positions pos);
defs::ROI getRxROI() const;
void setRxROI(const defs::ROI arg);
void clearRxROI();
std::vector<std::string> getCtbDacNames() const;
std::string getCtbDacName(defs::dacIndex i) const;
@ -389,6 +392,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/
int kbhit();
defs::xy getPortGeometry() const;
defs::xy calculatePosition(int moduleIndex, defs::xy geometry) const;
const int detectorIndex{0};
sls::SharedMemory<sharedDetector> shm{0, -1};
sls::SharedMemory<CtbConfig> ctb_shm{0, -1, CtbConfig::shm_tag()};

View File

@ -1410,6 +1410,19 @@ void Module::setRxArping(bool enable) {
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
slsDetectorDefs::fileFormat Module::getFileFormat() const {
return sendToReceiver<fileFormat>(F_GET_RECEIVER_FILE_FORMAT);
@ -1837,7 +1850,7 @@ void Module::setROI(slsDetectorDefs::ROI arg) {
}
sendToDetector(F_SET_ROI, arg, nullptr);
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_ROI, arg, nullptr);
sendToReceiver(F_RECEIVER_SET_DETECTOR_ROI, arg, nullptr);
}
}

View File

@ -290,6 +290,9 @@ class Module : public virtual slsDetectorDefs {
std::array<pid_t, NUM_RX_THREAD_IDS> getReceiverThreadIds() const;
bool getRxArping() const;
void setRxArping(bool enable);
defs::ROI getRxROI() const;
void setRxROI(const slsDetectorDefs::ROI arg);
void setRxROIMetadata(const slsDetectorDefs::ROI arg);
/**************************************************
* *

View File

@ -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.getDetectrSize();
// 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 */
TEST_CASE("fformat", "[.cmd]") {

View File

@ -55,7 +55,8 @@ int64_t ClientInterface::getReceiverVersion() { return APIRECEIVER; }
/***callback functions***/
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) {
startAcquisitionCallBack = func;
pStartAcquisition = arg;
@ -122,7 +123,7 @@ int ClientInterface::functionTable(){
flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip;
flist[F_GET_RECEIVER_VERSION] = &ClientInterface::get_version;
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_SET_RECEIVER_NUM_TRIGGERS] = &ClientInterface::set_num_triggers;
flist[F_SET_RECEIVER_NUM_BURSTS] = &ClientInterface::set_num_bursts;
@ -217,6 +218,9 @@ int ClientInterface::functionTable(){
flist[F_RECEIVER_SET_DATASTREAM] = &ClientInterface::set_detector_datastream;
flist[F_GET_RECEIVER_ARPING] = &ClientInterface::get_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++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@ -247,7 +251,7 @@ int ClientInterface::decodeFunction(Interface &socket) {
void ClientInterface::functionNotImplemented() {
std::ostringstream os;
os << "Function: " << getFunctionNameFromEnum((enum detFuncs)fnum)
<< ", is is not implemented for this detector";
<< " is not implemented for this detector";
throw RuntimeError(os.str());
}
@ -455,7 +459,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
}
if (detType == GOTTHARD) {
try {
impl()->setROI(arg.roi);
impl()->setDetectorROI(arg.roi);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set ROI");
}
@ -497,8 +501,11 @@ void ClientInterface::setDetectorType(detectorType arg) {
detType = GENERIC;
receiver = sls::make_unique<Implementation>(arg);
detType = arg;
} catch (...) {
throw RuntimeError("Could not set detector type");
} catch (std::exception &e) {
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)
@ -518,16 +525,16 @@ void ClientInterface::setDetectorType(detectorType arg) {
impl()->setThreadIds(parentThreadId, tcpThreadId);
}
int ClientInterface::set_roi(Interface &socket) {
int ClientInterface::set_detector_roi(Interface &socket) {
auto arg = socket.Receive<ROI>();
LOG(logDEBUG1) << "Set ROI: [" << arg.xmin << ", " << arg.xmax << "]";
LOG(logDEBUG1) << "Set Detector ROI: " << sls::ToString(arg);
if (detType != GOTTHARD)
functionNotImplemented();
verifyIdle(socket);
try {
impl()->setROI(arg);
impl()->setDetectorROI(arg);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set ROI");
}
@ -1736,3 +1743,37 @@ int ClientInterface::set_arping(Interface &socket) {
impl()->setArping(value, udpips);
return socket.Send(OK);
}
int ClientInterface::get_receiver_roi(Interface &socket) {
auto retval = impl()->getReceiverROI();
LOG(logDEBUG1) << "Receiver roi retval:" << sls::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: " << sls::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: " << sls::ToString(arg);
verifyIdle(socket);
try {
impl()->setReceiverROIMetadata(arg);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set ReceiverROI metadata");
}
return socket.Send(OK);
}

View File

@ -66,7 +66,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_version(sls::ServerInterface &socket);
int setup_receiver(sls::ServerInterface &socket);
void setDetectorType(detectorType arg);
int set_roi(sls::ServerInterface &socket);
int set_detector_roi(sls::ServerInterface &socket);
int set_num_frames(sls::ServerInterface &socket);
int set_num_triggers(sls::ServerInterface &socket);
int set_num_bursts(sls::ServerInterface &socket);
@ -164,6 +164,9 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_detector_datastream(sls::ServerInterface &socket);
int get_arping(sls::ServerInterface &socket);
int set_arping(sls::ServerInterface &socket);
int get_receiver_roi(sls::ServerInterface &socket);
int set_receiver_roi(sls::ServerInterface &socket);
int set_receiver_roi_metadata(sls::ServerInterface &socket);
Implementation *impl() {
if (receiver != nullptr) {

View File

@ -27,19 +27,19 @@
const std::string DataProcessor::typeName_ = "DataProcessor";
DataProcessor::DataProcessor(int index, detectorType detectorType, Fifo *fifo,
bool *activated, bool *dataStreamEnable,
bool *dataStreamEnable,
uint32_t *streamingFrequency,
uint32_t *streamingTimerInMs,
uint32_t *streamingStartFnum, bool *framePadding,
std::vector<int> *ctbDbitList, int *ctbDbitOffset,
int *ctbAnalogDataBytes)
: ThreadObject(index, typeName_), fifo_(fifo), detectorType_(detectorType),
dataStreamEnable_(dataStreamEnable), activated_(activated),
dataStreamEnable_(dataStreamEnable),
streamingFrequency_(streamingFrequency),
streamingTimerInMs_(streamingTimerInMs),
streamingStartFnum_(streamingStartFnum), framePadding_(framePadding),
ctbDbitList_(ctbDbitList), ctbDbitOffset_(ctbDbitOffset),
ctbAnalogDataBytes_(ctbAnalogDataBytes), firstStreamerFrame_(false) {
ctbAnalogDataBytes_(ctbAnalogDataBytes) {
LOG(logDEBUG) << "DataProcessor " << index << " created";
}
@ -50,6 +50,13 @@ bool DataProcessor::GetStartedFlag() const { return startedFlag_; }
void DataProcessor::SetFifo(Fifo *fifo) { fifo_ = fifo; }
void DataProcessor::SetActivate(bool enable) { activated_ = enable; }
void DataProcessor::SetReceiverROI(ROI roi) {
receiverRoi_ = roi;
receiverRoiEnabled_ = receiverRoi_.completeRoi() ? false : true;
}
void DataProcessor::ResetParametersforNewAcquisition() {
StopRunning();
startedFlag_ = false;
@ -57,6 +64,8 @@ void DataProcessor::ResetParametersforNewAcquisition() {
firstIndex_ = 0;
currentFrameIndex_ = 0;
firstStreamerFrame_ = true;
streamCurrentFrame_ = false;
completeImageToStreamBeforeCropping = sls::make_unique<char[]>(generalData_->imageSize);
}
void DataProcessor::RecordFirstIndex(uint64_t fnum) {
@ -115,18 +124,28 @@ void DataProcessor::CreateFirstFiles(
CloseFiles();
// deactivated (half module/ single port), dont write file
if ((!*activated_) || (!detectorDataStream)) {
if (!activated_ || !detectorDataStream) {
return;
}
#ifdef HDF5C
int nx = generalData_->nPixelsX;
int ny = generalData_->nPixelsY;
if (receiverRoiEnabled_) {
nx = receiverRoi_.xmax - receiverRoi_.xmin + 1;
ny = receiverRoi_.ymax - receiverRoi_.ymin + 1;
if (receiverRoi_.ymax == -1 || receiverRoi_.ymin == -1) {
ny = 1;
}
}
#endif
switch (dataFile_->GetFileFormat()) {
#ifdef HDF5C
case HDF5:
dataFile_->CreateFirstHDF5DataFile(
filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode,
modulePos, numUnitsPerReadout, udpPortNumber, maxFramesPerFile,
numImages, generalData_->nPixelsX, generalData_->nPixelsY,
dynamicRange);
numImages, nx, ny, dynamicRange);
break;
#endif
case BINARY:
@ -156,6 +175,10 @@ std::array<std::string, 2> DataProcessor::CreateVirtualFile(
const int numModX, const int numModY, const uint32_t dynamicRange,
std::mutex *hdf5LibMutex) {
if (receiverRoiEnabled_) {
throw std::runtime_error("Skipping virtual hdf5 file since rx_roi is enabled.");
}
bool gotthard25um =
((detectorType_ == GOTTHARD || detectorType_ == GOTTHARD2) &&
(numModX * numModY) == 2);
@ -182,6 +205,10 @@ void DataProcessor::LinkFileInMaster(const std::string &masterFileName,
const std::string &virtualDatasetName,
const bool silentMode,
std::mutex *hdf5LibMutex) {
if (receiverRoiEnabled_) {
throw std::runtime_error("Should not be here, roi with hdf5 virtual should throw.");
}
std::string fname{virtualFileName}, datasetName{virtualDatasetName};
// if no virtual file, link data file
if (virtualFileName.empty()) {
@ -234,21 +261,19 @@ void DataProcessor::ThreadExecution() {
return;
}
uint64_t fnum = 0;
try {
fnum = ProcessAnImage(buffer);
ProcessAnImage(buffer);
} catch (const std::exception &e) {
fifo_->FreeAddress(buffer);
return;
}
// stream (if time/freq to stream) or free
if (*dataStreamEnable_ && SendToStreamer()) {
// if first frame to stream, add frame index to fifo header (might
// not be the first)
if (firstStreamerFrame_) {
firstStreamerFrame_ = false;
(*((uint32_t *)(buffer + FIFO_DATASIZE_NUMBYTES))) =
(uint32_t)(fnum - firstIndex_);
if (streamCurrentFrame_) {
// copy the complete image back if roi enabled
if (receiverRoiEnabled_) {
(*((uint32_t *)buffer)) = generalData_->imageSize;
memcpy(buffer + generalData_->fifoBufferHeaderSize, &completeImageToStreamBeforeCropping[0], generalData_->imageSize);
}
fifo_->PushAddressToStream(buffer);
} else {
@ -270,9 +295,10 @@ void DataProcessor::StopProcessing(char *buf) {
LOG(logDEBUG1) << index << ": Processing Completed";
}
uint64_t DataProcessor::ProcessAnImage(char *buf) {
void DataProcessor::ProcessAnImage(char *buf) {
auto *rheader = reinterpret_cast<sls_receiver_header *>(buf + FIFO_HEADER_NUMBYTES);
auto *rheader =
reinterpret_cast<sls_receiver_header *>(buf + FIFO_HEADER_NUMBYTES);
sls_detector_header header = rheader->detHeader;
uint64_t fnum = header.frameNumber;
currentFrameIndex_ = fnum;
@ -295,7 +321,7 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) {
}
// frame padding
if (*activated_ && *framePadding_ && nump < generalData_->packetsPerFrame)
if (activated_ && *framePadding_ && nump < generalData_->packetsPerFrame)
PadMissingPackets(buf);
// rearrange ctb digital bits (if ctbDbitlist is not empty)
@ -303,6 +329,30 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) {
RearrangeDbitData(buf);
}
// 'stream Image' check has to be done here before crop image
// stream (if time/freq to stream) or free
if (*dataStreamEnable_ && SendToStreamer()) {
// if first frame to stream, add frame index to fifo header (might
// not be the first)
if (firstStreamerFrame_) {
firstStreamerFrame_ = false;
(*((uint32_t *)(buf + FIFO_DATASIZE_NUMBYTES))) =
(uint32_t)(fnum - firstIndex_);
}
streamCurrentFrame_ = true;
} else {
streamCurrentFrame_ = false;
}
if (receiverRoiEnabled_) {
// copy the complete image to stream before cropping
if (streamCurrentFrame_) {
memcpy(&completeImageToStreamBeforeCropping[0], buf + generalData_->fifoBufferHeaderSize, generalData_->imageSize);
}
CropImage(buf);
}
try {
// normal call back
if (rawDataReadyCallBack != nullptr) {
@ -341,7 +391,6 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) {
// via stopReceiver tcp)
}
}
return fnum;
}
bool DataProcessor::SendToStreamer() {
@ -508,3 +557,44 @@ void DataProcessor::RearrangeDbitData(char *buf) {
memcpy(buf + digOffset, result.data(), numResult8Bits * sizeof(uint8_t));
(*((uint32_t *)buf)) = numResult8Bits * sizeof(uint8_t);
}
void DataProcessor::CropImage(char *buf) {
LOG(logDEBUG) << "Cropping Image to ROI " << sls::ToString(receiverRoi_);
int nPixelsX = generalData_->nPixelsX;
int xmin = receiverRoi_.xmin;
int xmax = receiverRoi_.xmax;
int ymin = receiverRoi_.ymin;
int ymax = receiverRoi_.ymax;
int xwidth = xmax - xmin + 1;
int ywidth = ymax - ymin + 1;
if (ymin == -1 || ymax == -1) {
ywidth = 1;
ymin = 0;
}
// calculate total roi size
double bytesPerPixel = generalData_->dynamicRange / 8.00;
int startOffset = (int)((nPixelsX * ymin + xmin) * bytesPerPixel);
// write size into fifo buffer header
std::size_t roiImageSize = xwidth * ywidth * bytesPerPixel;
LOG(logDEBUG) << "roiImageSize:" << roiImageSize;
(*((uint32_t *)buf)) = roiImageSize;
// copy the roi to the beginning of the image
char *dstOffset = buf + generalData_->fifoBufferHeaderSize;
char *srcOffset = dstOffset + startOffset;
// entire width
if (xwidth == nPixelsX) {
memcpy(dstOffset, srcOffset, roiImageSize);
}
// width is cropped
else {
for (int y = 0; y != ywidth; ++y) {
memcpy(dstOffset, srcOffset, xwidth * bytesPerPixel);
dstOffset += (int)(xwidth * bytesPerPixel);
srcOffset += (int)(generalData_->nPixelsX * bytesPerPixel);
}
}
}

View File

@ -28,17 +28,18 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
public:
DataProcessor(int index, detectorType detectorType, Fifo *fifo,
bool *activated, bool *dataStreamEnable,
uint32_t *streamingFrequency, uint32_t *streamingTimerInMs,
uint32_t *streamingStartFnum, bool *framePadding,
std::vector<int> *ctbDbitList, int *ctbDbitOffset,
int *ctbAnalogDataBytes);
bool *dataStreamEnable, uint32_t *streamingFrequency,
uint32_t *streamingTimerInMs, uint32_t *streamingStartFnum,
bool *framePadding, std::vector<int> *ctbDbitList,
int *ctbDbitOffset, int *ctbAnalogDataBytes);
~DataProcessor() override;
bool GetStartedFlag() const;
void SetFifo(Fifo *f);
void SetActivate(bool enable);
void SetReceiverROI(ROI roi);
void ResetParametersforNewAcquisition();
void SetGeneralData(GeneralData *generalData);
@ -85,7 +86,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
char *, size_t, void *),
void *arg);
/** params: sls_receiver_header pointer, pointer to data, reference to image size */
/** params: sls_receiver_header pointer, pointer to data, reference to image
* size */
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header *,
char *, size_t &,
void *),
@ -110,9 +112,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
/**
* Process an image popped from fifo,
* write to file if fw enabled & update parameters
* @returns frame number
*/
uint64_t ProcessAnImage(char *buf);
void ProcessAnImage(char *buf);
/**
* Calls CheckTimer and CheckCount for streaming frequency and timer
@ -143,13 +144,18 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
*/
void RearrangeDbitData(char *buf);
void CropImage(char *buf);
static const std::string typeName_;
const GeneralData *generalData_{nullptr};
Fifo *fifo_;
detectorType detectorType_;
bool *dataStreamEnable_;
bool *activated_;
bool activated_{false};
ROI receiverRoi_{};
bool receiverRoiEnabled_{false};
std::unique_ptr<char[]> completeImageToStreamBeforeCropping;
/** if 0, sending random images with a timer */
uint32_t *streamingFrequency_;
uint32_t *streamingTimerInMs_;
@ -164,7 +170,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
std::atomic<uint64_t> firstIndex_{0};
// for statistics
/** Number of frames caught */
uint64_t numFramesCaught_{0};
/** Frame Number of latest processed frame number */
@ -173,6 +178,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
/** first streamer frame to add frame index in fifo header */
bool firstStreamerFrame_{false};
bool streamCurrentFrame_{false};
File *dataFile_{nullptr};
// call back

View File

@ -19,7 +19,7 @@ const std::string DataStreamer::TypeName = "DataStreamer";
DataStreamer::DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi,
bool fr, slsDetectorDefs::xy np, bool *qe,
uint64_t *tot)
: ThreadObject(ind, TypeName), fifo(f), dynamicRange(dr), roi(r),
: ThreadObject(ind, TypeName), fifo(f), dynamicRange(dr), detectorRoi(r),
fileIndex(fi), flipRows(fr), numPorts(np), quadEnable(qe),
totalNumFrames(tot) {
@ -43,8 +43,8 @@ void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
delete[] completeBuffer;
completeBuffer = nullptr;
}
if (generalData->myDetectorType == GOTTHARD && roi->xmin != -1) {
adcConfigured = generalData->GetAdcConfigured(index, *roi);
if (generalData->myDetectorType == GOTTHARD && detectorRoi->xmin != -1) {
adcConfigured = generalData->GetAdcConfigured(index, *detectorRoi);
completeBuffer = new char[generalData->imageSizeComplete];
memset(completeBuffer, 0, generalData->imageSizeComplete);
}
@ -114,7 +114,7 @@ void DataStreamer::ThreadExecution() {
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
// check dummy
uint32_t numBytes = (uint32_t)(*((uint32_t *)buffer));
auto numBytes = *reinterpret_cast<uint32_t *>(buffer);
LOG(logDEBUG1) << "DataStreamer " << index << ", Numbytes:" << numBytes;
if (numBytes == DUMMY_PACKET_VALUE) {
StopProcessing(buffer);
@ -153,6 +153,7 @@ void DataStreamer::ProcessAnImage(char *buf) {
if (!startedFlag) {
RecordFirstIndex(fnum, buf);
}
auto numBytes = *reinterpret_cast<uint32_t *>(buf);
// shortframe gotthard
if (completeBuffer) {
@ -170,7 +171,7 @@ void DataStreamer::ProcessAnImage(char *buf) {
}
memcpy(completeBuffer + ((generalData->imageSize) * adcConfigured),
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
(uint32_t)(*((uint32_t *)buf)));
numBytes);
if (!zmqSocket->SendData(completeBuffer,
generalData->imageSizeComplete)) {
@ -182,16 +183,15 @@ void DataStreamer::ProcessAnImage(char *buf) {
// normal
else {
if (!SendHeader(header, (uint32_t)(*((uint32_t *)buf)),
generalData->nPixelsX, generalData->nPixelsY,
if (!SendHeader(header, numBytes, generalData->nPixelsX,
generalData->nPixelsY,
false)) { // new size possibly from callback
LOG(logERROR) << "Could not send zmq header for fnum " << fnum
<< " and streamer " << index;
}
if (!zmqSocket->SendData(
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
(uint32_t)(*(
(uint32_t *)buf)))) { // new size possibly from callback
if (!zmqSocket->SendData(buf + FIFO_HEADER_NUMBYTES +
sizeof(sls_receiver_header),
numBytes)) { // new size possibly from callback
LOG(logERROR) << "Could not send zmq data for fnum " << fnum
<< " and streamer " << index;
}

View File

@ -30,7 +30,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param ind self index
* @param f address of Fifo pointer
* @param dr pointer to dynamic range
* @param r roi
* @param r detectorRoi
* @param fi pointer to file index
* @param fr flip rows
* @param nm number of ports in each dimension
@ -64,15 +64,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
*/
void CreateZmqSockets(int *nunits, uint32_t port, const sls::IpAddr ip,
int hwm);
/**
* Shuts down and deletes Zmq Sockets
*/
void CloseZmqSocket();
/**
* Restream stop dummy packet
*/
void RestreamStop();
private:
@ -82,24 +74,17 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param buf get frame index from buffer to calculate first index to record
*/
void RecordFirstIndex(uint64_t fnum, char *buf);
/**
* Thread Exeution for DataStreamer Class
* Stream an image via zmq
*/
void ThreadExecution();
/**
* Frees dummy buffer,
* reset running mask by calling StopRunning()
* @param buf address of pointer
*/
void StopProcessing(char *buf);
/**
* Process an image popped from fifo,
* write to file if fw enabled & update parameters
* @param buf address of pointer
*/
void ProcessAnImage(char *buf);
@ -120,11 +105,10 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
Fifo *fifo;
ZmqSocket *zmqSocket{nullptr};
uint32_t *dynamicRange;
ROI *roi;
ROI *detectorRoi;
int adcConfigured{-1};
uint64_t *fileIndex;
bool flipRows;
std::map<std::string, std::string> additionalJsonHeader;
/** Used by streamer thread to update local copy (reduce number of locks
@ -137,15 +121,10 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
/** local copy of additional json header (it can be update on the fly) */
std::map<std::string, std::string> localAdditionalJsonHeader;
/** Aquisition Started flag */
bool startedFlag{false};
/** Frame Number of First Frame */
uint64_t firstIndex{0};
std::string fileNametoStream;
/** Complete buffer used for roi, eg. shortGotthard */
/** Complete buffer used for detectorRoi, eg. shortGotthard */
char *completeBuffer{nullptr};
xy numPorts{1, 1};

View File

@ -72,7 +72,7 @@ class GeneralData {
void ThrowGenericError(std::string msg) const {
throw sls::RuntimeError(
msg + std::string("SetROI is a generic function that should be "
msg + std::string("This is a generic function that should be "
"overloaded by a derived class"));
}
@ -96,8 +96,8 @@ class GeneralData {
bunchId = -1;
}
virtual void SetROI(slsDetectorDefs::ROI i) {
ThrowGenericError("SetROI");
virtual void SetDetectorROI(slsDetectorDefs::ROI i) {
ThrowGenericError("SetDetectorROI");
};
/**@returns adc configured */
@ -248,7 +248,7 @@ class GotthardData : public GeneralData {
return oddStartingPacket;
};
void SetROI(slsDetectorDefs::ROI i) {
void SetDetectorROI(slsDetectorDefs::ROI i) {
roi = i;
UpdateImageSize();
};

View File

@ -165,7 +165,7 @@ void Implementation::setDetectorType(const detectorType d) {
readoutType = generalData->readoutType;
adcEnableMaskOneGiga = generalData->adcEnableMaskOneGiga;
adcEnableMaskTenGiga = generalData->adcEnableMaskTenGiga;
roi = generalData->roi;
detectorRoi = generalData->roi;
counterMask = generalData->counterMask;
SetLocalNetworkParameters();
@ -179,17 +179,16 @@ void Implementation::setDetectorType(const detectorType d) {
listener.push_back(sls::make_unique<Listener>(
i, detType, fifo_ptr, &status, &udpPortNum[i], &eth[i],
&udpSocketBufferSize, &actualUDPSocketBufferSize,
&framesPerFile, &frameDiscardMode, &activated,
&detectorDataStream[i], &silentMode));
&framesPerFile, &frameDiscardMode, &detectorDataStream[i],
&silentMode));
int ctbAnalogDataBytes = 0;
if (detType == CHIPTESTBOARD) {
ctbAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes();
}
dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, detType, fifo_ptr, &activated, &dataStreamEnable,
&streamingFrequency, &streamingTimerInMs, &streamingStartFnum,
&framePadding, &ctbDbitList, &ctbDbitOffset,
&ctbAnalogDataBytes));
i, detType, fifo_ptr, &dataStreamEnable, &streamingFrequency,
&streamingTimerInMs, &streamingStartFnum, &framePadding,
&ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes));
} catch (...) {
listener.clear();
dataProcessor.clear();
@ -200,10 +199,14 @@ void Implementation::setDetectorType(const detectorType d) {
}
// set up writer and callbacks
for (const auto &it : listener)
for (const auto &it : listener) {
it->SetGeneralData(generalData);
for (const auto &it : dataProcessor)
it->SetActivate(activated);
}
for (const auto &it : dataProcessor) {
it->SetGeneralData(generalData);
it->SetActivate(activated);
}
SetThreadPriorities();
LOG(logDEBUG) << " Detector type set to " << sls::ToString(d);
@ -213,7 +216,7 @@ slsDetectorDefs::xy Implementation::getDetectorSize() const {
return numModules;
}
slsDetectorDefs::xy Implementation::GetPortGeometry() {
const slsDetectorDefs::xy Implementation::GetPortGeometry() const {
xy portGeometry{1, 1};
if (detType == EIGER)
portGeometry.x = numUDPInterfaces;
@ -363,6 +366,91 @@ void Implementation::setArping(const bool i,
}
}
slsDetectorDefs::ROI Implementation::getReceiverROI() const {
return receiverRoi;
}
void Implementation::setReceiverROI(const slsDetectorDefs::ROI arg) {
receiverRoi = arg;
if (numUDPInterfaces == 1 || detType == slsDetectorDefs::GOTTHARD2) {
portRois[0] = arg;
} else {
slsDetectorDefs::xy nPortDim(generalData->nPixelsX,
generalData->nPixelsY);
for (int iPort = 0; iPort != numUDPInterfaces; ++iPort) {
// default init = complete roi
slsDetectorDefs::ROI portRoi{};
// no roi
if (arg.noRoi()) {
portRoi.setNoRoi();
}
// incomplete roi
else if (!arg.completeRoi()) {
// get port limits
slsDetectorDefs::ROI portFullRoi{0, nPortDim.x - 1, 0,
nPortDim.y - 1};
if (iPort == 1) {
// left right (eiger)
if (GetPortGeometry().x == 2) {
portFullRoi.xmin += nPortDim.x;
portFullRoi.xmax += nPortDim.x;
}
// top bottom (jungfrau)
else {
portFullRoi.ymin += nPortDim.y;
portFullRoi.ymax += nPortDim.y;
}
}
LOG(logDEBUG)
<< iPort << ": portfullroi:" << sls::ToString(portFullRoi);
// no roi
if (arg.xmin > portFullRoi.xmax ||
arg.xmax < portFullRoi.xmin ||
arg.ymin > portFullRoi.ymax ||
arg.ymax < portFullRoi.ymin) {
portRoi.setNoRoi();
}
// incomplete module roi
else if (arg.xmin > portFullRoi.xmin ||
arg.xmax < portFullRoi.xmax ||
arg.ymin > portFullRoi.ymin ||
arg.ymax < portFullRoi.ymax) {
portRoi.xmin = (arg.xmin <= portFullRoi.xmin)
? 0
: (arg.xmin % nPortDim.x);
portRoi.xmax = (arg.xmax >= portFullRoi.xmax)
? nPortDim.x - 1
: (arg.xmax % nPortDim.x);
portRoi.ymin = (arg.ymin <= portFullRoi.ymin)
? 0
: (arg.ymin % nPortDim.y);
portRoi.ymax = (arg.ymax >= portFullRoi.ymax)
? nPortDim.y - 1
: (arg.ymax % nPortDim.y);
}
}
portRois[iPort] = portRoi;
}
}
for (size_t i = 0; i != dataProcessor.size(); ++i)
dataProcessor[i]->SetReceiverROI(portRois[i]);
LOG(logINFO) << "receiver roi: " << sls::ToString(receiverRoi);
if (numUDPInterfaces == 2 && detType != slsDetectorDefs::GOTTHARD2) {
LOG(logINFO) << "port rois: " << sls::ToString(portRois);
}
}
void Implementation::setReceiverROIMetadata(const ROI arg) {
receiverRoiMetadata = arg;
LOG(logINFO) << "receiver roi Metadata: " << sls::ToString(receiverRoiMetadata);
}
/**************************************************
* *
* File Parameters *
@ -775,6 +863,8 @@ void Implementation::StartMasterWriter() {
masterAttributes.framePadding = framePadding;
masterAttributes.scanParams = scanParams;
masterAttributes.totalFrames = numberOfTotalFrames;
masterAttributes.receiverRoi =
receiverRoiMetadata;
masterAttributes.exptime = acquisitionTime;
masterAttributes.period = acquisitionPeriod;
masterAttributes.burstMode = burstMode;
@ -805,7 +895,7 @@ void Implementation::StartMasterWriter() {
for (auto &i : ctbDbitList) {
masterAttributes.dbitlist |= (1 << i);
}
masterAttributes.roi = roi;
masterAttributes.detectorRoi = detectorRoi;
masterAttributes.counterMask = counterMask;
masterAttributes.exptimeArray[0] = acquisitionTime1;
masterAttributes.exptimeArray[1] = acquisitionTime2;
@ -842,8 +932,9 @@ void Implementation::StartMasterWriter() {
}
}
#endif
} catch (...) {
; // ignore it and just print it
} catch (std::exception &e) {
// ignore it and just print it
LOG(logWARNING) << "Caught exception when handling virtual hdf5 file [" << e.what() << "]";
}
}
@ -895,6 +986,8 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
// fifo
udpSocketBufferSize = generalData->defaultUdpSocketBufferSize;
SetupFifoStructure();
// recalculate port rois
setReceiverROI(receiverRoi);
// create threads
for (int i = 0; i < numUDPInterfaces; ++i) {
@ -904,9 +997,10 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
listener.push_back(sls::make_unique<Listener>(
i, detType, fifo_ptr, &status, &udpPortNum[i], &eth[i],
&udpSocketBufferSize, &actualUDPSocketBufferSize,
&framesPerFile, &frameDiscardMode, &activated,
&detectorDataStream[i], &silentMode));
&framesPerFile, &frameDiscardMode, &detectorDataStream[i],
&silentMode));
listener[i]->SetGeneralData(generalData);
listener[i]->SetActivate(activated);
int ctbAnalogDataBytes = 0;
if (detType == CHIPTESTBOARD) {
@ -914,11 +1008,13 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
generalData->GetNumberOfAnalogDatabytes();
}
dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, detType, fifo_ptr, &activated, &dataStreamEnable,
i, detType, fifo_ptr, &dataStreamEnable,
&streamingFrequency, &streamingTimerInMs,
&streamingStartFnum, &framePadding, &ctbDbitList,
&ctbDbitOffset, &ctbAnalogDataBytes));
dataProcessor[i]->SetGeneralData(generalData);
dataProcessor[i]->SetActivate(activated);
dataProcessor[i]->SetReceiverROI(portRois[i]);
} catch (...) {
listener.clear();
dataProcessor.clear();
@ -934,15 +1030,15 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
flip = (i == 1 ? true : false);
}
dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, flip,
numPorts, &quadEnable, &numberOfTotalFrames));
i, fifo[i].get(), &dynamicRange, &detectorRoi,
&fileIndex, flip, numPorts, &quadEnable,
&numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets(
&numUDPInterfaces, streamingPort, streamingSrcIP,
streamingHwm);
dataStreamer[i]->SetAdditionalJsonHeader(
additionalJsonHeader);
} catch (...) {
if (dataStreamEnable) {
dataStreamer.clear();
@ -1061,8 +1157,9 @@ void Implementation::setDataStreamEnable(const bool enable) {
flip = (i == 1 ? true : false);
}
dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, flip,
numPorts, &quadEnable, &numberOfTotalFrames));
i, fifo[i].get(), &dynamicRange, &detectorRoi,
&fileIndex, flip, numPorts, &quadEnable,
&numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets(
&numUDPInterfaces, streamingPort, streamingSrcIP,
@ -1420,20 +1517,20 @@ void Implementation::setDynamicRange(const uint32_t i) {
LOG(logINFO) << "Dynamic Range: " << dynamicRange;
}
slsDetectorDefs::ROI Implementation::getROI() const { return roi; }
slsDetectorDefs::ROI Implementation::getROI() const { return detectorRoi; }
void Implementation::setROI(slsDetectorDefs::ROI arg) {
if (roi.xmin != arg.xmin || roi.xmax != arg.xmax) {
roi.xmin = arg.xmin;
roi.xmax = arg.xmax;
void Implementation::setDetectorROI(slsDetectorDefs::ROI arg) {
if (detectorRoi.xmin != arg.xmin || detectorRoi.xmax != arg.xmax) {
detectorRoi.xmin = arg.xmin;
detectorRoi.xmax = arg.xmax;
// only for gotthard
generalData->SetROI(arg);
generalData->SetDetectorROI(arg);
framesPerFile = generalData->maxFramesPerFile;
SetupFifoStructure();
}
LOG(logINFO) << "ROI: [" << roi.xmin << ", " << roi.xmax << "]";
LOG(logINFO) << "Detector ROI: " << sls::ToString(detectorRoi);
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
}
@ -1509,6 +1606,11 @@ bool Implementation::getActivate() const { return activated; }
void Implementation::setActivate(bool enable) {
activated = enable;
for (const auto &it : listener)
it->SetActivate(enable);
for (const auto &it : dataProcessor)
it->SetActivate(enable);
LOG(logINFO) << "Activation: " << (activated ? "enabled" : "disabled");
}

View File

@ -53,6 +53,9 @@ class Implementation : private virtual slsDetectorDefs {
bool getArping() const;
pid_t getArpingThreadId() const;
void setArping(const bool i, const std::vector<std::string> ips);
ROI getReceiverROI() const;
void setReceiverROI(const ROI arg);
void setReceiverROIMetadata(const ROI arg);
/**************************************************
* *
@ -204,7 +207,7 @@ class Implementation : private virtual slsDetectorDefs {
void setDynamicRange(const uint32_t i);
ROI getROI() const;
/* [Gotthard] */
void setROI(ROI arg);
void setDetectorROI(ROI arg);
bool getTenGigaEnable() const;
/* [Eiger][Ctb] */
void setTenGigaEnable(const bool b);
@ -253,7 +256,8 @@ class Implementation : private virtual slsDetectorDefs {
* *
* ************************************************/
/** params: file path, file name, file index, image size */
void registerCallBackStartAcquisition(int (*func)(const std::string &, const std::string &,
void registerCallBackStartAcquisition(int (*func)(const std::string &,
const std::string &,
uint64_t, size_t, void *),
void *arg);
/** params: total frames caught */
@ -263,7 +267,8 @@ class Implementation : private virtual slsDetectorDefs {
void registerCallBackRawDataReady(void (*func)(sls_receiver_header *,
char *, size_t, void *),
void *arg);
/** params: sls_receiver_header pointer, pointer to data, reference to image size */
/** params: sls_receiver_header pointer, pointer to data, reference to image
* size */
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header *,
char *, size_t &,
void *),
@ -274,7 +279,7 @@ class Implementation : private virtual slsDetectorDefs {
void SetThreadPriorities();
void SetupFifoStructure();
xy GetPortGeometry();
const xy GetPortGeometry() const;
void ResetParametersforNewAcquisition();
void CreateUDPSockets();
void SetupWriter();
@ -299,6 +304,10 @@ class Implementation : private virtual slsDetectorDefs {
bool framePadding{true};
pid_t parentThreadId;
pid_t tcpThreadId;
ROI receiverRoi{};
std::array<ROI, 2> portRois{};
// receiver roi for complete detector for metadata
ROI receiverRoiMetadata{};
// file parameters
fileFormat fileFormatType{BINARY};
@ -356,13 +365,14 @@ class Implementation : private virtual slsDetectorDefs {
uint32_t numberOfDigitalSamples{0};
uint32_t counterMask{0};
uint32_t dynamicRange{16};
ROI roi{};
ROI detectorRoi{};
bool tengigaEnable{false};
bool flipRows{false};
bool quadEnable{false};
bool activated{true};
std::array<bool, 2> detectorDataStream = {{true, true}};
std::array<bool, 2> detectorDataStream10GbE = {{true, true}};
std::array<bool, 2> portStream = {{true, true}};
int readNRows{0};
int thresholdEnergyeV{-1};
std::array<int, 3> thresholdAllEnergyeV = {{-1, -1, -1}};
@ -374,8 +384,8 @@ class Implementation : private virtual slsDetectorDefs {
int ctbDbitOffset{0};
// callbacks
int (*startAcquisitionCallBack)(const std::string &, const std::string &, uint64_t, size_t,
void *){nullptr};
int (*startAcquisitionCallBack)(const std::string &, const std::string &,
uint64_t, size_t, void *){nullptr};
void *pStartAcquisition{nullptr};
void (*acquisitionFinishedCallBack)(uint64_t, void *){nullptr};
void *pAcquisitionFinished{nullptr};

View File

@ -24,11 +24,11 @@ const std::string Listener::TypeName = "Listener";
Listener::Listener(int ind, detectorType dtype, Fifo *f,
std::atomic<runStatus> *s, uint32_t *portno, std::string *e,
int *us, int *as, uint32_t *fpf, frameDiscardPolicy *fdp,
bool *act, bool *detds, bool *sm)
bool *detds, bool *sm)
: ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype), status(s),
udpPortNumber(portno), eth(e), udpSocketBufferSize(us),
actualUDPSocketBufferSize(as), framesPerFile(fpf), frameDiscardMode(fdp),
activated(act), detectorDataStream(detds), silentMode(sm) {
detectorDataStream(detds), silentMode(sm) {
LOG(logDEBUG) << "Listener " << ind << " created";
}
@ -115,8 +115,10 @@ void Listener::RecordFirstIndex(uint64_t fnum) {
void Listener::SetGeneralData(GeneralData *g) { generalData = g; }
void Listener::SetActivate(bool enable) { activated = enable; }
void Listener::CreateUDPSockets() {
if (!(*activated) || !(*detectorDataStream)) {
if (!activated || !(*detectorDataStream)) {
return;
}
@ -166,7 +168,7 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int s) {
LOG(logINFO) << "Testing UDP Socket Buffer size " << s << " with test port "
<< *udpPortNumber;
if (!(*activated) || !(*detectorDataStream)) {
if (!activated || !(*detectorDataStream)) {
*actualUDPSocketBufferSize = (s * 2);
return;
}
@ -225,8 +227,7 @@ void Listener::ThreadExecution() {
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
// udpsocket doesnt exist
if (*activated && *detectorDataStream && !udpSocketAlive &&
!carryOverFlag) {
if (activated && *detectorDataStream && !udpSocketAlive && !carryOverFlag) {
// LOG(logERROR) << "Listening_Thread " << index << ": UDP Socket not
// created or shut down earlier";
(*((uint32_t *)buffer)) = 0;
@ -236,7 +237,7 @@ void Listener::ThreadExecution() {
// get data
if ((*status != TRANSMITTING &&
(!(*activated) || !(*detectorDataStream) || udpSocketAlive)) ||
(!activated || !(*detectorDataStream) || udpSocketAlive)) ||
carryOverFlag) {
rc = ListenToAnImage(buffer);
}
@ -319,7 +320,7 @@ uint32_t Listener::ListenToAnImage(char *buf) {
return 0;
}
// deactivated (eiger)
if (!(*activated)) {
if (!activated) {
return 0;
}

View File

@ -37,13 +37,12 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
* @param as pointer to actual udp socket buffer size
* @param fpf pointer to frames per file
* @param fdp frame discard policy
* @param act pointer to activated
* @param detds pointer to detector data stream
* @param sm pointer to silent mode
*/
Listener(int ind, detectorType dtype, Fifo *f, std::atomic<runStatus> *s,
uint32_t *portno, std::string *e, int *us, int *as, uint32_t *fpf,
frameDiscardPolicy *fdp, bool *act, bool *detds, bool *sm);
frameDiscardPolicy *fdp, bool *detds, bool *sm);
/**
* Destructor
@ -63,6 +62,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
void SetFifo(Fifo *f);
void ResetParametersforNewAcquisition();
void SetGeneralData(GeneralData *g);
void SetActivate(bool enable);
void CreateUDPSockets();
void ShutDownUDPSocket();
@ -76,8 +76,8 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
/**
* Set hard coded (calculated but not from detector) row and column
* r is in row index if detector has not send them yet in firmware,
* c is in col index for jungfrau and eiger (for missing packets/deactivated
* eiger) c when used is in 2d
* c is in col index for jungfrau and eiger (for missing
* packets/deactivated) c when used is in 2d
*/
void SetHardCodedPosition(uint16_t r, uint16_t c);
@ -125,7 +125,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
int *actualUDPSocketBufferSize;
uint32_t *framesPerFile;
frameDiscardPolicy *frameDiscardMode;
bool *activated;
bool activated{false};
bool *detectorDataStream;
bool *silentMode;
@ -135,7 +135,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
uint16_t row{0};
/** column hardcoded as 2D,
* deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/
* deactivated/missing packets (eiger/jungfrau sends 2d pos) **/
uint16_t column{0};
// acquisition start

View File

@ -109,6 +109,17 @@ void MasterAttributes::GetCommonBinaryAttributes(
w->String(sls::ToString(scanParams).c_str());
w->Key("Total Frames");
w->Uint64(totalFrames);
w->Key("Receiver Roi");
w->StartObject();
w->Key("xmin");
w->Uint(receiverRoi.xmin);
w->Key("xmax");
w->Uint(receiverRoi.xmax);
w->Key("ymin");
w->Uint(receiverRoi.ymin);
w->Key("ymax");
w->Uint(receiverRoi.ymax);
w->EndObject();
}
void MasterAttributes::GetFinalBinaryAttributes(
@ -274,6 +285,34 @@ void MasterAttributes::WriteCommonHDF5Attributes(H5File *fd, Group *group) {
PredType::STD_U64LE, dataspace);
dataset.write(&totalFrames, PredType::STD_U64LE);
}
// Receiver Roi xmin
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet("receiver roi xmin",
PredType::NATIVE_INT, dataspace);
dataset.write(&receiverRoi.xmin, PredType::NATIVE_INT);
}
// Receiver Roi xmax
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet("receiver roi xmax",
PredType::NATIVE_INT, dataspace);
dataset.write(&receiverRoi.xmax, PredType::NATIVE_INT);
}
// Receiver Roi ymin
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet("receiver roi ymin",
PredType::NATIVE_INT, dataspace);
dataset.write(&receiverRoi.ymin, PredType::NATIVE_INT);
}
// Receiver Roi ymax
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet("receiver roi ymax",
PredType::NATIVE_INT, dataspace);
dataset.write(&receiverRoi.ymax, PredType::NATIVE_INT);
}
}
void MasterAttributes::WriteFinalHDF5Attributes(H5File *fd, Group *group) {
@ -343,14 +382,14 @@ void MasterAttributes::WriteHDF5ROI(H5File *fd, Group *group) {
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group->createDataSet("roi xmin", PredType::NATIVE_INT, dataspace);
dataset.write(&roi.xmin, PredType::NATIVE_INT);
dataset.write(&detectorRoi.xmin, PredType::NATIVE_INT);
}
// Roi xmax
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group->createDataSet("roi xmax", PredType::NATIVE_INT, dataspace);
dataset.write(&roi.xmax, PredType::NATIVE_INT);
dataset.write(&detectorRoi.xmax, PredType::NATIVE_INT);
}
}
@ -533,8 +572,13 @@ void MasterAttributes::GetGotthardBinaryAttributes(
w->String(sls::ToString(exptime).c_str());
w->Key("Period");
w->String(sls::ToString(period).c_str());
w->Key("Roi (xmin, xmax)");
w->String(sls::ToString(roi).c_str());
w->Key("Detector Roi");
w->StartObject();
w->Key("xmin");
w->Uint(detectorRoi.xmin);
w->Key("xmax");
w->Uint(detectorRoi.xmax);
w->EndObject();
};
#ifdef HDF5C

View File

@ -7,8 +7,8 @@
#include "sls/logger.h"
#include "sls/sls_detector_defs.h"
#include <rapidjson/stringbuffer.h>
#include <rapidjson/prettywriter.h>
#include <rapidjson/stringbuffer.h>
#ifdef HDF5C
#include "H5Cpp.h"
@ -54,7 +54,8 @@ class MasterAttributes {
uint32_t digitalSamples{0};
uint32_t dbitoffset{0};
uint64_t dbitlist{0};
slsDetectorDefs::ROI roi{};
slsDetectorDefs::ROI detectorRoi{};
slsDetectorDefs::ROI receiverRoi{};
uint32_t counterMask{0};
std::array<ns, 3> exptimeArray{};
std::array<ns, 3> gateDelayArray{};
@ -65,15 +66,16 @@ class MasterAttributes {
MasterAttributes() = default;
~MasterAttributes() = default;
void GetBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void
GetBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteHDF5Attributes(H5File *fd, Group *group);
#endif
void
GetCommonBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void
GetFinalBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetCommonBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetFinalBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteCommonHDF5Attributes(H5File *fd, Group *group);
void WriteFinalHDF5Attributes(H5File *fd, Group *group);
@ -104,43 +106,44 @@ class MasterAttributes {
void WriteHDF5DbitList(H5File *fd, Group *group);
#endif
void
GetGotthardBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetGotthardBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteGotthardHDF5Attributes(H5File *fd, Group *group);
#endif
void
GetJungfrauBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetJungfrauBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteJungfrauHDF5Attributes(H5File *fd, Group *group);
#endif
void
GetEigerBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetEigerBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteEigerHDF5Attributes(H5File *fd, Group *group);
#endif
void
GetMythen3BinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetMythen3BinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteMythen3HDF5Attributes(H5File *fd, Group *group);
#endif
void
GetGotthard2BinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetGotthard2BinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteGotthard2HDF5Attributes(H5File *fd, Group *group);
#endif
void
GetMoenchBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void GetMoenchBinaryAttributes(
rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteMoenchHDF5Attributes(H5File *fd, Group *group);
#endif
void GetCtbBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
void
GetCtbBinaryAttributes(rapidjson::PrettyWriter<rapidjson::StringBuffer> *w);
#ifdef HDF5C
void WriteCtbHDF5Attributes(H5File *fd, Group *group);
#endif

View File

@ -17,8 +17,8 @@
// files
// versions
#define HDF5_WRITER_VERSION (6.4) // 1 decimal places
#define BINARY_WRITER_VERSION (7.0) // 1 decimal places
#define HDF5_WRITER_VERSION (6.5) // 1 decimal places
#define BINARY_WRITER_VERSION (7.1) // 1 decimal places
#define MAX_FRAMES_PER_FILE 20000
#define SHORT_MAX_FRAMES_PER_FILE 100000

View File

@ -49,9 +49,6 @@
// ctb/ moench 1g udp (read from fifo)
#define UDP_PACKET_DATA_BYTES (1344)
/** maximum rois */
#define MAX_ROIS 100
/** maximum trim en */
#define MAX_TRIMEN 100
@ -172,13 +169,38 @@ class slsDetectorDefs {
struct ROI {
int xmin{-1};
int xmax{-1};
int ymin{-1};
int ymax{-1};
ROI() = default;
ROI(int xmin, int xmax) : xmin(xmin), xmax(xmax){};
ROI(int xmin, int xmax, int ymin, int ymax)
: xmin(xmin), xmax(xmax), ymin(ymin), ymax(ymax){};
constexpr std::array<int, 4> getIntArray() const {
return std::array<int, 4> ({xmin, xmax, ymin, ymax});
}
constexpr bool completeRoi() const {
return (xmin == -1 && xmax == -1 && ymin == -1 && ymax == -1);
}
constexpr bool noRoi() const {
return (xmin == 0 && xmax == 0 && ymin == 0 && ymax == 0);
}
void setNoRoi() {
xmin = 0;
xmax = 0;
ymin = 0;
ymax = 0;
}
constexpr bool operator==(const ROI &other) const {
return ((xmin == other.xmin) && (xmax == other.xmax) &&
(ymin == other.ymin) && (ymax == other.ymax));
}
} __attribute__((packed));
#else
typedef struct {
int xmin;
int xmax;
int ymin;
int ymax;
} ROI;
#endif

View File

@ -279,7 +279,7 @@ enum detFuncs {
F_LOCK_RECEIVER,
F_GET_LAST_RECEIVER_CLIENT_IP,
F_GET_RECEIVER_VERSION,
F_RECEIVER_SET_ROI,
F_RECEIVER_SET_DETECTOR_ROI,
F_RECEIVER_SET_NUM_FRAMES,
F_SET_RECEIVER_NUM_TRIGGERS,
F_SET_RECEIVER_NUM_BURSTS,
@ -375,6 +375,9 @@ enum detFuncs {
F_RECEIVER_SET_DATASTREAM,
F_GET_RECEIVER_ARPING,
F_SET_RECEIVER_ARPING,
F_RECEIVER_GET_RECEIVER_ROI,
F_RECEIVER_SET_RECEIVER_ROI,
F_RECEIVER_SET_RECEIVER_ROI_METADATA,
NUM_REC_FUNCTIONS
};
@ -652,7 +655,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER";
case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP";
case F_GET_RECEIVER_VERSION: return "F_GET_RECEIVER_VERSION";
case F_RECEIVER_SET_ROI: return "F_RECEIVER_SET_ROI";
case F_RECEIVER_SET_DETECTOR_ROI: return "F_RECEIVER_SET_DETECTOR_ROI";
case F_RECEIVER_SET_NUM_FRAMES: return "F_RECEIVER_SET_NUM_FRAMES";
case F_SET_RECEIVER_NUM_TRIGGERS: return "F_SET_RECEIVER_NUM_TRIGGERS";
case F_SET_RECEIVER_NUM_BURSTS: return "F_SET_RECEIVER_NUM_BURSTS";
@ -748,6 +751,9 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_RECEIVER_SET_DATASTREAM: return "F_RECEIVER_SET_DATASTREAM";
case F_GET_RECEIVER_ARPING: return "F_GET_RECEIVER_ARPING";
case F_SET_RECEIVER_ARPING: return "F_SET_RECEIVER_ARPING";
case F_RECEIVER_GET_RECEIVER_ROI: return "F_RECEIVER_GET_RECEIVER_ROI";
case F_RECEIVER_SET_RECEIVER_ROI: return "F_RECEIVER_SET_RECEIVER_ROI";
case F_RECEIVER_SET_RECEIVER_ROI_METADATA: return "F_RECEIVER_SET_RECEIVER_ROI_METADATA";
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function";

View File

@ -5,11 +5,10 @@
#define APILIB 0x220408
#define APIRECEIVER 0x220408
#define APIGUI 0x220328
#define APICTB 0x220428
#define APIGOTTHARD 0x220428
#define APIGOTTHARD2 0x220428
#define APIJUNGFRAU 0x220428
#define APIMOENCH 0x220427
#define APIEIGER 0x220428
#define APIMYTHEN3 0x220510
#define APICTB 0x220516
#define APIGOTTHARD 0x220516
#define APIGOTTHARD2 0x220516
#define APIJUNGFRAU 0x220516
#define APIMYTHEN3 0x220516
#define APIMOENCH 0x220503
#define APIEIGER 0x220516

View File

@ -31,8 +31,10 @@ ServerSocket::ServerSocket(int port)
if (bind(getSocketId(), (struct sockaddr *)&serverAddr,
sizeof(serverAddr)) != 0) {
close();
throw sls::SocketError("Server ERROR: cannot bind socket. Please check "
"if another instance is running.");
throw sls::SocketError(
std::string("Server ERROR: cannot bind socket with port number ") +
std::to_string(port) +
std::string(". Please check if another instance is running."));
}
if (listen(getSocketId(), DEFAULT_BACKLOG) != 0) {
close();

View File

@ -17,7 +17,11 @@ std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord) {
std::string ToString(const slsDetectorDefs::ROI &roi) {
std::ostringstream oss;
oss << '[' << roi.xmin << ", " << roi.xmax << ']';
oss << '[' << roi.xmin << ", " << roi.xmax;
if (roi.ymin != -1 || roi.ymax != -1) {
oss << ", " << roi.ymin << ", " << roi.ymax;
}
oss << ']';
return oss.str();
}

View File

@ -131,82 +131,57 @@ int ZmqSocket::Connect() {
}
int ZmqSocket::SendHeader(int index, zmqHeader header) {
std::ostringstream oss;
oss << "{\"jsonversion\":" << header.jsonversion
<< ", \"bitmode\":" << header.dynamicRange
<< ", \"fileIndex\":" << header.fileIndex << ", \"detshape\":["
<< header.ndetx << ", " << header.ndety << ']' << ", \"shape\":["
<< header.npixelsx << ", " << header.npixelsy << ']'
<< ", \"size\":" << header.imageSize
<< ", \"acqIndex\":" << header.acqIndex
<< ", \"frameIndex\":" << header.frameIndex
<< ", \"progress\":" << header.progress << ", \"fname\":\""
<< header.fname << '\"' << ", \"data\":" << (header.data ? 1 : 0)
<< ", \"completeImage\":" << (header.completeImage ? 1 : 0)
/** Json Header Format */
const char jsonHeaderFormat[] = "{"
"\"jsonversion\":%u, "
"\"bitmode\":%u, "
"\"fileIndex\":%lu, "
"\"detshape\":[%u, %u], "
"\"shape\":[%u, %u], "
"\"size\":%u, "
"\"acqIndex\":%lu, "
"\"frameIndex\":%lu, "
"\"progress\":%lf, "
"\"fname\":\"%s\", "
"\"data\": %d, "
"\"completeImage\": %d, "
"\"frameNumber\":%lu, "
"\"expLength\":%u, "
"\"packetNumber\":%u, "
"\"bunchId\":%lu, "
"\"timestamp\":%lu, "
"\"modId\":%u, "
"\"row\":%u, "
"\"column\":%u, "
"\"reserved\":%u, "
"\"debug\":%u, "
"\"roundRNumber\":%u, "
"\"detType\":%u, "
"\"version\":%u, "
<< ", \"frameNumber\":" << header.frameNumber
<< ", \"expLength\":" << header.expLength
<< ", \"packetNumber\":" << header.packetNumber
<< ", \"bunchId\":" << header.bunchId
<< ", \"timestamp\":" << header.timestamp
<< ", \"modId\":" << header.modId << ", \"row\":" << header.row
<< ", \"column\":" << header.column
<< ", \"reserved\":" << header.reserved
<< ", \"debug\":" << header.debug
<< ", \"roundRNumber\":" << header.roundRNumber
<< ", \"detType\":" << static_cast<int>(header.detType)
<< ", \"version\":"
<< static_cast<int>(header.version)
// additional stuff
"\"flipRows\":%u, "
"\"quad\":%u"
; //"}\n";
memset(header_buffer.get(), '\0', MAX_STR_LENGTH); // TODO! Do we need this
sprintf(header_buffer.get(), jsonHeaderFormat, header.jsonversion,
header.dynamicRange, header.fileIndex, header.ndetx, header.ndety,
header.npixelsx, header.npixelsy, header.imageSize, header.acqIndex,
header.frameIndex, header.progress, header.fname.c_str(),
header.data ? 1 : 0, header.completeImage ? 1 : 0,
header.frameNumber, header.expLength, header.packetNumber,
header.bunchId, header.timestamp, header.modId, header.row,
header.column, header.reserved, header.debug, header.roundRNumber,
header.detType, header.version,
// additional stuff
header.flipRows, header.quad);
<< ", \"flipRows\":" << header.flipRows << ", \"quad\":" << header.quad;
if (!header.addJsonHeader.empty()) {
strcat(header_buffer.get(), ", ");
strcat(header_buffer.get(), "\"addJsonHeader\": {");
oss << ", \"addJsonHeader\": {";
for (auto it = header.addJsonHeader.begin();
it != header.addJsonHeader.end(); ++it) {
if (it != header.addJsonHeader.begin()) {
strcat(header_buffer.get(), ", ");
oss << ", ";
}
strcat(header_buffer.get(), "\"");
strcat(header_buffer.get(), it->first.c_str());
strcat(header_buffer.get(), "\":\"");
strcat(header_buffer.get(), it->second.c_str());
strcat(header_buffer.get(), "\"");
oss << "\"" << it->first.c_str() << "\":\"" << it->second.c_str()
<< "\"";
}
strcat(header_buffer.get(), " } ");
oss << " } ";
}
strcat(header_buffer.get(), "}\n");
int length = strlen(header_buffer.get());
#ifdef VERBOSE
oss << "}\n";
std::string message = oss.str();
int length = message.length();
#ifdef ZMQ_DETAIL
// if(!index)
cprintf(BLUE, "%d : Streamer: buf: %s\n", index, buf);
LOG(logINFOBLUE) << index << " : Streamer: buf: " << message;
#endif
if (zmq_send(sockfd.socketDescriptor, header_buffer.get(), length,
if (zmq_send(sockfd.socketDescriptor, message.c_str(), length,
header.data ? ZMQ_SNDMORE : 0) < 0) {
PrintError();
return 0;
@ -232,13 +207,13 @@ int ZmqSocket::ReceiveHeader(const int index, zmqHeader &zHeader,
if (bytes_received > 0) {
#ifdef ZMQ_DETAIL
cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno,
bytes_received, buffer.data());
bytes_received, header_buffer.get());
#endif
if (ParseHeader(index, bytes_received, header_buffer.get(), zHeader,
version)) {
#ifdef ZMQ_DETAIL
cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index,
portno, bytes_received, buffer.data());
portno, bytes_received, header_buffer.get());
#endif
if (!zHeader.data) {
#ifdef ZMQ_DETAIL
@ -333,7 +308,7 @@ int ZmqSocket::ReceiveData(const int index, char *buf, const int size) {
memset(buf + length, 0xFF, size - length);
} else {
LOG(logERROR) << "Received weird packet size " << length
<< " for socket " << index;
<< " (expected " << size << ") for socket " << index;
memset(buf, 0xFF, size);
}

View File

@ -227,14 +227,19 @@ TEST_CASE("Detector type") {
TEST_CASE("Formatting slsDetectorDefs::ROI") {
slsDetectorDefs::ROI roi(5, 159);
REQUIRE(ToString(roi) == "[5, 159]");
slsDetectorDefs::ROI roi1(5, 159, 6, 170);
REQUIRE(ToString(roi1) == "[5, 159, 6, 170]");
}
TEST_CASE("Streaming of slsDetectorDefs::ROI") {
using namespace sls;
slsDetectorDefs::ROI roi(-10, 1);
std::ostringstream oss;
std::ostringstream oss, oss1;
oss << roi;
REQUIRE(oss.str() == "[-10, 1]");
slsDetectorDefs::ROI roi1(-10, 1, 5, 11);
oss1 << roi1;
REQUIRE(oss1.str() == "[-10, 1, 5, 11]");
}
TEST_CASE("std::array") {