mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-20 02:40:03 +02:00
Gappixels (#89)
* WIP * WIP virtual delays, imagetest for saturation * WIP, vertical and horizontal * WIP * gap pixels work, fixed 32 bit data out (10gbe=0) for virtual servers * quad works (also in virtual), handling gappixels and quad * jungfrau gapppixels work * jungfrau: done * complete image or missing packets given in json header and gui * eiger virtual 4 bit mode bug fix * working version of zmq add json header, except printout * printout bug * fix for json para * to map WIP * map done * map print , mapwith result left * json result works, testing added * updated server binaries * compiling on rhels7, variable size char array iniitalization * zmqsocket parsing didnt need Document * const to map, json para is strings not map * json add header: mapping cleaner without insert make_pair
This commit is contained in:
parent
6a6af528ef
commit
d58eb1dc6e
@ -55,6 +55,149 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblCompleteImage">
|
||||
<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>0</red>
|
||||
<green>150</green>
|
||||
<blue>110</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>0</red>
|
||||
<green>150</green>
|
||||
<blue>110</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>Complete Image</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<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="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>117</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<widget class="QWidget" name="widgetStatistics" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -241,7 +384,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>376</width>
|
||||
<height>28</height>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuSave">
|
||||
|
@ -19,47 +19,8 @@
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="layout">
|
||||
<property name="margin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<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>false</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="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QWidget" name="widgetStatistics" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -86,73 +47,6 @@
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="6">
|
||||
<widget class="QLabel" name="lblSum">
|
||||
<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>40</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sum: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblMinDisp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="lblMaxDisp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="lblMax">
|
||||
<property name="sizePolicy">
|
||||
@ -181,8 +75,8 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="lblSumDisp">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblMinDisp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@ -194,6 +88,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblMin">
|
||||
<property name="sizePolicy">
|
||||
@ -222,6 +129,32 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="lblMaxDisp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="lblSumDisp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
@ -235,9 +168,213 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<widget class="QLabel" name="lblSum">
|
||||
<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>40</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sum: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>419</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</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">
|
||||
<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>0</red>
|
||||
<green>150</green>
|
||||
<blue>110</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>0</red>
|
||||
<green>150</green>
|
||||
<blue>110</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>Complete Image</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
@ -14,7 +14,7 @@ class qCloneWidget : public QMainWindow, private Ui::ClonePlotObject {
|
||||
qCloneWidget(QWidget *parent, SlsQt1DPlot *p1, SlsQt2DPlot *p2,
|
||||
SlsQt1DPlot *gp1, SlsQt2DPlot *gp, QString title,
|
||||
QString filePath, QString fileName, int64_t aIndex,
|
||||
bool displayStats, QString min, QString max, QString sum);
|
||||
bool displayStats, QString min, QString max, QString sum, bool completeImage);
|
||||
|
||||
~qCloneWidget();
|
||||
|
||||
|
@ -114,6 +114,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
|
||||
QString zTitle2d{"Intensity"};
|
||||
QString plotTitle{""};
|
||||
QString indexTitle{""};
|
||||
bool completeImage{false};
|
||||
bool xyRangeChanged{false};
|
||||
double xyRange[4]{0, 0, 0, 0};
|
||||
bool isXYRange[4]{false, false, false, false};
|
||||
|
@ -15,13 +15,20 @@ qCloneWidget::qCloneWidget(QWidget *parent, SlsQt1DPlot *p1, SlsQt2DPlot *p2,
|
||||
SlsQt1DPlot *gp1, SlsQt2DPlot *gp, QString title,
|
||||
QString fPath, QString fName, int64_t aIndex,
|
||||
bool displayStats, QString min, QString max,
|
||||
QString sum)
|
||||
QString sum, bool completeImage)
|
||||
: QMainWindow(parent), plot1d(p1), plot2d(p2), gainplot1d(gp1),
|
||||
gainplot2d(gp), filePath(fPath), fileName(fName), acqIndex(aIndex) {
|
||||
setupUi(this);
|
||||
id = qCloneWidget::NumClones++;
|
||||
SetupWidgetWindow(title);
|
||||
DisplayStats(displayStats, min, max, sum);
|
||||
lblCompleteImage->hide();
|
||||
lblInCompleteImage->hide();
|
||||
if (completeImage) {
|
||||
lblCompleteImage->show();
|
||||
} else {
|
||||
lblInCompleteImage->show();
|
||||
}
|
||||
}
|
||||
|
||||
qCloneWidget::~qCloneWidget() {
|
||||
|
@ -97,27 +97,13 @@ void qDrawPlot::SetupPlots() {
|
||||
slsDetectorDefs::xy res = det->getDetectorSize();
|
||||
nPixelsX = res.x;
|
||||
nPixelsY = res.y;
|
||||
switch (detType) {
|
||||
case slsDetectorDefs::EIGER:
|
||||
try {
|
||||
if (det->getQuad().tsquash("Inconsistent values for quad type")) {
|
||||
nPixelsX /= 2;
|
||||
nPixelsY *= 2;
|
||||
if (nPixelsX != nPixelsY) {
|
||||
--nPixelsX;
|
||||
}
|
||||
}
|
||||
}
|
||||
CATCH_DISPLAY("Could not get quad.", "qDrawPlot::SetupPlots")
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
LOG(logINFO) << "nPixelsX:" << nPixelsX;
|
||||
LOG(logINFO) << "nPixelsY:" << nPixelsY;
|
||||
|
||||
boxPlot->setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
||||
widgetStatistics->hide();
|
||||
lblCompleteImage->hide();
|
||||
lblInCompleteImage->hide();
|
||||
|
||||
// setup 1d data
|
||||
|
||||
@ -586,7 +572,7 @@ void qDrawPlot::ClonePlot() {
|
||||
clonegainplot2D, boxPlot->title(), fileSavePath,
|
||||
fileSaveName, currentAcqIndex, displayStatistics,
|
||||
lblMinDisp->text(), lblMaxDisp->text(),
|
||||
lblSumDisp->text());
|
||||
lblSumDisp->text(), completeImage);
|
||||
}
|
||||
|
||||
void qDrawPlot::SavePlot() {
|
||||
@ -756,6 +742,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
|
||||
<< " ]";
|
||||
|
||||
progress = (int)data->progressIndex;
|
||||
@ -776,6 +763,11 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
|
||||
delete[] data2d;
|
||||
data2d = new double[nPixelsY * nPixelsX];
|
||||
std::fill(data2d, data2d + nPixelsX * nPixelsY, 0);
|
||||
if (gainData) {
|
||||
delete[] gainData;
|
||||
gainData = new double[nPixelsY * nPixelsX];
|
||||
std::fill(gainData, gainData + nPixelsX * nPixelsY, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// convert data to double
|
||||
@ -798,6 +790,7 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
|
||||
if ((int)subFrameIndex != -1) {
|
||||
indexTitle = QString("%1 %2").arg(frameIndex, subFrameIndex);
|
||||
}
|
||||
completeImage = data->completeImage;
|
||||
|
||||
// reset pedestal
|
||||
if (resetPedestal) {
|
||||
@ -1118,6 +1111,16 @@ void qDrawPlot::UpdatePlot() {
|
||||
LOG(logDEBUG) << "Update Plot";
|
||||
|
||||
boxPlot->setTitle(plotTitle);
|
||||
|
||||
// notify of incomplete images
|
||||
lblCompleteImage->hide();
|
||||
lblInCompleteImage->hide();
|
||||
if(completeImage) {
|
||||
lblCompleteImage->show();
|
||||
} else {
|
||||
lblInCompleteImage->show();
|
||||
}
|
||||
|
||||
if (is1d) {
|
||||
Update1dPlot();
|
||||
} else {
|
||||
|
@ -64,6 +64,7 @@ void qTabPlot::SetupWidgetWindow() {
|
||||
chkGapPixels->setEnabled(true);
|
||||
break;
|
||||
case slsDetectorDefs::JUNGFRAU:
|
||||
chkGapPixels->setEnabled(true);
|
||||
chkGainPlot->setEnabled(true);
|
||||
chkGainPlot->setChecked(true);
|
||||
plot->EnableGainPlot(true);
|
||||
@ -312,8 +313,7 @@ void qTabPlot::GetGapPixels() {
|
||||
disconnect(chkGapPixels, SIGNAL(toggled(bool)), this,
|
||||
SLOT(SetGapPixels(bool)));
|
||||
try {
|
||||
auto retval = det->getRxAddGapPixels().tsquash(
|
||||
"Inconsistent gap pixels enabled for all detectors.");
|
||||
auto retval = det->getGapPixelsinCallback();
|
||||
chkGapPixels->setChecked(retval);
|
||||
}
|
||||
CATCH_DISPLAY("Could not get gap pixels enable.", "qTabPlot::GetGapPixels")
|
||||
@ -324,7 +324,7 @@ void qTabPlot::GetGapPixels() {
|
||||
void qTabPlot::SetGapPixels(bool enable) {
|
||||
LOG(logINFO) << "Setting Gap Pixels Enable to " << enable;
|
||||
try {
|
||||
det->setRxAddGapPixels(enable);
|
||||
det->setGapPixelsinCallback(enable);
|
||||
}
|
||||
CATCH_HANDLE("Could not set gap pixels enable.", "qTabPlot::SetGapPixels",
|
||||
this, &qTabPlot::GetGapPixels)
|
||||
@ -672,6 +672,8 @@ void qTabPlot::Refresh() {
|
||||
break;
|
||||
case slsDetectorDefs::JUNGFRAU:
|
||||
chkGainPlot->setEnabled(true);
|
||||
chkGapPixels->setEnabled(true);
|
||||
GetGapPixels();
|
||||
break;
|
||||
case slsDetectorDefs::GOTTHARD2:
|
||||
chkGainPlot1D->setEnabled(true);
|
||||
|
Binary file not shown.
@ -22,7 +22,7 @@ target_include_directories(eigerDetectorServerMaster_virtual
|
||||
|
||||
target_compile_definitions(eigerDetectorServerMaster_virtual
|
||||
PUBLIC EIGERD PCCOMPILE STOP_SERVER
|
||||
PUBLIC VIRTUAL DVIRTUAL_9M
|
||||
PUBLIC VIRTUAL #VIRTUAL_9M
|
||||
PUBLIC VIRTUAL_MASTER
|
||||
)
|
||||
|
||||
@ -38,27 +38,60 @@ install(TARGETS eigerDetectorServerMaster_virtual
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
add_executable(eigerDetectorServerSlave_virtual
|
||||
|
||||
|
||||
|
||||
|
||||
add_executable(eigerDetectorServerSlaveTop_virtual
|
||||
${src}
|
||||
)
|
||||
|
||||
target_include_directories(eigerDetectorServerSlave_virtual
|
||||
target_include_directories(eigerDetectorServerSlaveTop_virtual
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(eigerDetectorServerSlave_virtual
|
||||
target_compile_definitions(eigerDetectorServerSlaveTop_virtual
|
||||
PUBLIC EIGERD PCCOMPILE STOP_SERVER
|
||||
PUBLIC VIRTUAL DVIRTUAL_9M
|
||||
PUBLIC VIRTUAL #VIRTUAL_9M
|
||||
PUBLIC VIRTUAL_TOP
|
||||
)
|
||||
|
||||
target_link_libraries(eigerDetectorServerSlave_virtual
|
||||
target_link_libraries(eigerDetectorServerSlaveTop_virtual
|
||||
PUBLIC pthread rt
|
||||
)
|
||||
|
||||
set_target_properties(eigerDetectorServerSlave_virtual PROPERTIES
|
||||
set_target_properties(eigerDetectorServerSlaveTop_virtual PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
|
||||
install(TARGETS eigerDetectorServerSlave_virtual
|
||||
install(TARGETS eigerDetectorServerSlaveTop_virtual
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
add_executable(eigerDetectorServerSlaveBottom_virtual
|
||||
${src}
|
||||
)
|
||||
|
||||
target_include_directories(eigerDetectorServerSlaveBottom_virtual
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(eigerDetectorServerSlaveBottom_virtual
|
||||
PUBLIC EIGERD PCCOMPILE STOP_SERVER
|
||||
PUBLIC VIRTUAL #VIRTUAL_9M
|
||||
)
|
||||
|
||||
target_link_libraries(eigerDetectorServerSlaveBottom_virtual
|
||||
PUBLIC pthread rt
|
||||
)
|
||||
|
||||
set_target_properties(eigerDetectorServerSlaveBottom_virtual PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
|
||||
install(TARGETS eigerDetectorServerSlaveBottom_virtual
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
Binary file not shown.
@ -20,6 +20,7 @@
|
||||
// Global variable from slsDetectorServer_funcs
|
||||
extern int debugflag;
|
||||
extern udpStruct udpDetails;
|
||||
extern const enum detectorType myDetectorType;
|
||||
|
||||
// Global variable from communication_funcs.c
|
||||
extern int isControlServer;
|
||||
@ -88,6 +89,8 @@ pthread_t eiger_virtual_tid;
|
||||
int eiger_virtual_stop = 0;
|
||||
uint64_t eiger_virtual_startingframenumber = 0;
|
||||
int eiger_virtual_detPos[2] = {0, 0};
|
||||
int eiger_virtual_test_mode = 0;
|
||||
int eiger_virtual_quad_mode = 0;
|
||||
#endif
|
||||
|
||||
|
||||
@ -179,8 +182,23 @@ void basictests() {
|
||||
LOG(logINFO, ("Compatibility - success\n"));
|
||||
}
|
||||
|
||||
#ifdef VIRTUAL
|
||||
void setTestImageMode(int ival) {
|
||||
if (ival >= 0) {
|
||||
if (ival == 0) {
|
||||
LOG(logINFO, ("Switching off Image Test Mode\n"));
|
||||
eiger_virtual_test_mode = 0;
|
||||
} else {
|
||||
LOG(logINFO, ("Switching on Image Test Mode\n"));
|
||||
eiger_virtual_test_mode = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int getTestImageMode() {
|
||||
return eiger_virtual_test_mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Ids */
|
||||
@ -361,7 +379,11 @@ void getModuleConfiguration() {
|
||||
top = 1;
|
||||
#else
|
||||
master = 0;
|
||||
#ifdef VIRTUAL_TOP
|
||||
top = 1;
|
||||
#else
|
||||
top = 0;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef VIRTUAL_9M
|
||||
normal = 0;
|
||||
@ -1291,13 +1313,15 @@ int setQuad(int value) {
|
||||
if (!Feb_Control_SetQuad(value)) {
|
||||
return FAIL;
|
||||
}
|
||||
#else
|
||||
eiger_virtual_quad_mode = value;
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getQuad() {
|
||||
#ifdef VIRTUAL
|
||||
return 0;
|
||||
return eiger_virtual_quad_mode;
|
||||
#else
|
||||
return Beb_GetQuad();
|
||||
#endif
|
||||
@ -1779,95 +1803,144 @@ void* start_timer(void* arg) {
|
||||
int numPacketsPerFrame = (tgEnable ? 4 : 16) * dr;
|
||||
int npixelsx = 256 * 2 * bytesPerPixel;
|
||||
int databytes = 256 * 256 * 2 * bytesPerPixel;
|
||||
LOG(logINFO, (" dr:%f\n bytesperpixel:%d\n tgenable:%d\n datasize:%d\n packetsize:%d\n numpackes:%d\n npixelsx:%d\n databytes:%d\n",
|
||||
dr, bytesPerPixel, tgEnable, datasize, packetsize, numPacketsPerFrame, npixelsx, databytes));
|
||||
int row = eiger_virtual_detPos[0];
|
||||
int colLeft = top ? eiger_virtual_detPos[1] : eiger_virtual_detPos[1] + 1;
|
||||
int colRight = top ? eiger_virtual_detPos[1] + 1 : eiger_virtual_detPos[1];
|
||||
int ntotpixels = 256 * 256 * 4;
|
||||
|
||||
LOG(logINFO, (" dr:%d\n bytesperpixel:%f\n tgenable:%d\n datasize:%d\n packetsize:%d\n numpackes:%d\n npixelsx:%d\n databytes:%d\n ntotpixels:%d\n",
|
||||
dr, bytesPerPixel, tgEnable, datasize, packetsize, numPacketsPerFrame, npixelsx, databytes, ntotpixels));
|
||||
|
||||
//TODO: Generate data
|
||||
char imageData[databytes * 2];
|
||||
memset(imageData, 0, databytes * 2);
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < databytes * 2; i += sizeof(uint8_t)) {
|
||||
*((uint8_t*)(imageData + i)) = i;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Send data
|
||||
{
|
||||
int frameNr = 1;
|
||||
for(frameNr=1; frameNr <= numFrames; ++frameNr ) {
|
||||
|
||||
//check if virtual_stop is high
|
||||
if(eiger_virtual_stop == 1){
|
||||
break;
|
||||
//TODO: Generate data
|
||||
char imageData[databytes * 2];
|
||||
memset(imageData, 0, databytes * 2);
|
||||
{
|
||||
int i = 0;
|
||||
switch (dr) {
|
||||
case 4:
|
||||
for (i = 0; i < ntotpixels/2; ++i) {
|
||||
*((uint8_t*)(imageData + i)) = eiger_virtual_test_mode ? 0xEE : (uint8_t)(((2 * i & 0xF) << 4) | ((2 * i + 1) & 0xF));
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
for (i = 0; i < ntotpixels; ++i) {
|
||||
*((uint8_t*)(imageData + i)) = eiger_virtual_test_mode ? 0xFE : (uint8_t)i;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
for (i = 0; i < ntotpixels; ++i) {
|
||||
*((uint16_t*)(imageData + i * sizeof(uint16_t))) = eiger_virtual_test_mode ? 0xFFE : (uint16_t)i;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
for (i = 0; i < ntotpixels; ++i) {
|
||||
*((uint32_t*)(imageData + i * sizeof(uint32_t))) = eiger_virtual_test_mode ? 0xFFFFFE : (uint32_t)i;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int srcOffset = 0;
|
||||
int srcOffset2 = npixelsx;
|
||||
//TODO: Send data
|
||||
{
|
||||
int frameNr = 1;
|
||||
for(frameNr=1; frameNr <= numFrames; ++frameNr ) {
|
||||
|
||||
struct timespec begin, end;
|
||||
clock_gettime(CLOCK_REALTIME, &begin);
|
||||
usleep(exp_us);
|
||||
char packetData[packetsize];
|
||||
memset(packetData, 0, packetsize);
|
||||
char packetData2[packetsize];
|
||||
memset(packetData2, 0, packetsize);
|
||||
usleep(eiger_virtual_transmission_delay_frame);
|
||||
|
||||
// loop packet
|
||||
{
|
||||
int i = 0;
|
||||
for(i = 0; i != numPacketsPerFrame; ++i) {
|
||||
int dstOffset = sizeof(sls_detector_header);
|
||||
int dstOffset2 = sizeof(sls_detector_header);
|
||||
// set header
|
||||
sls_detector_header* header = (sls_detector_header*)(packetData);
|
||||
header->frameNumber = frameNr;
|
||||
header->packetNumber = i;
|
||||
header = (sls_detector_header*)(packetData2);
|
||||
header->frameNumber = frameNr;
|
||||
header->packetNumber = i;
|
||||
//check if virtual_stop is high
|
||||
if(eiger_virtual_stop == 1){
|
||||
break;
|
||||
}
|
||||
|
||||
// fill data
|
||||
{
|
||||
int psize = 0;
|
||||
for (psize = 0; psize < datasize; psize += npixelsx) {
|
||||
int srcOffset = 0;
|
||||
int srcOffset2 = npixelsx;
|
||||
|
||||
if (dr == 32 && tgEnable == 0) {
|
||||
memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx/2);
|
||||
memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx/2);
|
||||
struct timespec begin, end;
|
||||
clock_gettime(CLOCK_REALTIME, &begin);
|
||||
usleep(exp_us);
|
||||
char packetData[packetsize];
|
||||
memset(packetData, 0, packetsize);
|
||||
char packetData2[packetsize];
|
||||
memset(packetData2, 0, packetsize);
|
||||
|
||||
// loop packet
|
||||
{
|
||||
int i = 0;
|
||||
for(i = 0; i != numPacketsPerFrame; ++i) {
|
||||
int dstOffset = sizeof(sls_detector_header);
|
||||
int dstOffset2 = sizeof(sls_detector_header);
|
||||
// set header
|
||||
sls_detector_header* header = (sls_detector_header*)(packetData);
|
||||
header->detType = 3;//(uint16_t)myDetectorType; updated when firmware updates
|
||||
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
|
||||
header->frameNumber = frameNr;
|
||||
header->packetNumber = i;
|
||||
header->row = row;
|
||||
header->column = colLeft;
|
||||
|
||||
header = (sls_detector_header*)(packetData2);
|
||||
header->detType = (uint16_t)myDetectorType;
|
||||
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
|
||||
header->frameNumber = frameNr;
|
||||
header->packetNumber = i;
|
||||
header->row = row;
|
||||
header->column = colRight;
|
||||
if (eiger_virtual_quad_mode) {
|
||||
header->row = 1; // right is next row
|
||||
header->column = 0; // right same first column
|
||||
}
|
||||
|
||||
// fill data
|
||||
{
|
||||
int psize = 0;
|
||||
for (psize = 0; psize < datasize; psize += npixelsx) {
|
||||
|
||||
if (dr == 32 && tgEnable == 0) {
|
||||
memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx/2);
|
||||
memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx/2);
|
||||
if (srcOffset % npixelsx == 0) {
|
||||
srcOffset += npixelsx/2;
|
||||
srcOffset2 += npixelsx/2;
|
||||
}
|
||||
// skip the other half (2 packets in 1 line for 32 bit)
|
||||
else {
|
||||
srcOffset += npixelsx;
|
||||
srcOffset2 += npixelsx;
|
||||
dstOffset += npixelsx/2;
|
||||
dstOffset2 += npixelsx/2;
|
||||
} else {
|
||||
memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx);
|
||||
memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx);
|
||||
srcOffset += 2 * npixelsx;
|
||||
srcOffset2 += 2 * npixelsx;
|
||||
dstOffset += npixelsx;
|
||||
dstOffset2 += npixelsx;
|
||||
}
|
||||
dstOffset += npixelsx/2;
|
||||
dstOffset2 += npixelsx/2;
|
||||
} else {
|
||||
memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx);
|
||||
memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx);
|
||||
srcOffset += 2 * npixelsx;
|
||||
srcOffset2 += 2 * npixelsx;
|
||||
dstOffset += npixelsx;
|
||||
dstOffset2 += npixelsx;
|
||||
}
|
||||
}
|
||||
|
||||
sendUDPPacket(0, packetData, packetsize);
|
||||
sendUDPPacket(1, packetData2, packetsize);
|
||||
}
|
||||
usleep(eiger_virtual_transmission_delay_left);
|
||||
sendUDPPacket(0, packetData, packetsize);
|
||||
usleep(eiger_virtual_transmission_delay_right);
|
||||
sendUDPPacket(1, packetData2, packetsize);
|
||||
}
|
||||
LOG(logINFO, ("Sent frame: %d\n", frameNr));
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 +
|
||||
(end.tv_nsec - begin.tv_nsec));
|
||||
}
|
||||
LOG(logINFO, ("Sent frame: %d\n", frameNr));
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 +
|
||||
(end.tv_nsec - begin.tv_nsec));
|
||||
|
||||
// sleep for (period - exptime)
|
||||
if (frameNr < numFrames) { // if there is a next frame
|
||||
if (periodns > time_ns) {
|
||||
usleep((periodns - time_ns)/ 1000);
|
||||
}
|
||||
// sleep for (period - exptime)
|
||||
if (frameNr < numFrames) { // if there is a next frame
|
||||
if (periodns > time_ns) {
|
||||
usleep((periodns - time_ns)/ 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
closeUDPSocket(0);
|
||||
closeUDPSocket(1);
|
||||
|
Binary file not shown.
Binary file not shown.
@ -239,10 +239,10 @@ void setTestImageMode(int ival) {
|
||||
uint32_t addr = MULTI_PURPOSE_REG;
|
||||
if (ival >= 0) {
|
||||
if (ival == 0) {
|
||||
LOG(logINFO, ("Switching on Image Test Mode\n"));
|
||||
LOG(logINFO, ("Switching off Image Test Mode\n"));
|
||||
bus_w (addr, bus_r(addr) & ~DGTL_TST_MSK);
|
||||
} else {
|
||||
LOG(logINFO, ("Switching off Image Test Mode\n"));
|
||||
LOG(logINFO, ("Switching on Image Test Mode\n"));
|
||||
bus_w (addr, bus_r(addr) | DGTL_TST_MSK);
|
||||
}
|
||||
}
|
||||
@ -915,8 +915,9 @@ int getModule(sls_detector_module *myMod){
|
||||
if (dacValues[idac] >= 0)
|
||||
initialized = 1;
|
||||
}
|
||||
if (initialized)
|
||||
if (initialized) {
|
||||
return OK;
|
||||
}
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -31,6 +31,7 @@ char initErrorMessage[MAX_STR_LENGTH];
|
||||
pthread_t pthread_virtual_tid;
|
||||
int virtual_status = 0;
|
||||
int virtual_stop = 0;
|
||||
int virtual_image_test_mode = 0;
|
||||
#endif
|
||||
|
||||
enum detectorSettings thisSettings = UNINITIALIZED;
|
||||
@ -41,6 +42,7 @@ int detPos[4] = {};
|
||||
int numUDPInterfaces = 1;
|
||||
|
||||
|
||||
|
||||
int isInitCheckDone() {
|
||||
return initCheckDone;
|
||||
}
|
||||
@ -226,6 +228,23 @@ int testBus() {
|
||||
}
|
||||
|
||||
|
||||
#ifdef VIRTUAL
|
||||
void setTestImageMode(int ival) {
|
||||
if (ival >= 0) {
|
||||
if (ival == 0) {
|
||||
LOG(logINFO, ("Switching off Image Test Mode\n"));
|
||||
virtual_image_test_mode = 0;
|
||||
} else {
|
||||
LOG(logINFO, ("Switching on Image Test Mode\n"));
|
||||
virtual_image_test_mode = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getTestImageMode() {
|
||||
return virtual_image_test_mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Ids */
|
||||
@ -727,8 +746,9 @@ int getModule(sls_detector_module *myMod){
|
||||
if (dacValues[idac] >= 0)
|
||||
initialized = 1;
|
||||
}
|
||||
if (initialized)
|
||||
if (initialized) {
|
||||
return OK;
|
||||
}
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@ -1646,75 +1666,81 @@ void* start_timer(void* arg) {
|
||||
getNumTriggers() *
|
||||
(getNumAdditionalStorageCells() + 1));
|
||||
int64_t exp_us = getExpTime() / 1000;
|
||||
const int npixels = 256 * 256 * 8;
|
||||
const int datasize = 8192;
|
||||
const int packetsize = datasize + sizeof(sls_detector_header);
|
||||
const int numPacketsPerFrame = 128;
|
||||
int transmissionDelayUs = getTransmissionDelayFrame() * 1000;
|
||||
|
||||
//TODO: Generate data
|
||||
char imageData[DATA_BYTES];
|
||||
memset(imageData, 0, DATA_BYTES);
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < DATA_BYTES; i += sizeof(uint16_t)) {
|
||||
*((uint16_t*)(imageData + i)) = i;
|
||||
}
|
||||
//TODO: Generate data
|
||||
char imageData[DATA_BYTES];
|
||||
memset(imageData, 0, DATA_BYTES);
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < npixels; ++i) {
|
||||
// avoiding gain also being divided when gappixels enabled in call back
|
||||
*((uint16_t*)(imageData + i * sizeof(uint16_t))) = virtual_image_test_mode ? 0x0FFE : (uint16_t)i;
|
||||
}
|
||||
int datasize = 8192;
|
||||
}
|
||||
|
||||
|
||||
//TODO: Send data
|
||||
{
|
||||
int frameNr = 0;
|
||||
for(frameNr=0; frameNr!= numFrames; ++frameNr ) {
|
||||
//TODO: Send data
|
||||
{
|
||||
int frameNr = 0;
|
||||
for(frameNr=0; frameNr!= numFrames; ++frameNr ) {
|
||||
|
||||
//check if virtual_stop is high
|
||||
if(virtual_stop == 1){
|
||||
break;
|
||||
usleep(transmissionDelayUs);
|
||||
|
||||
//check if virtual_stop is high
|
||||
if(virtual_stop == 1){
|
||||
break;
|
||||
}
|
||||
|
||||
int srcOffset = 0;
|
||||
|
||||
struct timespec begin, end;
|
||||
clock_gettime(CLOCK_REALTIME, &begin);
|
||||
|
||||
usleep(exp_us);
|
||||
|
||||
char packetData[packetsize];
|
||||
memset(packetData, 0, packetsize);
|
||||
|
||||
// loop packet
|
||||
{
|
||||
int i = 0;
|
||||
for(i = 0; i != numPacketsPerFrame; ++i) {
|
||||
// set header
|
||||
sls_detector_header* header = (sls_detector_header*)(packetData);
|
||||
header->detType = (uint16_t)myDetectorType;
|
||||
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
|
||||
header->frameNumber = frameNr;
|
||||
header->packetNumber = i;
|
||||
header->modId = 0;
|
||||
header->row = detPos[X];
|
||||
header->column = detPos[Y];
|
||||
|
||||
// fill data
|
||||
memcpy(packetData + sizeof(sls_detector_header), imageData + srcOffset, datasize);
|
||||
srcOffset += datasize;
|
||||
|
||||
sendUDPPacket(0, packetData, packetsize);
|
||||
}
|
||||
}
|
||||
LOG(logINFO, ("Sent frame: %d\n", frameNr));
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 +
|
||||
(end.tv_nsec - begin.tv_nsec));
|
||||
|
||||
int srcOffset = 0;
|
||||
|
||||
struct timespec begin, end;
|
||||
clock_gettime(CLOCK_REALTIME, &begin);
|
||||
|
||||
usleep(exp_us);
|
||||
|
||||
const int size = datasize + sizeof(sls_detector_header);
|
||||
char packetData[size];
|
||||
memset(packetData, 0, sizeof(sls_detector_header));
|
||||
|
||||
// loop packet
|
||||
{
|
||||
int i = 0;
|
||||
for(i=0; i!=128; ++i) {
|
||||
// set header
|
||||
sls_detector_header* header = (sls_detector_header*)(packetData);
|
||||
header->frameNumber = frameNr;
|
||||
header->packetNumber = i;
|
||||
header->modId = 0;
|
||||
header->row = detPos[X];
|
||||
header->column = detPos[Y];
|
||||
header->detType = (uint16_t)myDetectorType;
|
||||
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
|
||||
// fill data
|
||||
memcpy(packetData + sizeof(sls_detector_header), imageData + srcOffset, datasize);
|
||||
srcOffset += datasize;
|
||||
|
||||
sendUDPPacket(0, packetData, size);
|
||||
}
|
||||
}
|
||||
LOG(logINFO, ("Sent frame: %d\n", frameNr));
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 +
|
||||
(end.tv_nsec - begin.tv_nsec));
|
||||
|
||||
// sleep for (period - exptime)
|
||||
if (frameNr < numFrames) { // if there is a next frame
|
||||
if (periodns > time_ns) {
|
||||
usleep((periodns - time_ns)/ 1000);
|
||||
}
|
||||
// sleep for (period - exptime)
|
||||
if (frameNr < numFrames) { // if there is a next frame
|
||||
if (periodns > time_ns) {
|
||||
usleep((periodns - time_ns)/ 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
|
||||
closeUDPSocket(0);
|
||||
|
Binary file not shown.
@ -969,8 +969,9 @@ enum detectorSettings getSettings() {
|
||||
|
||||
|
||||
void setDAC(enum DACINDEX ind, int val, int mV) {
|
||||
if (val < 0 && val != LTC2620_GetPowerDownValue())
|
||||
if (val < 0 && val != LTC2620_GetPowerDownValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
char* dac_names[] = {DAC_NAMES};
|
||||
LOG(logINFO, ("Setting DAC %s\n", dac_names[ind]));
|
||||
|
Binary file not shown.
@ -61,7 +61,7 @@ int testFpga();
|
||||
int testBus();
|
||||
#endif
|
||||
|
||||
#ifdef GOTTHARDD
|
||||
#if defined(GOTTHARDD) || ((defined(EIGERD) || defined(JUNGFRAUD)) && defined(VIRTUAL))
|
||||
void setTestImageMode(int ival);
|
||||
int getTestImageMode();
|
||||
#endif
|
||||
|
@ -26,8 +26,12 @@ void ASIC_Driver_SetDefines(char* driverfname) {
|
||||
}
|
||||
|
||||
int ASIC_Driver_Set (int index, int length, char* buffer) {
|
||||
char temp[20];
|
||||
memset(temp, 0, sizeof(temp));
|
||||
sprintf(temp, "%d", index + 1);
|
||||
char fname[MAX_STR_LENGTH];
|
||||
sprintf(fname, "%s%d", ASIC_Driver_DriverFileName, index + 1);
|
||||
strcpy(fname, ASIC_Driver_DriverFileName);
|
||||
strcat(fname, temp);
|
||||
LOG(logDEBUG2, ("\t[chip index: %d, length: %d, fname: %s]\n", index, length, fname));
|
||||
{
|
||||
LOG(logDEBUG2, ("\t[values: \n"));
|
||||
|
@ -73,7 +73,11 @@ int LTC2620_D_SetDACValue (int dacnum, int val, int mV, char* dacname, int* dacv
|
||||
LOG(logINFO, ("Setting DAC %2d [%-12s] : %d dac (%d mV)\n",dacnum, dacname, *dacval, dacmV));
|
||||
|
||||
char fname[MAX_STR_LENGTH];
|
||||
sprintf(fname, "%s%d", LTC2620_D_DriverFileName, dacnum);
|
||||
strcpy(fname, LTC2620_D_DriverFileName);
|
||||
char temp[20];
|
||||
memset(temp, 0, sizeof(temp));
|
||||
sprintf(temp, "%d", dacnum);
|
||||
strcat(fname, temp);
|
||||
LOG(logDEBUG1, ("fname %s\n",fname));
|
||||
|
||||
//open file
|
||||
|
@ -101,17 +101,25 @@ int main(int argc, char *argv[]){
|
||||
}
|
||||
|
||||
#ifdef STOP_SERVER
|
||||
char cmd[100];
|
||||
memset(cmd, 0, 100);
|
||||
char cmd[MAX_STR_LENGTH];
|
||||
memset(cmd, 0, MAX_STR_LENGTH);
|
||||
#endif
|
||||
if (isControlServer) {
|
||||
LOG(logINFO, ("Opening control server on port %d \n", portno));
|
||||
#ifdef STOP_SERVER
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < argc; ++i)
|
||||
sprintf(cmd, "%s %s", cmd, argv[i]);
|
||||
sprintf(cmd,"%s -stopserver -port %d &", cmd, portno + 1);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (i > 0) {
|
||||
strcat(cmd, " ");
|
||||
}
|
||||
strcat(cmd, argv[i]);
|
||||
}
|
||||
char temp[50];
|
||||
memset(temp, 0, sizeof(temp));
|
||||
sprintf(temp, " -stopserver -port %d &", portno + 1);
|
||||
strcat(cmd, temp);
|
||||
|
||||
LOG(logDEBUG1, ("Command to start stop server:%s\n", cmd));
|
||||
system(cmd);
|
||||
}
|
||||
|
@ -776,10 +776,10 @@ int set_image_test_mode(int file_des) {
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Setting image test mode to \n", arg));
|
||||
|
||||
#ifndef GOTTHARDD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
#if defined(GOTTHARDD) || ((defined(EIGERD) || defined(JUNGFRAUD)) && defined(VIRTUAL))
|
||||
setTestImageMode(arg);
|
||||
#else
|
||||
functionNotImplemented();
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, UPDATE, NULL, 0);
|
||||
}
|
||||
@ -790,11 +790,11 @@ int get_image_test_mode(int file_des) {
|
||||
int retval = -1;
|
||||
LOG(logDEBUG1, ("Getting image test mode\n"));
|
||||
|
||||
#ifndef GOTTHARDD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
#if defined(GOTTHARDD) || ((defined(EIGERD) || defined(JUNGFRAUD)) && defined(VIRTUAL))
|
||||
retval = getTestImageMode();
|
||||
LOG(logDEBUG1, ("image test mode retval: %d\n", retval));
|
||||
#else
|
||||
functionNotImplemented();
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval));
|
||||
}
|
||||
@ -1844,7 +1844,8 @@ int start_acquisition(int file_des) {
|
||||
#endif
|
||||
if (configured == FAIL) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not start acquisition because %s\n", configureMessage);
|
||||
strcpy(mess, "Could not start acquisition because ");
|
||||
strcat(mess, configureMessage);
|
||||
LOG(logERROR,(mess));
|
||||
} else {
|
||||
ret = startStateMachine();
|
||||
@ -1979,7 +1980,8 @@ int start_and_read_all(int file_des) {
|
||||
#endif
|
||||
if (configured == FAIL) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not start acquisition because %s\n", configureMessage);
|
||||
strcpy(mess, "Could not start acquisition because ");
|
||||
strcat(mess, configureMessage);
|
||||
LOG(logERROR,(mess));
|
||||
} else {
|
||||
ret = startStateMachine();
|
||||
@ -4352,7 +4354,11 @@ int copy_detector_server(int file_des) {
|
||||
memset(cmd, 0, MAX_STR_LENGTH);
|
||||
|
||||
// copy server
|
||||
sprintf(cmd, "tftp %s -r %s -g", hostname, sname);
|
||||
strcpy(cmd, "tftp ");
|
||||
strcat(cmd, hostname);
|
||||
strcat(cmd, " -r ");
|
||||
strcat(cmd, sname);
|
||||
strcat(cmd, " -g");
|
||||
int success = executeCommand(cmd, retvals, logDEBUG1);
|
||||
if (success == FAIL) {
|
||||
ret = FAIL;
|
||||
@ -4364,7 +4370,8 @@ int copy_detector_server(int file_des) {
|
||||
else {
|
||||
LOG(logINFO, ("Server copied successfully\n"));
|
||||
// give permissions
|
||||
sprintf(cmd, "chmod 777 %s", sname);
|
||||
strcpy(cmd, "chmod 777 ");
|
||||
strcat(cmd, sname);
|
||||
executeCommand(cmd, retvals, logDEBUG1);
|
||||
|
||||
// edit /etc/inittab
|
||||
@ -4384,7 +4391,9 @@ int copy_detector_server(int file_des) {
|
||||
LOG(logINFO, ("Deleted all lines containing DetectorServer in /etc/inittab\n"));
|
||||
|
||||
// append line
|
||||
sprintf(cmd, "echo \"ttyS0::respawn:/./%s\" >> /etc/inittab", sname);
|
||||
strcpy(cmd, "echo \"ttyS0::respawn:/./");
|
||||
strcat(cmd, sname);
|
||||
strcat(cmd, "\" >> /etc/inittab");
|
||||
executeCommand(cmd, retvals, logDEBUG1);
|
||||
|
||||
LOG(logINFO, ("/etc/inittab modified to have %s\n", sname));
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
class detectorData;
|
||||
@ -137,6 +138,16 @@ class Detector {
|
||||
void *),
|
||||
void *pArg);
|
||||
|
||||
/**[Eiger][Jungfrau] */
|
||||
bool getGapPixelsinCallback() const;
|
||||
|
||||
/**
|
||||
* [Eiger][Jungfrau]
|
||||
* Only in client data call back
|
||||
* Fills in gap pixels in data
|
||||
*/
|
||||
void setGapPixelsinCallback(const bool enable);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Acquisition Parameters *
|
||||
@ -255,12 +266,6 @@ class Detector {
|
||||
|
||||
Result<int> getHighVoltage(Positions pos = {}) const;
|
||||
|
||||
/** [Jungfrau][Mythen3][Gotthard2][Moench] */
|
||||
Result<bool> getPowerChip(Positions pos = {}) const;
|
||||
|
||||
/** [Jungfrau][Mythen3][Gotthard2][Moench] */
|
||||
void setPowerChip(bool on, Positions pos = {});
|
||||
|
||||
/**
|
||||
* [Gotthard] Options: 0, 90, 110, 120, 150, 180, 200
|
||||
* [Jungfrau][CTB][Moench] Options: 0, 60 - 200
|
||||
@ -268,6 +273,21 @@ class Detector {
|
||||
*/
|
||||
void setHighVoltage(int value, Positions pos = {});
|
||||
|
||||
/** [Jungfrau][Mythen3][Gotthard2][Moench] */
|
||||
Result<bool> getPowerChip(Positions pos = {}) const;
|
||||
|
||||
/** [Jungfrau][Mythen3][Gotthard2][Moench] */
|
||||
void setPowerChip(bool on, Positions pos = {});
|
||||
|
||||
/** [Gotthard][Eiger virtual] */
|
||||
Result<int> getImageTestMode(Positions pos = {});
|
||||
|
||||
/** [Gotthard] If 1, adds channel intensity with precalculated values.
|
||||
* Default is 0
|
||||
* [Eiger virtual] If 1, pixels are saturated. If 0, increasing intensity
|
||||
* Only for virtual servers */
|
||||
void setImageTestMode(const int value, Positions pos = {});
|
||||
|
||||
/**
|
||||
* (Degrees)
|
||||
* [Gotthard] Options: TEMPERATURE_ADC, TEMPERATURE_FPGA
|
||||
@ -694,16 +714,6 @@ class Detector {
|
||||
/** [Eiger] */
|
||||
void loadTrimbits(const std::string &fname, Positions pos = {});
|
||||
|
||||
/**[Eiger] */
|
||||
Result<bool> getRxAddGapPixels(Positions pos = {}) const;
|
||||
|
||||
/**
|
||||
* [Eiger]
|
||||
* 4 bit mode not implemented in Receiver, but in client data call back
|
||||
* Fills in gap pixels in data
|
||||
*/
|
||||
void setRxAddGapPixels(bool enable);
|
||||
|
||||
/** [Eiger] */
|
||||
Result<bool> getParallelMode(Positions pos = {}) const;
|
||||
|
||||
@ -905,12 +915,6 @@ class Detector {
|
||||
void setExternalSignalFlags(defs::externalSignalFlag value,
|
||||
Positions pos = {});
|
||||
|
||||
/** [Gotthard] */
|
||||
Result<int> getImageTestMode(Positions pos = {});
|
||||
|
||||
/** [Gotthard] If 1, adds channel intensity with precalculated values.
|
||||
* Default is 0 */
|
||||
void setImageTestMode(const int value, Positions pos = {});
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
@ -1196,10 +1200,10 @@ class Detector {
|
||||
* ************************************************/
|
||||
|
||||
/** [Moench] */
|
||||
Result<std::string> getAdditionalJsonHeader(Positions pos = {}) const;
|
||||
Result<std::map<std::string, std::string>> getAdditionalJsonHeader(Positions pos = {}) const;
|
||||
|
||||
/** [Moench] */
|
||||
void setAdditionalJsonHeader(const std::string &jsonheader,
|
||||
/** [Moench] If empty, reset additional json header. Max 20 characters for each key/value */
|
||||
void setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader,
|
||||
Positions pos = {});
|
||||
|
||||
/** [Moench] */
|
||||
@ -1207,12 +1211,11 @@ class Detector {
|
||||
Positions pos = {}) const;
|
||||
/**
|
||||
* [Moench]
|
||||
* Sets the value for additional json header parameter if found,
|
||||
* Sets the value for additional json header parameters if found,
|
||||
* else appends the parameter key and value
|
||||
* The value cannot be empty
|
||||
* If empty, deletes parameter. Max 20 characters for each key/value
|
||||
*/
|
||||
void setAdditionalJsonParameter(const std::string &key,
|
||||
const std::string &value,
|
||||
void setAdditionalJsonParameter(const std::string &key, const std::string &value,
|
||||
Positions pos = {});
|
||||
|
||||
/** [Moench] TODO! How do we do this best??? Can be refactored to something
|
||||
|
@ -16,9 +16,10 @@ class detectorData {
|
||||
* @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) :
|
||||
progressIndex(progress), fileName(fname), fileIndex(fIndex), nx(x), ny(y), data(d), databytes(dbytes), dynamicRange(dr) {};
|
||||
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) {};
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -55,4 +56,5 @@ class detectorData {
|
||||
char* data;
|
||||
int databytes;
|
||||
int dynamicRange;
|
||||
bool completeImage;
|
||||
};
|
||||
|
@ -1001,24 +1001,27 @@ std::string CmdProxy::GapPixels(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[0, 1]\n\t[Eiger] Include Gap pixels in data file or data call "
|
||||
"back. 4 bit mode gap pixels only ind ata call back."
|
||||
os << "[0, 1]\n\t[Eiger][Jungfrau] Include Gap pixels only in data call back."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (det_id != -1) {
|
||||
throw sls::RuntimeError(
|
||||
"Cannot get gap pixels at module level");
|
||||
}
|
||||
if (!args.empty()) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto t = det->getRxAddGapPixels({det_id});
|
||||
os << OutString(t) << '\n';
|
||||
auto t = det->getGapPixelsinCallback();
|
||||
os << t << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (det_id != -1) {
|
||||
throw sls::RuntimeError(
|
||||
"Cannot execute dynamic range at module level");
|
||||
"Cannot add gap pixels at module level");
|
||||
}
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
det->setRxAddGapPixels(StringTo<int>(args[0]));
|
||||
det->setGapPixelsinCallback(StringTo<int>(args[0]));
|
||||
os << args.front() << '\n';
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
@ -1224,7 +1227,7 @@ std::string CmdProxy::Quad(int action) {
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (det_id != -1) {
|
||||
throw sls::RuntimeError(
|
||||
"Cannot execute dynamic range at module level");
|
||||
"Cannot execute quad at module level");
|
||||
}
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
@ -1879,13 +1882,47 @@ std::string CmdProxy::PatternWaitTime(int action) {
|
||||
|
||||
/* Moench */
|
||||
|
||||
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. 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.size() != 0) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto t = det->getAdditionalJsonHeader({det_id});
|
||||
os << OutString(t) << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
// arguments can be empty
|
||||
std::map<std::string, std::string> json;
|
||||
for (size_t i = 0; i < args.size(); i = i + 2) {
|
||||
// last value is empty
|
||||
if (i + 1 >= args.size()) {
|
||||
json[args[i]] = "";
|
||||
} else {
|
||||
json[args[i]] = args[i + 1];
|
||||
}
|
||||
}
|
||||
det->setAdditionalJsonHeader(json, {det_id});
|
||||
os << sls::ToString(json) << '\n';
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::JsonParameter(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[key1] [value1]\n\tAdditional json header parameter streamed "
|
||||
"out from receiver. If empty in a get, then no parameter found. "
|
||||
"This is same as calling rx_jsonaddheader \"key\":\"value1\"."
|
||||
"out from receiver. If not found in header, the pair is appended. "
|
||||
"An empty values deletes parameter."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (args.size() != 1) {
|
||||
@ -1894,11 +1931,21 @@ std::string CmdProxy::JsonParameter(int action) {
|
||||
auto t = det->getAdditionalJsonParameter(args[0], {det_id});
|
||||
os << OutString(t) << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 2) {
|
||||
WrongNumberOfParameters(2);
|
||||
switch (args.size()) {
|
||||
case 1:
|
||||
det->setAdditionalJsonParameter(args[0], "", {det_id});
|
||||
break;
|
||||
case 2:
|
||||
det->setAdditionalJsonParameter(args[0], args[1], {det_id});
|
||||
break;
|
||||
default:
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
if (args.size() == 1) {
|
||||
os << args[0] << " deleted" << '\n';
|
||||
} else {
|
||||
os << "{" << args[0] << ": " << args[1] << "}" << '\n';
|
||||
}
|
||||
det->setAdditionalJsonParameter(args[0], args[1], {det_id});
|
||||
os << sls::ToString(args) << '\n';
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
|
@ -477,6 +477,7 @@ class CmdProxy {
|
||||
{"cycles", "triggers"},
|
||||
{"cyclesl", "triggersl"},
|
||||
{"clkdivider", "speed"},
|
||||
{"digitest", "imagetest"},
|
||||
|
||||
/** temperature */
|
||||
/** dacs */
|
||||
@ -527,8 +528,6 @@ class CmdProxy {
|
||||
|
||||
/* Jungfrau Specific */
|
||||
/* Gotthard Specific */
|
||||
{"digitest", "imagetest"},
|
||||
|
||||
/* Gotthard2 Specific */
|
||||
/* Mythen3 Specific */
|
||||
/* CTB Specific */
|
||||
@ -591,6 +590,7 @@ class CmdProxy {
|
||||
{"clkdiv", &CmdProxy::ClockDivider},
|
||||
{"vhighvoltage", &CmdProxy::vhighvoltage},
|
||||
{"powerchip", &CmdProxy::powerchip},
|
||||
{"imagetest", &CmdProxy::imagetest},
|
||||
|
||||
/** temperature */
|
||||
{"temp_adc", &CmdProxy::temp_adc},
|
||||
@ -789,7 +789,6 @@ class CmdProxy {
|
||||
{"clearroi", &CmdProxy::ClearROI},
|
||||
{"exptimel", &CmdProxy::exptimel},
|
||||
{"extsig", &CmdProxy::extsig},
|
||||
{"imagetest", &CmdProxy::imagetest},
|
||||
|
||||
/* Gotthard2 Specific */
|
||||
{"bursts", &CmdProxy::bursts},
|
||||
@ -867,7 +866,7 @@ class CmdProxy {
|
||||
{"patsetbit", &CmdProxy::patsetbit},
|
||||
|
||||
/* Moench */
|
||||
{"rx_jsonaddheader", &CmdProxy::rx_jsonaddheader},
|
||||
{"rx_jsonaddheader", &CmdProxy::AdditionalJsonHeader},
|
||||
{"rx_jsonpara", &CmdProxy::JsonParameter},
|
||||
{"emin", &CmdProxy::MinMaxEnergyThreshold},
|
||||
{"emax", &CmdProxy::MinMaxEnergyThreshold},
|
||||
@ -980,6 +979,7 @@ class CmdProxy {
|
||||
std::string PatternWaitAddress(int action);
|
||||
std::string PatternWaitTime(int action);
|
||||
/* Moench */
|
||||
std::string AdditionalJsonHeader(int action);
|
||||
std::string JsonParameter(int action);
|
||||
std::string MinMaxEnergyThreshold(int action);
|
||||
/* Advanced */
|
||||
@ -1088,6 +1088,10 @@ class CmdProxy {
|
||||
"\n\t[Mythen3] If module not connected or wrong module, 1 will fail. By default, not powered on"
|
||||
"\n\t[Gotthard2] If module not connected or wrong module, 1 will fail. By default, powered on at server start up.");
|
||||
|
||||
INTEGER_COMMAND(imagetest, getImageTestMode, setImageTestMode, StringTo<int>,
|
||||
"[0, 1]\n\t[Gotthard] 1 adds channel intensity with precalculated values when taking an acquisition. Default is 0."
|
||||
"\n\t[Eiger][Jungfrau] Only for Virtual servers. If 0, each pixel intensity incremented by 1. If 1, all pixels almost saturated.");
|
||||
|
||||
/** temperature */
|
||||
|
||||
GET_IND_COMMAND(temp_adc, getTemperature, slsDetectorDefs::TEMPERATURE_ADC, " °C",
|
||||
@ -1582,9 +1586,6 @@ class CmdProxy {
|
||||
INTEGER_COMMAND(extsig, getExternalSignalFlags, setExternalSignalFlags, sls::StringTo<slsDetectorDefs::externalSignalFlag>,
|
||||
"[trigger_in_rising_edge|trigger_in_falling_edge]\n\t[Gotthard] External signal mode for trigger timing mode.");
|
||||
|
||||
INTEGER_COMMAND(imagetest, getImageTestMode, setImageTestMode, StringTo<int>,
|
||||
"[0, 1]\n\t[Gotthard] 1 adds channel intensity with precalculated values when taking an acquisition. Default is 0.");
|
||||
|
||||
/* Gotthard2 Specific */
|
||||
INTEGER_COMMAND_NOID(bursts, getNumberOfBursts, setNumberOfBursts,
|
||||
StringTo<int64_t>,
|
||||
@ -1719,9 +1720,6 @@ class CmdProxy {
|
||||
|
||||
/* Moench */
|
||||
|
||||
STRING_COMMAND(rx_jsonaddheader, getAdditionalJsonHeader, setAdditionalJsonHeader,
|
||||
"[\\\"label1\\\":\\\"value1\\\"], [\\\"label2\\\":\\\"value2\\\"]\n\tAdditional json header to be streamd out from receiver via zmq. Default is empty. Use only if to be processed by an intermediate user process listening to receiver zmq packets.");
|
||||
|
||||
INTEGER_COMMAND(framemode, getFrameMode, setFrameMode, sls::StringTo<slsDetectorDefs::frameModeType>,
|
||||
"[pedestal|newpedestal|flatfield|newflatfield]\n\t[Moench] Frame mode (soft setting) in processor.");
|
||||
|
||||
|
@ -167,6 +167,14 @@ void Detector::registerDataCallback(void (*func)(detectorData *, uint64_t,
|
||||
pimpl->registerDataCallback(func, pArg);
|
||||
}
|
||||
|
||||
bool Detector::getGapPixelsinCallback() const {
|
||||
return pimpl->getGapPixelsinCallback();
|
||||
}
|
||||
|
||||
void Detector::setGapPixelsinCallback(bool enable) {
|
||||
pimpl->setGapPixelsinCallback(enable);
|
||||
}
|
||||
|
||||
// Acquisition Parameters
|
||||
|
||||
Result<int64_t> Detector::getNumberOfFrames(Positions pos) const {
|
||||
@ -359,6 +367,14 @@ void Detector::setPowerChip(bool on, Positions pos) {
|
||||
}
|
||||
}
|
||||
|
||||
Result<int> Detector::getImageTestMode(Positions pos) {
|
||||
return pimpl->Parallel(&Module::getImageTestMode, pos);
|
||||
}
|
||||
|
||||
void Detector::setImageTestMode(int value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setImageTestMode, pos, value);
|
||||
}
|
||||
|
||||
Result<int> Detector::getTemperature(defs::dacIndex index,
|
||||
Positions pos) const {
|
||||
switch (index) {
|
||||
@ -953,14 +969,6 @@ void Detector::loadTrimbits(const std::string &fname, Positions pos) {
|
||||
pimpl->Parallel(&Module::loadSettingsFile, pos, fname);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getRxAddGapPixels(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::enableGapPixels, pos, -1);
|
||||
}
|
||||
|
||||
void Detector::setRxAddGapPixels(bool enable) {
|
||||
pimpl->setGapPixelsinReceiver(enable);
|
||||
}
|
||||
|
||||
Result<bool> Detector::getParallelMode(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getParallelMode, pos);
|
||||
}
|
||||
@ -1195,14 +1203,6 @@ void Detector::setExternalSignalFlags(defs::externalSignalFlag value,
|
||||
pimpl->Parallel(&Module::setExternalSignalFlags, pos, value);
|
||||
}
|
||||
|
||||
Result<int> Detector::getImageTestMode(Positions pos) {
|
||||
return pimpl->Parallel(&Module::getImageTestMode, pos);
|
||||
}
|
||||
|
||||
void Detector::setImageTestMode(int value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setImageTestMode, pos, value);
|
||||
}
|
||||
|
||||
// Gotthard2 Specific
|
||||
|
||||
Result<int64_t> Detector::getNumberOfBursts(Positions pos) const {
|
||||
@ -1612,13 +1612,13 @@ void Detector::setPatternBitMask(uint64_t mask, Positions pos) {
|
||||
|
||||
// Moench
|
||||
|
||||
Result<std::string> Detector::getAdditionalJsonHeader(Positions pos) const {
|
||||
Result<std::map<std::string, std::string>> Detector::getAdditionalJsonHeader(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getAdditionalJsonHeader, pos);
|
||||
}
|
||||
|
||||
void Detector::setAdditionalJsonHeader(const std::string &jsonheader,
|
||||
void Detector::setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader,
|
||||
Positions pos) {
|
||||
pimpl->Parallel(&Module::setAdditionalJsonHeader, pos, jsonheader);
|
||||
pimpl->Parallel(&Module::setAdditionalJsonHeader, pos, jsonHeader);
|
||||
}
|
||||
|
||||
Result<std::string> Detector::getAdditionalJsonParameter(const std::string &key,
|
||||
@ -1626,8 +1626,7 @@ Result<std::string> Detector::getAdditionalJsonParameter(const std::string &key,
|
||||
return pimpl->Parallel(&Module::getAdditionalJsonParameter, pos, key);
|
||||
}
|
||||
|
||||
void Detector::setAdditionalJsonParameter(const std::string &key,
|
||||
const std::string &value,
|
||||
void Detector::setAdditionalJsonParameter(const std::string &key, const std::string &value,
|
||||
Positions pos) {
|
||||
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos, key, value);
|
||||
}
|
||||
|
@ -157,6 +157,7 @@ void DetectorImpl::initializeDetectorStructure() {
|
||||
multi_shm()->numberOfChannels.y = 0;
|
||||
multi_shm()->acquiringFlag = false;
|
||||
multi_shm()->initialChecks = true;
|
||||
multi_shm()->gapPixels = false;
|
||||
}
|
||||
|
||||
void DetectorImpl::initializeMembers(bool verify) {
|
||||
@ -339,17 +340,30 @@ void DetectorImpl::setNumberOfChannels(const slsDetectorDefs::xy c) {
|
||||
multi_shm()->numberOfChannels = c;
|
||||
}
|
||||
|
||||
void DetectorImpl::setGapPixelsinReceiver(bool enable) {
|
||||
Parallel(&Module::enableGapPixels, {}, static_cast<int>(enable));
|
||||
// update number of channels
|
||||
Result<slsDetectorDefs::xy> res =
|
||||
Parallel(&Module::getNumberOfChannels, {});
|
||||
multi_shm()->numberOfChannels.x = 0;
|
||||
multi_shm()->numberOfChannels.y = 0;
|
||||
for (auto &it : res) {
|
||||
multi_shm()->numberOfChannels.x += it.x;
|
||||
multi_shm()->numberOfChannels.y += it.y;
|
||||
bool DetectorImpl::getGapPixelsinCallback() const {
|
||||
return multi_shm()->gapPixels;
|
||||
}
|
||||
|
||||
void DetectorImpl::setGapPixelsinCallback(const bool enable) {
|
||||
if (enable) {
|
||||
switch (multi_shm()->multiDetectorType) {
|
||||
case JUNGFRAU:
|
||||
break;
|
||||
case EIGER:
|
||||
if (size() && detectors[0]->getQuad()) {
|
||||
break;
|
||||
}
|
||||
if (multi_shm()->numberOfDetector.y % 2 != 0) {
|
||||
throw RuntimeError("Gap pixels can only be used "
|
||||
"for full modules.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError("Gap Pixels is not implemented for "
|
||||
+ multi_shm()->multiDetectorType);
|
||||
}
|
||||
}
|
||||
multi_shm()->gapPixels = enable;
|
||||
}
|
||||
|
||||
int DetectorImpl::createReceivingDataSockets(const bool destroy) {
|
||||
@ -406,11 +420,13 @@ int DetectorImpl::createReceivingDataSockets(const bool destroy) {
|
||||
|
||||
void DetectorImpl::readFrameFromReceiver() {
|
||||
|
||||
bool gapPixels = multi_shm()->gapPixels;
|
||||
LOG(logDEBUG) << "Gap pixels: " << gapPixels;
|
||||
|
||||
int nX = 0;
|
||||
int nY = 0;
|
||||
int nDetPixelsX = 0;
|
||||
int nDetPixelsY = 0;
|
||||
bool gappixelsenable = false;
|
||||
bool quadEnable = false;
|
||||
bool eiger = false;
|
||||
bool numInterfaces =
|
||||
@ -434,6 +450,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
}
|
||||
int numConnected = numRunning;
|
||||
bool data = false;
|
||||
bool completeImage = false;
|
||||
char *image = nullptr;
|
||||
char *multiframe = nullptr;
|
||||
char *multigappixels = nullptr;
|
||||
@ -461,6 +478,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
if (multiframe != nullptr) {
|
||||
memset(multiframe, 0xFF, multisize);
|
||||
}
|
||||
completeImage = true;
|
||||
|
||||
// get each frame
|
||||
for (unsigned int isocket = 0; isocket < zmqSocket.size(); ++isocket) {
|
||||
@ -470,9 +488,9 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
|
||||
// HEADER
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
zmqHeader zHeader;
|
||||
if (zmqSocket[isocket]->ReceiveHeader(
|
||||
isocket, doc, SLS_DETECTOR_JSON_HEADER_VERSION) ==
|
||||
isocket, zHeader, SLS_DETECTOR_JSON_HEADER_VERSION) ==
|
||||
0) {
|
||||
// parse error, version error or end of acquisition for
|
||||
// socket
|
||||
@ -484,33 +502,29 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
// if first message, allocate (all one time stuff)
|
||||
if (image == nullptr) {
|
||||
// allocate
|
||||
size = doc["size"].GetUint();
|
||||
size = zHeader.imageSize;
|
||||
multisize = size * zmqSocket.size();
|
||||
image = new char[size];
|
||||
multiframe = new char[multisize];
|
||||
memset(multiframe, 0xFF, multisize);
|
||||
// dynamic range
|
||||
dynamicRange = doc["bitmode"].GetUint();
|
||||
dynamicRange = zHeader.dynamicRange;
|
||||
bytesPerPixel = (float)dynamicRange / 8;
|
||||
// shape
|
||||
nPixelsX = doc["shape"][0].GetUint();
|
||||
nPixelsY = doc["shape"][1].GetUint();
|
||||
nPixelsX = zHeader.npixelsx;
|
||||
nPixelsY = zHeader.npixelsy;
|
||||
// detector shape
|
||||
nX = doc["detshape"][0].GetUint();
|
||||
nY = doc["detshape"][1].GetUint();
|
||||
nX = zHeader.ndetx;
|
||||
nY = zHeader.ndety;
|
||||
nY *= numInterfaces;
|
||||
nDetPixelsX = nX * nPixelsX;
|
||||
nDetPixelsY = nY * nPixelsY;
|
||||
// det type
|
||||
eiger =
|
||||
(doc["detType"].GetUint() == static_cast<int>(3))
|
||||
eiger = (zHeader.detType == static_cast<int>(3))
|
||||
? true
|
||||
: false; // to be changed to EIGER when firmware
|
||||
// updates its header data
|
||||
gappixelsenable =
|
||||
(doc["gappixels"].GetUint() == 0) ? false : true;
|
||||
quadEnable =
|
||||
(doc["quad"].GetUint() == 0) ? false : true;
|
||||
quadEnable = (zHeader.quad == 0) ? false : true;
|
||||
LOG(logDEBUG1)
|
||||
<< "One Time Header Info:"
|
||||
"\n\tsize: "
|
||||
@ -520,21 +534,23 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
<< "\n\tnPixelsX: " << nPixelsX
|
||||
<< "\n\tnPixelsY: " << nPixelsY << "\n\tnX: " << nX
|
||||
<< "\n\tnY: " << nY << "\n\teiger: " << eiger
|
||||
<< "\n\tgappixelsenable: " << gappixelsenable
|
||||
<< "\n\tquadEnable: " << quadEnable;
|
||||
}
|
||||
// each time, parse rest of header
|
||||
currentFileName = doc["fname"].GetString();
|
||||
currentAcquisitionIndex = doc["acqIndex"].GetUint64();
|
||||
currentFrameIndex = doc["fIndex"].GetUint64();
|
||||
currentFileIndex = doc["fileIndex"].GetUint64();
|
||||
currentSubFrameIndex = doc["expLength"].GetUint();
|
||||
coordY = doc["row"].GetUint();
|
||||
coordX = doc["column"].GetUint();
|
||||
currentFileName = zHeader.fname;
|
||||
currentAcquisitionIndex = zHeader.acqIndex;
|
||||
currentFrameIndex = zHeader.frameIndex;
|
||||
currentFileIndex = zHeader.fileIndex;
|
||||
currentSubFrameIndex = zHeader.expLength;
|
||||
coordY = zHeader.row;
|
||||
coordX = zHeader.column;
|
||||
if (eiger) {
|
||||
coordY = (nY - 1) - coordY;
|
||||
}
|
||||
flippedDataX = doc["flippedDataX"].GetUint();
|
||||
flippedDataX = zHeader.flippedDataX;
|
||||
if (zHeader.completeImage == 0) {
|
||||
completeImage = false;
|
||||
}
|
||||
LOG(logDEBUG1)
|
||||
<< "Header Info:"
|
||||
"\n\tcurrentFileName: "
|
||||
@ -544,12 +560,14 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
<< "\n\tcurrentFileIndex: " << currentFileIndex
|
||||
<< "\n\tcurrentSubFrameIndex: " << currentSubFrameIndex
|
||||
<< "\n\tcoordX: " << coordX << "\n\tcoordY: " << coordY
|
||||
<< "\n\tflippedDataX: " << flippedDataX;
|
||||
<< "\n\tflippedDataX: " << flippedDataX
|
||||
<< "\n\tcompleteImage: " << completeImage;
|
||||
}
|
||||
|
||||
// DATA
|
||||
data = true;
|
||||
zmqSocket[isocket]->ReceiveData(isocket, image, size);
|
||||
|
||||
// creating multi image
|
||||
{
|
||||
uint32_t xoffset = coordX * nPixelsX * bytesPerPixel;
|
||||
@ -586,43 +604,36 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG(logDEBUG)<< "Call Back Info:"
|
||||
<< "\n\t nDetPixelsX: " << nDetPixelsX
|
||||
<< "\n\t nDetPixelsY: " << nDetPixelsY
|
||||
<< "\n\t databytes: " << multisize
|
||||
<< "\n\t dynamicRange: " << dynamicRange ;
|
||||
<< "\n\t dynamicRange: " << dynamicRange;
|
||||
|
||||
// send data to callback
|
||||
if (data) {
|
||||
setCurrentProgress(currentFrameIndex + 1);
|
||||
// 4bit gap pixels
|
||||
if (dynamicRange == 4 && gappixelsenable) {
|
||||
if (quadEnable) {
|
||||
nDetPixelsX += 2;
|
||||
nDetPixelsY += 2;
|
||||
} else {
|
||||
nDetPixelsX = nX * (nPixelsX + 3);
|
||||
nDetPixelsY = nY * (nPixelsY + 1);
|
||||
}
|
||||
int n = processImageWithGapPixels(multiframe, multigappixels,
|
||||
quadEnable);
|
||||
LOG(logDEBUG)
|
||||
<< "Call Back Info Recalculated:"
|
||||
<< "\n\t nDetPixelsX: " << nDetPixelsX
|
||||
<< "\n\t nDetPixelsY: " << nDetPixelsY
|
||||
<< "\n\t databytes: " << n;
|
||||
thisData =
|
||||
new detectorData(getCurrentProgress(), currentFileName,
|
||||
nDetPixelsX, nDetPixelsY, multigappixels,
|
||||
n, dynamicRange, currentFileIndex);
|
||||
}
|
||||
// normal pixels
|
||||
else {
|
||||
thisData =
|
||||
new detectorData(getCurrentProgress(), currentFileName,
|
||||
nDetPixelsX, nDetPixelsY, multiframe,
|
||||
multisize, dynamicRange, currentFileIndex);
|
||||
char* image = multiframe;
|
||||
int imagesize = multisize;
|
||||
|
||||
if (gapPixels) {
|
||||
int n = InsertGapPixels(multiframe, multigappixels,
|
||||
quadEnable, dynamicRange, nDetPixelsX, nDetPixelsY);
|
||||
image = multigappixels;
|
||||
imagesize = n;
|
||||
}
|
||||
LOG(logDEBUG)
|
||||
<< "Image Info:"
|
||||
<< "\n\tnDetPixelsX: " << nDetPixelsX
|
||||
<< "\n\tnDetPixelsY: " << nDetPixelsY
|
||||
<< "\n\timagesize: " << imagesize
|
||||
<< "\n\tdynamicRange: " << dynamicRange;
|
||||
|
||||
thisData = new detectorData(getCurrentProgress(),
|
||||
currentFileName, nDetPixelsX, nDetPixelsY, image,
|
||||
imagesize, dynamicRange, currentFileIndex, completeImage);
|
||||
|
||||
dataReady(
|
||||
thisData, currentFrameIndex,
|
||||
((dynamicRange == 32 && eiger) ? currentSubFrameIndex : -1),
|
||||
@ -667,141 +678,301 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
delete[] multigappixels;
|
||||
}
|
||||
|
||||
int DetectorImpl::processImageWithGapPixels(char *image, char *&gpImage,
|
||||
bool quadEnable) {
|
||||
// eiger 4 bit mode
|
||||
int nxb =
|
||||
multi_shm()->numberOfDetector.x * (512 + 3); //(divided by 2 already)
|
||||
int nyb = multi_shm()->numberOfDetector.y * (256 + 1);
|
||||
int nchipInRow = 4;
|
||||
int nxchip = multi_shm()->numberOfDetector.x * 4;
|
||||
int nychip = multi_shm()->numberOfDetector.y * 1;
|
||||
int DetectorImpl::InsertGapPixels(char *image, char *&gpImage,
|
||||
bool quadEnable, int dr, int &nPixelsx, int &nPixelsy) {
|
||||
|
||||
LOG(logDEBUG)<< "Insert Gap pixels:"
|
||||
<< "\n\t nPixelsx: " << nPixelsx
|
||||
<< "\n\t nPixelsy: " << nPixelsy
|
||||
<< "\n\t quadEnable: " << quadEnable
|
||||
<< "\n\t dr: " << dr;
|
||||
|
||||
// inter module gap pixels
|
||||
int modGapPixelsx = 8;
|
||||
int modGapPixelsy = 36;
|
||||
// inter chip gap pixels
|
||||
int chipGapPixelsx = 2;
|
||||
int chipGapPixelsy = 2;
|
||||
// number of pixels in a chip
|
||||
int nChipPixelsx = 256;
|
||||
int nChipPixelsy = 256;
|
||||
// 1 module
|
||||
// number of chips in a module
|
||||
int nMod1Chipx = 4;
|
||||
int nMod1Chipy = 2;
|
||||
if (quadEnable) {
|
||||
nxb = multi_shm()->numberOfDetector.x *
|
||||
(256 + 1); //(divided by 2 already)
|
||||
nyb = multi_shm()->numberOfDetector.y * (512 + 2);
|
||||
nxchip /= 2;
|
||||
nychip *= 2;
|
||||
nchipInRow /= 2;
|
||||
nMod1Chipx = 2;
|
||||
}
|
||||
int gapdatabytes = nxb * nyb;
|
||||
// number of pixels in a module
|
||||
int nMod1Pixelsx = nChipPixelsx * nMod1Chipx;
|
||||
int nMod1Pixelsy = nChipPixelsy * nMod1Chipy;
|
||||
// number of gap pixels in a module
|
||||
int nMod1GapPixelsx = (nMod1Chipx - 1) * chipGapPixelsx;
|
||||
int nMod1GapPixelsy = (nMod1Chipy - 1) * chipGapPixelsy;
|
||||
// total number of modules
|
||||
int nModx = nPixelsx / nMod1Pixelsx;
|
||||
int nMody = nPixelsy / nMod1Pixelsy;
|
||||
|
||||
// allocate
|
||||
if (gpImage == nullptr) {
|
||||
gpImage = new char[gapdatabytes];
|
||||
// check if not full modules
|
||||
// (setting gap pixels and then adding half module or disabling quad)
|
||||
if (nPixelsy / nMod1Pixelsy == 0) {
|
||||
LOG(logERROR) << "Gap pixels can only be enabled with full modules. "
|
||||
"Sending dummy data without gap pixels.\n";
|
||||
double bytesPerPixel = (double)dr / 8.00;
|
||||
int imagesize = nPixelsy * nPixelsx * bytesPerPixel;
|
||||
if (gpImage == NULL) {
|
||||
gpImage = new char[imagesize];
|
||||
}
|
||||
memset(gpImage, 0xFF, imagesize);
|
||||
return imagesize;
|
||||
}
|
||||
// fill value
|
||||
memset(gpImage, 0xFF, gapdatabytes);
|
||||
|
||||
const int b1chipx = 128;
|
||||
const int b1chipy = 256;
|
||||
// total number of pixels
|
||||
int nTotx = nPixelsx + (nMod1GapPixelsx * nModx) + (modGapPixelsx * (nModx - 1));
|
||||
int nToty = nPixelsy + (nMod1GapPixelsy * nMody) + (modGapPixelsy * (nMody - 1));
|
||||
// total number of chips
|
||||
int nChipx = nPixelsx / nChipPixelsx;
|
||||
int nChipy = nPixelsy / nChipPixelsy;
|
||||
|
||||
double bytesPerPixel = (double)dr / 8.00;
|
||||
int imagesize = nTotx * nToty * bytesPerPixel;
|
||||
|
||||
int nChipBytesx = nChipPixelsx * bytesPerPixel; // 1 chip bytes in x
|
||||
int nChipGapBytesx = chipGapPixelsx * bytesPerPixel; // 2 pixel bytes
|
||||
int nModGapBytesx = modGapPixelsx * bytesPerPixel; // 8 pixel bytes
|
||||
int nChipBytesy = nChipPixelsy * nTotx * bytesPerPixel; // 1 chip bytes in y
|
||||
int nChipGapBytesy = chipGapPixelsy * nTotx * bytesPerPixel; // 2 lines
|
||||
int nModGapBytesy = modGapPixelsy * nTotx * bytesPerPixel; // 36 lines
|
||||
// 4 bit mode, its 1 byte (because for 4 bit mode, we handle 1 byte at a time)
|
||||
int pixel1 = (int)(ceil(bytesPerPixel));
|
||||
int row1Bytes = nTotx * bytesPerPixel;
|
||||
int nMod1TotPixelsx = nMod1Pixelsx + nMod1GapPixelsx;
|
||||
if (dr == 4) {
|
||||
nMod1TotPixelsx /= 2;
|
||||
}
|
||||
// eiger requires inter chip gap pixels are halved
|
||||
// jungfrau prefers same inter chip gap pixels as the boundary pixels
|
||||
int divisionValue = 2;
|
||||
slsDetectorDefs::detectorType detType = multi_shm()->multiDetectorType;
|
||||
if (detType == JUNGFRAU) {
|
||||
divisionValue = 1;
|
||||
}
|
||||
LOG(logDEBUG)
|
||||
<< "Insert Gap pixels Calculations:\n\t"
|
||||
<< "nPixelsx: " << nPixelsx << "\n\t"
|
||||
<< "nPixelsy: " << nPixelsy << "\n\t"
|
||||
<< "nMod1Pixelsx: " << nMod1Pixelsx << "\n\t"
|
||||
<< "nMod1Pixelsy: " << nMod1Pixelsy << "\n\t"
|
||||
<< "nMod1GapPixelsx: " << nMod1GapPixelsx << "\n\t"
|
||||
<< "nMod1GapPixelsy: " << nMod1GapPixelsy << "\n\t"
|
||||
<< "nChipy: " << nChipy << "\n\t"
|
||||
<< "nChipx: " << nChipx << "\n\t"
|
||||
<< "nModx: " << nModx << "\n\t"
|
||||
<< "nMody: " << nMody << "\n\t"
|
||||
<< "nTotx: " << nTotx << "\n\t"
|
||||
<< "nToty: " << nToty << "\n\t"
|
||||
<< "bytesPerPixel: " << bytesPerPixel << "\n\t"
|
||||
<< "imagesize: " << imagesize << "\n\t"
|
||||
<< "nChipBytesx: " << nChipBytesx << "\n\t"
|
||||
<< "nChipGapBytesx: " << nChipGapBytesx << "\n\t"
|
||||
<< "nModGapBytesx: " << nModGapBytesx << "\n\t"
|
||||
<< "nChipBytesy: " << nChipBytesy << "\n\t"
|
||||
<< "nChipGapBytesy: " << nChipGapBytesy << "\n\t"
|
||||
<< "nModGapBytesy: " << nModGapBytesy << "\n\t"
|
||||
<< "pixel1: " << pixel1 << "\n\t"
|
||||
<< "row1Bytes: " << row1Bytes << "\n\t"
|
||||
<< "nMod1TotPixelsx: " << nMod1TotPixelsx << "\n\t"
|
||||
<< "divisionValue: " << divisionValue << "\n\n";
|
||||
|
||||
if (gpImage == NULL) {
|
||||
gpImage = new char[imagesize];
|
||||
}
|
||||
memset(gpImage, 0xFF, imagesize);
|
||||
//memcpy(gpImage, image, imagesize);
|
||||
char *src = nullptr;
|
||||
char *dst = nullptr;
|
||||
|
||||
// copying line by line
|
||||
src = image;
|
||||
dst = gpImage;
|
||||
for (int row = 0; row < nychip; ++row) { // for each chip row
|
||||
for (int ichipy = 0; ichipy < b1chipy;
|
||||
++ichipy) { // for each row in a chip
|
||||
for (int col = 0; col < nxchip; ++col) { // for each chip in a row
|
||||
memcpy(dst, src, b1chipx);
|
||||
src += b1chipx;
|
||||
dst += b1chipx;
|
||||
if (((col + 1) % nchipInRow) != 0) { // skip gap pixels
|
||||
++dst;
|
||||
// for each chip row in y
|
||||
for (int iChipy = 0; iChipy < nChipy; ++iChipy) {
|
||||
// for each row
|
||||
for (int iy = 0; iy < nChipPixelsy; ++iy) {
|
||||
// in each row, for every chip
|
||||
for (int iChipx = 0; iChipx < nChipx; ++iChipx) {
|
||||
// copy 1 chip line
|
||||
memcpy(dst, src, nChipBytesx);
|
||||
src += nChipBytesx;
|
||||
dst += nChipBytesx;
|
||||
// skip inter chip gap pixels in x
|
||||
if (((iChipx + 1) % nMod1Chipx) != 0) {
|
||||
dst += nChipGapBytesx;
|
||||
}
|
||||
// skip inter module gap pixels in x
|
||||
else if (iChipx + 1 != nChipx) {
|
||||
dst += nModGapBytesx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dst += (2 * nxb);
|
||||
// skip inter chip gap pixels in y
|
||||
if (((iChipy + 1) % nMod1Chipy) != 0) {
|
||||
dst += nChipGapBytesy;
|
||||
}
|
||||
// skip inter module gap pixels in y
|
||||
else if (iChipy + 1 != nChipy) {
|
||||
dst += nModGapBytesy;
|
||||
}
|
||||
}
|
||||
|
||||
// vertical filling of values
|
||||
{
|
||||
uint8_t temp, g1, g2;
|
||||
int mod;
|
||||
dst = gpImage;
|
||||
for (int row = 0; row < nychip; ++row) { // for each chip row
|
||||
for (int ichipy = 0; ichipy < b1chipy;
|
||||
++ichipy) { // for each row in a chip
|
||||
for (int col = 0; col < nxchip;
|
||||
++col) { // for each chip in a row
|
||||
dst += b1chipx;
|
||||
mod = (col + 1) % nchipInRow; // get gap pixels
|
||||
// copy gap pixel(chip 0, 1, 2)
|
||||
if (mod != 0) {
|
||||
// iner chip gap pixel values is half of neighboring one
|
||||
// (corners becomes divide by 4 automatically after horizontal filling)
|
||||
|
||||
// vertical filling of inter chip gap pixels
|
||||
dst = gpImage;
|
||||
// for each chip row in y
|
||||
for (int iChipy = 0; iChipy < nChipy; ++iChipy) {
|
||||
// for each row
|
||||
for (int iy = 0; iy < nChipPixelsy; ++iy) {
|
||||
// in each row, for every chip
|
||||
for (int iChipx = 0; iChipx < nChipx; ++iChipx) {
|
||||
// go to gap pixels
|
||||
dst += nChipBytesx;
|
||||
// fix inter chip gap pixels in x
|
||||
if (((iChipx + 1) % nMod1Chipx) != 0) {
|
||||
uint8_t temp8 = 0;
|
||||
uint16_t temp16 = 0;
|
||||
uint32_t temp32 = 0;
|
||||
uint8_t g1 = 0;
|
||||
uint8_t g2 = 0;
|
||||
switch (dr) {
|
||||
case 4:
|
||||
// neighbouring gap pixels to left
|
||||
temp = (*((uint8_t *)(dst - 1)));
|
||||
g1 = ((temp & 0xF) / 2);
|
||||
(*((uint8_t *)(dst - 1))) = (temp & 0xF0) + g1;
|
||||
|
||||
temp8 = (*((uint8_t *)(dst - 1)));
|
||||
g1 = ((temp8 & 0xF) / 2);
|
||||
(*((uint8_t *)(dst - 1))) = (temp8 & 0xF0) + g1;
|
||||
// neighbouring gap pixels to right
|
||||
temp = (*((uint8_t *)(dst + 1)));
|
||||
g2 = ((temp >> 4) / 2);
|
||||
(*((uint8_t *)(dst + 1))) = (g2 << 4) + (temp & 0x0F);
|
||||
|
||||
temp8 = (*((uint8_t *)(dst + 1)));
|
||||
g2 = ((temp8 >> 4) / 2);
|
||||
(*((uint8_t *)(dst + 1))) = (g2 << 4) + (temp8 & 0x0F);
|
||||
// gap pixels
|
||||
(*((uint8_t *)dst)) = (g1 << 4) + g2;
|
||||
|
||||
// increment to point to proper chip destination
|
||||
++dst;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
// neighbouring gap pixels to left
|
||||
temp8 = (*((uint8_t *)(dst - pixel1))) / 2;
|
||||
(*((uint8_t *)dst)) = temp8;
|
||||
(*((uint8_t *)(dst - pixel1))) = temp8;
|
||||
// neighbouring gap pixels to right
|
||||
temp8 = (*((uint8_t *)(dst + 2 * pixel1))) / 2;
|
||||
(*((uint8_t *)(dst + pixel1))) = temp8;
|
||||
(*((uint8_t *)(dst + 2 * pixel1))) = temp8;
|
||||
break;
|
||||
case 16:
|
||||
// neighbouring gap pixels to left
|
||||
temp16 = (*((uint16_t *)(dst - pixel1))) / divisionValue;
|
||||
(*((uint16_t *)dst)) = temp16;
|
||||
(*((uint16_t *)(dst - pixel1))) = temp16;
|
||||
// neighbouring gap pixels to right
|
||||
temp16 = (*((uint16_t *)(dst + 2 * pixel1))) / divisionValue;
|
||||
(*((uint16_t *)(dst + pixel1))) = temp16;
|
||||
(*((uint16_t *)(dst + 2 * pixel1))) = temp16;
|
||||
break;
|
||||
default:
|
||||
// neighbouring gap pixels to left
|
||||
temp32 = (*((uint32_t *)(dst - pixel1))) / 2;
|
||||
(*((uint32_t *)dst)) = temp32;
|
||||
(*((uint32_t *)(dst - pixel1))) = temp32;
|
||||
// neighbouring gap pixels to right
|
||||
temp32 = (*((uint32_t *)(dst + 2 * pixel1))) / 2;
|
||||
(*((uint32_t *)(dst + pixel1))) = temp32;
|
||||
(*((uint32_t *)(dst + 2 * pixel1))) = temp32;
|
||||
break;
|
||||
}
|
||||
dst += nChipGapBytesx;
|
||||
}
|
||||
// skip inter module gap pixels in x
|
||||
else if (iChipx + 1 != nChipx) {
|
||||
dst += nModGapBytesx;
|
||||
}
|
||||
}
|
||||
|
||||
dst += (2 * nxb);
|
||||
}
|
||||
// skip inter chip gap pixels in y
|
||||
if (((iChipy + 1) % nMod1Chipy) != 0) {
|
||||
dst += nChipGapBytesy;
|
||||
}
|
||||
// skip inter module gap pixels in y
|
||||
else if (iChipy + 1 != nChipy) {
|
||||
dst += nModGapBytesy;
|
||||
}
|
||||
}
|
||||
|
||||
// return gapdatabytes;
|
||||
// horizontal filling
|
||||
{
|
||||
uint8_t temp, g1, g2;
|
||||
char *dst_prevline = nullptr;
|
||||
dst = gpImage;
|
||||
for (int row = 0; row < nychip; ++row) { // for each chip row
|
||||
dst += (b1chipy * nxb);
|
||||
// horizontal copying of gap pixels from neighboring past line
|
||||
// (bottom parts)
|
||||
if (row < nychip - 1) {
|
||||
dst_prevline = dst - nxb;
|
||||
for (int gapline = 0; gapline < nxb; ++gapline) {
|
||||
temp = (*((uint8_t *)dst_prevline));
|
||||
g1 = ((temp >> 4) / 2);
|
||||
g2 = ((temp & 0xF) / 2);
|
||||
(*((uint8_t *)dst_prevline)) = (g1 << 4) + g2;
|
||||
(*((uint8_t *)dst)) = (*((uint8_t *)dst_prevline));
|
||||
++dst;
|
||||
++dst_prevline;
|
||||
// horizontal filling of inter chip gap pixels
|
||||
// starting at bottom part (1 line below to copy from)
|
||||
src = gpImage + (nChipBytesy - row1Bytes);
|
||||
dst = gpImage + nChipBytesy;
|
||||
// for each chip row in y
|
||||
for (int iChipy = 0; iChipy < nChipy; ++iChipy) {
|
||||
// for each module in x
|
||||
for (int iModx = 0; iModx < nModx; ++iModx) {
|
||||
// in each module, for every pixel in x
|
||||
for (int iPixel = 0; iPixel < nMod1TotPixelsx; ++iPixel) {
|
||||
uint8_t temp8 = 0, g1 = 0, g2 = 0;
|
||||
uint16_t temp16 = 0;
|
||||
uint32_t temp32 = 0;
|
||||
switch (dr) {
|
||||
case 4:
|
||||
temp8 = (*((uint8_t *)src));
|
||||
g1 = ((temp8 >> 4) / 2);
|
||||
g2 = ((temp8 & 0xF) / 2);
|
||||
temp8 = (g1 << 4) + g2;
|
||||
(*((uint8_t *)dst)) = temp8;
|
||||
(*((uint8_t *)src)) = temp8;
|
||||
break;
|
||||
case 8:
|
||||
temp8 = (*((uint8_t *)src)) / divisionValue;
|
||||
(*((uint8_t *)dst)) = temp8;
|
||||
(*((uint8_t *)src)) = temp8;
|
||||
break;
|
||||
case 16:
|
||||
temp16 = (*((uint16_t *)src)) / divisionValue;
|
||||
(*((uint16_t *)dst)) = temp16;
|
||||
(*((uint16_t *)src)) = temp16;
|
||||
break;
|
||||
default:
|
||||
temp32 = (*((uint32_t *)src)) / 2;
|
||||
(*((uint32_t *)dst)) = temp32;
|
||||
(*((uint32_t *)src)) = temp32;
|
||||
break;
|
||||
}
|
||||
// every pixel (but 4 bit mode, every byte)
|
||||
src += pixel1;
|
||||
dst += pixel1;
|
||||
}
|
||||
|
||||
// horizontal copying of gap pixels from neihboring future line (top
|
||||
// part)
|
||||
if (row > 0) {
|
||||
dst -= ((b1chipy + 1) * nxb);
|
||||
dst_prevline = dst + nxb;
|
||||
for (int gapline = 0; gapline < nxb; ++gapline) {
|
||||
temp = (*((uint8_t *)dst_prevline));
|
||||
g1 = ((temp >> 4) / 2);
|
||||
g2 = ((temp & 0xF) / 2);
|
||||
temp = (g1 << 4) + g2;
|
||||
(*((uint8_t *)dst_prevline)) = temp;
|
||||
(*((uint8_t *)dst)) = temp;
|
||||
++dst;
|
||||
++dst_prevline;
|
||||
}
|
||||
dst += ((b1chipy + 1) * nxb);
|
||||
// skip inter module gap pixels in x
|
||||
if (iModx + 1 < nModx) {
|
||||
src += nModGapBytesx;
|
||||
dst += nModGapBytesx;
|
||||
}
|
||||
|
||||
dst += nxb;
|
||||
}
|
||||
// bottom parts, skip inter chip gap pixels
|
||||
if ((iChipy % nMod1Chipy) == 0) {
|
||||
src += nChipGapBytesy;
|
||||
}
|
||||
// top parts, skip inter module gap pixels and two chips
|
||||
else {
|
||||
src += (nModGapBytesy + 2 * nChipBytesy - 2 * row1Bytes);
|
||||
dst += (nModGapBytesy + 2 * nChipBytesy);
|
||||
}
|
||||
}
|
||||
|
||||
return gapdatabytes;
|
||||
nPixelsx = nTotx;
|
||||
nPixelsy = nToty;
|
||||
return imagesize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool DetectorImpl::enableDataStreamingToClient(int enable) {
|
||||
if (enable >= 0) {
|
||||
// destroy data threads
|
||||
|
@ -16,7 +16,7 @@ class detectorData;
|
||||
#include <vector>
|
||||
|
||||
#define MULTI_SHMAPIVERSION 0x190809
|
||||
#define MULTI_SHMVERSION 0x200131
|
||||
#define MULTI_SHMVERSION 0x200319
|
||||
#define SHORT_STRING_LENGTH 50
|
||||
|
||||
#include <future>
|
||||
@ -47,10 +47,7 @@ struct sharedMultiSlsDetector {
|
||||
/** last time stamp when accessing the shared memory */
|
||||
char lastDate[SHORT_STRING_LENGTH];
|
||||
|
||||
/** number of sls detectors in shared memory */
|
||||
int numberOfDetectors;
|
||||
|
||||
/** multi detector type */
|
||||
slsDetectorDefs::detectorType multiDetectorType;
|
||||
|
||||
/** END OF FIXED PATTERN
|
||||
@ -62,11 +59,9 @@ struct sharedMultiSlsDetector {
|
||||
/** max number of channels for complete detector*/
|
||||
slsDetectorDefs::xy numberOfChannels;
|
||||
|
||||
/** flag for acquiring */
|
||||
bool acquiringFlag;
|
||||
|
||||
/** initial checks */
|
||||
bool initialChecks;
|
||||
bool gapPixels;
|
||||
};
|
||||
|
||||
class DetectorImpl : public virtual slsDetectorDefs {
|
||||
@ -236,11 +231,10 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* Sets maximum number of channels of all sls detectors */
|
||||
void setNumberOfChannels(const slsDetectorDefs::xy c);
|
||||
|
||||
/**
|
||||
* Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger)
|
||||
* 4 bit mode gap pixels only in gui call back
|
||||
*/
|
||||
void setGapPixelsinReceiver(bool enable);
|
||||
/** [Eiger][Jungfrau] */
|
||||
bool getGapPixelsinCallback() const;
|
||||
/** [Eiger][Jungfrau] */
|
||||
void setGapPixelsinCallback(const bool enable);
|
||||
|
||||
/**
|
||||
* Enable data streaming to client
|
||||
@ -347,15 +341,18 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
*/
|
||||
void readFrameFromReceiver();
|
||||
|
||||
/**
|
||||
* add gap pixels to the image (only for Eiger in 4 bit mode)
|
||||
/** [Eiger][Jungfrau]
|
||||
* add gap pixels to the imag
|
||||
* @param image pointer to image without gap pixels
|
||||
* @param gpImage poiner to image with gap pixels, if NULL, allocated
|
||||
* inside function
|
||||
* quadEnable quad enabled
|
||||
* @returns number of data bytes of image with gap pixels
|
||||
* @param quadEnable quad enabled
|
||||
* @param dr dynamic range
|
||||
* @param nPixelsx number of pixels in X axis (updated)
|
||||
* @param nPixelsy number of pixels in Y axis (updated)
|
||||
* @returns total data bytes for updated image
|
||||
*/
|
||||
int processImageWithGapPixels(char *image, char *&gpImage, bool quadEnable);
|
||||
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
|
||||
int &nPixelsx, int &nPixelsy);
|
||||
|
||||
double setTotalProgress();
|
||||
|
||||
|
@ -410,7 +410,6 @@ void Module::initializeDetectorStructure(detectorType type) {
|
||||
shm()->zmqport = DEFAULT_ZMQ_CL_PORTNO +
|
||||
(detId * ((shm()->myDetectorType == EIGER) ? 2 : 1));
|
||||
shm()->zmqip = IpAddr{};
|
||||
shm()->gappixels = 0U;
|
||||
shm()->numUDPInterfaces = 1;
|
||||
shm()->stoppedFlag = false;
|
||||
|
||||
@ -422,8 +421,6 @@ void Module::initializeDetectorStructure(detectorType type) {
|
||||
shm()->nChip.y = parameters.nChipY;
|
||||
shm()->nDacs = parameters.nDacs;
|
||||
shm()->dynamicRange = parameters.dynamicRange;
|
||||
shm()->nGappixels.x = parameters.nGappixelsX;
|
||||
shm()->nGappixels.y = parameters.nGappixelsY;
|
||||
}
|
||||
|
||||
int Module::sendModule(sls_detector_module *myMod,
|
||||
@ -582,10 +579,8 @@ void Module::updateNumberOfChannels() {
|
||||
|
||||
slsDetectorDefs::xy Module::getNumberOfChannels() const {
|
||||
slsDetectorDefs::xy coord{};
|
||||
coord.x = (shm()->nChan.x * shm()->nChip.x +
|
||||
shm()->gappixels * shm()->nGappixels.x);
|
||||
coord.y = (shm()->nChan.y * shm()->nChip.y +
|
||||
shm()->gappixels * shm()->nGappixels.y);
|
||||
coord.x = (shm()->nChan.x * shm()->nChip.x);
|
||||
coord.y = (shm()->nChan.y * shm()->nChip.y);
|
||||
return coord;
|
||||
}
|
||||
|
||||
@ -937,23 +932,17 @@ int Module::getThresholdEnergy() {
|
||||
return retval;
|
||||
}
|
||||
|
||||
int Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
|
||||
void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
|
||||
int tb) {
|
||||
|
||||
// check as there is client processing
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
setThresholdEnergyAndSettings(e_eV, isettings, tb);
|
||||
return e_eV;
|
||||
}
|
||||
|
||||
// moench - send threshold energy to processor
|
||||
else if (shm()->myDetectorType == MOENCH) {
|
||||
std::string result =
|
||||
setAdditionalJsonParameter("threshold", std::to_string(e_eV));
|
||||
if (result == std::to_string(e_eV)) {
|
||||
return e_eV;
|
||||
}
|
||||
return -1;
|
||||
setAdditionalJsonParameter("threshold", std::to_string(e_eV));
|
||||
}
|
||||
throw RuntimeError(
|
||||
"Set threshold energy not implemented for this detector");
|
||||
@ -1719,7 +1708,6 @@ std::string Module::setReceiverHostname(const std::string &receiverIP) {
|
||||
setSubDeadTime(getSubDeadTime());
|
||||
setDynamicRange(shm()->dynamicRange);
|
||||
activate(-1);
|
||||
enableGapPixels(shm()->gappixels);
|
||||
enableTenGigabitEthernet(-1);
|
||||
setQuad(getQuad());
|
||||
break;
|
||||
@ -2105,106 +2093,99 @@ void Module::setTransmissionDelayRight(int value) {
|
||||
}
|
||||
|
||||
|
||||
void Module::setAdditionalJsonHeader(const std::string &jsonheader) {
|
||||
void Module::setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader) {
|
||||
if (!shm()->useReceiverFlag) {
|
||||
throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json header)");
|
||||
}
|
||||
char args[MAX_STR_LENGTH]{};
|
||||
sls::strcpy_safe(args, jsonheader.c_str());
|
||||
sendToReceiver(F_SET_ADDITIONAL_JSON_HEADER, args, nullptr);
|
||||
}
|
||||
|
||||
std::string Module::getAdditionalJsonHeader() {
|
||||
if (!shm()->useReceiverFlag) {
|
||||
throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json header)");
|
||||
}
|
||||
char retvals[MAX_STR_LENGTH]{};
|
||||
sendToReceiver(F_GET_ADDITIONAL_JSON_HEADER, nullptr, retvals);
|
||||
return std::string(retvals);
|
||||
}
|
||||
|
||||
std::string Module::setAdditionalJsonParameter(const std::string &key,
|
||||
const std::string &value) {
|
||||
if (key.empty() || value.empty()) {
|
||||
throw RuntimeError(
|
||||
"Could not set additional json header parameter as the key or "
|
||||
"value is empty");
|
||||
}
|
||||
|
||||
// validation (ignore if key or value has , : ")
|
||||
if (key.find_first_of(",\":") != std::string::npos ||
|
||||
value.find_first_of(",\":") != std::string::npos) {
|
||||
throw RuntimeError("Could not set additional json header parameter as "
|
||||
"the key or value has "
|
||||
"illegal characters (,\":)");
|
||||
}
|
||||
|
||||
// create actual key to search for and actual value to put, (key has
|
||||
// additional ':' as value could exist the same way)
|
||||
std::string keyLiteral(std::string("\"") + key + std::string("\":"));
|
||||
std::string valueLiteral(value);
|
||||
// add quotations to value only if it is a string
|
||||
try {
|
||||
std::stoi(valueLiteral);
|
||||
} catch (...) {
|
||||
// add quotations if it failed to convert to integer, otherwise nothing
|
||||
valueLiteral.insert(0, "\"");
|
||||
valueLiteral.append("\"");
|
||||
}
|
||||
|
||||
std::string header = getAdditionalJsonHeader();
|
||||
size_t keyPos = header.find(keyLiteral);
|
||||
|
||||
// if key found, replace value
|
||||
if (keyPos != std::string::npos) {
|
||||
size_t valueStartPos = header.find(std::string(":"), keyPos) + 1;
|
||||
size_t valueEndPos = header.find(std::string(","), valueStartPos) - 1;
|
||||
// if valueEndPos doesnt find comma (end of string), it goes anyway to
|
||||
// end of line
|
||||
header.replace(valueStartPos, valueEndPos - valueStartPos + 1,
|
||||
valueLiteral);
|
||||
}
|
||||
|
||||
// key not found, append key value pair
|
||||
else {
|
||||
if (header.length() != 0U) {
|
||||
header.append(",");
|
||||
for (auto &it : jsonHeader) {
|
||||
if (it.first.empty() || it.first.length() > SHORT_STR_LENGTH ||
|
||||
it.second.length() > SHORT_STR_LENGTH ) {
|
||||
throw RuntimeError(it.first + " or " + it.second + " pair has invalid size. "
|
||||
"Key cannot be empty. Both can have max 20 characters");
|
||||
}
|
||||
header.append(keyLiteral + valueLiteral);
|
||||
}
|
||||
const int size = jsonHeader.size();
|
||||
int fnum = F_SET_ADDITIONAL_JSON_HEADER;
|
||||
int ret = FAIL;
|
||||
LOG(logDEBUG) << "Sending to receiver additional json header " << ToString(jsonHeader);
|
||||
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
|
||||
client.Send(&fnum, sizeof(fnum));
|
||||
client.Send(&size, sizeof(size));
|
||||
if (size > 0) {
|
||||
char args[size * 2][SHORT_STR_LENGTH];
|
||||
memset(args, 0, sizeof(args));
|
||||
int iarg = 0;
|
||||
for (auto &it : jsonHeader) {
|
||||
sls::strcpy_safe(args[iarg], it.first.c_str());
|
||||
sls::strcpy_safe(args[iarg + 1], it.second.c_str());
|
||||
iarg += 2;
|
||||
}
|
||||
client.Send(args, sizeof(args));
|
||||
}
|
||||
client.Receive(&ret, sizeof(ret));
|
||||
if (ret == FAIL) {
|
||||
char mess[MAX_STR_LENGTH]{};
|
||||
client.Receive(mess, MAX_STR_LENGTH);
|
||||
throw RuntimeError("Receiver " + std::to_string(detId) +
|
||||
" returned error: " + std::string(mess));
|
||||
}
|
||||
}
|
||||
|
||||
// update additional json header
|
||||
setAdditionalJsonHeader(header);
|
||||
return getAdditionalJsonParameter(key);
|
||||
std::map<std::string, std::string> Module::getAdditionalJsonHeader() {
|
||||
if (!shm()->useReceiverFlag) {
|
||||
throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json header)");
|
||||
}
|
||||
int fnum = F_GET_ADDITIONAL_JSON_HEADER;
|
||||
int ret = FAIL;
|
||||
int size = 0;
|
||||
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
|
||||
client.Send(&fnum, sizeof(fnum));
|
||||
client.Receive(&ret, sizeof(ret));
|
||||
if (ret == FAIL) {
|
||||
char mess[MAX_STR_LENGTH]{};
|
||||
client.Receive(mess, MAX_STR_LENGTH);
|
||||
throw RuntimeError("Receiver " + std::to_string(detId) +
|
||||
" returned error: " + std::string(mess));
|
||||
} else {
|
||||
client.Receive(&size, sizeof(size));
|
||||
std::map<std::string, std::string> retval;
|
||||
if (size > 0) {
|
||||
char retvals[size * 2][SHORT_STR_LENGTH];
|
||||
memset(retvals, 0, sizeof(retvals));
|
||||
client.Receive(retvals, sizeof(retvals));
|
||||
for (int i = 0; i < size; ++i) {
|
||||
retval[retvals[2 * i]] = retvals[2 * i + 1];
|
||||
}
|
||||
}
|
||||
LOG(logDEBUG) << "Getting additional json header " << ToString(retval);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
void Module::setAdditionalJsonParameter(const std::string &key, const std::string &value) {
|
||||
if (!shm()->useReceiverFlag) {
|
||||
throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json parameter)");
|
||||
}
|
||||
if (key.empty() || key.length() > SHORT_STR_LENGTH ||
|
||||
value.length() > SHORT_STR_LENGTH ) {
|
||||
throw RuntimeError(key + " or " + value + " pair has invalid size. "
|
||||
"Key cannot be empty. Both can have max 2 characters");
|
||||
}
|
||||
char args[2][SHORT_STR_LENGTH]{};
|
||||
sls::strcpy_safe(args[0], key.c_str());
|
||||
sls::strcpy_safe(args[1], value.c_str());
|
||||
sendToReceiver(F_SET_ADDITIONAL_JSON_PARAMETER, args, nullptr);
|
||||
}
|
||||
|
||||
std::string Module::getAdditionalJsonParameter(const std::string &key) {
|
||||
// additional json header is empty
|
||||
std::string jsonheader = getAdditionalJsonHeader();
|
||||
if (jsonheader.empty())
|
||||
return jsonheader;
|
||||
|
||||
// add quotations before and after the key value
|
||||
std::string keyLiteral = key;
|
||||
keyLiteral.insert(0, "\"");
|
||||
keyLiteral.append("\"");
|
||||
|
||||
// loop through the parameters
|
||||
for (const auto ¶meter :
|
||||
sls::split(jsonheader, ',')) {
|
||||
// get a vector of key value pair for each parameter
|
||||
const auto &pairs = sls::split(parameter, ':');
|
||||
// match for key
|
||||
if (pairs[0] == keyLiteral) {
|
||||
// return value without quotations (if it has any)
|
||||
if (pairs[1][0] == '\"')
|
||||
return pairs[1].substr(1, pairs[1].length() - 2);
|
||||
else
|
||||
return pairs[1];
|
||||
}
|
||||
if (!shm()->useReceiverFlag) {
|
||||
throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json parameter)");
|
||||
}
|
||||
// return empty string as no match found with key
|
||||
return std::string();
|
||||
char arg[SHORT_STR_LENGTH]{};
|
||||
sls::strcpy_safe(arg, key.c_str());
|
||||
char retval[SHORT_STR_LENGTH]{};
|
||||
sendToReceiver(F_GET_ADDITIONAL_JSON_PARAMETER, arg, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int64_t Module::setReceiverUDPSocketBufferSize(int64_t udpsockbufsize) {
|
||||
@ -2672,24 +2653,6 @@ int Module::setAllTrimbits(int val) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
int Module::enableGapPixels(int val) {
|
||||
if (val >= 0) {
|
||||
if (shm()->myDetectorType != EIGER) {
|
||||
throw NotImplementedError(
|
||||
"Function (enableGapPixels) not implemented for this detector");
|
||||
}
|
||||
int fnum = F_ENABLE_GAPPIXELS_IN_RECEIVER;
|
||||
int retval = -1;
|
||||
LOG(logDEBUG1) << "Sending gap pixels enable to receiver: " << val;
|
||||
if (shm()->useReceiverFlag) {
|
||||
sendToReceiver(fnum, val, retval);
|
||||
LOG(logDEBUG1) << "Gap pixels enable to receiver:" << retval;
|
||||
shm()->gappixels = retval;
|
||||
}
|
||||
}
|
||||
return shm()->gappixels;
|
||||
}
|
||||
|
||||
int Module::setTrimEn(const std::vector<int>& energies) {
|
||||
if (shm()->myDetectorType != EIGER) {
|
||||
throw RuntimeError("setTrimEn not implemented for this detector.");
|
||||
@ -3084,33 +3047,6 @@ void Module::execReceiverCommand(const std::string &cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
void Module::updateCachedReceiverVariables() const {
|
||||
int fnum = F_UPDATE_RECEIVER_CLIENT;
|
||||
LOG(logDEBUG1) << "Sending update client to receiver server";
|
||||
|
||||
if (shm()->useReceiverFlag) {
|
||||
auto receiver =
|
||||
sls::ClientSocket("Receiver", shm()->rxHostname, shm()->rxTCPPort);
|
||||
receiver.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0);
|
||||
int n = 0, i32 = 0;
|
||||
IpAddr ip;
|
||||
|
||||
n += receiver.Receive(&ip, sizeof(ip));
|
||||
LOG(logDEBUG1)
|
||||
<< "Updating receiver last modified by " << ip;
|
||||
|
||||
// gap pixels
|
||||
n += receiver.Receive(&i32, sizeof(i32));
|
||||
shm()->gappixels = i32;
|
||||
|
||||
if (n == 0) {
|
||||
throw RuntimeError(
|
||||
"Could not update receiver: " + std::string(shm()->rxHostname) +
|
||||
", received 0 bytes\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Module::sendMultiDetectorSize() {
|
||||
int args[]{shm()->multiSize.x, shm()->multiSize.y};
|
||||
int retval = -1;
|
||||
@ -3317,9 +3253,6 @@ std::vector<uint64_t> Module::getNumMissingPackets() const {
|
||||
throw RuntimeError("Receiver " + std::to_string(detId) +
|
||||
" returned error: " + std::string(mess));
|
||||
} else {
|
||||
if (ret == FORCE_UPDATE) {
|
||||
updateCachedReceiverVariables();
|
||||
}
|
||||
int nports = -1;
|
||||
client.Receive(&nports, sizeof(nports));
|
||||
uint64_t mp[nports];
|
||||
|
@ -9,11 +9,12 @@
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class ServerInterface;
|
||||
|
||||
#define SLS_SHMAPIVERSION 0x190726
|
||||
#define SLS_SHMVERSION 0x200318
|
||||
#define SLS_SHMVERSION 0x200324
|
||||
|
||||
namespace sls{
|
||||
|
||||
@ -104,12 +105,6 @@ struct sharedSlsDetector {
|
||||
/** zmq tcp src ip address in client (only data) **/
|
||||
sls::IpAddr zmqip;
|
||||
|
||||
/** gap pixels enable */
|
||||
int gappixels;
|
||||
|
||||
/** gap pixels in each direction */
|
||||
slsDetectorDefs::xy nGappixels;
|
||||
|
||||
/** num udp interfaces */
|
||||
int numUDPInterfaces;
|
||||
|
||||
@ -221,10 +216,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
*/
|
||||
void updateNumberOfChannels();
|
||||
|
||||
/**
|
||||
* Returns the total number of channels including gap pixels
|
||||
* @returns the total number of channels including gap pixels
|
||||
*/
|
||||
|
||||
slsDetectorDefs::xy getNumberOfChannels() const;
|
||||
|
||||
/**
|
||||
@ -353,9 +345,8 @@ class Module : public virtual slsDetectorDefs {
|
||||
* @param e_eV threshold in eV
|
||||
* @param isettings ev. change settings
|
||||
* @param tb 1 to include trimbits, 0 to exclude
|
||||
* @returns current threshold value in ev (-1 failed)
|
||||
*/
|
||||
int setThresholdEnergy(int e_eV, detectorSettings isettings = GET_SETTINGS,
|
||||
void setThresholdEnergy(int e_eV, detectorSettings isettings = GET_SETTINGS,
|
||||
int tb = 1);
|
||||
|
||||
/**
|
||||
@ -988,36 +979,14 @@ class Module : public virtual slsDetectorDefs {
|
||||
*/
|
||||
void setTransmissionDelayRight(int value);
|
||||
|
||||
/**
|
||||
* Sets the additional json header\sa sharedSlsDetector
|
||||
* @param jsonheader additional json header
|
||||
*/
|
||||
void setAdditionalJsonHeader(const std::string &jsonheader);
|
||||
/** empty vector deletes entire additional json header */
|
||||
void setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader);
|
||||
std::map<std::string, std::string> getAdditionalJsonHeader();
|
||||
|
||||
/**
|
||||
* Returns the additional json header \sa sharedSlsDetector
|
||||
* @returns the additional json header, returns "none" if default setting
|
||||
* and no custom ip set
|
||||
*/
|
||||
std::string getAdditionalJsonHeader();
|
||||
|
||||
/**
|
||||
* Sets the value for the additional json header parameter if found, else
|
||||
* append it
|
||||
* @param key additional json header parameter
|
||||
* @param value additional json header parameter value (cannot be empty)
|
||||
* @returns the additional json header parameter value,
|
||||
* empty if no parameter found in additional json header
|
||||
*/
|
||||
std::string setAdditionalJsonParameter(const std::string &key,
|
||||
const std::string &value);
|
||||
|
||||
/**
|
||||
* Returns the additional json header parameter value
|
||||
* @param key additional json header parameter
|
||||
* @returns the additional json header parameter value,
|
||||
* empty if no parameter found in additional json header
|
||||
*/
|
||||
* Sets the value for the additional json header parameter key if found, else
|
||||
* append it. If value empty, then deletes parameter */
|
||||
void setAdditionalJsonParameter(const std::string &key, const std::string &value);
|
||||
std::string getAdditionalJsonParameter(const std::string &key);
|
||||
|
||||
/**
|
||||
@ -1045,11 +1014,13 @@ class Module : public virtual slsDetectorDefs {
|
||||
/** [Gotthard][Jungfrau][CTB][Moench] */
|
||||
void executeBusTest();
|
||||
|
||||
/** [Gotthard] */
|
||||
/** [Gotthard][Eiger virtual] */
|
||||
int getImageTestMode();
|
||||
|
||||
/** [Gotthard] If 1, adds channel intensity with precalculated values.
|
||||
* Default is 0 */
|
||||
* Default is 0
|
||||
* [Eiger virtual] If 1, pixels are saturated. If 0, increasing intensity
|
||||
* Only for virtual servers */
|
||||
void setImageTestMode(const int value);
|
||||
|
||||
|
||||
@ -1232,14 +1203,6 @@ class Module : public virtual slsDetectorDefs {
|
||||
*/
|
||||
int setAllTrimbits(int val);
|
||||
|
||||
/**
|
||||
* Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger)
|
||||
* 4 bit mode gap pixels only in gui call back
|
||||
* @param val 1 sets, 0 unsets, -1 gets
|
||||
* @returns gap pixel enable or -1 for error
|
||||
*/
|
||||
int enableGapPixels(int val = -1);
|
||||
|
||||
/**
|
||||
* Sets the number of trim energies and their value (Eiger)
|
||||
* \sa sharedSlsDetector
|
||||
@ -1436,11 +1399,6 @@ class Module : public virtual slsDetectorDefs {
|
||||
*/
|
||||
void execReceiverCommand(const std::string &cmd);
|
||||
|
||||
/**
|
||||
* Updates the shared memory receiving the data from the detector
|
||||
*/
|
||||
void updateCachedReceiverVariables() const;
|
||||
|
||||
/**
|
||||
* Send the multi detector size to the detector
|
||||
* @param detx number of detectors in x dir
|
||||
|
@ -680,7 +680,7 @@ TEST_CASE("rx_dbitlist", "[.cmd][.rx][.new]") {
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::CHIPTESTBOARD) {
|
||||
auto previous = det.getRxDbitList();
|
||||
auto prev_val = det.getRxDbitList();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_dbitlist", {"0", "4", "5", "8", "9", "10", "52", "63"}, -1, PUT, oss);
|
||||
@ -694,9 +694,8 @@ TEST_CASE("rx_dbitlist", "[.cmd][.rx][.new]") {
|
||||
REQUIRE_THROWS(proxy.Call("rx_dbitlist", {"67"}, -1, PUT));
|
||||
REQUIRE_THROWS(proxy.Call("rx_dbitlist", {"-1"}, -1, PUT));
|
||||
REQUIRE_NOTHROW(proxy.Call("rx_dbitlist", {"all"}, -1, PUT));
|
||||
// Reset to previous value
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setRxDbitList(previous[i], {i});
|
||||
det.setRxDbitList(prev_val[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("rx_dbitlist", {}, -1, GET));
|
||||
@ -708,7 +707,7 @@ TEST_CASE("rx_dbitoffset", "[.cmd][.rx][.new]") {
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::CHIPTESTBOARD) {
|
||||
auto previous = det.getRxDbitOffset();
|
||||
auto prev_val = det.getRxDbitOffset();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_dbitoffset", {"1"}, -1, PUT, oss);
|
||||
@ -729,9 +728,8 @@ TEST_CASE("rx_dbitoffset", "[.cmd][.rx][.new]") {
|
||||
proxy.Call("rx_dbitoffset", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "rx_dbitoffset 15\n");
|
||||
}
|
||||
// Reset to previous value
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setRxDbitOffset(previous[i], {i});
|
||||
det.setRxDbitOffset(prev_val[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("rx_dbitoffset", {}, -1, GET));
|
||||
@ -740,7 +738,60 @@ TEST_CASE("rx_dbitoffset", "[.cmd][.rx][.new]") {
|
||||
|
||||
/* Moench */
|
||||
|
||||
//FIXME: rx_jsonaddheader, rx_jsonpara
|
||||
TEST_CASE("rx_jsonaddheader", "[.cmd][.rx][.new]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto prev_val = det.getAdditionalJsonHeader();
|
||||
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_jsonaddheader", {"key1", "value1", "key2", "value2"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_jsonaddheader {key1: value1, key2: value2}\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_jsonaddheader", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "rx_jsonaddheader {key1: value1, key2: value2}\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_jsonaddheader", {}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_jsonaddheader {}\n");
|
||||
}
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setAdditionalJsonHeader(prev_val[i], {i});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("rx_jsonpara", "[.cmd][.rx][.new]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto prev_val = det.getAdditionalJsonHeader();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_jsonpara", {"key1", "value1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_jsonpara {key1: value1}\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_jsonpara", {"key1", "value2"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_jsonpara {key1: value2}\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_jsonpara", {"key1"}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "rx_jsonpara value2\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("rx_jsonpara", {"key1"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "rx_jsonpara key1 deleted\n");
|
||||
}
|
||||
REQUIRE_THROWS(proxy.Call("rx_jsonpara", {"key1"}, -1, GET));
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setAdditionalJsonHeader(prev_val[i], {i});
|
||||
}
|
||||
}
|
||||
|
||||
/* Insignificant */
|
||||
|
||||
|
@ -715,33 +715,6 @@ TEST_CASE("stopport", "[.cmd]") {
|
||||
// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonaddheader \"\"", PUT));
|
||||
// }
|
||||
|
||||
// TEST_CASE("rx_jsonpara", "[.cmd][.moench]") {
|
||||
// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonaddheader
|
||||
// \"key1\":\"value1\"", PUT));
|
||||
// {
|
||||
// std::ostringstream oss;
|
||||
// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonpara key1", GET,
|
||||
// nullptr, oss)); REQUIRE(oss.str() == "rx_jsonpara value1\n");
|
||||
// }
|
||||
// {
|
||||
// std::ostringstream oss;
|
||||
// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonpara key1 value2",
|
||||
// PUT, nullptr, oss)); REQUIRE(oss.str() == "rx_jsonpara [key1,
|
||||
// value2]\n");
|
||||
// }
|
||||
// {
|
||||
// std::ostringstream oss;
|
||||
// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonpara key2 98", PUT,
|
||||
// nullptr, oss)); REQUIRE(oss.str() == "rx_jsonpara [key2, 98]\n");
|
||||
// }
|
||||
// {
|
||||
// std::ostringstream oss;
|
||||
// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonaddheader", GET,
|
||||
// nullptr, oss)); REQUIRE(oss.str() == "rx_jsonaddheader
|
||||
// \"key1\":\"value2\",\"key2\":98\n");
|
||||
// }
|
||||
// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonaddheader \"\"", PUT));
|
||||
// }
|
||||
|
||||
// TEST_CASE("patsetbit", "[.cmd][.ctb]") {
|
||||
// if (test::type == slsDetectorDefs::CHIPTESTBOARD) {
|
||||
|
@ -128,7 +128,6 @@ class BinaryFileStatic {
|
||||
"SubExptime (ns) : %lld\n"
|
||||
"SubPeriod(ns) : %lld\n"
|
||||
"Period (ns) : %lld\n"
|
||||
"Gap Pixels Enable : %d\n"
|
||||
"Quad Enable : %d\n"
|
||||
"Analog Flag : %d\n"
|
||||
"Digital Flag : %d\n"
|
||||
@ -167,7 +166,6 @@ class BinaryFileStatic {
|
||||
(long long int)attr.subExptimeNs,
|
||||
(long long int)attr.subPeriodNs,
|
||||
(long long int)attr.periodNs,
|
||||
attr.gapPixelsEnable,
|
||||
attr.quadEnable,
|
||||
attr.analogFlag,
|
||||
attr.digitalFlag,
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <vector>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
|
||||
using sls::RuntimeError;
|
||||
using sls::SocketError;
|
||||
@ -113,7 +114,6 @@ int ClientInterface::functionTable(){
|
||||
flist[F_LOCK_RECEIVER] = &ClientInterface::lock_receiver;
|
||||
flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip;
|
||||
flist[F_SET_RECEIVER_PORT] = &ClientInterface::set_port;
|
||||
flist[F_UPDATE_RECEIVER_CLIENT] = &ClientInterface::update_client;
|
||||
flist[F_GET_RECEIVER_VERSION] = &ClientInterface::get_version;
|
||||
flist[F_GET_RECEIVER_TYPE] = &ClientInterface::set_detector_type;
|
||||
flist[F_SEND_RECEIVER_DETHOSTNAME] = &ClientInterface::set_detector_hostname;
|
||||
@ -163,7 +163,6 @@ int ClientInterface::functionTable(){
|
||||
flist[F_GET_RECEIVER_STREAMING_SRC_IP] = &ClientInterface::get_streaming_source_ip;
|
||||
flist[F_SET_RECEIVER_SILENT_MODE] = &ClientInterface::set_silent_mode;
|
||||
flist[F_GET_RECEIVER_SILENT_MODE] = &ClientInterface::get_silent_mode;
|
||||
flist[F_ENABLE_GAPPIXELS_IN_RECEIVER] = &ClientInterface::enable_gap_pixels;
|
||||
flist[F_RESTREAM_STOP_FROM_RECEIVER] = &ClientInterface::restream_stop;
|
||||
flist[F_SET_ADDITIONAL_JSON_HEADER] = &ClientInterface::set_additional_json_header;
|
||||
flist[F_GET_ADDITIONAL_JSON_HEADER] = &ClientInterface::get_additional_json_header;
|
||||
@ -194,6 +193,8 @@ int ClientInterface::functionTable(){
|
||||
flist[F_RECEIVER_SET_ADC_MASK_10G] = &ClientInterface::set_adc_mask_10g;
|
||||
flist[F_RECEIVER_SET_NUM_COUNTERS] = &ClientInterface::set_num_counters;
|
||||
flist[F_INCREMENT_FILE_INDEX] = &ClientInterface::increment_file_index;
|
||||
flist[F_SET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::set_additional_json_parameter;
|
||||
flist[F_GET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::get_additional_json_parameter;
|
||||
|
||||
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
|
||||
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
|
||||
@ -325,29 +326,6 @@ int ClientInterface::set_port(Interface &socket) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int ClientInterface::update_client(Interface &socket) {
|
||||
if (receiver == nullptr)
|
||||
throw sls::SocketError(
|
||||
"Receiver not set up. Please use rx_hostname first.\n");
|
||||
socket.Send(OK);
|
||||
return send_update(socket);
|
||||
}
|
||||
|
||||
int ClientInterface::send_update(Interface &socket) {
|
||||
int n = 0;
|
||||
int i32 = -1;
|
||||
|
||||
sls::IpAddr ip;
|
||||
ip = server->getLastClient();
|
||||
n += socket.Send(&ip, sizeof(ip));
|
||||
|
||||
// gap pixels
|
||||
i32 = (int)receiver->getGapPixelsEnable();
|
||||
n += socket.Send(&i32, sizeof(i32));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int ClientInterface::get_version(Interface &socket) {
|
||||
return socket.sendResult(getReceiverVersion());
|
||||
}
|
||||
@ -989,26 +967,6 @@ int ClientInterface::get_silent_mode(Interface &socket) {
|
||||
return socket.sendResult(retval);
|
||||
}
|
||||
|
||||
int ClientInterface::enable_gap_pixels(Interface &socket) {
|
||||
auto enable = socket.Receive<int>();
|
||||
if (myDetectorType != EIGER)
|
||||
functionNotImplemented();
|
||||
|
||||
if (enable >= 0) {
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting gap pixels enable:" << enable;
|
||||
try {
|
||||
impl()->setGapPixelsEnable(static_cast<bool>(enable));
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set gap pixels enable to " + std::to_string(enable));
|
||||
}
|
||||
}
|
||||
auto retval = static_cast<int>(impl()->getGapPixelsEnable());
|
||||
validate(enable, retval, "set gap pixels enable", DEC);
|
||||
LOG(logDEBUG1) << "Gap Pixels Enable: " << retval;
|
||||
return socket.sendResult(retval);
|
||||
}
|
||||
|
||||
int ClientInterface::restream_stop(Interface &socket) {
|
||||
verifyIdle(socket);
|
||||
if (!impl()->getDataStreamEnable()) {
|
||||
@ -1022,19 +980,39 @@ int ClientInterface::restream_stop(Interface &socket) {
|
||||
}
|
||||
|
||||
int ClientInterface::set_additional_json_header(Interface &socket) {
|
||||
char arg[MAX_STR_LENGTH]{};
|
||||
socket.Receive(arg);
|
||||
std::map<std::string, std::string> json;
|
||||
int size = socket.Receive<int>();
|
||||
if (size > 0) {
|
||||
char args[size * 2][SHORT_STR_LENGTH];
|
||||
memset(args, 0, sizeof(args));
|
||||
socket.Receive(args, sizeof(args));
|
||||
for (int i = 0; i < size; ++i) {
|
||||
json[args[2 * i]] = args[2 * i + 1];
|
||||
}
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting additional json header: " << arg;
|
||||
impl()->setAdditionalJsonHeader(arg);
|
||||
LOG(logDEBUG1) << "Setting additional json header: " << sls::ToString(json);
|
||||
impl()->setAdditionalJsonHeader(json);
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
||||
int ClientInterface::get_additional_json_header(Interface &socket) {
|
||||
char retval[MAX_STR_LENGTH]{};
|
||||
sls::strcpy_safe(retval, impl()->getAdditionalJsonHeader().c_str());
|
||||
LOG(logDEBUG1) << "additional json header:" << retval;
|
||||
return socket.sendResult(retval);
|
||||
std::map<std::string, std::string> json = impl()->getAdditionalJsonHeader();
|
||||
LOG(logDEBUG1) << "additional json header:" << sls::ToString(json);
|
||||
int size = json.size();
|
||||
socket.sendResult(size);
|
||||
if (size > 0) {
|
||||
char retvals[size * 2][SHORT_STR_LENGTH];
|
||||
memset(retvals, 0, sizeof(retvals));
|
||||
int iarg = 0;
|
||||
for (auto & it : json) {
|
||||
sls::strcpy_safe(retvals[iarg], it.first.c_str());
|
||||
sls::strcpy_safe(retvals[iarg + 1], it.second.c_str());
|
||||
iarg += 2;
|
||||
}
|
||||
socket.Send(retvals, sizeof(retvals));
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int ClientInterface::set_udp_socket_buffer_size(Interface &socket) {
|
||||
@ -1428,3 +1406,22 @@ int ClientInterface::increment_file_index(Interface &socket) {
|
||||
}
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
||||
|
||||
int ClientInterface::set_additional_json_parameter(Interface &socket) {
|
||||
char args[2][SHORT_STR_LENGTH]{};
|
||||
socket.Receive(args);
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting additional json parameter (" << args[0] << "): " << args[1];
|
||||
impl()->setAdditionalJsonParameter(args[0], args[1]);
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
||||
int ClientInterface::get_additional_json_parameter(Interface &socket) {
|
||||
char arg[SHORT_STR_LENGTH]{};
|
||||
socket.Receive(arg);
|
||||
char retval[SHORT_STR_LENGTH]{};
|
||||
sls::strcpy_safe(retval, impl()->getAdditionalJsonParameter(arg).c_str());
|
||||
LOG(logDEBUG1) << "additional json parameter (" << arg << "):" << retval;
|
||||
return socket.sendResult(retval);
|
||||
}
|
||||
|
@ -55,8 +55,6 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int lock_receiver(sls::ServerInterface &socket);
|
||||
int get_last_client_ip(sls::ServerInterface &socket);
|
||||
int set_port(sls::ServerInterface &socket);
|
||||
int update_client(sls::ServerInterface &socket);
|
||||
int send_update(sls::ServerInterface &socket);
|
||||
int get_version(sls::ServerInterface &socket);
|
||||
int set_detector_type(sls::ServerInterface &socket);
|
||||
int set_detector_hostname(sls::ServerInterface &socket);
|
||||
@ -107,7 +105,6 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int get_streaming_source_ip(sls::ServerInterface &socket);
|
||||
int set_silent_mode(sls::ServerInterface &socket);
|
||||
int get_silent_mode(sls::ServerInterface &socket);
|
||||
int enable_gap_pixels(sls::ServerInterface &socket);
|
||||
int restream_stop(sls::ServerInterface &socket);
|
||||
int set_additional_json_header(sls::ServerInterface &socket);
|
||||
int get_additional_json_header(sls::ServerInterface &socket);
|
||||
@ -138,6 +135,8 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int set_adc_mask_10g(sls::ServerInterface &socket);
|
||||
int set_num_counters(sls::ServerInterface &socket);
|
||||
int increment_file_index(sls::ServerInterface &socket);
|
||||
int set_additional_json_parameter(sls::ServerInterface &socket);
|
||||
int get_additional_json_parameter(sls::ServerInterface &socket);
|
||||
|
||||
Implementation *impl() {
|
||||
if (receiver != nullptr) {
|
||||
|
@ -25,7 +25,7 @@ const std::string DataProcessor::TypeName = "DataProcessor";
|
||||
|
||||
DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
|
||||
fileFormat* ftype, bool fwenable, bool* mfwenable,
|
||||
bool* dsEnable, bool* gpEnable, uint32_t* dr,
|
||||
bool* dsEnable, uint32_t* dr,
|
||||
uint32_t* freq, uint32_t* timer,
|
||||
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
|
||||
std::vector <int> * cdl, int* cdo, int* cad) :
|
||||
@ -40,12 +40,10 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
|
||||
fileFormatType(ftype),
|
||||
fileWriteEnable(fwenable),
|
||||
masterFileWriteEnable(mfwenable),
|
||||
gapPixelsEnable(gpEnable),
|
||||
dynamicRange(dr),
|
||||
streamingFrequency(freq),
|
||||
streamingTimerInMs(timer),
|
||||
currentFreqCount(0),
|
||||
tempBuffer(nullptr),
|
||||
activated(act),
|
||||
deactivatedPaddingEnable(depaden),
|
||||
silentMode(sm),
|
||||
@ -69,7 +67,6 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
|
||||
|
||||
DataProcessor::~DataProcessor() {
|
||||
delete file;
|
||||
delete [] tempBuffer;
|
||||
}
|
||||
|
||||
/** getters */
|
||||
@ -116,15 +113,6 @@ void DataProcessor::ResetParametersforNewAcquisition(){
|
||||
numFramesCaught = 0;
|
||||
firstIndex = 0;
|
||||
currentFrameIndex = 0;
|
||||
|
||||
if (tempBuffer != nullptr) {
|
||||
delete [] tempBuffer;
|
||||
tempBuffer = nullptr;
|
||||
}
|
||||
if (*gapPixelsEnable) {
|
||||
tempBuffer = new char[generalData->imageSize];
|
||||
memset(tempBuffer, 0, generalData->imageSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -296,11 +284,6 @@ void DataProcessor::ProcessAnImage(char* buf) {
|
||||
}
|
||||
}
|
||||
|
||||
if (*gapPixelsEnable && (*dynamicRange!=4))
|
||||
InsertGapPixels(buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
|
||||
*dynamicRange);
|
||||
|
||||
|
||||
// frame padding
|
||||
if (*activated && *framePadding && nump < generalData->packetsPerFrame)
|
||||
PadMissingPackets(buf);
|
||||
@ -512,103 +495,3 @@ void DataProcessor::RearrangeDbitData(char* buf) {
|
||||
(*((uint32_t*)buf)) = numResult8Bits * sizeof(uint8_t);
|
||||
}
|
||||
|
||||
/** eiger specific */
|
||||
void DataProcessor::InsertGapPixels(char* buf, uint32_t dr) {
|
||||
|
||||
memset(tempBuffer, 0xFF, generalData->imageSize);
|
||||
|
||||
int rightChip = ((*quadEnable) ? 0 : index); // quad enable, then faking both to be left chips
|
||||
const uint32_t nx = generalData->nPixelsX;
|
||||
const uint32_t ny = generalData->nPixelsY;
|
||||
const uint32_t npx = nx * ny;
|
||||
bool group3 = (*quadEnable) ? false : true; // if quad enabled, no last line for left chips
|
||||
char* srcptr = nullptr;
|
||||
char* dstptr = nullptr;
|
||||
|
||||
const uint32_t b1px = generalData->imageSize / (npx); // not double as not dealing with 4 bit mode
|
||||
const uint32_t b2px = 2 * b1px;
|
||||
const uint32_t b1pxofst = (rightChip == 0 ? 0 : b1px); // left fpga (rightChip 0) has no extra 1px offset, but right fpga has
|
||||
const uint32_t b1chip = 256 * b1px;
|
||||
const uint32_t b1line = (nx * b1px);
|
||||
const uint32_t bgroup3chip = b1chip + (group3 ? b1px : 0);
|
||||
|
||||
// copying line by line
|
||||
srcptr = buf;
|
||||
dstptr = tempBuffer + b1line + b1pxofst; // left fpga (rightChip 0) has no extra 1px offset, but right fpga has
|
||||
for (uint32_t i = 0; i < (ny-1); ++i) {
|
||||
memcpy(dstptr, srcptr, b1chip);
|
||||
srcptr += b1chip;
|
||||
dstptr += (b1chip + b2px);
|
||||
memcpy(dstptr, srcptr, b1chip);
|
||||
srcptr += b1chip;
|
||||
dstptr += bgroup3chip;
|
||||
}
|
||||
|
||||
// vertical filling of values
|
||||
{
|
||||
char* srcgp1 = nullptr; char* srcgp2 = nullptr; char* srcgp3 = nullptr;
|
||||
char* dstgp1 = nullptr; char* dstgp2 = nullptr; char* dstgp3 = nullptr;
|
||||
const uint32_t b3px = 3 * b1px;
|
||||
|
||||
srcptr = tempBuffer + b1line;
|
||||
dstptr = tempBuffer + b1line;
|
||||
|
||||
for (uint32_t i = 0; i < (ny-1); ++i) {
|
||||
srcgp1 = srcptr + b1pxofst + b1chip - b1px;
|
||||
dstgp1 = srcgp1 + b1px;
|
||||
srcgp2 = srcgp1 + b3px;
|
||||
dstgp2 = dstgp1 + b1px;
|
||||
if (group3) {
|
||||
if (rightChip == 0u) {
|
||||
srcgp3 = srcptr + b1line - b2px;
|
||||
dstgp3 = srcgp3 + b1px;
|
||||
} else {
|
||||
srcgp3 = srcptr + b1px;
|
||||
dstgp3 = srcptr;
|
||||
}
|
||||
}
|
||||
switch (dr) {
|
||||
case 8:
|
||||
(*((uint8_t*)srcgp1)) = (*((uint8_t*)srcgp1))/2; (*((uint8_t*)dstgp1)) = (*((uint8_t*)srcgp1));
|
||||
(*((uint8_t*)srcgp2)) = (*((uint8_t*)srcgp2))/2; (*((uint8_t*)dstgp2)) = (*((uint8_t*)srcgp2));
|
||||
if (group3) {
|
||||
(*((uint8_t*)srcgp3)) = (*((uint8_t*)srcgp3))/2; (*((uint8_t*)dstgp3)) = (*((uint8_t*)srcgp3));
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
(*((uint16_t*)srcgp1)) = (*((uint16_t*)srcgp1))/2; (*((uint16_t*)dstgp1)) = (*((uint16_t*)srcgp1));
|
||||
(*((uint16_t*)srcgp2)) = (*((uint16_t*)srcgp2))/2; (*((uint16_t*)dstgp2)) = (*((uint16_t*)srcgp2));
|
||||
if (group3) {
|
||||
(*((uint16_t*)srcgp3)) = (*((uint16_t*)srcgp3))/2; (*((uint16_t*)dstgp3)) = (*((uint16_t*)srcgp3));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
(*((uint32_t*)srcgp1)) = (*((uint32_t*)srcgp1))/2; (*((uint32_t*)dstgp1)) = (*((uint32_t*)srcgp1));
|
||||
(*((uint32_t*)srcgp2)) = (*((uint32_t*)srcgp2))/2; (*((uint32_t*)dstgp2)) = (*((uint32_t*)srcgp2));
|
||||
if (group3) {
|
||||
(*((uint32_t*)srcgp3)) = (*((uint32_t*)srcgp3))/2; (*((uint32_t*)dstgp3)) = (*((uint32_t*)srcgp3));
|
||||
}
|
||||
break;
|
||||
}
|
||||
srcptr += b1line;
|
||||
dstptr += b1line;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// horizontal filling of values
|
||||
srcptr = tempBuffer + b1line;
|
||||
dstptr = tempBuffer;
|
||||
for (uint32_t i = 0; i < nx; ++i) {
|
||||
switch (dr) {
|
||||
case 8: (*((uint8_t*)srcptr)) = (*((uint8_t*)srcptr))/2; (*((uint8_t*)dstptr)) = (*((uint8_t*)srcptr)); break;
|
||||
case 16:(*((uint16_t*)srcptr)) = (*((uint16_t*)srcptr))/2; (*((uint16_t*)dstptr)) = (*((uint16_t*)srcptr)); break;
|
||||
default:(*((uint32_t*)srcptr)) = (*((uint32_t*)srcptr))/2; (*((uint32_t*)dstptr)) = (*((uint32_t*)srcptr)); break;
|
||||
}
|
||||
srcptr += b1px;
|
||||
dstptr += b1px;
|
||||
}
|
||||
|
||||
memcpy(buf, tempBuffer, generalData->imageSize);
|
||||
return;
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* @param fwenable file writer enable
|
||||
* @apram mfwenable pointer to master file write enable
|
||||
* @param dsEnable pointer to data stream enable
|
||||
* @param gpEnable pointer to gap pixels enable
|
||||
* @param dr pointer to dynamic range
|
||||
* @param freq pointer to streaming frequency
|
||||
* @param timer pointer to timer if streaming frequency is random
|
||||
@ -47,7 +46,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* @param cad pointer to ctb analog databytes
|
||||
*/
|
||||
DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat* ftype,
|
||||
bool fwenable, bool* mfwenable, bool* dsEnable, bool* gpEnable, uint32_t* dr,
|
||||
bool fwenable, bool* mfwenable, bool* dsEnable, uint32_t* dr,
|
||||
uint32_t* freq, uint32_t* timer,
|
||||
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
|
||||
std::vector <int> * cdl, int* cdo, int* cad);
|
||||
@ -252,13 +251,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
*/
|
||||
void RearrangeDbitData(char* buf);
|
||||
|
||||
/**
|
||||
* Processing Function (inserting gap pixels) eiger specific
|
||||
* @param buf pointer to image
|
||||
* @param dr dynamic range
|
||||
*/
|
||||
void InsertGapPixels(char* buf, uint32_t dr);
|
||||
|
||||
/** type of thread */
|
||||
static const std::string TypeName;
|
||||
|
||||
@ -291,10 +283,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** Master File Write Enable */
|
||||
bool* masterFileWriteEnable;
|
||||
|
||||
/** Gap Pixels Enable */
|
||||
bool* gapPixelsEnable;
|
||||
|
||||
|
||||
/** Dynamic Range */
|
||||
uint32_t* dynamicRange;
|
||||
|
||||
@ -310,9 +298,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** timer beginning stamp for random streaming */
|
||||
struct timespec timerBegin;
|
||||
|
||||
/** temporary buffer for processing */
|
||||
char* tempBuffer;
|
||||
|
||||
/** Activated/Deactivated */
|
||||
bool* activated;
|
||||
|
||||
|
@ -17,7 +17,7 @@ const std::string DataStreamer::TypeName = "DataStreamer";
|
||||
|
||||
|
||||
DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
|
||||
uint64_t* fi, int fd, std::string* ajh, int* nd, bool* gpEnable, bool* qe) :
|
||||
uint64_t* fi, int fd, int* nd, bool* qe) :
|
||||
ThreadObject(ind, TypeName),
|
||||
runningFlag(0),
|
||||
generalData(nullptr),
|
||||
@ -28,11 +28,9 @@ DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
|
||||
adcConfigured(-1),
|
||||
fileIndex(fi),
|
||||
flippedDataX(fd),
|
||||
additionJsonHeader(ajh),
|
||||
startedFlag(false),
|
||||
firstIndex(0),
|
||||
completeBuffer(nullptr),
|
||||
gapPixelsEnable(gpEnable),
|
||||
quadEnable(qe)
|
||||
{
|
||||
numDet[0] = nd[0];
|
||||
@ -108,6 +106,10 @@ void DataStreamer::SetFlippedDataX(int fd) {
|
||||
flippedDataX = fd;
|
||||
}
|
||||
|
||||
void DataStreamer::SetAdditionalJsonHeader(const std::map<std::string, std::string> &json) {
|
||||
additionJsonHeader = json;
|
||||
}
|
||||
|
||||
void DataStreamer::CreateZmqSockets(int* nunits, uint32_t port, const sls::IpAddr ip) {
|
||||
uint32_t portnum = port + index;
|
||||
std::string sip = ip.str();
|
||||
@ -217,31 +219,58 @@ void DataStreamer::ProcessAnImage(char* buf) {
|
||||
|
||||
int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32_t nx, uint32_t ny, bool dummy) {
|
||||
|
||||
if (dummy)
|
||||
return zmqSocket->SendHeaderData(index, dummy,SLS_DETECTOR_JSON_HEADER_VERSION);
|
||||
zmqHeader zHeader;
|
||||
zHeader.data = !dummy;
|
||||
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
|
||||
|
||||
if (dummy) {
|
||||
return zmqSocket->SendHeader(index, zHeader);
|
||||
}
|
||||
|
||||
sls_detector_header header = rheader->detHeader;
|
||||
|
||||
uint64_t frameIndex = header.frameNumber - firstIndex;
|
||||
uint64_t acquisitionIndex = header.frameNumber;
|
||||
|
||||
return zmqSocket->SendHeaderData(index, dummy, SLS_DETECTOR_JSON_HEADER_VERSION, *dynamicRange, *fileIndex,
|
||||
numDet[0], numDet[1], nx, ny, size,
|
||||
acquisitionIndex, frameIndex, fileNametoStream,
|
||||
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,
|
||||
*gapPixelsEnable ? 1 : 0, flippedDataX, *quadEnable,
|
||||
additionJsonHeader
|
||||
);
|
||||
zHeader.dynamicRange = *dynamicRange;
|
||||
zHeader.fileIndex = *fileIndex;
|
||||
zHeader.ndetx = numDet[0];
|
||||
zHeader.ndety = numDet[1];
|
||||
zHeader.npixelsx = nx;
|
||||
zHeader.npixelsy = ny;
|
||||
zHeader.imageSize = size;
|
||||
zHeader.acqIndex = acquisitionIndex;
|
||||
zHeader.frameIndex = frameIndex;
|
||||
zHeader.fname = fileNametoStream;
|
||||
zHeader.frameNumber = header.frameNumber;
|
||||
zHeader.expLength = header.expLength;
|
||||
zHeader.packetNumber = header.packetNumber;
|
||||
zHeader.bunchId = header.bunchId;
|
||||
zHeader.timestamp = header.timestamp;
|
||||
zHeader.modId = header.modId;
|
||||
zHeader.row = header.row;
|
||||
zHeader.column = header.column;
|
||||
zHeader.reserved = header.reserved;
|
||||
zHeader.debug = header.debug;
|
||||
zHeader.roundRNumber = header.roundRNumber;
|
||||
zHeader.detType = header.detType;
|
||||
zHeader.version = header.version;
|
||||
zHeader.flippedDataX = flippedDataX;
|
||||
zHeader.quad = *quadEnable;
|
||||
zHeader.completeImage = (header.packetNumber < generalData->packetsPerFrame ? false : true);
|
||||
zHeader.addJsonHeader = additionJsonHeader;
|
||||
|
||||
return zmqSocket->SendHeader(index, zHeader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataStreamer::RestreamStop() {
|
||||
//send dummy header
|
||||
int ret = zmqSocket->SendHeaderData(index, true, SLS_DETECTOR_JSON_HEADER_VERSION);
|
||||
zmqHeader zHeader;
|
||||
zHeader.data = false;
|
||||
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
|
||||
int ret = zmqSocket->SendHeader(index, zHeader);
|
||||
if (!ret) {
|
||||
throw sls::RuntimeError("Could not restream Dummy Header via ZMQ for port " + std::to_string(zmqSocket->GetPortNumber()));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ class Fifo;
|
||||
class DataStreamer;
|
||||
class ZmqSocket;
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
@ -29,13 +29,11 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
* @param r roi
|
||||
* @param fi pointer to file index
|
||||
* @param fd flipped data enable for x dimension
|
||||
* @param ajh additional json header
|
||||
* @param nd pointer to number of detectors in each dimension
|
||||
* @param gpEnable pointer to gap pixels enable
|
||||
* @param qe pointer to quad Enable
|
||||
*/
|
||||
DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
|
||||
uint64_t* fi, int fd, std::string* ajh, int* nd, bool* gpEnable, bool* qe);
|
||||
uint64_t* fi, int fd, int* nd, bool* qe);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -91,6 +89,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
*/
|
||||
void SetFlippedDataX(int fd);
|
||||
|
||||
/**
|
||||
* Set additional json header
|
||||
* @param json additional json header
|
||||
*/
|
||||
void SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
|
||||
|
||||
/**
|
||||
* Creates Zmq Sockets
|
||||
* (throws an exception if it couldnt create zmq sockets)
|
||||
@ -183,7 +187,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
int flippedDataX;
|
||||
|
||||
/** additional json header */
|
||||
std::string* additionJsonHeader;
|
||||
std::map<std::string, std::string> additionJsonHeader;
|
||||
|
||||
/** Aquisition Started flag */
|
||||
bool startedFlag;
|
||||
@ -200,9 +204,6 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
/** Number of Detectors in X and Y dimension */
|
||||
int numDet[2];
|
||||
|
||||
/** Gap Pixels Enable */
|
||||
bool* gapPixelsEnable;
|
||||
|
||||
/** Quad Enable */
|
||||
bool* quadEnable;
|
||||
|
||||
|
@ -171,16 +171,6 @@ public:
|
||||
LOG(logERROR) << "SetTenGigaEnable is a generic function that should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable Gap Pixels changes member variables
|
||||
* @param enable true if gap pixels enable, else false
|
||||
* @param dr dynamic range
|
||||
* @param q quad enable
|
||||
*/
|
||||
virtual void SetGapPixelsEnable(bool b, int dr, bool q) {
|
||||
LOG(logERROR) << "SetGapPixelsEnable is a generic function that should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
/**
|
||||
* Set odd starting packet (gotthard)
|
||||
* @param index thread index for debugging purposes
|
||||
@ -452,39 +442,6 @@ class EigerData : public GeneralData {
|
||||
imageSize = dataSize*packetsPerFrame;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable Gap Pixels changes member variables
|
||||
* @param enable true if gap pixels enable, else false
|
||||
* @param dr dynamic range
|
||||
* @param q quad enable
|
||||
*/
|
||||
void SetGapPixelsEnable(bool b, int dr, bool q) {
|
||||
if (dr == 4)
|
||||
b = 0;
|
||||
switch((int)b) {
|
||||
case 1:
|
||||
nPixelsX = (256 * 2) + 3;
|
||||
if (q) {
|
||||
nPixelsX = (256 * 2) + 2;
|
||||
}
|
||||
nPixelsY = 256 + 1;
|
||||
imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit
|
||||
((dr > 8) ? 2 : // 16 bit
|
||||
((dr > 4) ? 1 : // 8 bit
|
||||
0.5))); // 4 bit
|
||||
break;
|
||||
default:
|
||||
nPixelsX = (256*2);
|
||||
nPixelsY = 256;
|
||||
imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit
|
||||
((dr > 8) ? 2 : // 16 bit
|
||||
((dr > 4) ? 1 : // 8 bit
|
||||
0.5))); // 4 bit
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -383,41 +383,29 @@ public:
|
||||
attribute = dataset.createAttribute("unit",strdatatype, dataspace);
|
||||
attribute.write(strdatatype, std::string("ns"));
|
||||
|
||||
//Gap Pixels Enable
|
||||
dataset = group5.createDataSet ( "gap pixels enable", PredType::NATIVE_INT, dataspace );
|
||||
dataset.write ( &(attr.gapPixelsEnable), PredType::NATIVE_INT);
|
||||
|
||||
//Quad Enable
|
||||
dataset = group5.createDataSet ( "quad enable", PredType::NATIVE_INT, dataspace );
|
||||
dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT);
|
||||
|
||||
//Gap Pixels Enable
|
||||
dataset = group5.createDataSet ( "gap pixels enable", PredType::NATIVE_INT, dataspace );
|
||||
dataset.write ( &(attr.gapPixelsEnable), PredType::NATIVE_INT);
|
||||
|
||||
//Quad Enable
|
||||
dataset = group5.createDataSet ( "quad enable", PredType::NATIVE_INT, dataspace );
|
||||
dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT);
|
||||
|
||||
//Analog Flag
|
||||
dataset = group5.createDataSet ( "analog flag", PredType::NATIVE_INT, dataspace );
|
||||
dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT);
|
||||
dataset.write ( &(attr.analogFlag), PredType::NATIVE_INT);
|
||||
|
||||
//Digital Flag
|
||||
dataset = group5.createDataSet ( "digital flag", PredType::NATIVE_INT, dataspace );
|
||||
dataset.write ( &(attr.gapPixelsEnable), PredType::NATIVE_INT);
|
||||
dataset.write ( &(attr.digitalFlag), PredType::NATIVE_INT);
|
||||
|
||||
//ADC Mask
|
||||
dataset = group5.createDataSet ( "adc mask", PredType::NATIVE_INT, dataspace );
|
||||
dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT);
|
||||
dataset.write ( &(attr.adcmask), PredType::NATIVE_INT);
|
||||
|
||||
//Dbit Offset
|
||||
dataset = group5.createDataSet ( "dbit offset", PredType::NATIVE_INT, dataspace );
|
||||
dataset.write ( &(attr.gapPixelsEnable), PredType::NATIVE_INT);
|
||||
dataset.write ( &(attr.dbitoffset), PredType::NATIVE_INT);
|
||||
|
||||
// Dbit List
|
||||
dataset = group5.createDataSet ( "dbit bitset list", PredType::STD_U64LE, dataspace );
|
||||
dataset.write ( &(attr.periodNs), PredType::STD_U64LE);
|
||||
dataset.write ( &(attr.dbitlist), PredType::STD_U64LE);
|
||||
|
||||
// Roi xmin
|
||||
dataset = group5.createDataSet ( "roi xmin", PredType::NATIVE_INT, dataspace );
|
||||
|
@ -37,6 +37,7 @@ void Implementation::DeleteMembers() {
|
||||
generalData = nullptr;
|
||||
}
|
||||
|
||||
additionalJsonHeader.clear();
|
||||
listener.clear();
|
||||
dataProcessor.clear();
|
||||
dataStreamer.clear();
|
||||
@ -92,7 +93,6 @@ void Implementation::InitializeMembers() {
|
||||
streamingTimerInMs = DEFAULT_STREAMING_TIMER_IN_MS;
|
||||
streamingPort = 0;
|
||||
streamingSrcIP = sls::IpAddr{};
|
||||
additionalJsonHeader = "";
|
||||
|
||||
// detector parameters
|
||||
numberOfFrames = 0;
|
||||
@ -108,7 +108,6 @@ void Implementation::InitializeMembers() {
|
||||
roi.xmax = -1;
|
||||
tengigaEnable = false;
|
||||
flippedDataX = 0;
|
||||
gapPixelsEnable = false;
|
||||
quadEnable = false;
|
||||
activated = true;
|
||||
deactivatedPaddingEnable = true;
|
||||
@ -273,7 +272,7 @@ void Implementation::setDetectorType(const detectorType d) {
|
||||
&activated, &deactivatedPaddingEnable, &silentMode));
|
||||
dataProcessor.push_back(sls::make_unique<DataProcessor>(
|
||||
i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable,
|
||||
&masterFileWriteEnable, &dataStreamEnable, &gapPixelsEnable,
|
||||
&masterFileWriteEnable, &dataStreamEnable,
|
||||
&dynamicRange, &streamingFrequency, &streamingTimerInMs,
|
||||
&framePadding, &activated, &deactivatedPaddingEnable,
|
||||
&silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset,
|
||||
@ -848,7 +847,6 @@ void Implementation::SetupWriter() {
|
||||
attr.subExptimeNs = subExpTime;
|
||||
attr.subPeriodNs = subPeriod;
|
||||
attr.periodNs = acquisitionPeriod;
|
||||
attr.gapPixelsEnable = gapPixelsEnable;
|
||||
attr.quadEnable = quadEnable;
|
||||
attr.analogFlag = (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0;
|
||||
attr.digitalFlag = (readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0;
|
||||
@ -943,7 +941,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
|
||||
dataProcessor.push_back(sls::make_unique<DataProcessor>(
|
||||
i, myDetectorType, fifo_ptr, &fileFormatType,
|
||||
fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable,
|
||||
&gapPixelsEnable, &dynamicRange, &streamingFrequency,
|
||||
&dynamicRange, &streamingFrequency,
|
||||
&streamingTimerInMs, &framePadding, &activated,
|
||||
&deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList,
|
||||
&ctbDbitOffset, &ctbAnalogDataBytes));
|
||||
@ -965,10 +963,11 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
|
||||
}
|
||||
dataStreamer.push_back(sls::make_unique<DataStreamer>(
|
||||
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
|
||||
fd, &additionalJsonHeader, (int*)nd, &gapPixelsEnable, &quadEnable));
|
||||
fd, (int*)nd, &quadEnable));
|
||||
dataStreamer[i]->SetGeneralData(generalData);
|
||||
dataStreamer[i]->CreateZmqSockets(
|
||||
&numThreads, streamingPort, streamingSrcIP);
|
||||
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader);
|
||||
|
||||
} catch (...) {
|
||||
if (dataStreamEnable) {
|
||||
@ -1108,10 +1107,11 @@ void Implementation::setDataStreamEnable(const bool enable) {
|
||||
}
|
||||
dataStreamer.push_back(sls::make_unique<DataStreamer>(
|
||||
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
|
||||
fd, &additionalJsonHeader, (int*)nd, &gapPixelsEnable, &quadEnable));
|
||||
fd, (int*)nd, &quadEnable));
|
||||
dataStreamer[i]->SetGeneralData(generalData);
|
||||
dataStreamer[i]->CreateZmqSockets(
|
||||
&numThreads, streamingPort, streamingSrcIP);
|
||||
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader);
|
||||
} catch (...) {
|
||||
dataStreamer.clear();
|
||||
dataStreamEnable = false;
|
||||
@ -1170,17 +1170,55 @@ void Implementation::setStreamingSourceIP(const sls::IpAddr ip) {
|
||||
LOG(logINFO) << "Streaming Source IP: " << streamingSrcIP;
|
||||
}
|
||||
|
||||
std::string Implementation::getAdditionalJsonHeader() const {
|
||||
std::map<std::string, std::string> Implementation::getAdditionalJsonHeader() const {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
return additionalJsonHeader;
|
||||
}
|
||||
|
||||
void Implementation::setAdditionalJsonHeader(const std::string& c) {
|
||||
void Implementation::setAdditionalJsonHeader(const std::map<std::string, std::string> &c) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
additionalJsonHeader = c;
|
||||
LOG(logINFO) << "Additional JSON Header: " << additionalJsonHeader;
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetAdditionalJsonHeader(c);
|
||||
}
|
||||
LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader);
|
||||
}
|
||||
|
||||
std::string Implementation::getAdditionalJsonParameter(const std::string &key) const {
|
||||
if (additionalJsonHeader.find(key) != additionalJsonHeader.end()) {
|
||||
return additionalJsonHeader.at(key);
|
||||
}
|
||||
throw sls::RuntimeError("No key " + key + " found in additional json header");
|
||||
}
|
||||
|
||||
void Implementation::setAdditionalJsonParameter(const std::string &key, const std::string &value) {
|
||||
auto pos = additionalJsonHeader.find(key);
|
||||
|
||||
// if value is empty, delete
|
||||
if (value.empty()) {
|
||||
// doesnt exist
|
||||
if (pos == additionalJsonHeader.end()) {
|
||||
LOG(logINFO) << "Additional json parameter (" << key << ") does not exist anyway";
|
||||
} else {
|
||||
LOG(logINFO) << "Deleting additional json parameter (" << key << ")";
|
||||
additionalJsonHeader.erase(pos);
|
||||
}
|
||||
}
|
||||
// if found, set it
|
||||
else if (pos != additionalJsonHeader.end()) {
|
||||
additionalJsonHeader[key] = value;
|
||||
LOG(logINFO) << "Setting additional json parameter (" << key << ") to " << value;
|
||||
}
|
||||
// append if not found
|
||||
else {
|
||||
additionalJsonHeader[key] = value;
|
||||
LOG(logINFO) << "Adding additional json parameter (" << key << ") to " << value;
|
||||
}
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetAdditionalJsonHeader(additionalJsonHeader);
|
||||
}
|
||||
LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader);
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
@ -1330,9 +1368,6 @@ void Implementation::setDynamicRange(const uint32_t i) {
|
||||
|
||||
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
|
||||
generalData->SetDynamicRange(i, tengigaEnable);
|
||||
if (myDetectorType == EIGER) {
|
||||
generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable);
|
||||
}
|
||||
// to update npixelsx, npixelsy in file writer
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
@ -1377,7 +1412,6 @@ void Implementation::setTenGigaEnable(const bool b) {
|
||||
switch (myDetectorType) {
|
||||
case EIGER:
|
||||
generalData->SetTenGigaEnable(b, dynamicRange);
|
||||
generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable);
|
||||
break;
|
||||
case MOENCH:
|
||||
case CHIPTESTBOARD:
|
||||
@ -1421,24 +1455,6 @@ void Implementation::setFlippedDataX(int enable) {
|
||||
LOG(logINFO) << "Flipped Data X: " << flippedDataX;
|
||||
}
|
||||
|
||||
bool Implementation::getGapPixelsEnable() const {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
return gapPixelsEnable;
|
||||
}
|
||||
|
||||
void Implementation::setGapPixelsEnable(const bool b) {
|
||||
if (gapPixelsEnable != b) {
|
||||
gapPixelsEnable = b;
|
||||
|
||||
// side effects
|
||||
generalData->SetGapPixelsEnable(b, dynamicRange, quadEnable);
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "Gap Pixels Enable: " << gapPixelsEnable;
|
||||
}
|
||||
|
||||
bool Implementation::getQuad() const {
|
||||
LOG(logDEBUG) << __AT__ << " starting";
|
||||
return quadEnable;
|
||||
@ -1448,12 +1464,6 @@ void Implementation::setQuad(const bool b) {
|
||||
if (quadEnable != b) {
|
||||
quadEnable = b;
|
||||
|
||||
generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, b);
|
||||
// to update npixelsx, npixelsy in file writer
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
|
||||
if (!quadEnable) {
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(numDet);
|
||||
|
@ -14,6 +14,7 @@ class slsDetectorDefs;
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class Implementation : private virtual slsDetectorDefs {
|
||||
public:
|
||||
@ -123,8 +124,10 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
void setStreamingPort(const uint32_t i);
|
||||
sls::IpAddr getStreamingSourceIP() const;
|
||||
void setStreamingSourceIP(const sls::IpAddr ip);
|
||||
std::string getAdditionalJsonHeader() const;
|
||||
void setAdditionalJsonHeader(const std::string& c);
|
||||
std::map<std::string, std::string> getAdditionalJsonHeader() const;
|
||||
void setAdditionalJsonHeader(const std::map<std::string, std::string> &c);
|
||||
std::string getAdditionalJsonParameter(const std::string &key) const;
|
||||
void setAdditionalJsonParameter(const std::string &key, const std::string &value);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
@ -161,9 +164,6 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
void setTenGigaEnable(const bool b);
|
||||
int getFlippedDataX() const;
|
||||
void setFlippedDataX(int enable = -1);
|
||||
bool getGapPixelsEnable() const;
|
||||
/* [Eiger] */
|
||||
void setGapPixelsEnable(const bool b);
|
||||
bool getQuad() const;
|
||||
/* [Eiger] */
|
||||
void setQuad(const bool b);
|
||||
@ -263,7 +263,7 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
uint32_t streamingTimerInMs;
|
||||
uint32_t streamingPort;
|
||||
sls::IpAddr streamingSrcIP;
|
||||
std::string additionalJsonHeader;
|
||||
std::map<std::string, std::string> additionalJsonHeader;
|
||||
|
||||
// detector parameters
|
||||
uint64_t numberOfFrames;
|
||||
@ -278,7 +278,6 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
ROI roi;
|
||||
bool tengigaEnable;
|
||||
int flippedDataX;
|
||||
bool gapPixelsEnable;
|
||||
bool quadEnable;
|
||||
bool activated;
|
||||
bool deactivatedPaddingEnable;
|
||||
|
@ -74,7 +74,6 @@ struct masterAttributes {
|
||||
uint64_t subExptimeNs;
|
||||
uint64_t subPeriodNs;
|
||||
uint64_t periodNs;
|
||||
uint32_t gapPixelsEnable;
|
||||
uint32_t quadEnable;
|
||||
uint32_t analogFlag;
|
||||
uint32_t digitalFlag;
|
||||
|
@ -17,9 +17,59 @@
|
||||
|
||||
|
||||
class zmq_msg_t;
|
||||
#include <map>
|
||||
|
||||
/** zmq header structure */
|
||||
struct zmqHeader {
|
||||
/** true if incoming data, false if end of acquisition */
|
||||
bool data{true};
|
||||
uint32_t jsonversion{0};
|
||||
uint32_t dynamicRange{0};
|
||||
uint64_t fileIndex{0};
|
||||
/** number of detectors in x axis */
|
||||
uint32_t ndetx{0};
|
||||
/** number of detectors in y axis */
|
||||
uint32_t ndety{0};
|
||||
/** number of pixels/channels in x axis for this zmq socket */
|
||||
uint32_t npixelsx{0};
|
||||
/** number of pixels/channels in y axis for this zmq socket */
|
||||
uint32_t npixelsy{0};
|
||||
/** number of bytes for an image in this socket */
|
||||
uint32_t imageSize{0};
|
||||
/** frame number from detector */
|
||||
uint64_t acqIndex{0};
|
||||
/** frame index (starting at 0 for each acquisition) */
|
||||
uint64_t frameIndex{0};
|
||||
/** file name prefix */
|
||||
std::string fname{""};
|
||||
/** header from detector */
|
||||
uint64_t frameNumber{0};
|
||||
uint32_t expLength{0};
|
||||
uint32_t packetNumber{0};
|
||||
uint64_t bunchId{0};
|
||||
uint64_t timestamp{0};
|
||||
uint16_t modId{0};
|
||||
uint16_t row{0};
|
||||
uint16_t column{0};
|
||||
uint16_t reserved{0};
|
||||
uint32_t debug{0};
|
||||
uint16_t roundRNumber{0};
|
||||
uint8_t detType{0};
|
||||
uint8_t version{0};
|
||||
/** if image should be flipped across x axis */
|
||||
int flippedDataX{0};
|
||||
/** quad type (eiger hardware specific) */
|
||||
uint32_t quad{0};
|
||||
/** true if complete image, else missing packets */
|
||||
bool completeImage{false};
|
||||
/** additional json header */
|
||||
std::map<std::string, std::string> addJsonHeader;
|
||||
};
|
||||
|
||||
class ZmqSocket {
|
||||
|
||||
public:
|
||||
|
||||
// Socket Options for optimization
|
||||
// ZMQ_LINGER default is already -1 means no messages discarded. use this
|
||||
// options if optimizing required ZMQ_SNDHWM default is 0 means no limit. use
|
||||
@ -110,47 +160,10 @@ class ZmqSocket {
|
||||
/**
|
||||
* Send Message Header
|
||||
* @param index self index for debugging
|
||||
* @param dummy true if a dummy message for end of acquisition
|
||||
* @param jsonversion json version
|
||||
* @param dynamicrange dynamic range
|
||||
* @param fileIndex file or acquisition index
|
||||
* @param ndetx number of detectors in x axis
|
||||
* @param ndety number of detectors in y axis
|
||||
* @param npixelsx number of pixels/channels in x axis for this zmq socket
|
||||
* @param npixelsy number of pixels/channels in y axis for this zmq socket
|
||||
* @param imageSize number of bytes for an image in this socket
|
||||
* @param frameNumber current frame number
|
||||
* @param expLength exposure length or subframe index if eiger
|
||||
* @param packetNumber number of packets caught for this frame
|
||||
* @param bunchId bunch id
|
||||
* @param timestamp time stamp
|
||||
* @param modId module Id
|
||||
* @param row row index in complete detector
|
||||
* @param column column index in complete detector
|
||||
* @param reserved reserved
|
||||
* @param debug debug
|
||||
* @param roundRNumber not used yet
|
||||
* @param detType detector enum
|
||||
* @param version detector header version
|
||||
* @param gapPixelsEnable gap pixels enable (exception: if gap pixels enable
|
||||
* for 4 bit mode, data is not yet gap pixel enabled in receiver)
|
||||
* @param flippedDataX if it is flipped across x axis
|
||||
* @param quadEnable if quad is enabled
|
||||
* @param additionalJsonHeader additional json header
|
||||
* @param header zmq header (from json)
|
||||
* @returns 0 if error, else 1
|
||||
*/
|
||||
int SendHeaderData(
|
||||
int index, bool dummy, uint32_t jsonversion, uint32_t dynamicrange = 0,
|
||||
uint64_t fileIndex = 0, uint32_t ndetx = 0, uint32_t ndety = 0,
|
||||
uint32_t npixelsx = 0, uint32_t npixelsy = 0, uint32_t imageSize = 0,
|
||||
uint64_t acqIndex = 0, uint64_t fIndex = 0, std::string fname = "",
|
||||
uint64_t frameNumber = 0, uint32_t expLength = 0,
|
||||
uint32_t packetNumber = 0, uint64_t bunchId = 0, uint64_t timestamp = 0,
|
||||
uint16_t modId = 0, uint16_t row = 0, uint16_t column = 0,
|
||||
uint16_t reserved = 0, uint32_t debug = 0, uint16_t roundRNumber = 0,
|
||||
uint8_t detType = 0, uint8_t version = 0, int gapPixelsEnable = 0,
|
||||
int flippedDataX = 0, uint32_t quadEnable = 0,
|
||||
std::string *additionalJsonHeader = 0);
|
||||
int SendHeader(int index, zmqHeader header);
|
||||
|
||||
/**
|
||||
* Send Message Body
|
||||
@ -160,38 +173,15 @@ class ZmqSocket {
|
||||
*/
|
||||
int SendData(char *buf, int length);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Receive Header (Important to close message after parsing header)
|
||||
* Receive Header
|
||||
* @param index self index for debugging
|
||||
* @param document parsed document reference
|
||||
* @param zHeader filled out zmqHeader structure (parsed from json header)
|
||||
* @param version version that has to match, -1 to not care
|
||||
* @returns 0 if error or end of acquisition, else 1 (call
|
||||
* CloseHeaderMessage after parsing header)
|
||||
*/
|
||||
int ReceiveHeader(const int index, rapidjson::Document &document, uint32_t version);
|
||||
|
||||
/**
|
||||
* Close Header Message. Call this function if ReceiveHeader returned 1
|
||||
*/
|
||||
// void CloseHeaderMessage() {
|
||||
// if (headerMessage)
|
||||
// zmq_msg_close(headerMessage);
|
||||
// headerMessage = 0;
|
||||
// };
|
||||
/**
|
||||
* Parse Header
|
||||
* @param index self index for debugging
|
||||
* @param length length of message
|
||||
* @param message message
|
||||
* @param document parsed document reference
|
||||
* @param dummy true if end of acqusition, else false, loaded upon parsing
|
||||
* @param version version that has to match, -1 to not care
|
||||
* @returns true if successful else false
|
||||
*/
|
||||
int ParseHeader(const int index, int length, char *buff, rapidjson::Document &document,
|
||||
bool &dummy, uint32_t version);
|
||||
int ReceiveHeader(const int index, zmqHeader& zHeader, uint32_t version);
|
||||
|
||||
/**
|
||||
* Receive Data
|
||||
@ -216,6 +206,19 @@ class ZmqSocket {
|
||||
* @returns length of message, -1 if error
|
||||
*/
|
||||
int ReceiveMessage(const int index, zmq_msg_t &message);
|
||||
|
||||
/**
|
||||
* Parse Header
|
||||
* @param index self index for debugging
|
||||
* @param length length of message
|
||||
* @param message message
|
||||
* @param zHeader filled out zmqHeader structure (parsed from json header)
|
||||
* @param version version that has to match, -1 to not care
|
||||
* @returns true if successful else false
|
||||
*/
|
||||
int ParseHeader(const int index, int length, char *buff,
|
||||
zmqHeader& zHeader, uint32_t version);
|
||||
|
||||
/**
|
||||
* Class to close socket descriptors automatically
|
||||
* upon encountering exceptions in the ZmqSocket constructor
|
||||
@ -246,4 +249,6 @@ class ZmqSocket {
|
||||
|
||||
/** Socket descriptor */
|
||||
mySocketDescriptors sockfd;
|
||||
|
||||
|
||||
};
|
||||
|
@ -37,7 +37,7 @@
|
||||
#define DEFAULT_ZMQ_RX_PORTNO 30001
|
||||
|
||||
#define SLS_DETECTOR_HEADER_VERSION 0x2
|
||||
#define SLS_DETECTOR_JSON_HEADER_VERSION 0x3
|
||||
#define SLS_DETECTOR_JSON_HEADER_VERSION 0x4
|
||||
|
||||
// ctb/ moench 1g udp (read from fifo)
|
||||
#define UDP_PACKET_DATA_BYTES (1344)
|
||||
@ -61,6 +61,7 @@
|
||||
|
||||
/** default maximum string length */
|
||||
#define MAX_STR_LENGTH 1000
|
||||
#define SHORT_STR_LENGTH 20
|
||||
|
||||
#define DEFAULT_STREAMING_TIMER_IN_MS 200
|
||||
|
||||
@ -480,8 +481,6 @@ struct detParameters {
|
||||
int nChipY{0};
|
||||
int nDacs{0};
|
||||
int dynamicRange{0};
|
||||
int nGappixelsX{0};
|
||||
int nGappixelsY{0};
|
||||
|
||||
detParameters() = default;
|
||||
explicit detParameters(slsDetectorDefs::detectorType type) {
|
||||
@ -493,8 +492,6 @@ struct detParameters {
|
||||
nChipY = 1;
|
||||
nDacs = 8;
|
||||
dynamicRange = 16;
|
||||
nGappixelsX = 0;
|
||||
nGappixelsY = 0;
|
||||
break;
|
||||
case slsDetectorDefs::detectorType::JUNGFRAU:
|
||||
nChanX = 256;
|
||||
@ -503,8 +500,6 @@ struct detParameters {
|
||||
nChipY = 2;
|
||||
nDacs = 8;
|
||||
dynamicRange = 16;
|
||||
nGappixelsX = 0;
|
||||
nGappixelsY = 0;
|
||||
break;
|
||||
case slsDetectorDefs::detectorType::CHIPTESTBOARD:
|
||||
nChanX = 36;
|
||||
@ -513,8 +508,6 @@ struct detParameters {
|
||||
nChipY = 1;
|
||||
nDacs = 24;
|
||||
dynamicRange = 16;
|
||||
nGappixelsX = 0;
|
||||
nGappixelsY = 0;
|
||||
break;
|
||||
case slsDetectorDefs::detectorType::MOENCH:
|
||||
nChanX = 32;
|
||||
@ -523,8 +516,6 @@ struct detParameters {
|
||||
nChipY = 1;
|
||||
nDacs = 8;
|
||||
dynamicRange = 16;
|
||||
nGappixelsX = 0;
|
||||
nGappixelsY = 0;
|
||||
break;
|
||||
case slsDetectorDefs::detectorType::EIGER:
|
||||
nChanX = 256;
|
||||
@ -533,8 +524,6 @@ struct detParameters {
|
||||
nChipY = 1;
|
||||
nDacs = 16;
|
||||
dynamicRange = 16;
|
||||
nGappixelsX = 6;
|
||||
nGappixelsY = 1;
|
||||
break;
|
||||
case slsDetectorDefs::detectorType::MYTHEN3:
|
||||
nChanX = 128 * 3;
|
||||
@ -543,8 +532,6 @@ struct detParameters {
|
||||
nChipY = 1;
|
||||
nDacs = 16;
|
||||
dynamicRange = 32;
|
||||
nGappixelsX = 0;
|
||||
nGappixelsY = 0;
|
||||
break;
|
||||
case slsDetectorDefs::detectorType::GOTTHARD2:
|
||||
nChanX = 128;
|
||||
@ -553,8 +540,6 @@ struct detParameters {
|
||||
nChipY = 1;
|
||||
nDacs = 14;
|
||||
dynamicRange = 16;
|
||||
nGappixelsX = 0;
|
||||
nGappixelsY = 0;
|
||||
break;
|
||||
default:
|
||||
throw sls::RuntimeError("Unknown detector type! " + std::to_string(type));
|
||||
|
@ -206,7 +206,6 @@ enum detFuncs{
|
||||
F_LOCK_RECEIVER,
|
||||
F_GET_LAST_RECEIVER_CLIENT_IP,
|
||||
F_SET_RECEIVER_PORT,
|
||||
F_UPDATE_RECEIVER_CLIENT,
|
||||
F_GET_RECEIVER_VERSION,
|
||||
F_GET_RECEIVER_TYPE,
|
||||
F_SEND_RECEIVER_DETHOSTNAME,
|
||||
@ -256,7 +255,6 @@ enum detFuncs{
|
||||
F_GET_RECEIVER_STREAMING_SRC_IP,
|
||||
F_SET_RECEIVER_SILENT_MODE,
|
||||
F_GET_RECEIVER_SILENT_MODE,
|
||||
F_ENABLE_GAPPIXELS_IN_RECEIVER,
|
||||
F_RESTREAM_STOP_FROM_RECEIVER,
|
||||
F_SET_ADDITIONAL_JSON_HEADER,
|
||||
F_GET_ADDITIONAL_JSON_HEADER,
|
||||
@ -287,6 +285,8 @@ enum detFuncs{
|
||||
F_RECEIVER_SET_ADC_MASK_10G,
|
||||
F_RECEIVER_SET_NUM_COUNTERS,
|
||||
F_INCREMENT_FILE_INDEX,
|
||||
F_SET_ADDITIONAL_JSON_PARAMETER,
|
||||
F_GET_ADDITIONAL_JSON_PARAMETER,
|
||||
NUM_REC_FUNCTIONS
|
||||
};
|
||||
|
||||
@ -489,7 +489,6 @@ static 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_SET_RECEIVER_PORT: return "F_SET_RECEIVER_PORT";
|
||||
case F_UPDATE_RECEIVER_CLIENT: return "F_UPDATE_RECEIVER_CLIENT";
|
||||
case F_GET_RECEIVER_VERSION: return "F_GET_RECEIVER_VERSION";
|
||||
case F_GET_RECEIVER_TYPE: return "F_GET_RECEIVER_TYPE";
|
||||
case F_SEND_RECEIVER_DETHOSTNAME: return "F_SEND_RECEIVER_DETHOSTNAME";
|
||||
@ -539,7 +538,6 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
|
||||
case F_GET_RECEIVER_STREAMING_SRC_IP: return "F_GET_RECEIVER_STREAMING_SRC_IP";
|
||||
case F_SET_RECEIVER_SILENT_MODE: return "F_SET_RECEIVER_SILENT_MODE";
|
||||
case F_GET_RECEIVER_SILENT_MODE: return "F_GET_RECEIVER_SILENT_MODE";
|
||||
case F_ENABLE_GAPPIXELS_IN_RECEIVER: return "F_ENABLE_GAPPIXELS_IN_RECEIVER";
|
||||
case F_RESTREAM_STOP_FROM_RECEIVER: return "F_RESTREAM_STOP_FROM_RECEIVER";
|
||||
case F_SET_ADDITIONAL_JSON_HEADER: return "F_SET_ADDITIONAL_JSON_HEADER";
|
||||
case F_GET_ADDITIONAL_JSON_HEADER: return "F_GET_ADDITIONAL_JSON_HEADER";
|
||||
@ -570,7 +568,8 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
|
||||
case F_RECEIVER_SET_ADC_MASK_10G: return "F_RECEIVER_SET_ADC_MASK_10G";
|
||||
case F_RECEIVER_SET_NUM_COUNTERS: return "F_RECEIVER_SET_NUM_COUNTERS";
|
||||
case F_INCREMENT_FILE_INDEX: return "F_INCREMENT_FILE_INDEX";
|
||||
|
||||
case F_SET_ADDITIONAL_JSON_PARAMETER: return "F_SET_ADDITIONAL_JSON_PARAMETER";
|
||||
case F_GET_ADDITIONAL_JSON_PARAMETER: return "F_GET_ADDITIONAL_JSON_PARAMETER";
|
||||
|
||||
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
|
||||
default: return "Unknown Function";
|
||||
|
@ -3,10 +3,10 @@
|
||||
#define APILIB 0x200227
|
||||
#define APIRECEIVER 0x200227
|
||||
#define APIGUI 0x200227
|
||||
#define APICTB 0x200310
|
||||
#define APIGOTTHARD 0x200310
|
||||
#define APIJUNGFRAU 0x200310
|
||||
#define APIMYTHEN3 0x200310
|
||||
#define APIMOENCH 0x200310
|
||||
#define APIEIGER 0x200310
|
||||
#define APIGOTTHARD2 0x200313
|
||||
#define APICTB 0x200311
|
||||
#define APIGOTTHARD 0x200326
|
||||
#define APIGOTTHARD2 0x200326
|
||||
#define APIJUNGFRAU 0x200326
|
||||
#define APIMYTHEN3 0x200311
|
||||
#define APIMOENCH 0x200326
|
||||
#define APIEIGER 0x200326
|
||||
|
@ -145,6 +145,244 @@ int ZmqSocket::ConvertInternetAddresstoIpString(struct addrinfo *res, char *ip,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ZmqSocket::SendHeader(
|
||||
int index, zmqHeader header) {
|
||||
|
||||
/** Json Header Format */
|
||||
const char jsonHeaderFormat[] = "{"
|
||||
"\"jsonversion\":%u, "
|
||||
"\"bitmode\":%u, "
|
||||
"\"fileIndex\":%lu, "
|
||||
"\"detshape\":[%u, %u], "
|
||||
"\"shape\":[%u, %u], "
|
||||
"\"size\":%u, "
|
||||
"\"acqIndex\":%lu, "
|
||||
"\"frameIndex\":%lu, "
|
||||
"\"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, "
|
||||
|
||||
// additional stuff
|
||||
"\"flippedDataX\":%u, "
|
||||
"\"quad\":%u"
|
||||
|
||||
; //"}\n";
|
||||
char buf[MAX_STR_LENGTH] = "";
|
||||
sprintf(buf, jsonHeaderFormat,
|
||||
header.jsonversion,
|
||||
header.dynamicRange,
|
||||
header.fileIndex,
|
||||
header.ndetx,
|
||||
header.ndety,
|
||||
header.npixelsx,
|
||||
header.npixelsy,
|
||||
header.imageSize,
|
||||
header.acqIndex,
|
||||
header.frameIndex,
|
||||
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.flippedDataX,
|
||||
header.quad);
|
||||
|
||||
if (header.addJsonHeader.size() > 0) {
|
||||
strcat(buf, ", ");
|
||||
strcat(buf, "\"addJsonHeader\": {");
|
||||
for (auto it = header.addJsonHeader.begin(); it != header.addJsonHeader.end(); ++it) {
|
||||
if (it != header.addJsonHeader.begin()) {
|
||||
strcat(buf, ", ");
|
||||
}
|
||||
strcat(buf, "\"");
|
||||
strcat(buf, it->first.c_str());
|
||||
strcat(buf, "\":\"");
|
||||
strcat(buf, it->second.c_str());
|
||||
strcat(buf, "\"");
|
||||
}
|
||||
strcat(buf, " } ");
|
||||
}
|
||||
|
||||
strcat(buf, "}\n");
|
||||
int length = strlen(buf);
|
||||
|
||||
#ifdef VERBOSE
|
||||
// if(!index)
|
||||
cprintf(BLUE, "%d : Streamer: buf: %s\n", index, buf);
|
||||
#endif
|
||||
|
||||
if (zmq_send(sockfd.socketDescriptor, buf, length,
|
||||
header.data ? ZMQ_SNDMORE : 0) < 0) {
|
||||
PrintError();
|
||||
return 0;
|
||||
}
|
||||
#ifdef VERBOSE
|
||||
cprintf(GREEN, "[%u] send header data\n", portno);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ZmqSocket::SendData(char *buf, int length) {
|
||||
if (zmq_send(sockfd.socketDescriptor, buf, length, 0) < 0) {
|
||||
PrintError();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ZmqSocket::ReceiveHeader(const int index, zmqHeader& zHeader,
|
||||
uint32_t version) {
|
||||
std::vector<char> buffer(MAX_STR_LENGTH);
|
||||
int len =
|
||||
zmq_recv(sockfd.socketDescriptor, buffer.data(), buffer.size(), 0);
|
||||
if (len > 0) {
|
||||
#ifdef ZMQ_DETAIL
|
||||
cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno,
|
||||
len, buffer.data());
|
||||
#endif
|
||||
if (ParseHeader(index, len, buffer.data(), zHeader, version)) {
|
||||
#ifdef ZMQ_DETAIL
|
||||
cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index,
|
||||
portno, len, buffer.data());
|
||||
#endif
|
||||
if (!zHeader.data) {
|
||||
#ifdef ZMQ_DETAIL
|
||||
cprintf(RED, "%d [%d] Received end of acquisition\n", index,
|
||||
portno);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#ifdef ZMQ_DETAIL
|
||||
cprintf(GREEN, "%d [%d] data\n", index, portno);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
int ZmqSocket::ParseHeader(const int index, int length, char *buff,
|
||||
zmqHeader& zHeader, uint32_t version) {
|
||||
Document document;
|
||||
if (document.Parse(buff, length).HasParseError()) {
|
||||
LOG(logERROR) << index << " Could not parse. len:" << length
|
||||
<< ": Message:" << buff;
|
||||
fflush(stdout);
|
||||
// char* buf = (char*) zmq_msg_data (&message);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
cprintf(RED, "%02x ", buff[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// version check
|
||||
zHeader.jsonversion = document["jsonversion"].GetUint();
|
||||
if (zHeader.jsonversion != version) {
|
||||
LOG(logERROR) << "version mismatch. required " << version << ", got "
|
||||
<< zHeader.jsonversion;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// parse
|
||||
zHeader.data = ((document["data"].GetUint()) == 0) ? false : true;
|
||||
zHeader.dynamicRange = document["bitmode"].GetUint();
|
||||
zHeader.fileIndex = document["fileIndex"].GetUint64();
|
||||
zHeader.ndetx = document["detshape"][0].GetUint();
|
||||
zHeader.ndety = document["detshape"][1].GetUint();
|
||||
zHeader.npixelsx = document["shape"][0].GetUint();
|
||||
zHeader.npixelsy = document["shape"][1].GetUint();
|
||||
zHeader.imageSize = document["size"].GetUint();
|
||||
zHeader.acqIndex = document["acqIndex"].GetUint64();
|
||||
zHeader.frameIndex = document["frameIndex"].GetUint64();
|
||||
zHeader.fname = document["fname"].GetString();
|
||||
|
||||
zHeader.frameNumber = document["frameNumber"].GetUint64();
|
||||
zHeader.expLength = document["expLength"].GetUint();
|
||||
zHeader.packetNumber = document["packetNumber"].GetUint();
|
||||
zHeader.bunchId = document["bunchId"].GetUint64();
|
||||
zHeader.timestamp = document["timestamp"].GetUint64();
|
||||
zHeader.modId = document["modId"].GetUint();
|
||||
zHeader.row = document["row"].GetUint();
|
||||
zHeader.column = document["column"].GetUint();
|
||||
zHeader.reserved = document["reserved"].GetUint();
|
||||
zHeader.debug = document["debug"].GetUint();
|
||||
zHeader.roundRNumber = document["roundRNumber"].GetUint();
|
||||
zHeader.detType = document["detType"].GetUint();
|
||||
zHeader.version = document["version"].GetUint();
|
||||
|
||||
zHeader.flippedDataX = document["flippedDataX"].GetUint();
|
||||
zHeader.quad = document["quad"].GetUint();
|
||||
zHeader.completeImage = document["completeImage"].GetUint();
|
||||
|
||||
if (document.HasMember("addJsonHeader")) {
|
||||
const Value& V = document["addJsonHeader"];
|
||||
zHeader.addJsonHeader.clear();
|
||||
for (Value::ConstMemberIterator iter = V.MemberBegin(); iter != V.MemberEnd(); ++iter){
|
||||
zHeader.addJsonHeader[iter->name.GetString()] = iter->value.GetString();
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ZmqSocket::ReceiveData(const int index, char *buf, const int size) {
|
||||
zmq_msg_t message;
|
||||
zmq_msg_init(&message);
|
||||
int length = ReceiveMessage(index, message);
|
||||
if (length == size) {
|
||||
memcpy(buf, (char *)zmq_msg_data(&message), size);
|
||||
} else if (length < size) {
|
||||
memcpy(buf, (char *)zmq_msg_data(&message), length);
|
||||
memset(buf + length, 0xFF, size - length);
|
||||
} else {
|
||||
LOG(logERROR) << "Received weird packet size " << length
|
||||
<< " for socket " << index;
|
||||
memset(buf, 0xFF, size);
|
||||
}
|
||||
|
||||
zmq_msg_close(&message);
|
||||
return length;
|
||||
}
|
||||
|
||||
int ZmqSocket::ReceiveMessage(const int index, zmq_msg_t &message) {
|
||||
int length = zmq_msg_recv(&message, sockfd.socketDescriptor, 0);
|
||||
if (length == -1) {
|
||||
PrintError();
|
||||
LOG(logERROR) << "Could not read header for socket " << index;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
void ZmqSocket::PrintError() {
|
||||
switch (errno) {
|
||||
case EINVAL:
|
||||
@ -210,181 +448,6 @@ void ZmqSocket::PrintError() {
|
||||
}
|
||||
}
|
||||
|
||||
int ZmqSocket::ReceiveData(const int index, char *buf, const int size) {
|
||||
zmq_msg_t message;
|
||||
zmq_msg_init(&message);
|
||||
int length = ReceiveMessage(index, message);
|
||||
if (length == size) {
|
||||
memcpy(buf, (char *)zmq_msg_data(&message), size);
|
||||
} else if (length < size) {
|
||||
memcpy(buf, (char *)zmq_msg_data(&message), length);
|
||||
memset(buf + length, 0xFF, size - length);
|
||||
} else {
|
||||
LOG(logERROR) << "Received weird packet size " << length
|
||||
<< " for socket " << index;
|
||||
memset(buf, 0xFF, size);
|
||||
}
|
||||
|
||||
zmq_msg_close(&message);
|
||||
return length;
|
||||
}
|
||||
|
||||
int ZmqSocket::ParseHeader(const int index, int length, char *buff,
|
||||
Document &document, bool &dummy, uint32_t version) {
|
||||
if (document.Parse(buff, length).HasParseError()) {
|
||||
LOG(logERROR) << index << " Could not parse. len:" << length
|
||||
<< ": Message:" << buff;
|
||||
fflush(stdout);
|
||||
// char* buf = (char*) zmq_msg_data (&message);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
cprintf(RED, "%02x ", buff[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (document["jsonversion"].GetUint() != version) {
|
||||
LOG(logERROR) << "version mismatch. required " << version << ", got "
|
||||
<< document["jsonversion"].GetUint();
|
||||
return 0;
|
||||
}
|
||||
|
||||
dummy = false;
|
||||
int temp = document["data"].GetUint();
|
||||
dummy = temp ? false : true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ZmqSocket::ReceiveHeader(const int index, Document &document,
|
||||
uint32_t version) {
|
||||
std::vector<char> buffer(MAX_STR_LENGTH);
|
||||
int len =
|
||||
zmq_recv(sockfd.socketDescriptor, buffer.data(), buffer.size(), 0);
|
||||
if (len > 0) {
|
||||
bool dummy = false;
|
||||
#ifdef ZMQ_DETAIL
|
||||
cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno,
|
||||
len, buffer.data());
|
||||
#endif
|
||||
if (ParseHeader(index, len, buffer.data(), document, dummy, version)) {
|
||||
#ifdef ZMQ_DETAIL
|
||||
cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index,
|
||||
portno, len, buffer.data());
|
||||
#endif
|
||||
if (dummy) {
|
||||
#ifdef ZMQ_DETAIL
|
||||
cprintf(RED, "%d [%d] Received end of acquisition\n", index,
|
||||
portno);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#ifdef ZMQ_DETAIL
|
||||
cprintf(GREEN, "%d [%d] data\n", index, portno);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
int ZmqSocket::ReceiveMessage(const int index, zmq_msg_t &message) {
|
||||
int length = zmq_msg_recv(&message, sockfd.socketDescriptor, 0);
|
||||
if (length == -1) {
|
||||
PrintError();
|
||||
LOG(logERROR) << "Could not read header for socket " << index;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
int ZmqSocket::SendData(char *buf, int length) {
|
||||
if (zmq_send(sockfd.socketDescriptor, buf, length, 0) < 0) {
|
||||
PrintError();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ZmqSocket::SendHeaderData(
|
||||
int index, bool dummy, uint32_t jsonversion, uint32_t dynamicrange,
|
||||
uint64_t fileIndex, uint32_t ndetx, uint32_t ndety, uint32_t npixelsx,
|
||||
uint32_t npixelsy, uint32_t imageSize, uint64_t acqIndex, uint64_t fIndex,
|
||||
std::string fname, uint64_t frameNumber, uint32_t expLength,
|
||||
uint32_t packetNumber, uint64_t bunchId, uint64_t timestamp, uint16_t modId,
|
||||
uint16_t row, uint16_t column, uint16_t reserved, uint32_t debug,
|
||||
uint16_t roundRNumber, uint8_t detType, uint8_t version,
|
||||
int gapPixelsEnable, int flippedDataX, uint32_t quadEnable,
|
||||
std::string *additionalJsonHeader) {
|
||||
|
||||
/** Json Header Format */
|
||||
const char jsonHeaderFormat[] = "{"
|
||||
"\"jsonversion\":%u, "
|
||||
"\"bitmode\":%u, "
|
||||
"\"fileIndex\":%lu, "
|
||||
"\"detshape\":[%u, %u], "
|
||||
"\"shape\":[%u, %u], "
|
||||
"\"size\":%u, "
|
||||
"\"acqIndex\":%lu, "
|
||||
"\"fIndex\":%lu, "
|
||||
"\"fname\":\"%s\", "
|
||||
"\"data\": %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, "
|
||||
|
||||
// additional stuff
|
||||
"\"gappixels\":%u, "
|
||||
"\"flippedDataX\":%u, "
|
||||
"\"quad\":%u"
|
||||
|
||||
; //"}\n";
|
||||
char buf[MAX_STR_LENGTH] = "";
|
||||
sprintf(buf, jsonHeaderFormat, jsonversion, dynamicrange, fileIndex, ndetx,
|
||||
ndety, npixelsx, npixelsy, imageSize, acqIndex, fIndex,
|
||||
fname.c_str(), dummy ? 0 : 1,
|
||||
|
||||
frameNumber, expLength, packetNumber, bunchId, timestamp, modId,
|
||||
row, column, reserved, debug, roundRNumber, detType, version,
|
||||
|
||||
// additional stuff
|
||||
gapPixelsEnable, flippedDataX, quadEnable);
|
||||
|
||||
if (additionalJsonHeader && !((*additionalJsonHeader).empty())) {
|
||||
strcat(buf, ", ");
|
||||
strcat(buf, (*additionalJsonHeader).c_str());
|
||||
}
|
||||
strcat(buf, "}\n");
|
||||
int length = strlen(buf);
|
||||
|
||||
#ifdef VERBOSE
|
||||
// if(!index)
|
||||
cprintf(BLUE, "%d : Streamer: buf: %s\n", index, buf);
|
||||
#endif
|
||||
|
||||
if (zmq_send(sockfd.socketDescriptor, buf, length,
|
||||
dummy ? 0 : ZMQ_SNDMORE) < 0) {
|
||||
PrintError();
|
||||
return 0;
|
||||
}
|
||||
#ifdef VERBOSE
|
||||
cprintf(GREEN, "[%u] send header data\n", portno);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//Nested class to do RAII handling of socket descriptors
|
||||
ZmqSocket::mySocketDescriptors::mySocketDescriptors()
|
||||
: server(false), contextDescriptor(0), socketDescriptor(0){};
|
||||
|
Loading…
x
Reference in New Issue
Block a user