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:
Dhanya Thattil 2020-03-30 14:54:35 +02:00 committed by GitHub
parent 6a6af528ef
commit d58eb1dc6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 1879 additions and 1398 deletions

View File

@ -55,6 +55,149 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <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"> <widget class="QWidget" name="widgetStatistics" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -241,7 +384,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>376</width> <width>376</width>
<height>28</height> <height>27</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuSave"> <widget class="QMenu" name="menuSave">

View File

@ -19,47 +19,8 @@
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QGridLayout" name="layout"> <layout class="QGridLayout" name="gridLayout">
<property name="margin"> <item row="2" column="0" colspan="4">
<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">
<widget class="QWidget" name="widgetStatistics" native="true"> <widget class="QWidget" name="widgetStatistics" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -86,73 +47,6 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </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"> <item row="0" column="3">
<widget class="QLabel" name="lblMax"> <widget class="QLabel" name="lblMax">
<property name="sizePolicy"> <property name="sizePolicy">
@ -181,8 +75,8 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="7"> <item row="0" column="1">
<widget class="QLabel" name="lblSumDisp"> <widget class="QLabel" name="lblMinDisp">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -194,6 +88,19 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="0" column="0">
<widget class="QLabel" name="lblMin"> <widget class="QLabel" name="lblMin">
<property name="sizePolicy"> <property name="sizePolicy">
@ -222,6 +129,32 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="0" column="5">
<spacer name="horizontalSpacer_2"> <spacer name="horizontalSpacer_2">
<property name="orientation"> <property name="orientation">
@ -235,9 +168,213 @@
</property> </property>
</spacer> </spacer>
</item> </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> </layout>
</widget> </widget>
</item> </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> </layout>
</widget> </widget>
<resources/> <resources/>

View File

@ -14,7 +14,7 @@ class qCloneWidget : public QMainWindow, private Ui::ClonePlotObject {
qCloneWidget(QWidget *parent, SlsQt1DPlot *p1, SlsQt2DPlot *p2, qCloneWidget(QWidget *parent, SlsQt1DPlot *p1, SlsQt2DPlot *p2,
SlsQt1DPlot *gp1, SlsQt2DPlot *gp, QString title, SlsQt1DPlot *gp1, SlsQt2DPlot *gp, QString title,
QString filePath, QString fileName, int64_t aIndex, 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(); ~qCloneWidget();

View File

@ -114,6 +114,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
QString zTitle2d{"Intensity"}; QString zTitle2d{"Intensity"};
QString plotTitle{""}; QString plotTitle{""};
QString indexTitle{""}; QString indexTitle{""};
bool completeImage{false};
bool xyRangeChanged{false}; bool xyRangeChanged{false};
double xyRange[4]{0, 0, 0, 0}; double xyRange[4]{0, 0, 0, 0};
bool isXYRange[4]{false, false, false, false}; bool isXYRange[4]{false, false, false, false};

View File

@ -15,13 +15,20 @@ qCloneWidget::qCloneWidget(QWidget *parent, SlsQt1DPlot *p1, SlsQt2DPlot *p2,
SlsQt1DPlot *gp1, SlsQt2DPlot *gp, QString title, SlsQt1DPlot *gp1, SlsQt2DPlot *gp, QString title,
QString fPath, QString fName, int64_t aIndex, QString fPath, QString fName, int64_t aIndex,
bool displayStats, QString min, QString max, bool displayStats, QString min, QString max,
QString sum) QString sum, bool completeImage)
: QMainWindow(parent), plot1d(p1), plot2d(p2), gainplot1d(gp1), : QMainWindow(parent), plot1d(p1), plot2d(p2), gainplot1d(gp1),
gainplot2d(gp), filePath(fPath), fileName(fName), acqIndex(aIndex) { gainplot2d(gp), filePath(fPath), fileName(fName), acqIndex(aIndex) {
setupUi(this); setupUi(this);
id = qCloneWidget::NumClones++; id = qCloneWidget::NumClones++;
SetupWidgetWindow(title); SetupWidgetWindow(title);
DisplayStats(displayStats, min, max, sum); DisplayStats(displayStats, min, max, sum);
lblCompleteImage->hide();
lblInCompleteImage->hide();
if (completeImage) {
lblCompleteImage->show();
} else {
lblInCompleteImage->show();
}
} }
qCloneWidget::~qCloneWidget() { qCloneWidget::~qCloneWidget() {

View File

@ -97,27 +97,13 @@ void qDrawPlot::SetupPlots() {
slsDetectorDefs::xy res = det->getDetectorSize(); slsDetectorDefs::xy res = det->getDetectorSize();
nPixelsX = res.x; nPixelsX = res.x;
nPixelsY = res.y; 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) << "nPixelsX:" << nPixelsX;
LOG(logINFO) << "nPixelsY:" << nPixelsY; LOG(logINFO) << "nPixelsY:" << nPixelsY;
boxPlot->setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal)); boxPlot->setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
widgetStatistics->hide(); widgetStatistics->hide();
lblCompleteImage->hide();
lblInCompleteImage->hide();
// setup 1d data // setup 1d data
@ -586,7 +572,7 @@ void qDrawPlot::ClonePlot() {
clonegainplot2D, boxPlot->title(), fileSavePath, clonegainplot2D, boxPlot->title(), fileSavePath,
fileSaveName, currentAcqIndex, displayStatistics, fileSaveName, currentAcqIndex, displayStatistics,
lblMinDisp->text(), lblMaxDisp->text(), lblMinDisp->text(), lblMaxDisp->text(),
lblSumDisp->text()); lblSumDisp->text(), completeImage);
} }
void qDrawPlot::SavePlot() { void qDrawPlot::SavePlot() {
@ -756,6 +742,7 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
<< " \t dynamic range: " << data->dynamicRange << " \t dynamic range: " << data->dynamicRange
<< std::endl << std::endl
<< " \t file index: " << data->fileIndex << std::endl << " \t file index: " << data->fileIndex << std::endl
<< " \t complete image: " << data->completeImage << std::endl
<< " ]"; << " ]";
progress = (int)data->progressIndex; progress = (int)data->progressIndex;
@ -776,6 +763,11 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
delete[] data2d; delete[] data2d;
data2d = new double[nPixelsY * nPixelsX]; data2d = new double[nPixelsY * nPixelsX];
std::fill(data2d, data2d + nPixelsX * nPixelsY, 0); 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 // convert data to double
@ -798,6 +790,7 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
if ((int)subFrameIndex != -1) { if ((int)subFrameIndex != -1) {
indexTitle = QString("%1 %2").arg(frameIndex, subFrameIndex); indexTitle = QString("%1 %2").arg(frameIndex, subFrameIndex);
} }
completeImage = data->completeImage;
// reset pedestal // reset pedestal
if (resetPedestal) { if (resetPedestal) {
@ -1118,6 +1111,16 @@ void qDrawPlot::UpdatePlot() {
LOG(logDEBUG) << "Update Plot"; LOG(logDEBUG) << "Update Plot";
boxPlot->setTitle(plotTitle); boxPlot->setTitle(plotTitle);
// notify of incomplete images
lblCompleteImage->hide();
lblInCompleteImage->hide();
if(completeImage) {
lblCompleteImage->show();
} else {
lblInCompleteImage->show();
}
if (is1d) { if (is1d) {
Update1dPlot(); Update1dPlot();
} else { } else {

View File

@ -64,6 +64,7 @@ void qTabPlot::SetupWidgetWindow() {
chkGapPixels->setEnabled(true); chkGapPixels->setEnabled(true);
break; break;
case slsDetectorDefs::JUNGFRAU: case slsDetectorDefs::JUNGFRAU:
chkGapPixels->setEnabled(true);
chkGainPlot->setEnabled(true); chkGainPlot->setEnabled(true);
chkGainPlot->setChecked(true); chkGainPlot->setChecked(true);
plot->EnableGainPlot(true); plot->EnableGainPlot(true);
@ -312,8 +313,7 @@ void qTabPlot::GetGapPixels() {
disconnect(chkGapPixels, SIGNAL(toggled(bool)), this, disconnect(chkGapPixels, SIGNAL(toggled(bool)), this,
SLOT(SetGapPixels(bool))); SLOT(SetGapPixels(bool)));
try { try {
auto retval = det->getRxAddGapPixels().tsquash( auto retval = det->getGapPixelsinCallback();
"Inconsistent gap pixels enabled for all detectors.");
chkGapPixels->setChecked(retval); chkGapPixels->setChecked(retval);
} }
CATCH_DISPLAY("Could not get gap pixels enable.", "qTabPlot::GetGapPixels") CATCH_DISPLAY("Could not get gap pixels enable.", "qTabPlot::GetGapPixels")
@ -324,7 +324,7 @@ void qTabPlot::GetGapPixels() {
void qTabPlot::SetGapPixels(bool enable) { void qTabPlot::SetGapPixels(bool enable) {
LOG(logINFO) << "Setting Gap Pixels Enable to " << enable; LOG(logINFO) << "Setting Gap Pixels Enable to " << enable;
try { try {
det->setRxAddGapPixels(enable); det->setGapPixelsinCallback(enable);
} }
CATCH_HANDLE("Could not set gap pixels enable.", "qTabPlot::SetGapPixels", CATCH_HANDLE("Could not set gap pixels enable.", "qTabPlot::SetGapPixels",
this, &qTabPlot::GetGapPixels) this, &qTabPlot::GetGapPixels)
@ -672,6 +672,8 @@ void qTabPlot::Refresh() {
break; break;
case slsDetectorDefs::JUNGFRAU: case slsDetectorDefs::JUNGFRAU:
chkGainPlot->setEnabled(true); chkGainPlot->setEnabled(true);
chkGapPixels->setEnabled(true);
GetGapPixels();
break; break;
case slsDetectorDefs::GOTTHARD2: case slsDetectorDefs::GOTTHARD2:
chkGainPlot1D->setEnabled(true); chkGainPlot1D->setEnabled(true);

View File

@ -22,7 +22,7 @@ target_include_directories(eigerDetectorServerMaster_virtual
target_compile_definitions(eigerDetectorServerMaster_virtual target_compile_definitions(eigerDetectorServerMaster_virtual
PUBLIC EIGERD PCCOMPILE STOP_SERVER PUBLIC EIGERD PCCOMPILE STOP_SERVER
PUBLIC VIRTUAL DVIRTUAL_9M PUBLIC VIRTUAL #VIRTUAL_9M
PUBLIC VIRTUAL_MASTER PUBLIC VIRTUAL_MASTER
) )
@ -38,27 +38,60 @@ install(TARGETS eigerDetectorServerMaster_virtual
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
) )
add_executable(eigerDetectorServerSlave_virtual
add_executable(eigerDetectorServerSlaveTop_virtual
${src} ${src}
) )
target_include_directories(eigerDetectorServerSlave_virtual target_include_directories(eigerDetectorServerSlaveTop_virtual
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
) )
target_compile_definitions(eigerDetectorServerSlave_virtual target_compile_definitions(eigerDetectorServerSlaveTop_virtual
PUBLIC EIGERD PCCOMPILE STOP_SERVER 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 PUBLIC pthread rt
) )
set_target_properties(eigerDetectorServerSlave_virtual PROPERTIES set_target_properties(eigerDetectorServerSlaveTop_virtual PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 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} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
) )

View File

@ -20,6 +20,7 @@
// Global variable from slsDetectorServer_funcs // Global variable from slsDetectorServer_funcs
extern int debugflag; extern int debugflag;
extern udpStruct udpDetails; extern udpStruct udpDetails;
extern const enum detectorType myDetectorType;
// Global variable from communication_funcs.c // Global variable from communication_funcs.c
extern int isControlServer; extern int isControlServer;
@ -88,6 +89,8 @@ pthread_t eiger_virtual_tid;
int eiger_virtual_stop = 0; int eiger_virtual_stop = 0;
uint64_t eiger_virtual_startingframenumber = 0; uint64_t eiger_virtual_startingframenumber = 0;
int eiger_virtual_detPos[2] = {0, 0}; int eiger_virtual_detPos[2] = {0, 0};
int eiger_virtual_test_mode = 0;
int eiger_virtual_quad_mode = 0;
#endif #endif
@ -179,8 +182,23 @@ void basictests() {
LOG(logINFO, ("Compatibility - success\n")); 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 */ /* Ids */
@ -361,7 +379,11 @@ void getModuleConfiguration() {
top = 1; top = 1;
#else #else
master = 0; master = 0;
#ifdef VIRTUAL_TOP
top = 1; top = 1;
#else
top = 0;
#endif
#endif #endif
#ifdef VIRTUAL_9M #ifdef VIRTUAL_9M
normal = 0; normal = 0;
@ -1291,13 +1313,15 @@ int setQuad(int value) {
if (!Feb_Control_SetQuad(value)) { if (!Feb_Control_SetQuad(value)) {
return FAIL; return FAIL;
} }
#else
eiger_virtual_quad_mode = value;
#endif #endif
return OK; return OK;
} }
int getQuad() { int getQuad() {
#ifdef VIRTUAL #ifdef VIRTUAL
return 0; return eiger_virtual_quad_mode;
#else #else
return Beb_GetQuad(); return Beb_GetQuad();
#endif #endif
@ -1779,17 +1803,42 @@ void* start_timer(void* arg) {
int numPacketsPerFrame = (tgEnable ? 4 : 16) * dr; int numPacketsPerFrame = (tgEnable ? 4 : 16) * dr;
int npixelsx = 256 * 2 * bytesPerPixel; int npixelsx = 256 * 2 * bytesPerPixel;
int databytes = 256 * 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", int row = eiger_virtual_detPos[0];
dr, bytesPerPixel, tgEnable, datasize, packetsize, numPacketsPerFrame, npixelsx, databytes)); 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 //TODO: Generate data
char imageData[databytes * 2]; char imageData[databytes * 2];
memset(imageData, 0, databytes * 2); memset(imageData, 0, databytes * 2);
{ {
int i = 0; int i = 0;
for (i = 0; i < databytes * 2; i += sizeof(uint8_t)) { switch (dr) {
*((uint8_t*)(imageData + i)) = i; 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;
} }
} }
@ -1798,6 +1847,8 @@ void* start_timer(void* arg) {
int frameNr = 1; int frameNr = 1;
for(frameNr=1; frameNr <= numFrames; ++frameNr ) { for(frameNr=1; frameNr <= numFrames; ++frameNr ) {
usleep(eiger_virtual_transmission_delay_frame);
//check if virtual_stop is high //check if virtual_stop is high
if(eiger_virtual_stop == 1){ if(eiger_virtual_stop == 1){
break; break;
@ -1822,11 +1873,24 @@ void* start_timer(void* arg) {
int dstOffset2 = sizeof(sls_detector_header); int dstOffset2 = sizeof(sls_detector_header);
// set header // set header
sls_detector_header* header = (sls_detector_header*)(packetData); 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->frameNumber = frameNr;
header->packetNumber = i; header->packetNumber = i;
header->row = row;
header->column = colLeft;
header = (sls_detector_header*)(packetData2); header = (sls_detector_header*)(packetData2);
header->detType = (uint16_t)myDetectorType;
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
header->frameNumber = frameNr; header->frameNumber = frameNr;
header->packetNumber = i; 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 // fill data
{ {
@ -1836,8 +1900,15 @@ void* start_timer(void* arg) {
if (dr == 32 && tgEnable == 0) { if (dr == 32 && tgEnable == 0) {
memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx/2); memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx/2);
memcpy(packetData2 + dstOffset2, imageData + srcOffset2, 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; srcOffset += npixelsx;
srcOffset2 += npixelsx; srcOffset2 += npixelsx;
}
dstOffset += npixelsx/2; dstOffset += npixelsx/2;
dstOffset2 += npixelsx/2; dstOffset2 += npixelsx/2;
} else { } else {
@ -1850,8 +1921,9 @@ void* start_timer(void* arg) {
} }
} }
} }
usleep(eiger_virtual_transmission_delay_left);
sendUDPPacket(0, packetData, packetsize); sendUDPPacket(0, packetData, packetsize);
usleep(eiger_virtual_transmission_delay_right);
sendUDPPacket(1, packetData2, packetsize); sendUDPPacket(1, packetData2, packetsize);
} }
} }
@ -1869,6 +1941,7 @@ void* start_timer(void* arg) {
} }
} }
closeUDPSocket(0); closeUDPSocket(0);
closeUDPSocket(1); closeUDPSocket(1);

View File

@ -239,10 +239,10 @@ void setTestImageMode(int ival) {
uint32_t addr = MULTI_PURPOSE_REG; uint32_t addr = MULTI_PURPOSE_REG;
if (ival >= 0) { if (ival >= 0) {
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); bus_w (addr, bus_r(addr) & ~DGTL_TST_MSK);
} else { } 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); bus_w (addr, bus_r(addr) | DGTL_TST_MSK);
} }
} }
@ -915,8 +915,9 @@ int getModule(sls_detector_module *myMod){
if (dacValues[idac] >= 0) if (dacValues[idac] >= 0)
initialized = 1; initialized = 1;
} }
if (initialized) if (initialized) {
return OK; return OK;
}
return FAIL; return FAIL;
} }

View File

@ -31,6 +31,7 @@ char initErrorMessage[MAX_STR_LENGTH];
pthread_t pthread_virtual_tid; pthread_t pthread_virtual_tid;
int virtual_status = 0; int virtual_status = 0;
int virtual_stop = 0; int virtual_stop = 0;
int virtual_image_test_mode = 0;
#endif #endif
enum detectorSettings thisSettings = UNINITIALIZED; enum detectorSettings thisSettings = UNINITIALIZED;
@ -41,6 +42,7 @@ int detPos[4] = {};
int numUDPInterfaces = 1; int numUDPInterfaces = 1;
int isInitCheckDone() { int isInitCheckDone() {
return initCheckDone; 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 */ /* Ids */
@ -727,8 +746,9 @@ int getModule(sls_detector_module *myMod){
if (dacValues[idac] >= 0) if (dacValues[idac] >= 0)
initialized = 1; initialized = 1;
} }
if (initialized) if (initialized) {
return OK; return OK;
}
return FAIL; return FAIL;
} }
@ -1646,17 +1666,22 @@ void* start_timer(void* arg) {
getNumTriggers() * getNumTriggers() *
(getNumAdditionalStorageCells() + 1)); (getNumAdditionalStorageCells() + 1));
int64_t exp_us = getExpTime() / 1000; 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 //TODO: Generate data
char imageData[DATA_BYTES]; char imageData[DATA_BYTES];
memset(imageData, 0, DATA_BYTES); memset(imageData, 0, DATA_BYTES);
{ {
int i = 0; int i = 0;
for (i = 0; i < DATA_BYTES; i += sizeof(uint16_t)) { for (i = 0; i < npixels; ++i) {
*((uint16_t*)(imageData + i)) = 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 //TODO: Send data
@ -1664,6 +1689,8 @@ void* start_timer(void* arg) {
int frameNr = 0; int frameNr = 0;
for(frameNr=0; frameNr!= numFrames; ++frameNr ) { for(frameNr=0; frameNr!= numFrames; ++frameNr ) {
usleep(transmissionDelayUs);
//check if virtual_stop is high //check if virtual_stop is high
if(virtual_stop == 1){ if(virtual_stop == 1){
break; break;
@ -1676,28 +1703,28 @@ void* start_timer(void* arg) {
usleep(exp_us); usleep(exp_us);
const int size = datasize + sizeof(sls_detector_header); char packetData[packetsize];
char packetData[size]; memset(packetData, 0, packetsize);
memset(packetData, 0, sizeof(sls_detector_header));
// loop packet // loop packet
{ {
int i = 0; int i = 0;
for(i=0; i!=128; ++i) { for(i = 0; i != numPacketsPerFrame; ++i) {
// set header // set header
sls_detector_header* header = (sls_detector_header*)(packetData); sls_detector_header* header = (sls_detector_header*)(packetData);
header->detType = (uint16_t)myDetectorType;
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
header->frameNumber = frameNr; header->frameNumber = frameNr;
header->packetNumber = i; header->packetNumber = i;
header->modId = 0; header->modId = 0;
header->row = detPos[X]; header->row = detPos[X];
header->column = detPos[Y]; header->column = detPos[Y];
header->detType = (uint16_t)myDetectorType;
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
// fill data // fill data
memcpy(packetData + sizeof(sls_detector_header), imageData + srcOffset, datasize); memcpy(packetData + sizeof(sls_detector_header), imageData + srcOffset, datasize);
srcOffset += datasize; srcOffset += datasize;
sendUDPPacket(0, packetData, size); sendUDPPacket(0, packetData, packetsize);
} }
} }
LOG(logINFO, ("Sent frame: %d\n", frameNr)); LOG(logINFO, ("Sent frame: %d\n", frameNr));
@ -1714,7 +1741,6 @@ void* start_timer(void* arg) {
} }
} }
// }
closeUDPSocket(0); closeUDPSocket(0);

View File

@ -969,8 +969,9 @@ enum detectorSettings getSettings() {
void setDAC(enum DACINDEX ind, int val, int mV) { void setDAC(enum DACINDEX ind, int val, int mV) {
if (val < 0 && val != LTC2620_GetPowerDownValue()) if (val < 0 && val != LTC2620_GetPowerDownValue()) {
return; return;
}
char* dac_names[] = {DAC_NAMES}; char* dac_names[] = {DAC_NAMES};
LOG(logINFO, ("Setting DAC %s\n", dac_names[ind])); LOG(logINFO, ("Setting DAC %s\n", dac_names[ind]));

View File

@ -61,7 +61,7 @@ int testFpga();
int testBus(); int testBus();
#endif #endif
#ifdef GOTTHARDD #if defined(GOTTHARDD) || ((defined(EIGERD) || defined(JUNGFRAUD)) && defined(VIRTUAL))
void setTestImageMode(int ival); void setTestImageMode(int ival);
int getTestImageMode(); int getTestImageMode();
#endif #endif

View File

@ -26,8 +26,12 @@ void ASIC_Driver_SetDefines(char* driverfname) {
} }
int ASIC_Driver_Set (int index, int length, char* buffer) { 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]; 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[chip index: %d, length: %d, fname: %s]\n", index, length, fname));
{ {
LOG(logDEBUG2, ("\t[values: \n")); LOG(logDEBUG2, ("\t[values: \n"));

View File

@ -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)); LOG(logINFO, ("Setting DAC %2d [%-12s] : %d dac (%d mV)\n",dacnum, dacname, *dacval, dacmV));
char fname[MAX_STR_LENGTH]; 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)); LOG(logDEBUG1, ("fname %s\n",fname));
//open file //open file

View File

@ -101,17 +101,25 @@ int main(int argc, char *argv[]){
} }
#ifdef STOP_SERVER #ifdef STOP_SERVER
char cmd[100]; char cmd[MAX_STR_LENGTH];
memset(cmd, 0, 100); memset(cmd, 0, MAX_STR_LENGTH);
#endif #endif
if (isControlServer) { if (isControlServer) {
LOG(logINFO, ("Opening control server on port %d \n", portno)); LOG(logINFO, ("Opening control server on port %d \n", portno));
#ifdef STOP_SERVER #ifdef STOP_SERVER
{ {
int i; int i;
for (i = 0; i < argc; ++i) for (i = 0; i < argc; ++i) {
sprintf(cmd, "%s %s", cmd, argv[i]); if (i > 0) {
sprintf(cmd,"%s -stopserver -port %d &", cmd, portno + 1); 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)); LOG(logDEBUG1, ("Command to start stop server:%s\n", cmd));
system(cmd); system(cmd);
} }

View File

@ -776,10 +776,10 @@ int set_image_test_mode(int file_des) {
return printSocketReadError(); return printSocketReadError();
LOG(logDEBUG1, ("Setting image test mode to \n", arg)); LOG(logDEBUG1, ("Setting image test mode to \n", arg));
#ifndef GOTTHARDD #if defined(GOTTHARDD) || ((defined(EIGERD) || defined(JUNGFRAUD)) && defined(VIRTUAL))
functionNotImplemented();
#else
setTestImageMode(arg); setTestImageMode(arg);
#else
functionNotImplemented();
#endif #endif
return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); return Server_SendResult(file_des, INT32, UPDATE, NULL, 0);
} }
@ -790,11 +790,11 @@ int get_image_test_mode(int file_des) {
int retval = -1; int retval = -1;
LOG(logDEBUG1, ("Getting image test mode\n")); LOG(logDEBUG1, ("Getting image test mode\n"));
#ifndef GOTTHARDD #if defined(GOTTHARDD) || ((defined(EIGERD) || defined(JUNGFRAUD)) && defined(VIRTUAL))
functionNotImplemented();
#else
retval = getTestImageMode(); retval = getTestImageMode();
LOG(logDEBUG1, ("image test mode retval: %d\n", retval)); LOG(logDEBUG1, ("image test mode retval: %d\n", retval));
#else
functionNotImplemented();
#endif #endif
return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval));
} }
@ -1844,7 +1844,8 @@ int start_acquisition(int file_des) {
#endif #endif
if (configured == FAIL) { if (configured == FAIL) {
ret = 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)); LOG(logERROR,(mess));
} else { } else {
ret = startStateMachine(); ret = startStateMachine();
@ -1979,7 +1980,8 @@ int start_and_read_all(int file_des) {
#endif #endif
if (configured == FAIL) { if (configured == FAIL) {
ret = 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)); LOG(logERROR,(mess));
} else { } else {
ret = startStateMachine(); ret = startStateMachine();
@ -4352,7 +4354,11 @@ int copy_detector_server(int file_des) {
memset(cmd, 0, MAX_STR_LENGTH); memset(cmd, 0, MAX_STR_LENGTH);
// copy server // 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); int success = executeCommand(cmd, retvals, logDEBUG1);
if (success == FAIL) { if (success == FAIL) {
ret = FAIL; ret = FAIL;
@ -4364,7 +4370,8 @@ int copy_detector_server(int file_des) {
else { else {
LOG(logINFO, ("Server copied successfully\n")); LOG(logINFO, ("Server copied successfully\n"));
// give permissions // give permissions
sprintf(cmd, "chmod 777 %s", sname); strcpy(cmd, "chmod 777 ");
strcat(cmd, sname);
executeCommand(cmd, retvals, logDEBUG1); executeCommand(cmd, retvals, logDEBUG1);
// edit /etc/inittab // 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")); LOG(logINFO, ("Deleted all lines containing DetectorServer in /etc/inittab\n"));
// append line // 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); executeCommand(cmd, retvals, logDEBUG1);
LOG(logINFO, ("/etc/inittab modified to have %s\n", sname)); LOG(logINFO, ("/etc/inittab modified to have %s\n", sname));

View File

@ -5,6 +5,7 @@
#include <chrono> #include <chrono>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <map>
class detectorData; class detectorData;
@ -137,6 +138,16 @@ class Detector {
void *), void *),
void *pArg); 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 * * Acquisition Parameters *
@ -255,12 +266,6 @@ class Detector {
Result<int> getHighVoltage(Positions pos = {}) const; 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 * [Gotthard] Options: 0, 90, 110, 120, 150, 180, 200
* [Jungfrau][CTB][Moench] Options: 0, 60 - 200 * [Jungfrau][CTB][Moench] Options: 0, 60 - 200
@ -268,6 +273,21 @@ class Detector {
*/ */
void setHighVoltage(int value, Positions pos = {}); 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) * (Degrees)
* [Gotthard] Options: TEMPERATURE_ADC, TEMPERATURE_FPGA * [Gotthard] Options: TEMPERATURE_ADC, TEMPERATURE_FPGA
@ -694,16 +714,6 @@ class Detector {
/** [Eiger] */ /** [Eiger] */
void loadTrimbits(const std::string &fname, Positions pos = {}); 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] */ /** [Eiger] */
Result<bool> getParallelMode(Positions pos = {}) const; Result<bool> getParallelMode(Positions pos = {}) const;
@ -905,12 +915,6 @@ class Detector {
void setExternalSignalFlags(defs::externalSignalFlag value, void setExternalSignalFlags(defs::externalSignalFlag value,
Positions pos = {}); 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] */ /** [Moench] */
Result<std::string> getAdditionalJsonHeader(Positions pos = {}) const; Result<std::map<std::string, std::string>> getAdditionalJsonHeader(Positions pos = {}) const;
/** [Moench] */ /** [Moench] If empty, reset additional json header. Max 20 characters for each key/value */
void setAdditionalJsonHeader(const std::string &jsonheader, void setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader,
Positions pos = {}); Positions pos = {});
/** [Moench] */ /** [Moench] */
@ -1207,12 +1211,11 @@ class Detector {
Positions pos = {}) const; Positions pos = {}) const;
/** /**
* [Moench] * [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 * 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, void setAdditionalJsonParameter(const std::string &key, const std::string &value,
const std::string &value,
Positions pos = {}); Positions pos = {});
/** [Moench] TODO! How do we do this best??? Can be refactored to something /** [Moench] TODO! How do we do this best??? Can be refactored to something

View File

@ -16,9 +16,10 @@ class detectorData {
* @param dbytes number of bytes of image pointed to by cval pointer * @param dbytes number of bytes of image pointed to by cval pointer
* @param dr dynamic range or bits per pixel * @param dr dynamic range or bits per pixel
* @param fIndex file index * @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) : 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) {}; progressIndex(progress), fileName(fname), fileIndex(fIndex), nx(x), ny(y), data(d), databytes(dbytes), dynamicRange(dr), completeImage(complete) {};
/** /**
* Destructor * Destructor
@ -55,4 +56,5 @@ class detectorData {
char* data; char* data;
int databytes; int databytes;
int dynamicRange; int dynamicRange;
bool completeImage;
}; };

View File

@ -1001,24 +1001,27 @@ std::string CmdProxy::GapPixels(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "[0, 1]\n\t[Eiger] Include Gap pixels in data file or data call " os << "[0, 1]\n\t[Eiger][Jungfrau] Include Gap pixels only in data call back."
"back. 4 bit mode gap pixels only ind ata call back."
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
if (det_id != -1) {
throw sls::RuntimeError(
"Cannot get gap pixels at module level");
}
if (!args.empty()) { if (!args.empty()) {
WrongNumberOfParameters(0); WrongNumberOfParameters(0);
} }
auto t = det->getRxAddGapPixels({det_id}); auto t = det->getGapPixelsinCallback();
os << OutString(t) << '\n'; os << t << '\n';
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
if (det_id != -1) { if (det_id != -1) {
throw sls::RuntimeError( throw sls::RuntimeError(
"Cannot execute dynamic range at module level"); "Cannot add gap pixels at module level");
} }
if (args.size() != 1) { if (args.size() != 1) {
WrongNumberOfParameters(1); WrongNumberOfParameters(1);
} }
det->setRxAddGapPixels(StringTo<int>(args[0])); det->setGapPixelsinCallback(StringTo<int>(args[0]));
os << args.front() << '\n'; os << args.front() << '\n';
} else { } else {
throw sls::RuntimeError("Unknown action"); throw sls::RuntimeError("Unknown action");
@ -1224,7 +1227,7 @@ std::string CmdProxy::Quad(int action) {
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
if (det_id != -1) { if (det_id != -1) {
throw sls::RuntimeError( throw sls::RuntimeError(
"Cannot execute dynamic range at module level"); "Cannot execute quad at module level");
} }
if (args.size() != 1) { if (args.size() != 1) {
WrongNumberOfParameters(1); WrongNumberOfParameters(1);
@ -1879,13 +1882,47 @@ std::string CmdProxy::PatternWaitTime(int action) {
/* Moench */ /* 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::string CmdProxy::JsonParameter(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "[key1] [value1]\n\tAdditional json header parameter streamed " os << "[key1] [value1]\n\tAdditional json header parameter streamed "
"out from receiver. If empty in a get, then no parameter found. " "out from receiver. If not found in header, the pair is appended. "
"This is same as calling rx_jsonaddheader \"key\":\"value1\"." "An empty values deletes parameter."
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
if (args.size() != 1) { if (args.size() != 1) {
@ -1894,11 +1931,21 @@ std::string CmdProxy::JsonParameter(int action) {
auto t = det->getAdditionalJsonParameter(args[0], {det_id}); auto t = det->getAdditionalJsonParameter(args[0], {det_id});
os << OutString(t) << '\n'; os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
if (args.size() != 2) { switch (args.size()) {
WrongNumberOfParameters(2); case 1:
} det->setAdditionalJsonParameter(args[0], "", {det_id});
break;
case 2:
det->setAdditionalJsonParameter(args[0], args[1], {det_id}); det->setAdditionalJsonParameter(args[0], args[1], {det_id});
os << sls::ToString(args) << '\n'; break;
default:
WrongNumberOfParameters(1);
}
if (args.size() == 1) {
os << args[0] << " deleted" << '\n';
} else {
os << "{" << args[0] << ": " << args[1] << "}" << '\n';
}
} else { } else {
throw sls::RuntimeError("Unknown action"); throw sls::RuntimeError("Unknown action");
} }

View File

@ -477,6 +477,7 @@ class CmdProxy {
{"cycles", "triggers"}, {"cycles", "triggers"},
{"cyclesl", "triggersl"}, {"cyclesl", "triggersl"},
{"clkdivider", "speed"}, {"clkdivider", "speed"},
{"digitest", "imagetest"},
/** temperature */ /** temperature */
/** dacs */ /** dacs */
@ -527,8 +528,6 @@ class CmdProxy {
/* Jungfrau Specific */ /* Jungfrau Specific */
/* Gotthard Specific */ /* Gotthard Specific */
{"digitest", "imagetest"},
/* Gotthard2 Specific */ /* Gotthard2 Specific */
/* Mythen3 Specific */ /* Mythen3 Specific */
/* CTB Specific */ /* CTB Specific */
@ -591,6 +590,7 @@ class CmdProxy {
{"clkdiv", &CmdProxy::ClockDivider}, {"clkdiv", &CmdProxy::ClockDivider},
{"vhighvoltage", &CmdProxy::vhighvoltage}, {"vhighvoltage", &CmdProxy::vhighvoltage},
{"powerchip", &CmdProxy::powerchip}, {"powerchip", &CmdProxy::powerchip},
{"imagetest", &CmdProxy::imagetest},
/** temperature */ /** temperature */
{"temp_adc", &CmdProxy::temp_adc}, {"temp_adc", &CmdProxy::temp_adc},
@ -789,7 +789,6 @@ class CmdProxy {
{"clearroi", &CmdProxy::ClearROI}, {"clearroi", &CmdProxy::ClearROI},
{"exptimel", &CmdProxy::exptimel}, {"exptimel", &CmdProxy::exptimel},
{"extsig", &CmdProxy::extsig}, {"extsig", &CmdProxy::extsig},
{"imagetest", &CmdProxy::imagetest},
/* Gotthard2 Specific */ /* Gotthard2 Specific */
{"bursts", &CmdProxy::bursts}, {"bursts", &CmdProxy::bursts},
@ -867,7 +866,7 @@ class CmdProxy {
{"patsetbit", &CmdProxy::patsetbit}, {"patsetbit", &CmdProxy::patsetbit},
/* Moench */ /* Moench */
{"rx_jsonaddheader", &CmdProxy::rx_jsonaddheader}, {"rx_jsonaddheader", &CmdProxy::AdditionalJsonHeader},
{"rx_jsonpara", &CmdProxy::JsonParameter}, {"rx_jsonpara", &CmdProxy::JsonParameter},
{"emin", &CmdProxy::MinMaxEnergyThreshold}, {"emin", &CmdProxy::MinMaxEnergyThreshold},
{"emax", &CmdProxy::MinMaxEnergyThreshold}, {"emax", &CmdProxy::MinMaxEnergyThreshold},
@ -980,6 +979,7 @@ class CmdProxy {
std::string PatternWaitAddress(int action); std::string PatternWaitAddress(int action);
std::string PatternWaitTime(int action); std::string PatternWaitTime(int action);
/* Moench */ /* Moench */
std::string AdditionalJsonHeader(int action);
std::string JsonParameter(int action); std::string JsonParameter(int action);
std::string MinMaxEnergyThreshold(int action); std::string MinMaxEnergyThreshold(int action);
/* Advanced */ /* 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[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."); "\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 */ /** temperature */
GET_IND_COMMAND(temp_adc, getTemperature, slsDetectorDefs::TEMPERATURE_ADC, " °C", 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>, 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."); "[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 */ /* Gotthard2 Specific */
INTEGER_COMMAND_NOID(bursts, getNumberOfBursts, setNumberOfBursts, INTEGER_COMMAND_NOID(bursts, getNumberOfBursts, setNumberOfBursts,
StringTo<int64_t>, StringTo<int64_t>,
@ -1719,9 +1720,6 @@ class CmdProxy {
/* Moench */ /* 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>, INTEGER_COMMAND(framemode, getFrameMode, setFrameMode, sls::StringTo<slsDetectorDefs::frameModeType>,
"[pedestal|newpedestal|flatfield|newflatfield]\n\t[Moench] Frame mode (soft setting) in processor."); "[pedestal|newpedestal|flatfield|newflatfield]\n\t[Moench] Frame mode (soft setting) in processor.");

View File

@ -167,6 +167,14 @@ void Detector::registerDataCallback(void (*func)(detectorData *, uint64_t,
pimpl->registerDataCallback(func, pArg); pimpl->registerDataCallback(func, pArg);
} }
bool Detector::getGapPixelsinCallback() const {
return pimpl->getGapPixelsinCallback();
}
void Detector::setGapPixelsinCallback(bool enable) {
pimpl->setGapPixelsinCallback(enable);
}
// Acquisition Parameters // Acquisition Parameters
Result<int64_t> Detector::getNumberOfFrames(Positions pos) const { 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, Result<int> Detector::getTemperature(defs::dacIndex index,
Positions pos) const { Positions pos) const {
switch (index) { switch (index) {
@ -953,14 +969,6 @@ void Detector::loadTrimbits(const std::string &fname, Positions pos) {
pimpl->Parallel(&Module::loadSettingsFile, pos, fname); 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 { Result<bool> Detector::getParallelMode(Positions pos) const {
return pimpl->Parallel(&Module::getParallelMode, pos); return pimpl->Parallel(&Module::getParallelMode, pos);
} }
@ -1195,14 +1203,6 @@ void Detector::setExternalSignalFlags(defs::externalSignalFlag value,
pimpl->Parallel(&Module::setExternalSignalFlags, pos, 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 // Gotthard2 Specific
Result<int64_t> Detector::getNumberOfBursts(Positions pos) const { Result<int64_t> Detector::getNumberOfBursts(Positions pos) const {
@ -1612,13 +1612,13 @@ void Detector::setPatternBitMask(uint64_t mask, Positions pos) {
// Moench // 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); 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) { Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonHeader, pos, jsonheader); pimpl->Parallel(&Module::setAdditionalJsonHeader, pos, jsonHeader);
} }
Result<std::string> Detector::getAdditionalJsonParameter(const std::string &key, 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); return pimpl->Parallel(&Module::getAdditionalJsonParameter, pos, key);
} }
void Detector::setAdditionalJsonParameter(const std::string &key, void Detector::setAdditionalJsonParameter(const std::string &key, const std::string &value,
const std::string &value,
Positions pos) { Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos, key, value); pimpl->Parallel(&Module::setAdditionalJsonParameter, pos, key, value);
} }

View File

@ -157,6 +157,7 @@ void DetectorImpl::initializeDetectorStructure() {
multi_shm()->numberOfChannels.y = 0; multi_shm()->numberOfChannels.y = 0;
multi_shm()->acquiringFlag = false; multi_shm()->acquiringFlag = false;
multi_shm()->initialChecks = true; multi_shm()->initialChecks = true;
multi_shm()->gapPixels = false;
} }
void DetectorImpl::initializeMembers(bool verify) { void DetectorImpl::initializeMembers(bool verify) {
@ -339,17 +340,30 @@ void DetectorImpl::setNumberOfChannels(const slsDetectorDefs::xy c) {
multi_shm()->numberOfChannels = c; multi_shm()->numberOfChannels = c;
} }
void DetectorImpl::setGapPixelsinReceiver(bool enable) { bool DetectorImpl::getGapPixelsinCallback() const {
Parallel(&Module::enableGapPixels, {}, static_cast<int>(enable)); return multi_shm()->gapPixels;
// 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;
} }
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) { int DetectorImpl::createReceivingDataSockets(const bool destroy) {
@ -406,11 +420,13 @@ int DetectorImpl::createReceivingDataSockets(const bool destroy) {
void DetectorImpl::readFrameFromReceiver() { void DetectorImpl::readFrameFromReceiver() {
bool gapPixels = multi_shm()->gapPixels;
LOG(logDEBUG) << "Gap pixels: " << gapPixels;
int nX = 0; int nX = 0;
int nY = 0; int nY = 0;
int nDetPixelsX = 0; int nDetPixelsX = 0;
int nDetPixelsY = 0; int nDetPixelsY = 0;
bool gappixelsenable = false;
bool quadEnable = false; bool quadEnable = false;
bool eiger = false; bool eiger = false;
bool numInterfaces = bool numInterfaces =
@ -434,6 +450,7 @@ void DetectorImpl::readFrameFromReceiver() {
} }
int numConnected = numRunning; int numConnected = numRunning;
bool data = false; bool data = false;
bool completeImage = false;
char *image = nullptr; char *image = nullptr;
char *multiframe = nullptr; char *multiframe = nullptr;
char *multigappixels = nullptr; char *multigappixels = nullptr;
@ -461,6 +478,7 @@ void DetectorImpl::readFrameFromReceiver() {
if (multiframe != nullptr) { if (multiframe != nullptr) {
memset(multiframe, 0xFF, multisize); memset(multiframe, 0xFF, multisize);
} }
completeImage = true;
// get each frame // get each frame
for (unsigned int isocket = 0; isocket < zmqSocket.size(); ++isocket) { for (unsigned int isocket = 0; isocket < zmqSocket.size(); ++isocket) {
@ -470,9 +488,9 @@ void DetectorImpl::readFrameFromReceiver() {
// HEADER // HEADER
{ {
rapidjson::Document doc; zmqHeader zHeader;
if (zmqSocket[isocket]->ReceiveHeader( if (zmqSocket[isocket]->ReceiveHeader(
isocket, doc, SLS_DETECTOR_JSON_HEADER_VERSION) == isocket, zHeader, SLS_DETECTOR_JSON_HEADER_VERSION) ==
0) { 0) {
// parse error, version error or end of acquisition for // parse error, version error or end of acquisition for
// socket // socket
@ -484,33 +502,29 @@ void DetectorImpl::readFrameFromReceiver() {
// if first message, allocate (all one time stuff) // if first message, allocate (all one time stuff)
if (image == nullptr) { if (image == nullptr) {
// allocate // allocate
size = doc["size"].GetUint(); size = zHeader.imageSize;
multisize = size * zmqSocket.size(); multisize = size * zmqSocket.size();
image = new char[size]; image = new char[size];
multiframe = new char[multisize]; multiframe = new char[multisize];
memset(multiframe, 0xFF, multisize); memset(multiframe, 0xFF, multisize);
// dynamic range // dynamic range
dynamicRange = doc["bitmode"].GetUint(); dynamicRange = zHeader.dynamicRange;
bytesPerPixel = (float)dynamicRange / 8; bytesPerPixel = (float)dynamicRange / 8;
// shape // shape
nPixelsX = doc["shape"][0].GetUint(); nPixelsX = zHeader.npixelsx;
nPixelsY = doc["shape"][1].GetUint(); nPixelsY = zHeader.npixelsy;
// detector shape // detector shape
nX = doc["detshape"][0].GetUint(); nX = zHeader.ndetx;
nY = doc["detshape"][1].GetUint(); nY = zHeader.ndety;
nY *= numInterfaces; nY *= numInterfaces;
nDetPixelsX = nX * nPixelsX; nDetPixelsX = nX * nPixelsX;
nDetPixelsY = nY * nPixelsY; nDetPixelsY = nY * nPixelsY;
// det type // det type
eiger = eiger = (zHeader.detType == static_cast<int>(3))
(doc["detType"].GetUint() == static_cast<int>(3))
? true ? true
: false; // to be changed to EIGER when firmware : false; // to be changed to EIGER when firmware
// updates its header data // updates its header data
gappixelsenable = quadEnable = (zHeader.quad == 0) ? false : true;
(doc["gappixels"].GetUint() == 0) ? false : true;
quadEnable =
(doc["quad"].GetUint() == 0) ? false : true;
LOG(logDEBUG1) LOG(logDEBUG1)
<< "One Time Header Info:" << "One Time Header Info:"
"\n\tsize: " "\n\tsize: "
@ -520,21 +534,23 @@ void DetectorImpl::readFrameFromReceiver() {
<< "\n\tnPixelsX: " << nPixelsX << "\n\tnPixelsX: " << nPixelsX
<< "\n\tnPixelsY: " << nPixelsY << "\n\tnX: " << nX << "\n\tnPixelsY: " << nPixelsY << "\n\tnX: " << nX
<< "\n\tnY: " << nY << "\n\teiger: " << eiger << "\n\tnY: " << nY << "\n\teiger: " << eiger
<< "\n\tgappixelsenable: " << gappixelsenable
<< "\n\tquadEnable: " << quadEnable; << "\n\tquadEnable: " << quadEnable;
} }
// each time, parse rest of header // each time, parse rest of header
currentFileName = doc["fname"].GetString(); currentFileName = zHeader.fname;
currentAcquisitionIndex = doc["acqIndex"].GetUint64(); currentAcquisitionIndex = zHeader.acqIndex;
currentFrameIndex = doc["fIndex"].GetUint64(); currentFrameIndex = zHeader.frameIndex;
currentFileIndex = doc["fileIndex"].GetUint64(); currentFileIndex = zHeader.fileIndex;
currentSubFrameIndex = doc["expLength"].GetUint(); currentSubFrameIndex = zHeader.expLength;
coordY = doc["row"].GetUint(); coordY = zHeader.row;
coordX = doc["column"].GetUint(); coordX = zHeader.column;
if (eiger) { if (eiger) {
coordY = (nY - 1) - coordY; coordY = (nY - 1) - coordY;
} }
flippedDataX = doc["flippedDataX"].GetUint(); flippedDataX = zHeader.flippedDataX;
if (zHeader.completeImage == 0) {
completeImage = false;
}
LOG(logDEBUG1) LOG(logDEBUG1)
<< "Header Info:" << "Header Info:"
"\n\tcurrentFileName: " "\n\tcurrentFileName: "
@ -544,12 +560,14 @@ void DetectorImpl::readFrameFromReceiver() {
<< "\n\tcurrentFileIndex: " << currentFileIndex << "\n\tcurrentFileIndex: " << currentFileIndex
<< "\n\tcurrentSubFrameIndex: " << currentSubFrameIndex << "\n\tcurrentSubFrameIndex: " << currentSubFrameIndex
<< "\n\tcoordX: " << coordX << "\n\tcoordY: " << coordY << "\n\tcoordX: " << coordX << "\n\tcoordY: " << coordY
<< "\n\tflippedDataX: " << flippedDataX; << "\n\tflippedDataX: " << flippedDataX
<< "\n\tcompleteImage: " << completeImage;
} }
// DATA // DATA
data = true; data = true;
zmqSocket[isocket]->ReceiveData(isocket, image, size); zmqSocket[isocket]->ReceiveData(isocket, image, size);
// creating multi image // creating multi image
{ {
uint32_t xoffset = coordX * nPixelsX * bytesPerPixel; uint32_t xoffset = coordX * nPixelsX * bytesPerPixel;
@ -586,6 +604,7 @@ void DetectorImpl::readFrameFromReceiver() {
} }
} }
} }
LOG(logDEBUG)<< "Call Back Info:" LOG(logDEBUG)<< "Call Back Info:"
<< "\n\t nDetPixelsX: " << nDetPixelsX << "\n\t nDetPixelsX: " << nDetPixelsX
<< "\n\t nDetPixelsY: " << nDetPixelsY << "\n\t nDetPixelsY: " << nDetPixelsY
@ -595,34 +614,26 @@ void DetectorImpl::readFrameFromReceiver() {
// send data to callback // send data to callback
if (data) { if (data) {
setCurrentProgress(currentFrameIndex + 1); setCurrentProgress(currentFrameIndex + 1);
// 4bit gap pixels char* image = multiframe;
if (dynamicRange == 4 && gappixelsenable) { int imagesize = multisize;
if (quadEnable) {
nDetPixelsX += 2; if (gapPixels) {
nDetPixelsY += 2; int n = InsertGapPixels(multiframe, multigappixels,
} else { quadEnable, dynamicRange, nDetPixelsX, nDetPixelsY);
nDetPixelsX = nX * (nPixelsX + 3); image = multigappixels;
nDetPixelsY = nY * (nPixelsY + 1); imagesize = n;
} }
int n = processImageWithGapPixels(multiframe, multigappixels,
quadEnable);
LOG(logDEBUG) LOG(logDEBUG)
<< "Call Back Info Recalculated:" << "Image Info:"
<< "\n\tnDetPixelsX: " << nDetPixelsX << "\n\tnDetPixelsX: " << nDetPixelsX
<< "\n\tnDetPixelsY: " << nDetPixelsY << "\n\tnDetPixelsY: " << nDetPixelsY
<< "\n\t databytes: " << n; << "\n\timagesize: " << imagesize
thisData = << "\n\tdynamicRange: " << dynamicRange;
new detectorData(getCurrentProgress(), currentFileName,
nDetPixelsX, nDetPixelsY, multigappixels, thisData = new detectorData(getCurrentProgress(),
n, dynamicRange, currentFileIndex); currentFileName, nDetPixelsX, nDetPixelsY, image,
} imagesize, dynamicRange, currentFileIndex, completeImage);
// normal pixels
else {
thisData =
new detectorData(getCurrentProgress(), currentFileName,
nDetPixelsX, nDetPixelsY, multiframe,
multisize, dynamicRange, currentFileIndex);
}
dataReady( dataReady(
thisData, currentFrameIndex, thisData, currentFrameIndex,
((dynamicRange == 32 && eiger) ? currentSubFrameIndex : -1), ((dynamicRange == 32 && eiger) ? currentSubFrameIndex : -1),
@ -667,140 +678,300 @@ void DetectorImpl::readFrameFromReceiver() {
delete[] multigappixels; delete[] multigappixels;
} }
int DetectorImpl::processImageWithGapPixels(char *image, char *&gpImage, int DetectorImpl::InsertGapPixels(char *image, char *&gpImage,
bool quadEnable) { bool quadEnable, int dr, int &nPixelsx, int &nPixelsy) {
// eiger 4 bit mode
int nxb = LOG(logDEBUG)<< "Insert Gap pixels:"
multi_shm()->numberOfDetector.x * (512 + 3); //(divided by 2 already) << "\n\t nPixelsx: " << nPixelsx
int nyb = multi_shm()->numberOfDetector.y * (256 + 1); << "\n\t nPixelsy: " << nPixelsy
int nchipInRow = 4; << "\n\t quadEnable: " << quadEnable
int nxchip = multi_shm()->numberOfDetector.x * 4; << "\n\t dr: " << dr;
int nychip = multi_shm()->numberOfDetector.y * 1;
// 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) { if (quadEnable) {
nxb = multi_shm()->numberOfDetector.x * nMod1Chipx = 2;
(256 + 1); //(divided by 2 already)
nyb = multi_shm()->numberOfDetector.y * (512 + 2);
nxchip /= 2;
nychip *= 2;
nchipInRow /= 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 // check if not full modules
if (gpImage == nullptr) { // (setting gap pixels and then adding half module or disabling quad)
gpImage = new char[gapdatabytes]; 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; // total number of pixels
const int b1chipy = 256; 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 *src = nullptr;
char *dst = nullptr; char *dst = nullptr;
// copying line by line // copying line by line
src = image; src = image;
dst = gpImage; dst = gpImage;
for (int row = 0; row < nychip; ++row) { // for each chip row // for each chip row in y
for (int ichipy = 0; ichipy < b1chipy; for (int iChipy = 0; iChipy < nChipy; ++iChipy) {
++ichipy) { // for each row in a chip // for each row
for (int col = 0; col < nxchip; ++col) { // for each chip in a row for (int iy = 0; iy < nChipPixelsy; ++iy) {
memcpy(dst, src, b1chipx); // in each row, for every chip
src += b1chipx; for (int iChipx = 0; iChipx < nChipx; ++iChipx) {
dst += b1chipx; // copy 1 chip line
if (((col + 1) % nchipInRow) != 0) { // skip gap pixels memcpy(dst, src, nChipBytesx);
++dst; 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;
}
}
}
// 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;
} }
} }
dst += (2 * nxb); // iner chip gap pixel values is half of neighboring one
} // (corners becomes divide by 4 automatically after horizontal filling)
// vertical filling of values // vertical filling of inter chip gap pixels
{
uint8_t temp, g1, g2;
int mod;
dst = gpImage; dst = gpImage;
for (int row = 0; row < nychip; ++row) { // for each chip row // for each chip row in y
for (int ichipy = 0; ichipy < b1chipy; for (int iChipy = 0; iChipy < nChipy; ++iChipy) {
++ichipy) { // for each row in a chip // for each row
for (int col = 0; col < nxchip; for (int iy = 0; iy < nChipPixelsy; ++iy) {
++col) { // for each chip in a row // in each row, for every chip
dst += b1chipx; for (int iChipx = 0; iChipx < nChipx; ++iChipx) {
mod = (col + 1) % nchipInRow; // get gap pixels // go to gap pixels
// copy gap pixel(chip 0, 1, 2) dst += nChipBytesx;
if (mod != 0) { // 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 // neighbouring gap pixels to left
temp = (*((uint8_t *)(dst - 1))); temp8 = (*((uint8_t *)(dst - 1)));
g1 = ((temp & 0xF) / 2); g1 = ((temp8 & 0xF) / 2);
(*((uint8_t *)(dst - 1))) = (temp & 0xF0) + g1; (*((uint8_t *)(dst - 1))) = (temp8 & 0xF0) + g1;
// neighbouring gap pixels to right // neighbouring gap pixels to right
temp = (*((uint8_t *)(dst + 1))); temp8 = (*((uint8_t *)(dst + 1)));
g2 = ((temp >> 4) / 2); g2 = ((temp8 >> 4) / 2);
(*((uint8_t *)(dst + 1))) = (g2 << 4) + (temp & 0x0F); (*((uint8_t *)(dst + 1))) = (g2 << 4) + (temp8 & 0x0F);
// gap pixels // gap pixels
(*((uint8_t *)dst)) = (g1 << 4) + g2; (*((uint8_t *)dst)) = (g1 << 4) + g2;
break;
// increment to point to proper chip destination case 8:
++dst; // 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;
} }
} }
} }
// skip inter chip gap pixels in y
dst += (2 * nxb); 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 of inter chip gap pixels
// horizontal filling // starting at bottom part (1 line below to copy from)
{ src = gpImage + (nChipBytesy - row1Bytes);
uint8_t temp, g1, g2; dst = gpImage + nChipBytesy;
char *dst_prevline = nullptr; // for each chip row in y
dst = gpImage; for (int iChipy = 0; iChipy < nChipy; ++iChipy) {
for (int row = 0; row < nychip; ++row) { // for each chip row // for each module in x
dst += (b1chipy * nxb); for (int iModx = 0; iModx < nModx; ++iModx) {
// horizontal copying of gap pixels from neighboring past line // in each module, for every pixel in x
// (bottom parts) for (int iPixel = 0; iPixel < nMod1TotPixelsx; ++iPixel) {
if (row < nychip - 1) { uint8_t temp8 = 0, g1 = 0, g2 = 0;
dst_prevline = dst - nxb; uint16_t temp16 = 0;
for (int gapline = 0; gapline < nxb; ++gapline) { uint32_t temp32 = 0;
temp = (*((uint8_t *)dst_prevline)); switch (dr) {
g1 = ((temp >> 4) / 2); case 4:
g2 = ((temp & 0xF) / 2); temp8 = (*((uint8_t *)src));
(*((uint8_t *)dst_prevline)) = (g1 << 4) + g2; g1 = ((temp8 >> 4) / 2);
(*((uint8_t *)dst)) = (*((uint8_t *)dst_prevline)); g2 = ((temp8 & 0xF) / 2);
++dst; temp8 = (g1 << 4) + g2;
++dst_prevline; (*((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;
}
// skip inter module gap pixels in x
if (iModx + 1 < nModx) {
src += nModGapBytesx;
dst += nModGapBytesx;
}
}
// 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);
} }
} }
// horizontal copying of gap pixels from neihboring future line (top nPixelsx = nTotx;
// part) nPixelsy = nToty;
if (row > 0) { return imagesize;
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);
} }
dst += nxb;
}
}
return gapdatabytes;
}
bool DetectorImpl::enableDataStreamingToClient(int enable) { bool DetectorImpl::enableDataStreamingToClient(int enable) {
if (enable >= 0) { if (enable >= 0) {

View File

@ -16,7 +16,7 @@ class detectorData;
#include <vector> #include <vector>
#define MULTI_SHMAPIVERSION 0x190809 #define MULTI_SHMAPIVERSION 0x190809
#define MULTI_SHMVERSION 0x200131 #define MULTI_SHMVERSION 0x200319
#define SHORT_STRING_LENGTH 50 #define SHORT_STRING_LENGTH 50
#include <future> #include <future>
@ -47,10 +47,7 @@ struct sharedMultiSlsDetector {
/** last time stamp when accessing the shared memory */ /** last time stamp when accessing the shared memory */
char lastDate[SHORT_STRING_LENGTH]; char lastDate[SHORT_STRING_LENGTH];
/** number of sls detectors in shared memory */
int numberOfDetectors; int numberOfDetectors;
/** multi detector type */
slsDetectorDefs::detectorType multiDetectorType; slsDetectorDefs::detectorType multiDetectorType;
/** END OF FIXED PATTERN /** END OF FIXED PATTERN
@ -62,11 +59,9 @@ struct sharedMultiSlsDetector {
/** max number of channels for complete detector*/ /** max number of channels for complete detector*/
slsDetectorDefs::xy numberOfChannels; slsDetectorDefs::xy numberOfChannels;
/** flag for acquiring */
bool acquiringFlag; bool acquiringFlag;
/** initial checks */
bool initialChecks; bool initialChecks;
bool gapPixels;
}; };
class DetectorImpl : public virtual slsDetectorDefs { class DetectorImpl : public virtual slsDetectorDefs {
@ -236,11 +231,10 @@ class DetectorImpl : public virtual slsDetectorDefs {
* Sets maximum number of channels of all sls detectors */ * Sets maximum number of channels of all sls detectors */
void setNumberOfChannels(const slsDetectorDefs::xy c); void setNumberOfChannels(const slsDetectorDefs::xy c);
/** /** [Eiger][Jungfrau] */
* Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger) bool getGapPixelsinCallback() const;
* 4 bit mode gap pixels only in gui call back /** [Eiger][Jungfrau] */
*/ void setGapPixelsinCallback(const bool enable);
void setGapPixelsinReceiver(bool enable);
/** /**
* Enable data streaming to client * Enable data streaming to client
@ -347,15 +341,18 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/ */
void readFrameFromReceiver(); void readFrameFromReceiver();
/** /** [Eiger][Jungfrau]
* add gap pixels to the image (only for Eiger in 4 bit mode) * add gap pixels to the imag
* @param image pointer to image without gap pixels * @param image pointer to image without gap pixels
* @param gpImage poiner to image with gap pixels, if NULL, allocated * @param gpImage poiner to image with gap pixels, if NULL, allocated
* inside function * @param quadEnable quad enabled
* quadEnable quad enabled * @param dr dynamic range
* @returns number of data bytes of image with gap pixels * @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(); double setTotalProgress();

View File

@ -410,7 +410,6 @@ void Module::initializeDetectorStructure(detectorType type) {
shm()->zmqport = DEFAULT_ZMQ_CL_PORTNO + shm()->zmqport = DEFAULT_ZMQ_CL_PORTNO +
(detId * ((shm()->myDetectorType == EIGER) ? 2 : 1)); (detId * ((shm()->myDetectorType == EIGER) ? 2 : 1));
shm()->zmqip = IpAddr{}; shm()->zmqip = IpAddr{};
shm()->gappixels = 0U;
shm()->numUDPInterfaces = 1; shm()->numUDPInterfaces = 1;
shm()->stoppedFlag = false; shm()->stoppedFlag = false;
@ -422,8 +421,6 @@ void Module::initializeDetectorStructure(detectorType type) {
shm()->nChip.y = parameters.nChipY; shm()->nChip.y = parameters.nChipY;
shm()->nDacs = parameters.nDacs; shm()->nDacs = parameters.nDacs;
shm()->dynamicRange = parameters.dynamicRange; shm()->dynamicRange = parameters.dynamicRange;
shm()->nGappixels.x = parameters.nGappixelsX;
shm()->nGappixels.y = parameters.nGappixelsY;
} }
int Module::sendModule(sls_detector_module *myMod, int Module::sendModule(sls_detector_module *myMod,
@ -582,10 +579,8 @@ void Module::updateNumberOfChannels() {
slsDetectorDefs::xy Module::getNumberOfChannels() const { slsDetectorDefs::xy Module::getNumberOfChannels() const {
slsDetectorDefs::xy coord{}; slsDetectorDefs::xy coord{};
coord.x = (shm()->nChan.x * shm()->nChip.x + coord.x = (shm()->nChan.x * shm()->nChip.x);
shm()->gappixels * shm()->nGappixels.x); coord.y = (shm()->nChan.y * shm()->nChip.y);
coord.y = (shm()->nChan.y * shm()->nChip.y +
shm()->gappixels * shm()->nGappixels.y);
return coord; return coord;
} }
@ -937,23 +932,17 @@ int Module::getThresholdEnergy() {
return retval; return retval;
} }
int Module::setThresholdEnergy(int e_eV, detectorSettings isettings, void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
int tb) { int tb) {
// check as there is client processing // check as there is client processing
if (shm()->myDetectorType == EIGER) { if (shm()->myDetectorType == EIGER) {
setThresholdEnergyAndSettings(e_eV, isettings, tb); setThresholdEnergyAndSettings(e_eV, isettings, tb);
return e_eV;
} }
// moench - send threshold energy to processor // moench - send threshold energy to processor
else if (shm()->myDetectorType == MOENCH) { else if (shm()->myDetectorType == MOENCH) {
std::string result =
setAdditionalJsonParameter("threshold", std::to_string(e_eV)); setAdditionalJsonParameter("threshold", std::to_string(e_eV));
if (result == std::to_string(e_eV)) {
return e_eV;
}
return -1;
} }
throw RuntimeError( throw RuntimeError(
"Set threshold energy not implemented for this detector"); "Set threshold energy not implemented for this detector");
@ -1719,7 +1708,6 @@ std::string Module::setReceiverHostname(const std::string &receiverIP) {
setSubDeadTime(getSubDeadTime()); setSubDeadTime(getSubDeadTime());
setDynamicRange(shm()->dynamicRange); setDynamicRange(shm()->dynamicRange);
activate(-1); activate(-1);
enableGapPixels(shm()->gappixels);
enableTenGigabitEthernet(-1); enableTenGigabitEthernet(-1);
setQuad(getQuad()); setQuad(getQuad());
break; 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) { if (!shm()->useReceiverFlag) {
throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json header)"); throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json header)");
} }
char args[MAX_STR_LENGTH]{}; for (auto &it : jsonHeader) {
sls::strcpy_safe(args, jsonheader.c_str()); if (it.first.empty() || it.first.length() > SHORT_STR_LENGTH ||
sendToReceiver(F_SET_ADDITIONAL_JSON_HEADER, args, nullptr); 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");
}
}
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));
}
} }
std::string Module::getAdditionalJsonHeader() { std::map<std::string, std::string> Module::getAdditionalJsonHeader() {
if (!shm()->useReceiverFlag) { if (!shm()->useReceiverFlag) {
throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json header)"); throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json header)");
} }
char retvals[MAX_STR_LENGTH]{}; int fnum = F_GET_ADDITIONAL_JSON_HEADER;
sendToReceiver(F_GET_ADDITIONAL_JSON_HEADER, nullptr, retvals); int ret = FAIL;
return std::string(retvals); 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;
}
} }
std::string Module::setAdditionalJsonParameter(const std::string &key, void Module::setAdditionalJsonParameter(const std::string &key, const std::string &value) {
const std::string &value) { if (!shm()->useReceiverFlag) {
if (key.empty() || value.empty()) { throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json parameter)");
throw RuntimeError(
"Could not set additional json header parameter as the key or "
"value is empty");
} }
if (key.empty() || key.length() > SHORT_STR_LENGTH ||
// validation (ignore if key or value has , : ") value.length() > SHORT_STR_LENGTH ) {
if (key.find_first_of(",\":") != std::string::npos || throw RuntimeError(key + " or " + value + " pair has invalid size. "
value.find_first_of(",\":") != std::string::npos) { "Key cannot be empty. Both can have max 2 characters");
throw RuntimeError("Could not set additional json header parameter as "
"the key or value has "
"illegal characters (,\":)");
} }
char args[2][SHORT_STR_LENGTH]{};
// create actual key to search for and actual value to put, (key has sls::strcpy_safe(args[0], key.c_str());
// additional ':' as value could exist the same way) sls::strcpy_safe(args[1], value.c_str());
std::string keyLiteral(std::string("\"") + key + std::string("\":")); sendToReceiver(F_SET_ADDITIONAL_JSON_PARAMETER, args, nullptr);
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(",");
}
header.append(keyLiteral + valueLiteral);
}
// update additional json header
setAdditionalJsonHeader(header);
return getAdditionalJsonParameter(key);
} }
std::string Module::getAdditionalJsonParameter(const std::string &key) { std::string Module::getAdditionalJsonParameter(const std::string &key) {
// additional json header is empty if (!shm()->useReceiverFlag) {
std::string jsonheader = getAdditionalJsonHeader(); throw RuntimeError("Set rx_hostname first to use receiver parameters (zmq json parameter)");
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 &parameter :
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];
} }
} char arg[SHORT_STR_LENGTH]{};
// return empty string as no match found with key sls::strcpy_safe(arg, key.c_str());
return std::string(); char retval[SHORT_STR_LENGTH]{};
sendToReceiver(F_GET_ADDITIONAL_JSON_PARAMETER, arg, retval);
return retval;
} }
int64_t Module::setReceiverUDPSocketBufferSize(int64_t udpsockbufsize) { int64_t Module::setReceiverUDPSocketBufferSize(int64_t udpsockbufsize) {
@ -2672,24 +2653,6 @@ int Module::setAllTrimbits(int val) {
return retval; 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) { int Module::setTrimEn(const std::vector<int>& energies) {
if (shm()->myDetectorType != EIGER) { if (shm()->myDetectorType != EIGER) {
throw RuntimeError("setTrimEn not implemented for this detector."); 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() { void Module::sendMultiDetectorSize() {
int args[]{shm()->multiSize.x, shm()->multiSize.y}; int args[]{shm()->multiSize.x, shm()->multiSize.y};
int retval = -1; int retval = -1;
@ -3317,9 +3253,6 @@ std::vector<uint64_t> Module::getNumMissingPackets() const {
throw RuntimeError("Receiver " + std::to_string(detId) + throw RuntimeError("Receiver " + std::to_string(detId) +
" returned error: " + std::string(mess)); " returned error: " + std::string(mess));
} else { } else {
if (ret == FORCE_UPDATE) {
updateCachedReceiverVariables();
}
int nports = -1; int nports = -1;
client.Receive(&nports, sizeof(nports)); client.Receive(&nports, sizeof(nports));
uint64_t mp[nports]; uint64_t mp[nports];

View File

@ -9,11 +9,12 @@
#include <array> #include <array>
#include <cmath> #include <cmath>
#include <vector> #include <vector>
#include <map>
class ServerInterface; class ServerInterface;
#define SLS_SHMAPIVERSION 0x190726 #define SLS_SHMAPIVERSION 0x190726
#define SLS_SHMVERSION 0x200318 #define SLS_SHMVERSION 0x200324
namespace sls{ namespace sls{
@ -104,12 +105,6 @@ struct sharedSlsDetector {
/** zmq tcp src ip address in client (only data) **/ /** zmq tcp src ip address in client (only data) **/
sls::IpAddr zmqip; sls::IpAddr zmqip;
/** gap pixels enable */
int gappixels;
/** gap pixels in each direction */
slsDetectorDefs::xy nGappixels;
/** num udp interfaces */ /** num udp interfaces */
int numUDPInterfaces; int numUDPInterfaces;
@ -221,10 +216,7 @@ class Module : public virtual slsDetectorDefs {
*/ */
void updateNumberOfChannels(); void updateNumberOfChannels();
/**
* Returns the total number of channels including gap pixels
* @returns the total number of channels including gap pixels
*/
slsDetectorDefs::xy getNumberOfChannels() const; slsDetectorDefs::xy getNumberOfChannels() const;
/** /**
@ -353,9 +345,8 @@ class Module : public virtual slsDetectorDefs {
* @param e_eV threshold in eV * @param e_eV threshold in eV
* @param isettings ev. change settings * @param isettings ev. change settings
* @param tb 1 to include trimbits, 0 to exclude * @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); int tb = 1);
/** /**
@ -988,36 +979,14 @@ class Module : public virtual slsDetectorDefs {
*/ */
void setTransmissionDelayRight(int value); void setTransmissionDelayRight(int value);
/** /** empty vector deletes entire additional json header */
* Sets the additional json header\sa sharedSlsDetector void setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader);
* @param jsonheader additional json header std::map<std::string, std::string> getAdditionalJsonHeader();
*/
void setAdditionalJsonHeader(const std::string &jsonheader);
/** /**
* Returns the additional json header \sa sharedSlsDetector * Sets the value for the additional json header parameter key if found, else
* @returns the additional json header, returns "none" if default setting * append it. If value empty, then deletes parameter */
* and no custom ip set void setAdditionalJsonParameter(const std::string &key, const std::string &value);
*/
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
*/
std::string getAdditionalJsonParameter(const std::string &key); std::string getAdditionalJsonParameter(const std::string &key);
/** /**
@ -1045,11 +1014,13 @@ class Module : public virtual slsDetectorDefs {
/** [Gotthard][Jungfrau][CTB][Moench] */ /** [Gotthard][Jungfrau][CTB][Moench] */
void executeBusTest(); void executeBusTest();
/** [Gotthard] */ /** [Gotthard][Eiger virtual] */
int getImageTestMode(); int getImageTestMode();
/** [Gotthard] If 1, adds channel intensity with precalculated values. /** [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); void setImageTestMode(const int value);
@ -1232,14 +1203,6 @@ class Module : public virtual slsDetectorDefs {
*/ */
int setAllTrimbits(int val); 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) * Sets the number of trim energies and their value (Eiger)
* \sa sharedSlsDetector * \sa sharedSlsDetector
@ -1436,11 +1399,6 @@ class Module : public virtual slsDetectorDefs {
*/ */
void execReceiverCommand(const std::string &cmd); 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 * Send the multi detector size to the detector
* @param detx number of detectors in x dir * @param detx number of detectors in x dir

View File

@ -680,7 +680,7 @@ TEST_CASE("rx_dbitlist", "[.cmd][.rx][.new]") {
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD) { if (det_type == defs::CHIPTESTBOARD) {
auto previous = det.getRxDbitList(); auto prev_val = det.getRxDbitList();
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("rx_dbitlist", {"0", "4", "5", "8", "9", "10", "52", "63"}, -1, PUT, 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", {"67"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("rx_dbitlist", {"-1"}, -1, PUT)); REQUIRE_THROWS(proxy.Call("rx_dbitlist", {"-1"}, -1, PUT));
REQUIRE_NOTHROW(proxy.Call("rx_dbitlist", {"all"}, -1, PUT)); REQUIRE_NOTHROW(proxy.Call("rx_dbitlist", {"all"}, -1, PUT));
// Reset to previous value
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setRxDbitList(previous[i], {i}); det.setRxDbitList(prev_val[i], {i});
} }
} else { } else {
REQUIRE_THROWS(proxy.Call("rx_dbitlist", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("rx_dbitlist", {}, -1, GET));
@ -708,7 +707,7 @@ TEST_CASE("rx_dbitoffset", "[.cmd][.rx][.new]") {
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD) { if (det_type == defs::CHIPTESTBOARD) {
auto previous = det.getRxDbitOffset(); auto prev_val = det.getRxDbitOffset();
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("rx_dbitoffset", {"1"}, -1, PUT, 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); proxy.Call("rx_dbitoffset", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_dbitoffset 15\n"); REQUIRE(oss.str() == "rx_dbitoffset 15\n");
} }
// Reset to previous value
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setRxDbitOffset(previous[i], {i}); det.setRxDbitOffset(prev_val[i], {i});
} }
} else { } else {
REQUIRE_THROWS(proxy.Call("rx_dbitoffset", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("rx_dbitoffset", {}, -1, GET));
@ -740,7 +738,60 @@ TEST_CASE("rx_dbitoffset", "[.cmd][.rx][.new]") {
/* Moench */ /* 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 */ /* Insignificant */

View File

@ -715,33 +715,6 @@ TEST_CASE("stopport", "[.cmd]") {
// REQUIRE_NOTHROW(multiSlsDetectorClient("rx_jsonaddheader \"\"", PUT)); // 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]") { // TEST_CASE("patsetbit", "[.cmd][.ctb]") {
// if (test::type == slsDetectorDefs::CHIPTESTBOARD) { // if (test::type == slsDetectorDefs::CHIPTESTBOARD) {

View File

@ -128,7 +128,6 @@ class BinaryFileStatic {
"SubExptime (ns) : %lld\n" "SubExptime (ns) : %lld\n"
"SubPeriod(ns) : %lld\n" "SubPeriod(ns) : %lld\n"
"Period (ns) : %lld\n" "Period (ns) : %lld\n"
"Gap Pixels Enable : %d\n"
"Quad Enable : %d\n" "Quad Enable : %d\n"
"Analog Flag : %d\n" "Analog Flag : %d\n"
"Digital Flag : %d\n" "Digital Flag : %d\n"
@ -167,7 +166,6 @@ class BinaryFileStatic {
(long long int)attr.subExptimeNs, (long long int)attr.subExptimeNs,
(long long int)attr.subPeriodNs, (long long int)attr.subPeriodNs,
(long long int)attr.periodNs, (long long int)attr.periodNs,
attr.gapPixelsEnable,
attr.quadEnable, attr.quadEnable,
attr.analogFlag, attr.analogFlag,
attr.digitalFlag, attr.digitalFlag,

View File

@ -16,6 +16,7 @@
#include <vector> #include <vector>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <unistd.h> #include <unistd.h>
#include <map>
using sls::RuntimeError; using sls::RuntimeError;
using sls::SocketError; using sls::SocketError;
@ -113,7 +114,6 @@ int ClientInterface::functionTable(){
flist[F_LOCK_RECEIVER] = &ClientInterface::lock_receiver; flist[F_LOCK_RECEIVER] = &ClientInterface::lock_receiver;
flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip; flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip;
flist[F_SET_RECEIVER_PORT] = &ClientInterface::set_port; 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_VERSION] = &ClientInterface::get_version;
flist[F_GET_RECEIVER_TYPE] = &ClientInterface::set_detector_type; flist[F_GET_RECEIVER_TYPE] = &ClientInterface::set_detector_type;
flist[F_SEND_RECEIVER_DETHOSTNAME] = &ClientInterface::set_detector_hostname; 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_GET_RECEIVER_STREAMING_SRC_IP] = &ClientInterface::get_streaming_source_ip;
flist[F_SET_RECEIVER_SILENT_MODE] = &ClientInterface::set_silent_mode; flist[F_SET_RECEIVER_SILENT_MODE] = &ClientInterface::set_silent_mode;
flist[F_GET_RECEIVER_SILENT_MODE] = &ClientInterface::get_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_RESTREAM_STOP_FROM_RECEIVER] = &ClientInterface::restream_stop;
flist[F_SET_ADDITIONAL_JSON_HEADER] = &ClientInterface::set_additional_json_header; flist[F_SET_ADDITIONAL_JSON_HEADER] = &ClientInterface::set_additional_json_header;
flist[F_GET_ADDITIONAL_JSON_HEADER] = &ClientInterface::get_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_ADC_MASK_10G] = &ClientInterface::set_adc_mask_10g;
flist[F_RECEIVER_SET_NUM_COUNTERS] = &ClientInterface::set_num_counters; flist[F_RECEIVER_SET_NUM_COUNTERS] = &ClientInterface::set_num_counters;
flist[F_INCREMENT_FILE_INDEX] = &ClientInterface::increment_file_index; 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++) { for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" << LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@ -325,29 +326,6 @@ int ClientInterface::set_port(Interface &socket) {
return OK; 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) { int ClientInterface::get_version(Interface &socket) {
return socket.sendResult(getReceiverVersion()); return socket.sendResult(getReceiverVersion());
} }
@ -989,26 +967,6 @@ int ClientInterface::get_silent_mode(Interface &socket) {
return socket.sendResult(retval); 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) { int ClientInterface::restream_stop(Interface &socket) {
verifyIdle(socket); verifyIdle(socket);
if (!impl()->getDataStreamEnable()) { if (!impl()->getDataStreamEnable()) {
@ -1022,19 +980,39 @@ int ClientInterface::restream_stop(Interface &socket) {
} }
int ClientInterface::set_additional_json_header(Interface &socket) { int ClientInterface::set_additional_json_header(Interface &socket) {
char arg[MAX_STR_LENGTH]{}; std::map<std::string, std::string> json;
socket.Receive(arg); 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); verifyIdle(socket);
LOG(logDEBUG1) << "Setting additional json header: " << arg; LOG(logDEBUG1) << "Setting additional json header: " << sls::ToString(json);
impl()->setAdditionalJsonHeader(arg); impl()->setAdditionalJsonHeader(json);
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::get_additional_json_header(Interface &socket) { int ClientInterface::get_additional_json_header(Interface &socket) {
char retval[MAX_STR_LENGTH]{}; std::map<std::string, std::string> json = impl()->getAdditionalJsonHeader();
sls::strcpy_safe(retval, impl()->getAdditionalJsonHeader().c_str()); LOG(logDEBUG1) << "additional json header:" << sls::ToString(json);
LOG(logDEBUG1) << "additional json header:" << retval; int size = json.size();
return socket.sendResult(retval); 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) { int ClientInterface::set_udp_socket_buffer_size(Interface &socket) {
@ -1428,3 +1406,22 @@ int ClientInterface::increment_file_index(Interface &socket) {
} }
return socket.Send(OK); 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);
}

View File

@ -55,8 +55,6 @@ class ClientInterface : private virtual slsDetectorDefs {
int lock_receiver(sls::ServerInterface &socket); int lock_receiver(sls::ServerInterface &socket);
int get_last_client_ip(sls::ServerInterface &socket); int get_last_client_ip(sls::ServerInterface &socket);
int set_port(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 get_version(sls::ServerInterface &socket);
int set_detector_type(sls::ServerInterface &socket); int set_detector_type(sls::ServerInterface &socket);
int set_detector_hostname(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 get_streaming_source_ip(sls::ServerInterface &socket);
int set_silent_mode(sls::ServerInterface &socket); int set_silent_mode(sls::ServerInterface &socket);
int get_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 restream_stop(sls::ServerInterface &socket);
int set_additional_json_header(sls::ServerInterface &socket); int set_additional_json_header(sls::ServerInterface &socket);
int get_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_adc_mask_10g(sls::ServerInterface &socket);
int set_num_counters(sls::ServerInterface &socket); int set_num_counters(sls::ServerInterface &socket);
int increment_file_index(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() { Implementation *impl() {
if (receiver != nullptr) { if (receiver != nullptr) {

View File

@ -25,7 +25,7 @@ const std::string DataProcessor::TypeName = "DataProcessor";
DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f, DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
fileFormat* ftype, bool fwenable, bool* mfwenable, fileFormat* ftype, bool fwenable, bool* mfwenable,
bool* dsEnable, bool* gpEnable, uint32_t* dr, bool* dsEnable, uint32_t* dr,
uint32_t* freq, uint32_t* timer, uint32_t* freq, uint32_t* timer,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
std::vector <int> * cdl, int* cdo, int* cad) : std::vector <int> * cdl, int* cdo, int* cad) :
@ -40,12 +40,10 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
fileFormatType(ftype), fileFormatType(ftype),
fileWriteEnable(fwenable), fileWriteEnable(fwenable),
masterFileWriteEnable(mfwenable), masterFileWriteEnable(mfwenable),
gapPixelsEnable(gpEnable),
dynamicRange(dr), dynamicRange(dr),
streamingFrequency(freq), streamingFrequency(freq),
streamingTimerInMs(timer), streamingTimerInMs(timer),
currentFreqCount(0), currentFreqCount(0),
tempBuffer(nullptr),
activated(act), activated(act),
deactivatedPaddingEnable(depaden), deactivatedPaddingEnable(depaden),
silentMode(sm), silentMode(sm),
@ -69,7 +67,6 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
DataProcessor::~DataProcessor() { DataProcessor::~DataProcessor() {
delete file; delete file;
delete [] tempBuffer;
} }
/** getters */ /** getters */
@ -116,15 +113,6 @@ void DataProcessor::ResetParametersforNewAcquisition(){
numFramesCaught = 0; numFramesCaught = 0;
firstIndex = 0; firstIndex = 0;
currentFrameIndex = 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 // frame padding
if (*activated && *framePadding && nump < generalData->packetsPerFrame) if (*activated && *framePadding && nump < generalData->packetsPerFrame)
PadMissingPackets(buf); PadMissingPackets(buf);
@ -512,103 +495,3 @@ void DataProcessor::RearrangeDbitData(char* buf) {
(*((uint32_t*)buf)) = numResult8Bits * sizeof(uint8_t); (*((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;
}

View File

@ -33,7 +33,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* @param fwenable file writer enable * @param fwenable file writer enable
* @apram mfwenable pointer to master file write enable * @apram mfwenable pointer to master file write enable
* @param dsEnable pointer to data stream enable * @param dsEnable pointer to data stream enable
* @param gpEnable pointer to gap pixels enable
* @param dr pointer to dynamic range * @param dr pointer to dynamic range
* @param freq pointer to streaming frequency * @param freq pointer to streaming frequency
* @param timer pointer to timer if streaming frequency is random * @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 * @param cad pointer to ctb analog databytes
*/ */
DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat* ftype, 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, uint32_t* freq, uint32_t* timer,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
std::vector <int> * cdl, int* cdo, int* cad); std::vector <int> * cdl, int* cdo, int* cad);
@ -252,13 +251,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
*/ */
void RearrangeDbitData(char* buf); 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 */ /** type of thread */
static const std::string TypeName; static const std::string TypeName;
@ -291,10 +283,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
/** Master File Write Enable */ /** Master File Write Enable */
bool* masterFileWriteEnable; bool* masterFileWriteEnable;
/** Gap Pixels Enable */
bool* gapPixelsEnable;
/** Dynamic Range */ /** Dynamic Range */
uint32_t* dynamicRange; uint32_t* dynamicRange;
@ -310,9 +298,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
/** timer beginning stamp for random streaming */ /** timer beginning stamp for random streaming */
struct timespec timerBegin; struct timespec timerBegin;
/** temporary buffer for processing */
char* tempBuffer;
/** Activated/Deactivated */ /** Activated/Deactivated */
bool* activated; bool* activated;

View File

@ -17,7 +17,7 @@ const std::string DataStreamer::TypeName = "DataStreamer";
DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r, 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), ThreadObject(ind, TypeName),
runningFlag(0), runningFlag(0),
generalData(nullptr), generalData(nullptr),
@ -28,11 +28,9 @@ DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
adcConfigured(-1), adcConfigured(-1),
fileIndex(fi), fileIndex(fi),
flippedDataX(fd), flippedDataX(fd),
additionJsonHeader(ajh),
startedFlag(false), startedFlag(false),
firstIndex(0), firstIndex(0),
completeBuffer(nullptr), completeBuffer(nullptr),
gapPixelsEnable(gpEnable),
quadEnable(qe) quadEnable(qe)
{ {
numDet[0] = nd[0]; numDet[0] = nd[0];
@ -108,6 +106,10 @@ void DataStreamer::SetFlippedDataX(int fd) {
flippedDataX = 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) { void DataStreamer::CreateZmqSockets(int* nunits, uint32_t port, const sls::IpAddr ip) {
uint32_t portnum = port + index; uint32_t portnum = port + index;
std::string sip = ip.str(); 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) { int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32_t nx, uint32_t ny, bool dummy) {
if (dummy) zmqHeader zHeader;
return zmqSocket->SendHeaderData(index, dummy,SLS_DETECTOR_JSON_HEADER_VERSION); zHeader.data = !dummy;
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
if (dummy) {
return zmqSocket->SendHeader(index, zHeader);
}
sls_detector_header header = rheader->detHeader; sls_detector_header header = rheader->detHeader;
uint64_t frameIndex = header.frameNumber - firstIndex; uint64_t frameIndex = header.frameNumber - firstIndex;
uint64_t acquisitionIndex = header.frameNumber; uint64_t acquisitionIndex = header.frameNumber;
return zmqSocket->SendHeaderData(index, dummy, SLS_DETECTOR_JSON_HEADER_VERSION, *dynamicRange, *fileIndex, zHeader.dynamicRange = *dynamicRange;
numDet[0], numDet[1], nx, ny, size, zHeader.fileIndex = *fileIndex;
acquisitionIndex, frameIndex, fileNametoStream, zHeader.ndetx = numDet[0];
header.frameNumber, header.expLength, header.packetNumber, header.bunchId, header.timestamp, zHeader.ndety = numDet[1];
header.modId, header.row, header.column, header.reserved, zHeader.npixelsx = nx;
header.debug, header.roundRNumber, zHeader.npixelsy = ny;
header.detType, header.version, zHeader.imageSize = size;
*gapPixelsEnable ? 1 : 0, flippedDataX, *quadEnable, zHeader.acqIndex = acquisitionIndex;
additionJsonHeader 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() { void DataStreamer::RestreamStop() {
//send dummy header //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) { if (!ret) {
throw sls::RuntimeError("Could not restream Dummy Header via ZMQ for port " + std::to_string(zmqSocket->GetPortNumber())); throw sls::RuntimeError("Could not restream Dummy Header via ZMQ for port " + std::to_string(zmqSocket->GetPortNumber()));
} }

View File

@ -15,7 +15,7 @@ class Fifo;
class DataStreamer; class DataStreamer;
class ZmqSocket; class ZmqSocket;
#include <vector> #include <map>
class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
@ -29,13 +29,11 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param r roi * @param r roi
* @param fi pointer to file index * @param fi pointer to file index
* @param fd flipped data enable for x dimension * @param fd flipped data enable for x dimension
* @param ajh additional json header
* @param nd pointer to number of detectors in each dimension * @param nd pointer to number of detectors in each dimension
* @param gpEnable pointer to gap pixels enable
* @param qe pointer to quad Enable * @param qe pointer to quad Enable
*/ */
DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r, 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 * Destructor
@ -91,6 +89,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
*/ */
void SetFlippedDataX(int fd); 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 * Creates Zmq Sockets
* (throws an exception if it couldnt create zmq sockets) * (throws an exception if it couldnt create zmq sockets)
@ -183,7 +187,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
int flippedDataX; int flippedDataX;
/** additional json header */ /** additional json header */
std::string* additionJsonHeader; std::map<std::string, std::string> additionJsonHeader;
/** Aquisition Started flag */ /** Aquisition Started flag */
bool startedFlag; bool startedFlag;
@ -200,9 +204,6 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
/** Number of Detectors in X and Y dimension */ /** Number of Detectors in X and Y dimension */
int numDet[2]; int numDet[2];
/** Gap Pixels Enable */
bool* gapPixelsEnable;
/** Quad Enable */ /** Quad Enable */
bool* quadEnable; bool* quadEnable;

View File

@ -171,16 +171,6 @@ public:
LOG(logERROR) << "SetTenGigaEnable is a generic function that should be overloaded by a derived class"; 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) * Set odd starting packet (gotthard)
* @param index thread index for debugging purposes * @param index thread index for debugging purposes
@ -452,39 +442,6 @@ class EigerData : public GeneralData {
imageSize = dataSize*packetsPerFrame; 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;
}
};
}; };

View File

@ -383,41 +383,29 @@ public:
attribute = dataset.createAttribute("unit",strdatatype, dataspace); attribute = dataset.createAttribute("unit",strdatatype, dataspace);
attribute.write(strdatatype, std::string("ns")); 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 //Quad Enable
dataset = group5.createDataSet ( "quad enable", PredType::NATIVE_INT, dataspace ); dataset = group5.createDataSet ( "quad enable", PredType::NATIVE_INT, dataspace );
dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT); dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT);
//Analog Flag //Analog Flag
dataset = group5.createDataSet ( "analog flag", PredType::NATIVE_INT, dataspace ); 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 //Digital Flag
dataset = group5.createDataSet ( "digital flag", PredType::NATIVE_INT, dataspace ); 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 //ADC Mask
dataset = group5.createDataSet ( "adc mask", PredType::NATIVE_INT, dataspace ); 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 //Dbit Offset
dataset = group5.createDataSet ( "dbit offset", PredType::NATIVE_INT, dataspace ); 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 // Dbit List
dataset = group5.createDataSet ( "dbit bitset list", PredType::STD_U64LE, dataspace ); 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 // Roi xmin
dataset = group5.createDataSet ( "roi xmin", PredType::NATIVE_INT, dataspace ); dataset = group5.createDataSet ( "roi xmin", PredType::NATIVE_INT, dataspace );

View File

@ -37,6 +37,7 @@ void Implementation::DeleteMembers() {
generalData = nullptr; generalData = nullptr;
} }
additionalJsonHeader.clear();
listener.clear(); listener.clear();
dataProcessor.clear(); dataProcessor.clear();
dataStreamer.clear(); dataStreamer.clear();
@ -92,7 +93,6 @@ void Implementation::InitializeMembers() {
streamingTimerInMs = DEFAULT_STREAMING_TIMER_IN_MS; streamingTimerInMs = DEFAULT_STREAMING_TIMER_IN_MS;
streamingPort = 0; streamingPort = 0;
streamingSrcIP = sls::IpAddr{}; streamingSrcIP = sls::IpAddr{};
additionalJsonHeader = "";
// detector parameters // detector parameters
numberOfFrames = 0; numberOfFrames = 0;
@ -108,7 +108,6 @@ void Implementation::InitializeMembers() {
roi.xmax = -1; roi.xmax = -1;
tengigaEnable = false; tengigaEnable = false;
flippedDataX = 0; flippedDataX = 0;
gapPixelsEnable = false;
quadEnable = false; quadEnable = false;
activated = true; activated = true;
deactivatedPaddingEnable = true; deactivatedPaddingEnable = true;
@ -273,7 +272,7 @@ void Implementation::setDetectorType(const detectorType d) {
&activated, &deactivatedPaddingEnable, &silentMode)); &activated, &deactivatedPaddingEnable, &silentMode));
dataProcessor.push_back(sls::make_unique<DataProcessor>( dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable, i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable,
&masterFileWriteEnable, &dataStreamEnable, &gapPixelsEnable, &masterFileWriteEnable, &dataStreamEnable,
&dynamicRange, &streamingFrequency, &streamingTimerInMs, &dynamicRange, &streamingFrequency, &streamingTimerInMs,
&framePadding, &activated, &deactivatedPaddingEnable, &framePadding, &activated, &deactivatedPaddingEnable,
&silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset, &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset,
@ -848,7 +847,6 @@ void Implementation::SetupWriter() {
attr.subExptimeNs = subExpTime; attr.subExptimeNs = subExpTime;
attr.subPeriodNs = subPeriod; attr.subPeriodNs = subPeriod;
attr.periodNs = acquisitionPeriod; attr.periodNs = acquisitionPeriod;
attr.gapPixelsEnable = gapPixelsEnable;
attr.quadEnable = quadEnable; attr.quadEnable = quadEnable;
attr.analogFlag = (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0; attr.analogFlag = (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0;
attr.digitalFlag = (readoutType == DIGITAL_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>( dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, myDetectorType, fifo_ptr, &fileFormatType, i, myDetectorType, fifo_ptr, &fileFormatType,
fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable, fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable,
&gapPixelsEnable, &dynamicRange, &streamingFrequency, &dynamicRange, &streamingFrequency,
&streamingTimerInMs, &framePadding, &activated, &streamingTimerInMs, &framePadding, &activated,
&deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList, &deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList,
&ctbDbitOffset, &ctbAnalogDataBytes)); &ctbDbitOffset, &ctbAnalogDataBytes));
@ -965,10 +963,11 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
} }
dataStreamer.push_back(sls::make_unique<DataStreamer>( dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
fd, &additionalJsonHeader, (int*)nd, &gapPixelsEnable, &quadEnable)); fd, (int*)nd, &quadEnable));
dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets( dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP); &numThreads, streamingPort, streamingSrcIP);
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader);
} catch (...) { } catch (...) {
if (dataStreamEnable) { if (dataStreamEnable) {
@ -1108,10 +1107,11 @@ void Implementation::setDataStreamEnable(const bool enable) {
} }
dataStreamer.push_back(sls::make_unique<DataStreamer>( dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
fd, &additionalJsonHeader, (int*)nd, &gapPixelsEnable, &quadEnable)); fd, (int*)nd, &quadEnable));
dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets( dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP); &numThreads, streamingPort, streamingSrcIP);
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader);
} catch (...) { } catch (...) {
dataStreamer.clear(); dataStreamer.clear();
dataStreamEnable = false; dataStreamEnable = false;
@ -1170,17 +1170,55 @@ void Implementation::setStreamingSourceIP(const sls::IpAddr ip) {
LOG(logINFO) << "Streaming Source IP: " << streamingSrcIP; 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"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
return additionalJsonHeader; 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"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
additionalJsonHeader = c; 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) { if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
generalData->SetDynamicRange(i, tengigaEnable); generalData->SetDynamicRange(i, tengigaEnable);
if (myDetectorType == EIGER) {
generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable);
}
// to update npixelsx, npixelsy in file writer // to update npixelsx, npixelsy in file writer
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetPixelDimension(); it->SetPixelDimension();
@ -1377,7 +1412,6 @@ void Implementation::setTenGigaEnable(const bool b) {
switch (myDetectorType) { switch (myDetectorType) {
case EIGER: case EIGER:
generalData->SetTenGigaEnable(b, dynamicRange); generalData->SetTenGigaEnable(b, dynamicRange);
generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable);
break; break;
case MOENCH: case MOENCH:
case CHIPTESTBOARD: case CHIPTESTBOARD:
@ -1421,24 +1455,6 @@ void Implementation::setFlippedDataX(int enable) {
LOG(logINFO) << "Flipped Data X: " << flippedDataX; 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 { bool Implementation::getQuad() const {
LOG(logDEBUG) << __AT__ << " starting"; LOG(logDEBUG) << __AT__ << " starting";
return quadEnable; return quadEnable;
@ -1448,12 +1464,6 @@ void Implementation::setQuad(const bool b) {
if (quadEnable != b) { if (quadEnable != b) {
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) { if (!quadEnable) {
for (const auto &it : dataStreamer) { for (const auto &it : dataStreamer) {
it->SetNumberofDetectors(numDet); it->SetNumberofDetectors(numDet);

View File

@ -14,6 +14,7 @@ class slsDetectorDefs;
#include <exception> #include <exception>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <map>
class Implementation : private virtual slsDetectorDefs { class Implementation : private virtual slsDetectorDefs {
public: public:
@ -123,8 +124,10 @@ class Implementation : private virtual slsDetectorDefs {
void setStreamingPort(const uint32_t i); void setStreamingPort(const uint32_t i);
sls::IpAddr getStreamingSourceIP() const; sls::IpAddr getStreamingSourceIP() const;
void setStreamingSourceIP(const sls::IpAddr ip); void setStreamingSourceIP(const sls::IpAddr ip);
std::string getAdditionalJsonHeader() const; std::map<std::string, std::string> getAdditionalJsonHeader() const;
void setAdditionalJsonHeader(const std::string& c); 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); void setTenGigaEnable(const bool b);
int getFlippedDataX() const; int getFlippedDataX() const;
void setFlippedDataX(int enable = -1); void setFlippedDataX(int enable = -1);
bool getGapPixelsEnable() const;
/* [Eiger] */
void setGapPixelsEnable(const bool b);
bool getQuad() const; bool getQuad() const;
/* [Eiger] */ /* [Eiger] */
void setQuad(const bool b); void setQuad(const bool b);
@ -263,7 +263,7 @@ class Implementation : private virtual slsDetectorDefs {
uint32_t streamingTimerInMs; uint32_t streamingTimerInMs;
uint32_t streamingPort; uint32_t streamingPort;
sls::IpAddr streamingSrcIP; sls::IpAddr streamingSrcIP;
std::string additionalJsonHeader; std::map<std::string, std::string> additionalJsonHeader;
// detector parameters // detector parameters
uint64_t numberOfFrames; uint64_t numberOfFrames;
@ -278,7 +278,6 @@ class Implementation : private virtual slsDetectorDefs {
ROI roi; ROI roi;
bool tengigaEnable; bool tengigaEnable;
int flippedDataX; int flippedDataX;
bool gapPixelsEnable;
bool quadEnable; bool quadEnable;
bool activated; bool activated;
bool deactivatedPaddingEnable; bool deactivatedPaddingEnable;

View File

@ -74,7 +74,6 @@ struct masterAttributes {
uint64_t subExptimeNs; uint64_t subExptimeNs;
uint64_t subPeriodNs; uint64_t subPeriodNs;
uint64_t periodNs; uint64_t periodNs;
uint32_t gapPixelsEnable;
uint32_t quadEnable; uint32_t quadEnable;
uint32_t analogFlag; uint32_t analogFlag;
uint32_t digitalFlag; uint32_t digitalFlag;

View File

@ -17,9 +17,59 @@
class zmq_msg_t; 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 { class ZmqSocket {
public: public:
// Socket Options for optimization // Socket Options for optimization
// ZMQ_LINGER default is already -1 means no messages discarded. use this // 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 // options if optimizing required ZMQ_SNDHWM default is 0 means no limit. use
@ -110,47 +160,10 @@ class ZmqSocket {
/** /**
* Send Message Header * Send Message Header
* @param index self index for debugging * @param index self index for debugging
* @param dummy true if a dummy message for end of acquisition * @param header zmq header (from json)
* @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
* @returns 0 if error, else 1 * @returns 0 if error, else 1
*/ */
int SendHeaderData( int SendHeader(int index, zmqHeader header);
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);
/** /**
* Send Message Body * Send Message Body
@ -160,38 +173,15 @@ class ZmqSocket {
*/ */
int SendData(char *buf, int length); int SendData(char *buf, int length);
/** /**
* Receive Header (Important to close message after parsing header) * Receive Header
* @param index self index for debugging * @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 * @param version version that has to match, -1 to not care
* @returns 0 if error or end of acquisition, else 1 (call * @returns 0 if error or end of acquisition, else 1 (call
* CloseHeaderMessage after parsing header) * CloseHeaderMessage after parsing header)
*/ */
int ReceiveHeader(const int index, rapidjson::Document &document, uint32_t version); int ReceiveHeader(const int index, zmqHeader& zHeader, 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);
/** /**
* Receive Data * Receive Data
@ -216,6 +206,19 @@ class ZmqSocket {
* @returns length of message, -1 if error * @returns length of message, -1 if error
*/ */
int ReceiveMessage(const int index, zmq_msg_t &message); 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 * Class to close socket descriptors automatically
* upon encountering exceptions in the ZmqSocket constructor * upon encountering exceptions in the ZmqSocket constructor
@ -246,4 +249,6 @@ class ZmqSocket {
/** Socket descriptor */ /** Socket descriptor */
mySocketDescriptors sockfd; mySocketDescriptors sockfd;
}; };

View File

@ -37,7 +37,7 @@
#define DEFAULT_ZMQ_RX_PORTNO 30001 #define DEFAULT_ZMQ_RX_PORTNO 30001
#define SLS_DETECTOR_HEADER_VERSION 0x2 #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) // ctb/ moench 1g udp (read from fifo)
#define UDP_PACKET_DATA_BYTES (1344) #define UDP_PACKET_DATA_BYTES (1344)
@ -61,6 +61,7 @@
/** default maximum string length */ /** default maximum string length */
#define MAX_STR_LENGTH 1000 #define MAX_STR_LENGTH 1000
#define SHORT_STR_LENGTH 20
#define DEFAULT_STREAMING_TIMER_IN_MS 200 #define DEFAULT_STREAMING_TIMER_IN_MS 200
@ -480,8 +481,6 @@ struct detParameters {
int nChipY{0}; int nChipY{0};
int nDacs{0}; int nDacs{0};
int dynamicRange{0}; int dynamicRange{0};
int nGappixelsX{0};
int nGappixelsY{0};
detParameters() = default; detParameters() = default;
explicit detParameters(slsDetectorDefs::detectorType type) { explicit detParameters(slsDetectorDefs::detectorType type) {
@ -493,8 +492,6 @@ struct detParameters {
nChipY = 1; nChipY = 1;
nDacs = 8; nDacs = 8;
dynamicRange = 16; dynamicRange = 16;
nGappixelsX = 0;
nGappixelsY = 0;
break; break;
case slsDetectorDefs::detectorType::JUNGFRAU: case slsDetectorDefs::detectorType::JUNGFRAU:
nChanX = 256; nChanX = 256;
@ -503,8 +500,6 @@ struct detParameters {
nChipY = 2; nChipY = 2;
nDacs = 8; nDacs = 8;
dynamicRange = 16; dynamicRange = 16;
nGappixelsX = 0;
nGappixelsY = 0;
break; break;
case slsDetectorDefs::detectorType::CHIPTESTBOARD: case slsDetectorDefs::detectorType::CHIPTESTBOARD:
nChanX = 36; nChanX = 36;
@ -513,8 +508,6 @@ struct detParameters {
nChipY = 1; nChipY = 1;
nDacs = 24; nDacs = 24;
dynamicRange = 16; dynamicRange = 16;
nGappixelsX = 0;
nGappixelsY = 0;
break; break;
case slsDetectorDefs::detectorType::MOENCH: case slsDetectorDefs::detectorType::MOENCH:
nChanX = 32; nChanX = 32;
@ -523,8 +516,6 @@ struct detParameters {
nChipY = 1; nChipY = 1;
nDacs = 8; nDacs = 8;
dynamicRange = 16; dynamicRange = 16;
nGappixelsX = 0;
nGappixelsY = 0;
break; break;
case slsDetectorDefs::detectorType::EIGER: case slsDetectorDefs::detectorType::EIGER:
nChanX = 256; nChanX = 256;
@ -533,8 +524,6 @@ struct detParameters {
nChipY = 1; nChipY = 1;
nDacs = 16; nDacs = 16;
dynamicRange = 16; dynamicRange = 16;
nGappixelsX = 6;
nGappixelsY = 1;
break; break;
case slsDetectorDefs::detectorType::MYTHEN3: case slsDetectorDefs::detectorType::MYTHEN3:
nChanX = 128 * 3; nChanX = 128 * 3;
@ -543,8 +532,6 @@ struct detParameters {
nChipY = 1; nChipY = 1;
nDacs = 16; nDacs = 16;
dynamicRange = 32; dynamicRange = 32;
nGappixelsX = 0;
nGappixelsY = 0;
break; break;
case slsDetectorDefs::detectorType::GOTTHARD2: case slsDetectorDefs::detectorType::GOTTHARD2:
nChanX = 128; nChanX = 128;
@ -553,8 +540,6 @@ struct detParameters {
nChipY = 1; nChipY = 1;
nDacs = 14; nDacs = 14;
dynamicRange = 16; dynamicRange = 16;
nGappixelsX = 0;
nGappixelsY = 0;
break; break;
default: default:
throw sls::RuntimeError("Unknown detector type! " + std::to_string(type)); throw sls::RuntimeError("Unknown detector type! " + std::to_string(type));

View File

@ -206,7 +206,6 @@ enum detFuncs{
F_LOCK_RECEIVER, F_LOCK_RECEIVER,
F_GET_LAST_RECEIVER_CLIENT_IP, F_GET_LAST_RECEIVER_CLIENT_IP,
F_SET_RECEIVER_PORT, F_SET_RECEIVER_PORT,
F_UPDATE_RECEIVER_CLIENT,
F_GET_RECEIVER_VERSION, F_GET_RECEIVER_VERSION,
F_GET_RECEIVER_TYPE, F_GET_RECEIVER_TYPE,
F_SEND_RECEIVER_DETHOSTNAME, F_SEND_RECEIVER_DETHOSTNAME,
@ -256,7 +255,6 @@ enum detFuncs{
F_GET_RECEIVER_STREAMING_SRC_IP, F_GET_RECEIVER_STREAMING_SRC_IP,
F_SET_RECEIVER_SILENT_MODE, F_SET_RECEIVER_SILENT_MODE,
F_GET_RECEIVER_SILENT_MODE, F_GET_RECEIVER_SILENT_MODE,
F_ENABLE_GAPPIXELS_IN_RECEIVER,
F_RESTREAM_STOP_FROM_RECEIVER, F_RESTREAM_STOP_FROM_RECEIVER,
F_SET_ADDITIONAL_JSON_HEADER, F_SET_ADDITIONAL_JSON_HEADER,
F_GET_ADDITIONAL_JSON_HEADER, F_GET_ADDITIONAL_JSON_HEADER,
@ -287,6 +285,8 @@ enum detFuncs{
F_RECEIVER_SET_ADC_MASK_10G, F_RECEIVER_SET_ADC_MASK_10G,
F_RECEIVER_SET_NUM_COUNTERS, F_RECEIVER_SET_NUM_COUNTERS,
F_INCREMENT_FILE_INDEX, F_INCREMENT_FILE_INDEX,
F_SET_ADDITIONAL_JSON_PARAMETER,
F_GET_ADDITIONAL_JSON_PARAMETER,
NUM_REC_FUNCTIONS NUM_REC_FUNCTIONS
}; };
@ -489,7 +489,6 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER"; case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER";
case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP"; case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP";
case F_SET_RECEIVER_PORT: return "F_SET_RECEIVER_PORT"; 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_VERSION: return "F_GET_RECEIVER_VERSION";
case F_GET_RECEIVER_TYPE: return "F_GET_RECEIVER_TYPE"; case F_GET_RECEIVER_TYPE: return "F_GET_RECEIVER_TYPE";
case F_SEND_RECEIVER_DETHOSTNAME: return "F_SEND_RECEIVER_DETHOSTNAME"; 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_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_SET_RECEIVER_SILENT_MODE: return "F_SET_RECEIVER_SILENT_MODE";
case F_GET_RECEIVER_SILENT_MODE: return "F_GET_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_RESTREAM_STOP_FROM_RECEIVER: return "F_RESTREAM_STOP_FROM_RECEIVER";
case F_SET_ADDITIONAL_JSON_HEADER: return "F_SET_ADDITIONAL_JSON_HEADER"; case F_SET_ADDITIONAL_JSON_HEADER: return "F_SET_ADDITIONAL_JSON_HEADER";
case F_GET_ADDITIONAL_JSON_HEADER: return "F_GET_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_ADC_MASK_10G: return "F_RECEIVER_SET_ADC_MASK_10G";
case F_RECEIVER_SET_NUM_COUNTERS: return "F_RECEIVER_SET_NUM_COUNTERS"; case F_RECEIVER_SET_NUM_COUNTERS: return "F_RECEIVER_SET_NUM_COUNTERS";
case F_INCREMENT_FILE_INDEX: return "F_INCREMENT_FILE_INDEX"; 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"; case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function"; default: return "Unknown Function";

View File

@ -3,10 +3,10 @@
#define APILIB 0x200227 #define APILIB 0x200227
#define APIRECEIVER 0x200227 #define APIRECEIVER 0x200227
#define APIGUI 0x200227 #define APIGUI 0x200227
#define APICTB 0x200310 #define APICTB 0x200311
#define APIGOTTHARD 0x200310 #define APIGOTTHARD 0x200326
#define APIJUNGFRAU 0x200310 #define APIGOTTHARD2 0x200326
#define APIMYTHEN3 0x200310 #define APIJUNGFRAU 0x200326
#define APIMOENCH 0x200310 #define APIMYTHEN3 0x200311
#define APIEIGER 0x200310 #define APIMOENCH 0x200326
#define APIGOTTHARD2 0x200313 #define APIEIGER 0x200326

View File

@ -145,6 +145,244 @@ int ZmqSocket::ConvertInternetAddresstoIpString(struct addrinfo *res, char *ip,
return 1; 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() { void ZmqSocket::PrintError() {
switch (errno) { switch (errno) {
case EINVAL: 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 //Nested class to do RAII handling of socket descriptors
ZmqSocket::mySocketDescriptors::mySocketDescriptors() ZmqSocket::mySocketDescriptors::mySocketDescriptors()
: server(false), contextDescriptor(0), socketDescriptor(0){}; : server(false), contextDescriptor(0), socketDescriptor(0){};