Merge pull request #125 from slsdetectorgroup/eiger

Eiger
This commit is contained in:
Dhanya Thattil 2020-08-03 15:04:25 +02:00 committed by GitHub
commit 540a203139
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 856 additions and 612 deletions

View File

@ -12,7 +12,7 @@ hostname bchip007
0:rx_udpip 129.129.202.98
0:rx_hostname pc6898
0:outdir /bigRAID/datadir_gotthard/rec_test_data
0:vhighvoltage 120
0:highvoltage 120
master -1
sync none
outdir /bigRAID/datadir_gotthard/rec_test_data

View File

@ -6,12 +6,12 @@ hostname bchip074+bchip075+
0:extsig:0 trigger_in_rising_edge
0:rx_tcpport 1954
0:rx_udpport 50001
0:vhighvoltage 0
0:highvoltage 0
1:extsig:0 trigger_in_rising_edge
1:rx_tcpport 1955
1:rx_udpport 50002
1:vhighvoltage 0
1:highvoltage 0
##############################################################################
#########
@ -53,5 +53,5 @@ settings veryhighgain
exptime 0.000005
period 0.0001
vhighvoltage 90
highvoltage 90

View File

@ -498,4 +498,4 @@ rx_jsonpara detectorMode analog
reg 0x5e 0x00010000
#powerchip 1
vhighvoltage 90
highvoltage 90

View File

@ -6,7 +6,7 @@ hostname localhost
rx_hostname localhost
#powerchip 1
#vhighvoltage 200
#highvoltage 200
#extsig:0 trigger_in_rising_edge
#timing trigger

View File

@ -17,7 +17,7 @@ hostname bchip048+bchip052+
rx_hostname pcmoench01
powerchip 1
vhighvoltage 200
highvoltage 200
#extsig:0 trigger_in_rising_edge
#timing trigger

View File

@ -56,7 +56,7 @@ rx_discardpolicy discardpartial
adcpipeline 15
powerchip 1
vhighvoltage 90
highvoltage 90
#adcreg 0x14 0x40

View File

@ -19,7 +19,7 @@ hostname bchip007+bchip009+
0:rx_udpip 10.1.1.1
0:rx_hostname 129.129.202.134
0:outdir /data/speedt
0:vhighvoltage 120
0:highvoltage 120
#1:hostname bchip009
@ -37,7 +37,7 @@ hostname bchip007+bchip009+
1:rx_udpip 10.1.2.1
1:rx_hostname 129.129.202.134
1:outdir /data/speedt
1:vhighvoltage 120
1:highvoltage 120
master -1

View File

@ -196,7 +196,7 @@ sls_detector_put 0-parameters setup.det
\end{verbatim}
Note that the parameter file for any realease before 4.1.1 has not the possibility to understand parameters to be set differently for different half modules, i.e. {\tt{0:txndelay\_left xxxxx},\tt{1:txndelay\_left yyyyy}}.
In the case of \E, the proper bias voltage of the sensor has to be setup, i.e. the {\tt{setup.det}} file needs to contain the line {\tt{vhighvoltage 150}}. Other detector functionality, which are rarely changed can be setup here.
In the case of \E, the proper bias voltage of the sensor has to be setup, i.e. the {\tt{setup.det}} file needs to contain the line {\tt{highvoltage 150}}. Other detector functionality, which are rarely changed can be setup here.
Other important settings that are configured in the {\tt{setup.det}} file are:
\begin{itemize}
\item {\tt{tengiga 0/1}}, which sets whether the detector is enabled to send data through the 1~or the 10~Gb Ethernet.
@ -1174,10 +1174,10 @@ In 500k--2M pixel systems there is a hardware temperature safety switch, which w
The HV can also be set and read through the software:
\begin{verbatim}
./sls_detector_put vhighvoltage 150
./sls_detector_get vhighvoltage
./sls_detector_put highvoltage 150
./sls_detector_get highvoltage
\end{verbatim}
Note that the get {\tt{vhighvoltage}} would return the measured HV from the master module only. If getting the vhighvoltage for individual halfmodules, only the master will have a value different from -999.
Note that the get {\tt{highvoltage}} would return the measured HV from the master module only. If getting the highvoltage for individual halfmodules, only the master will have a value different from -999.
\appendix
@ -1454,7 +1454,7 @@ Environment variable SLSDETNAME can be set for using 2 different detectors from
\subsection{Measure the HV}
For every system:
\begin{itemize}
\item Software-wise measure it (now the software returns the measured value), with {\tt{sls\_detector\_get vhighvoltage}}. The returned value is the HV (for proper Eiger setting is approximately 150~V) if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:vhighvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
\item Software-wise measure it (now the software returns the measured value), with {\tt{sls\_detector\_get highvoltage}}. The returned value is the HV (for proper Eiger setting is approximately 150~V) if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:highvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
\item Hardware-wise (opening the detector) measure value of HV on C14 on the power distribution board. Check also that the small HV connector cable is really connected.
\end{itemize}
@ -1505,7 +1505,7 @@ Scroll up in the terminal till you find:\\
There is also an easier way, that is that only the master module will return the real value of the HV. If you have more than 1 detector system, then you will have more than 1 physical master, as the HV needs to be applied to all the systems.
\begin{verbatim}
for i in $(seq 0 36); do sls_detector_put $i:vhighvoltage; done
for i in $(seq 0 36); do sls_detector_put $i:highvoltage; done
\end{verbatim}
Only the master will return to you a sensible number (150 normally). the others will return -999.
@ -1666,10 +1666,10 @@ ratecorr number
where {\tt{number}} is a string that should be interpreted as a float in s. 0.000000 means correction off. Values above zero are the value of $\tau$ in ns.
\item \begin{verbatim}
sls_detector_get vhighvoltage
vhighvoltage number
sls_detector_get highvoltage
highvoltage number
\end{verbatim}
where {\tt{number}} is a string that should be interpreted as an int and for proper Eiger setting is approximately 150~V if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:vhighvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
where {\tt{number}} is a string that should be interpreted as an int and for proper Eiger setting is approximately 150~V if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:highvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
\item \begin{verbatim}
sls_detector_get busy

View File

@ -142,7 +142,7 @@
"vpreamp"; // sets/get vpreamp value (advanced! Mythen)
"vshaper1"; // sets/get vshaper1 value (advanced! Mythen)
"vshaper2"; // sets/get vshaper2 value (advanced! Mythen)
"vhighvoltage"; // sets/get vhighvoltage value (advanced! Chiptest board and Eiger)
"highvoltage"; // sets/get highvoltage value (advanced! Chiptest board and Eiger)
"vapower"; // sets/get vapower value (advanced! Chiptest board)
"vddpower"; // sets/get vddpower value (advanced! Chiptest board)
"vshpower"; // sets/get vshpower value (advanced! Chiptest board)

View File

@ -335,7 +335,7 @@ Advanced settings changing the analog or digital performance of the acquisition.
\item[vpreamp n] Sets the DAC value of the preamp feedback to n.
\item[vshaper1 n] Sets the DAC value of the shaper1 feedback to n.
\item[vshaper2 n] Sets the DAC value of the shaper2 feedback to n.
\item[vhighvoltage n] Sets the DAC value of the high voltage to n (in V).
\item[highvoltage n] Sets the DAC value of the high voltage to n (in V).
\item[vapower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
\item[vddpower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
\item[vshpower n] CHIPTEST BOARD ONLY - Sets the comparator power supply in dac units (0-1024).
@ -648,7 +648,7 @@ Advanced settings changing the analog or digital performance of the acquisition.
\item[vpreamp] Returns the DAC value of the preamp feedback to n.
\item[vshaper1] Returns the DAC value of the shaper1 feedback to n.
\item[vshaper2] Returns the DAC value of the shaper2 feedback to n.
\item[vhighvoltage] Returns the DAC value of the high voltage to n.
\item[highvoltage] Returns the DAC value of the high voltage to n.
\item[vapower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
\item[vddpower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
\item[vshpower] CHIPTEST BOARD ONLY - Returns the comparator power supply in dac units (0-1024).
@ -714,7 +714,7 @@ One can configure all the detector settings in a parameter file {\tt{setup.det}}
sls_detector_put parameters setup.det
\end{verbatim}
In the case of \E, the parameter file ({\tt{setup.det}} needs to setup the proper bias voltage of the sensor, i.e. needs to contain the line {\tt{vhighvoltage 150}}.
In the case of \E, the parameter file ({\tt{setup.det}} needs to setup the proper bias voltage of the sensor, i.e. needs to contain the line {\tt{highvoltage 150}}.
\subsection{Standard acquisition}

View File

@ -322,7 +322,7 @@ Advanced settings changing the analog or digital performance of the acquisition.
\item[vpreamp n] Sets the DAC value of the preamp feedback to n.
\item[vshaper1 n] Sets the DAC value of the shaper1 feedback to n.
\item[vshaper2 n] Sets the DAC value of the shaper2 feedback to n.
\item[vhighvoltage n] CHIPTEST BOARD ONLY - Sets the DAC value of the high voltage to n.
\item[highvoltage n] CHIPTEST BOARD ONLY - Sets the DAC value of the high voltage to n.
\item[vapower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
\item[vddpower n] CHIPTEST BOARD ONLY - Sets the DAC value of the analog voltage to n.
\item[vshpower n] CHIPTEST BOARD ONLY - Sets the comparator power supply in dac units (0-1024).
@ -594,7 +594,7 @@ Advanced settings changing the analog or digital performance of the acquisition.
\item[vpreamp] Returns the DAC value of the preamp feedback to n.
\item[vshaper1] Returns the DAC value of the shaper1 feedback to n.
\item[vshaper2] Returns the DAC value of the shaper2 feedback to n.
\item[vhighvoltage] CHIPTEST BOARD ONLY - Returns the DAC value of the high voltage to n.
\item[highvoltage] CHIPTEST BOARD ONLY - Returns the DAC value of the high voltage to n.
\item[vapower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
\item[vddpower] CHIPTEST BOARD ONLY - Returns the DAC value of the analog voltage to n.
\item[vshpower] CHIPTEST BOARD ONLY - Returns the comparator power supply in dac units (0-1024).

View File

@ -42,6 +42,7 @@ def extract_enums(lines):
except:
pass
fields = [f.strip() for f in fields]
enums[enum_name] = fields
return enums

View File

@ -27,7 +27,7 @@ dr 32
threaded 1
tengiga 0
vhighvoltage 150
highvoltage 150
iodelay 660
#gappixels 1

View File

@ -1 +1 @@
vhighvoltage 200
highvoltage 200

View File

@ -508,11 +508,11 @@ class Detector(CppDetectorApi):
self.setSourceUDPMAC2(MacAddr(mac))
@property
def vhighvoltage(self):
def highvoltage(self):
return element_if_equal(self.getHighVoltage())
@vhighvoltage.setter
def vhighvoltage(self, v):
@highvoltage.setter
def highvoltage(self, v):
self.setHighVoltage(v)
@property
@ -601,13 +601,12 @@ class Detector(CppDetectorApi):
self.setRateCorrection(tau)
@property
def clkdivider(self):
res = [int(value) for value in self.getSpeed()]
return element_if_equal(res)
def speed(self):
return element_if_equal(self.getSpeed())
@clkdivider.setter
def clkdivider(self, value):
self.setSpeed(speedLevel(value))
@speed.setter
def speed(self, value):
self.setSpeed(value)
@property
def frameindex(self):

View File

@ -176,6 +176,7 @@ void init_enums(py::module &m) {
slsDetectorDefs::dacIndex::TEMPERATURE_FPGA2)
.value("TEMPERATURE_FPGA3",
slsDetectorDefs::dacIndex::TEMPERATURE_FPGA3)
.value("TRIMBIT_SCAN", slsDetectorDefs::dacIndex::TRIMBIT_SCAN)
.value("V_POWER_A", slsDetectorDefs::dacIndex::V_POWER_A)
.value("V_POWER_B", slsDetectorDefs::dacIndex::V_POWER_B)
.value("V_POWER_C", slsDetectorDefs::dacIndex::V_POWER_C)

View File

@ -164,18 +164,18 @@ def test_cannot_set_fw_version(d):
def test_get_high_voltage_call_signature(d, mocker):
m = mocker.patch('_slsdet.DetectorApi.getDac')
d.high_voltage
m.assert_called_once_with('vhighvoltage', -1)
m.assert_called_once_with('highvoltage', -1)
def test_get_high_voltage(d, mocker):
m = mocker.patch('_slsdet.DetectorApi.getDac')
m.return_value = 80
assert d.high_voltage == 80
#self._api.setDac('vhighvoltage', -1, voltage)
#self._api.setDac('highvoltage', -1, voltage)
def test_set_high_voltage(d, mocker):
m = mocker.patch('_slsdet.DetectorApi.setDac')
d.high_voltage = 80
m.assert_called_once_with('vhighvoltage', -1, 80)
m.assert_called_once_with('highvoltage', -1, 80)
def test_decode_hostname_two_names(d, mocker):
m = mocker.patch('_slsdet.DetectorApi.getHostname')

View File

@ -170,18 +170,18 @@ def test_set_counters_single(d, mocker):
# def test_get_high_voltage_call_signature(d, mocker):
# m = mocker.patch('_slsdet.DetectorApi.getDac')
# d.high_voltage
# m.assert_called_once_with('vhighvoltage', -1)
# m.assert_called_once_with('highvoltage', -1)
# def test_get_high_voltage(d, mocker):
# m = mocker.patch('_slsdet.DetectorApi.getDac')
# m.return_value = 80
# assert d.high_voltage == 80
# #self._api.setDac('vhighvoltage', -1, voltage)
# #self._api.setDac('highvoltage', -1, voltage)
# def test_set_high_voltage(d, mocker):
# m = mocker.patch('_slsdet.DetectorApi.setDac')
# d.high_voltage = 80
# m.assert_called_once_with('vhighvoltage', -1, 80)
# m.assert_called_once_with('highvoltage', -1, 80)
# def test_decode_hostname_two_names(d, mocker):
# m = mocker.patch('_slsdet.DetectorApi.getHostname')

View File

@ -10,5 +10,5 @@ sls_detector_put exptime 0.000005
sls_detector_put period 0.01
sls_detector_put vhighvoltage 90
sls_detector_put highvoltage 90

View File

@ -86,7 +86,7 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;High Voltage&lt;/p&gt;&lt;p&gt; #vhighvoltage#&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;High Voltage&lt;/p&gt;&lt;p&gt; #highvoltage#&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>High Voltage: </string>
@ -108,7 +108,7 @@
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;High Voltage&lt;/p&gt;&lt;p&gt; #vhighvoltage#&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;High Voltage&lt;/p&gt;&lt;p&gt; #highvoltage#&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<item>
<property name="text">
@ -156,7 +156,7 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;High Voltage. Range: 60 - 200V. Swich off high voltage by setting to 0.&lt;/p&gt;&lt;p&gt;-1 corresponds to different values from detectors.&lt;/p&gt;&lt;p&gt;#vhighvoltage#&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;High Voltage. Range: 60 - 200V. Swich off high voltage by setting to 0.&lt;/p&gt;&lt;p&gt;-1 corresponds to different values from detectors.&lt;/p&gt;&lt;p&gt;#highvoltage#&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>High Voltage: </string>
@ -178,7 +178,7 @@
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;High Voltage. Range: 60 - 200V. Swich off high voltage by setting to 0.&lt;/p&gt;&lt;p&gt;-1 corresponds to different values from detectors.&lt;/p&gt;&lt;p&gt;#vhighvoltage#&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;High Voltage. Range: 60 - 200V. Swich off high voltage by setting to 0.&lt;/p&gt;&lt;p&gt;-1 corresponds to different values from detectors.&lt;/p&gt;&lt;p&gt;#highvoltage#&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>-1</number>

View File

@ -813,7 +813,7 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
plotTitlePrefix + QString(data->fileName.c_str()).section('/', -1);
indexTitle = QString("%1").arg(frameIndex);
if ((int)subFrameIndex != -1) {
indexTitle = QString("%1 %2").arg(frameIndex, subFrameIndex);
indexTitle = QString("%1 %2").arg(frameIndex).arg(subFrameIndex);
}
completeImage = data->completeImage;

View File

@ -560,9 +560,7 @@ void qTabAdvanced::ClearROI() {
void qTabAdvanced::SetROI() {
slsDetectorDefs::ROI roi;
roi.xmin = spinXmin->value();
roi.xmax = spinXmax->value();
slsDetectorDefs::ROI roi(spinXmin->value(), spinXmax->value());
// set roi
LOG(logINFO) << "Setting ROI: [" << roi.xmin << ", " << roi.xmax << "]";

View File

@ -2048,7 +2048,7 @@ void *start_timer(void *arg) {
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 "
LOG(logDEBUG1, (" 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,
@ -2181,7 +2181,7 @@ void *start_timer(void *arg) {
usleep(eiger_virtual_transmission_delay_right);
sendUDPPacket(1, packetData2, packetsize);
}
LOG(logINFO, ("Sent frame: %d\n", iframes));
LOG(logINFO, ("Sent frame: %d[%lld]\n", iframes, (long long unsigned int)(frameNr + iframes)));
clock_gettime(CLOCK_REALTIME, &end);
int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 +
(end.tv_nsec - begin.tv_nsec));

View File

@ -1469,6 +1469,7 @@ class Detector {
private:
std::vector<int> getPortNumbers(int start_port);
void updateRxRateCorrections();
};
} // namespace sls

View File

@ -1559,9 +1559,7 @@ std::string CmdProxy::ROI(int action) {
if (args.size() != 2) {
WrongNumberOfParameters(2);
}
defs::ROI t;
t.xmin = StringTo<int>(args[0]);
t.xmax = StringTo<int>(args[1]);
defs::ROI t(StringTo<int>(args[0]), StringTo<int>(args[1]));
det->setROI(t, det_id);
os << '[' << t.xmin << ", " << t.xmax << "]\n";
} else {

View File

@ -528,6 +528,7 @@ class CmdProxy {
{"cycles", "triggers"},
{"cyclesl", "triggersl"},
{"clkdivider", "speed"},
{"vhighvoltage", "highvoltage"},
{"digitest", "imagetest"},
/** temperature */
@ -654,7 +655,7 @@ class CmdProxy {
{"clkphase", &CmdProxy::ClockPhase},
{"maxclkphaseshift", &CmdProxy::MaxClockPhaseShift},
{"clkdiv", &CmdProxy::ClockDivider},
{"vhighvoltage", &CmdProxy::vhighvoltage},
{"highvoltage", &CmdProxy::highvoltage},
{"powerchip", &CmdProxy::powerchip},
{"imagetest", &CmdProxy::imagetest},
{"extsig", &CmdProxy::ExternalSignal},
@ -1185,7 +1186,7 @@ class CmdProxy {
"\n\t[CTB][Jungfrau] Absolute maximum Phase shift of of the "
"clock to latch digital bits.");
INTEGER_COMMAND(vhighvoltage, getHighVoltage, setHighVoltage, StringTo<int>,
INTEGER_COMMAND(highvoltage, getHighVoltage, setHighVoltage, StringTo<int>,
"[n_value]\n\tHigh voltage to the sensor in Voltage."
"\n\t[Gotthard] [0|90|110|120|150|180|200]"
"\n\t[Eiger][Mythen3][Gotthard2] 0-200"

View File

@ -281,6 +281,7 @@ Result<int> Detector::getDynamicRange(Positions pos) const {
void Detector::setDynamicRange(int value) {
pimpl->Parallel(&Module::setDynamicRange, {}, value);
updateRxRateCorrections();
}
Result<defs::timingMode> Detector::getTimingMode(Positions pos) const {
@ -771,6 +772,7 @@ Result<std::string> Detector::getRxHostname(Positions pos) const {
void Detector::setRxHostname(const std::string &receiver, Positions pos) {
pimpl->Parallel(&Module::setReceiverHostname, pos, receiver);
updateRxRateCorrections();
}
void Detector::setRxHostname(const std::vector<std::string> &name) {
@ -788,6 +790,7 @@ void Detector::setRxHostname(const std::vector<std::string> &name) {
pimpl->Parallel(&Module::setReceiverHostname, {idet}, name[idet]);
}
}
updateRxRateCorrections();
}
Result<int> Detector::getRxPort(Positions pos) const {
@ -1038,6 +1041,7 @@ Result<ns> Detector::getSubExptime(Positions pos) const {
void Detector::setSubExptime(ns t, Positions pos) {
pimpl->Parallel(&Module::setSubExptime, pos, t.count());
updateRxRateCorrections();
}
Result<ns> Detector::getSubDeadTime(Positions pos) const {
@ -1105,10 +1109,25 @@ Result<ns> Detector::getRateCorrection(Positions pos) const {
void Detector::setDefaultRateCorrection(Positions pos) {
pimpl->Parallel(&Module::setDefaultRateCorrection, pos);
updateRxRateCorrections();
}
void Detector::setRateCorrection(ns dead_time, Positions pos) {
pimpl->Parallel(&Module::setRateCorrection, pos, dead_time.count());
updateRxRateCorrections();
}
void Detector::updateRxRateCorrections() {
// get tau from all modules and send to Rx index 0
if (getDetectorType().squash() == defs::EIGER) {
if (getUseReceiverFlag().squash(false)) {
std::vector<int64_t> dead_times;
for (auto item : getRateCorrection())
dead_times.push_back(item.count());
pimpl->Parallel(&Module::sendReceiverRateCorrections, {0},
dead_times);
}
}
}
Result<int> Detector::getPartialReadout(Positions pos) const {
@ -1405,6 +1424,7 @@ Result<ns> Detector::getExptime(int gateIndex, Positions pos) const {
void Detector::setExptime(int gateIndex, ns t, Positions pos) {
pimpl->Parallel(&Module::setExptime, pos, gateIndex, t.count());
updateRxRateCorrections();
}
Result<std::array<ns, 3>> Detector::getExptimeForAllGates(Positions pos) const {

View File

@ -270,20 +270,23 @@ void Module::setDynamicRange(int dr) {
sendToReceiver<int>(F_SET_RECEIVER_DYNAMIC_RANGE, retval);
}
// EIGER only, update speed and rate correction when dr changes
if (dr != prev_val) {
// update speed
if (shm()->myDetectorType == EIGER) {
if (dr == 32) {
LOG(logINFO) << "Setting Clock to Quarter Speed to cope with "
"Dynamic Range of 32";
setClockDivider(RUN_CLOCK, 2);
} else if (prev_val == 32) {
} else {
LOG(logINFO) << "Setting Clock to Full Speed for Dynamic Range of "
<< dr;
setClockDivider(RUN_CLOCK, 0);
}
// EIGER only, update speed and rate correction when dr changes
if (dr != prev_val) {
updateRateCorrection();
}
}
}
slsDetectorDefs::timingMode Module::getTimingMode() const {
return sendToDetector<timingMode>(F_SET_TIMING_MODE, GET_FLAG);
@ -1160,6 +1163,19 @@ void Module::setRateCorrection(int64_t t) {
sendToDetector(F_SET_RATE_CORRECT, t, nullptr);
}
void Module::sendReceiverRateCorrections(const std::vector<int64_t> &t) {
LOG(logDEBUG) << "Sending to detector [rate corrections: " << ToString(t)
<< ']';
auto receiver = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
receiver.Send(F_SET_RECEIVER_RATE_CORRECT);
receiver.Send(static_cast<int>(t.size()));
receiver.Send(t);
if (receiver.Receive<int>() == FAIL) {
throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + receiver.readErrorMessage());
}
}
int Module::getReadNLines() const {
return sendToDetector<int>(F_GET_READ_N_LINES);
}

View File

@ -312,6 +312,7 @@ class Module : public virtual slsDetectorDefs {
int64_t getRateCorrection() const;
void setDefaultRateCorrection();
void setRateCorrection(int64_t t = 0);
void sendReceiverRateCorrections(const std::vector<int64_t> &t);
int getReadNLines() const;
void setReadNLines(const int value);
bool getInterruptSubframe() const;
@ -371,7 +372,8 @@ class Module : public virtual slsDetectorDefs {
void setBurstPeriod(int64_t value);
std::array<int, 2> getInjectChannel() const;
void setInjectChannel(const int offsetChannel, const int incrementChannel);
void sendVetoPhoton(const int chipIndex, const std::vector<int>& gainIndices,
void sendVetoPhoton(const int chipIndex,
const std::vector<int> &gainIndices,
const std::vector<int> &values);
void getVetoPhoton(const int chipIndex, const std::string &fname) const;
void setVetoPhoton(const int chipIndex, const int numPhotons,

View File

@ -793,97 +793,97 @@ TEST_CASE("maxclkphaseshift", "[.cmd][.new]") {
}
}
TEST_CASE("vhighvoltage", "[.cmd][.new]") {
TEST_CASE("highvoltage", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
auto prev_val = det.getHighVoltage();
// selected values
if (det_type == defs::GOTTHARD) {
REQUIRE_THROWS(proxy.Call("vhighvoltage", {"50"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("highvoltage", {"50"}, -1, PUT));
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"90"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 90\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 90\n");
proxy.Call("highvoltage", {"90"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 90\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 90\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 0\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 0\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 0\n");
}
}
// range 0, 60 - 200
else if (det_type == defs::JUNGFRAU || det_type == defs::CHIPTESTBOARD ||
det_type == defs::MOENCH) {
REQUIRE_THROWS(proxy.Call("vhighvoltage", {"50"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("highvoltage", {"50"}, -1, PUT));
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"90"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 90\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 90\n");
proxy.Call("highvoltage", {"90"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 90\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 90\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 0\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 0\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 0\n");
}
}
// full range 0 - 200 (get needs to wait)
else if (det_type == defs::EIGER) {
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"50"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 50\n");
proxy.Call("highvoltage", {"50"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 50\n");
std::this_thread::sleep_for(std::chrono::seconds(2));
proxy.Call("vhighvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 50\n");
proxy.Call("highvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 50\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"120"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 120\n");
proxy.Call("highvoltage", {"120"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 120\n");
std::this_thread::sleep_for(std::chrono::seconds(2));
proxy.Call("vhighvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 120\n");
proxy.Call("highvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 120\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"0"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {"0"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 0\n");
std::this_thread::sleep_for(std::chrono::seconds(2));
proxy.Call("vhighvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 0\n");
}
}
// full range 0 - 200
else {
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"50"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 50\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 50\n");
proxy.Call("highvoltage", {"50"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 50\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 50\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"120"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 120\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 120\n");
proxy.Call("highvoltage", {"120"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 120\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 120\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 0\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 0\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 0\n");
}
}
for (int i = 0; i != det.size(); ++i) {

View File

@ -6,6 +6,7 @@
#include "BinaryFile.h"
#include "Fifo.h"
#include "MasterAttributes.h"
#include "receiver_defs.h"
#include <iomanip>
@ -133,7 +134,7 @@ void BinaryFile::WriteToFile(char *buffer, int buffersize,
}
void BinaryFile::CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes) {
MasterAttributes *attr) {
// beginning of every acquisition
numFramesInFile = 0;
numActualPacketsInFile = 0;
@ -147,7 +148,6 @@ void BinaryFile::CreateMasterFile(bool masterFileWriteEnable,
if (!(*silentMode)) {
LOG(logINFO) << "Master File: " << masterFileName;
}
masterFileAttributes.version = BINARY_WRITER_VERSION;
// create master file
if (!(*overWriteEnable)) {
@ -166,91 +166,8 @@ void BinaryFile::CreateMasterFile(bool masterFileWriteEnable,
"(with overwrite enable) " +
masterFileName);
}
// create master file data
time_t t = time(nullptr);
char message[maxMasterFileSize];
sprintf(message,
"Version : %.1f\n"
"Detector Type : %d\n"
"Dynamic Range : %d\n"
"Ten Giga : %d\n"
"Image Size : %d bytes\n"
"nPixelsX : %d pixels\n"
"nPixelsY : %d pixels\n"
"Max Frames Per File : %u\n"
"Total Frames : %lld\n"
"Exptime (ns) : %lld\n"
"SubExptime (ns) : %lld\n"
"SubPeriod(ns) : %lld\n"
"Period (ns) : %lld\n"
"Quad Enable : %d\n"
"Analog Flag : %d\n"
"Digital Flag : %d\n"
"ADC Mask : %d\n"
"Dbit Offset : %d\n"
"Dbit Bitset : %lld\n"
"Roi (xmin, xmax) : %d %d\n"
"Exptime1 (ns) : %lld\n"
"Exptime2 (ns) : %lld\n"
"Exptime3 (ns) : %lld\n"
"GateDelay1 (ns) : %lld\n"
"GateDelay2 (ns) : %lld\n"
"GateDelay3 (ns) : %lld\n"
"Gates : %d\n"
"Timestamp : %s\n\n"
"#Frame Header\n"
"Frame Number : 8 bytes\n"
"SubFrame Number/ExpLength : 4 bytes\n"
"Packet Number : 4 bytes\n"
"Bunch ID : 8 bytes\n"
"Timestamp : 8 bytes\n"
"Module Id : 2 bytes\n"
"Row : 2 bytes\n"
"Column : 2 bytes\n"
"Reserved : 2 bytes\n"
"Debug : 4 bytes\n"
"Round Robin Number : 2 bytes\n"
"Detector Type : 1 byte\n"
"Header Version : 1 byte\n"
"Packets Caught Mask : 64 bytes\n",
masterFileAttributes.version, masterFileAttributes.detectorType,
masterFileAttributes.dynamicRange, masterFileAttributes.tenGiga,
masterFileAttributes.imageSize, masterFileAttributes.nPixelsX,
masterFileAttributes.nPixelsY,
masterFileAttributes.maxFramesPerFile,
(long long int)masterFileAttributes.totalFrames,
(long long int)masterFileAttributes.exptimeNs,
(long long int)masterFileAttributes.subExptimeNs,
(long long int)masterFileAttributes.subPeriodNs,
(long long int)masterFileAttributes.periodNs,
masterFileAttributes.quadEnable,
masterFileAttributes.analogFlag,
masterFileAttributes.digitalFlag, masterFileAttributes.adcmask,
masterFileAttributes.dbitoffset,
(long long int)masterFileAttributes.dbitlist,
masterFileAttributes.roiXmin, masterFileAttributes.roiXmax,
(long long int)masterFileAttributes.exptime1Ns,
(long long int)masterFileAttributes.exptime2Ns,
(long long int)masterFileAttributes.exptime3Ns,
(long long int)masterFileAttributes.gateDelay1Ns,
(long long int)masterFileAttributes.gateDelay2Ns,
(long long int)masterFileAttributes.gateDelay3Ns,
masterFileAttributes.gates, ctime(&t));
//TODO! snprintf? This would already have been a buffer overflow
if (strlen(message) > maxMasterFileSize) {
throw sls::RuntimeError("Master File Size " +
std::to_string(strlen(message)) +
" is greater than max str size " +
std::to_string(maxMasterFileSize));
}
// write and close file
if (fwrite((void *)message, 1, strlen(message), masterfd) !=
strlen(message)) {
throw sls::RuntimeError(
"Master binary file incorrect number of bytes written to file");
}
attr->WriteMasterBinaryAttributes(masterfd);
if (masterfd)
fclose(masterfd);
masterfd = nullptr;

View File

@ -42,7 +42,7 @@ class BinaryFile : private virtual slsDetectorDefs, public File {
void PrintMembers(TLogLevel level = logDEBUG1) override;
void CreateFile() override;
void CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes) override;
MasterAttributes *attr) override;
void CloseCurrentFile() override;
void CloseAllFiles() override;
void WriteToFile(char *buffer, int buffersize, uint64_t currentFrameNumber,
@ -55,8 +55,4 @@ class BinaryFile : private virtual slsDetectorDefs, public File {
static FILE *masterfd;
uint32_t numFramesInFile = 0;
uint64_t numActualPacketsInFile = 0;
//Make sure this is known at compile time
//TODO! Later away from stack allocation of message
static constexpr size_t maxMasterFileSize = 2000;
};

View File

@ -201,6 +201,7 @@ int ClientInterface::functionTable(){
flist[F_GET_RECEIVER_THREAD_IDS] = &ClientInterface::get_thread_ids;
flist[F_GET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::get_streaming_start_fnum;
flist[F_SET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::set_streaming_start_fnum;
flist[F_SET_RECEIVER_RATE_CORRECT] = &ClientInterface::set_rate_correct;
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@ -906,7 +907,8 @@ int ClientInterface::get_missing_packets(Interface &socket) {
auto size = static_cast<int>(missing_packets.size());
socket.Send(OK);
socket.Send(size);
socket.Send(missing_packets.data(), sizeof(missing_packets[0])* missing_packets.size());
socket.Send(missing_packets.data(),
sizeof(missing_packets[0]) * missing_packets.size());
return OK;
}
@ -1735,3 +1737,18 @@ int ClientInterface::set_streaming_start_fnum(Interface &socket) {
validate(index, retval, "set streaming start fnum", DEC);
return socket.Send(OK);
}
int ClientInterface::set_rate_correct(Interface &socket) {
auto index = socket.Receive<int>();
if (index <= 0) {
throw RuntimeError("Invalid number of rate correction values: " +
std::to_string(index));
}
LOG(logDEBUG) << "Number of detectors for rate correction: " << index;
std::vector<int64_t> t(index);
socket.Receive(t.data(), t.size() * sizeof(t[0]));
verifyIdle(socket);
LOG(logINFOBLUE) << "Setting rate corrections[" << index << ']';
impl()->setRateCorrections(t);
return socket.Send(OK);
}

View File

@ -157,6 +157,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_thread_ids(sls::ServerInterface &socket);
int get_streaming_start_fnum(sls::ServerInterface &socket);
int set_streaming_start_fnum(sls::ServerInterface &socket);
int set_rate_correct(sls::ServerInterface &socket);
Implementation *impl() {
if (receiver != nullptr) {

View File

@ -9,6 +9,7 @@
#include "BinaryFile.h"
#include "Fifo.h"
#include "GeneralData.h"
#include "MasterAttributes.h"
#ifdef HDF5C
#include "HDF5File.h"
#endif
@ -143,7 +144,7 @@ void DataProcessor::SetupFileWriter(bool fwe, int *nd, uint32_t *maxf,
}
// only the first file
void DataProcessor::CreateNewFile(masterAttributes &attr) {
void DataProcessor::CreateNewFile(MasterAttributes *attr) {
if (file == nullptr) {
throw sls::RuntimeError("file object not contstructed");
}

View File

@ -16,6 +16,7 @@ class GeneralData;
class Fifo;
class File;
class DataStreamer;
struct MasterAttributes;
#include <atomic>
#include <vector>
@ -134,7 +135,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* Create New File
* @param attr master file attributes
*/
void CreateNewFile(masterAttributes &attr);
void CreateNewFile(MasterAttributes *attr);
/**
* Closes files

View File

@ -15,6 +15,8 @@
#include <string>
struct MasterAttributes;
class File : private virtual slsDetectorDefs {
public:
@ -86,7 +88,7 @@ class File : private virtual slsDetectorDefs {
* @param mfwenable master file write enable
* @param attr master file attributes
*/
virtual void CreateMasterFile(bool mfwenable, masterAttributes &attr) = 0;
virtual void CreateMasterFile(bool mfwenable, MasterAttributes *attr) = 0;
// HDf5 specific
/**

View File

@ -5,6 +5,7 @@
***********************************************/
#include "HDF5File.h"
#include "Fifo.h"
#include "MasterAttributes.h"
#include "receiver_defs.h"
#include <iomanip>
@ -152,7 +153,7 @@ void HDF5File::WriteToFile(char *buffer, int bufferSize,
}
void HDF5File::CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes) {
MasterAttributes *attr) {
// beginning of every acquisition
numFramesInFile = 0;
@ -161,7 +162,7 @@ void HDF5File::CreateMasterFile(bool masterFileWriteEnable,
if (masterFileWriteEnable && master) {
virtualfd = 0;
CreateMasterDataFile(masterFileAttributes);
CreateMasterDataFile(attr);
}
}
@ -458,7 +459,7 @@ void HDF5File::CreateDataFile() {
}
}
void HDF5File::CreateMasterDataFile(masterAttributes &masterFileAttributes) {
void HDF5File::CreateMasterDataFile(MasterAttributes *attr) {
std::ostringstream os;
os << *filePath << "/" << *fileNamePrefix << "_master"
@ -468,7 +469,6 @@ void HDF5File::CreateMasterDataFile(masterAttributes &masterFileAttributes) {
if (!(*silentMode)) {
LOG(logINFO) << "Master File: " << masterFileName;
}
masterFileAttributes.version = HDF5_WRITER_VERSION;
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
@ -485,15 +485,6 @@ void HDF5File::CreateMasterDataFile(masterAttributes &masterFileAttributes) {
masterfd = new H5File(masterFileName.c_str(), H5F_ACC_TRUNC,
FileCreatPropList::DEFAULT, flist);
// create attributes
// version
{
double dValue = masterFileAttributes.version;
DataSpace dataspace = DataSpace(H5S_SCALAR);
Attribute attribute = masterfd->createAttribute(
"version", PredType::NATIVE_DOUBLE, dataspace);
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
}
// Create a group in the file
Group group1(masterfd->createGroup("entry"));
Group group2(group1.createGroup("data"));
@ -502,309 +493,7 @@ void HDF5File::CreateMasterDataFile(masterAttributes &masterFileAttributes) {
Group group5(group3.createGroup("detector"));
Group group6(group1.createGroup("sample"));
// Dynamic Range
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"dynamic range", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.dynamicRange),
PredType::NATIVE_INT);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("bits"));
}
// Ten Giga
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
int iValue = masterFileAttributes.tenGiga;
DataSet dataset = group5.createDataSet(
"ten giga enable", PredType::NATIVE_INT, dataspace);
dataset.write(&iValue, PredType::NATIVE_INT);
}
// Image Size
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"image size", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.imageSize),
PredType::NATIVE_INT);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("bytes"));
}
// x
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"number of pixels in x axis", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.nPixelsX),
PredType::NATIVE_INT);
}
// y
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"number of pixels in y axis", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.nPixelsY),
PredType::NATIVE_INT);
}
// Maximum frames per file
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"maximum frames per file", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.maxFramesPerFile),
PredType::NATIVE_INT);
}
// Total Frames
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"total frames", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.totalFrames),
PredType::STD_U64LE);
}
// Exptime
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"exposure time", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.exptimeNs),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// SubExptime
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"sub exposure time", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.subExptimeNs),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// SubPeriod
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"sub period", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.subPeriodNs),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// Period
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"acquisition period", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.periodNs),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// Quad Enable
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"quad enable", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.quadEnable),
PredType::NATIVE_INT);
}
// Analog Flag
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"analog flag", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.analogFlag),
PredType::NATIVE_INT);
}
// Digital Flag
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"digital flag", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.digitalFlag),
PredType::NATIVE_INT);
}
// ADC Mask
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"adc mask", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.adcmask),
PredType::NATIVE_INT);
}
// Dbit Offset
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"dbit offset", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.dbitoffset),
PredType::NATIVE_INT);
}
// Dbit List
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"dbit bitset list", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.dbitlist),
PredType::STD_U64LE);
}
// Roi xmin
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"roi xmin", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.roiXmin),
PredType::NATIVE_INT);
}
// Roi xmax
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"roi xmax", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.roiXmax),
PredType::NATIVE_INT);
}
// Exptime1
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"exposure time1", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.exptime1Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// Exptime2
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"exposure time2", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.exptime2Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// Exptime3
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"exposure time3", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.exptime3Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// GateDelay1
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"gate delay1", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.gateDelay1Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// GateDelay2
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"gate delay2", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.gateDelay2Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// GateDelay3
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet(
"gate delay3", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.gateDelay3Ns),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns"));
}
// Dbit Offset
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group5.createDataSet("gates", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.gates), PredType::NATIVE_INT);
}
// Timestamp
{
time_t t = time(nullptr);
StrType strdatatype(PredType::C_S1, 256);
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group5.createDataSet("timestamp", strdatatype, dataspace);
dataset.write(std::string(ctime(&t)), strdatatype);
}
attr->WriteMasterHDF5Attributes(masterfd, &group5);
masterfd->close();
} catch (const Exception &error) {
@ -892,7 +581,7 @@ void HDF5File::CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf) {
if (H5Pset_fill_value(dcpl, GetDataTypeinC(datatype), &fill_value) < 0)
throw sls::RuntimeError(
"Could not create fill value in virtual file " + vname);
hid_t dcpl_para[parameterNames.size()];
std::vector<hid_t> dcpl_para(parameterNames.size());
for (unsigned int i = 0; i < parameterNames.size(); ++i) {
dcpl_para[i] = H5Pcreate(H5P_DATASET_CREATE);
if (dcpl_para[i] < 0)

View File

@ -51,7 +51,7 @@ class HDF5File : private virtual slsDetectorDefs, public File {
void WriteToFile(char *buffer, int bufferSize, uint64_t currentFrameNumber,
uint32_t numPacketsCaught);
void CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes);
MasterAttributes *attr) override;
void EndofAcquisition(bool anyPacketsCaught, uint64_t numImagesCaught);
private:
@ -61,7 +61,7 @@ class HDF5File : private virtual slsDetectorDefs, public File {
sls_receiver_header *rheader);
void ExtendDataset();
void CreateDataFile();
void CreateMasterDataFile(masterAttributes &masterFileAttributes);
void CreateMasterDataFile(MasterAttributes *attr);
void CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf);
void LinkVirtualInMaster(std::string fname, std::string dsetname);
hid_t GetDataTypeinC(DataType dtype);

View File

@ -4,6 +4,7 @@
#include "Fifo.h"
#include "GeneralData.h"
#include "Listener.h"
#include "MasterAttributes.h"
#include "ToString.h"
#include "ZmqSocket.h" //just for the zmq port define
#include "file_utils.h"
@ -46,6 +47,7 @@ void Implementation::DeleteMembers() {
fifo.clear();
eth.clear();
udpPortNum.clear();
rateCorrections.clear();
ctbDbitList.clear();
}
@ -905,45 +907,72 @@ void Implementation::CreateUDPSockets() {
void Implementation::SetupWriter() {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
masterAttributes attr;
attr.detectorType = myDetectorType;
attr.dynamicRange = dynamicRange;
attr.tenGiga = tengigaEnable;
attr.imageSize = generalData->imageSize;
attr.nPixelsX = generalData->nPixelsX;
attr.nPixelsY = generalData->nPixelsY;
attr.maxFramesPerFile = framesPerFile;
attr.totalFrames = numberOfTotalFrames;
attr.exptimeNs = acquisitionTime;
attr.subExptimeNs = subExpTime;
attr.subPeriodNs = subPeriod;
attr.periodNs = acquisitionPeriod;
attr.quadEnable = quadEnable;
attr.analogFlag =
std::unique_ptr<MasterAttributes> masterAttributes;
switch (myDetectorType) {
case GOTTHARD:
masterAttributes = sls::make_unique<GotthardMasterAttributes>();
break;
case JUNGFRAU:
masterAttributes = sls::make_unique<JungfrauMasterAttributes>();
break;
case EIGER:
masterAttributes = sls::make_unique<EigerMasterAttributes>();
break;
case MYTHEN3:
masterAttributes = sls::make_unique<Mythen3MasterAttributes>();
break;
case GOTTHARD2:
masterAttributes = sls::make_unique<Gotthard2MasterAttributes>();
break;
case MOENCH:
masterAttributes = sls::make_unique<MoenchMasterAttributes>();
break;
case CHIPTESTBOARD:
masterAttributes = sls::make_unique<CtbMasterAttributes>();
break;
default:
throw sls::RuntimeError(
"Unknown detector type to set up master file attributes");
}
masterAttributes->detType = myDetectorType;
masterAttributes->imageSize = generalData->imageSize;
masterAttributes->nPixels =
xy(generalData->nPixelsX, generalData->nPixelsY);
masterAttributes->maxFramesPerFile = framesPerFile;
masterAttributes->totalFrames = numberOfTotalFrames;
masterAttributes->exptime = std::chrono::nanoseconds(acquisitionTime);
masterAttributes->period = std::chrono::nanoseconds(acquisitionPeriod);
masterAttributes->dynamicRange = dynamicRange;
masterAttributes->tenGiga = tengigaEnable;
masterAttributes->subExptime = std::chrono::nanoseconds(subExpTime);
masterAttributes->subPeriod = std::chrono::nanoseconds(subPeriod);
masterAttributes->quad = quadEnable;
masterAttributes->ratecorr = rateCorrections;
masterAttributes->adcmask =
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
masterAttributes->analog =
(readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
: 0;
attr.digitalFlag =
masterAttributes->digital =
(readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
: 0;
attr.adcmask = tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
attr.dbitoffset = ctbDbitOffset;
attr.dbitlist = 0;
attr.roiXmin = roi.xmin;
attr.roiXmax = roi.xmax;
masterAttributes->dbitoffset = ctbDbitOffset;
masterAttributes->dbitlist = 0;
for (auto &i : ctbDbitList) {
attr.dbitlist |= (1 << i);
masterAttributes->dbitlist |= (1 << i);
}
attr.exptime1Ns = acquisitionTime1;
attr.exptime2Ns = acquisitionTime2;
attr.exptime3Ns = acquisitionTime3;
attr.gateDelay1Ns = gateDelay1;
attr.gateDelay2Ns = gateDelay2;
attr.gateDelay3Ns = gateDelay3;
attr.gates = numberOfGates;
masterAttributes->roi = roi;
masterAttributes->exptime1 = std::chrono::nanoseconds(acquisitionTime1);
masterAttributes->exptime2 = std::chrono::nanoseconds(acquisitionTime2);
masterAttributes->exptime3 = std::chrono::nanoseconds(acquisitionTime3);
masterAttributes->gateDelay1 = std::chrono::nanoseconds(gateDelay1);
masterAttributes->gateDelay2 = std::chrono::nanoseconds(gateDelay2);
masterAttributes->gateDelay3 = std::chrono::nanoseconds(gateDelay3);
masterAttributes->gates = numberOfGates;
try {
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->CreateNewFile(attr);
dataProcessor[i]->CreateNewFile(masterAttributes.get());
}
} catch (const sls::RuntimeError &e) {
shutDownUDPSockets();
@ -1771,6 +1800,11 @@ void Implementation::setReadNLines(const int value) {
LOG(logINFO) << "Number of Lines to readout: " << numLinesReadout;
}
void Implementation::setRateCorrections(const std::vector<int64_t> &t) {
rateCorrections = t;
LOG(logINFO) << "Rate Corrections: " << sls::ToString(rateCorrections);
}
slsDetectorDefs::readoutMode Implementation::getReadoutMode() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return readoutType;

View File

@ -211,6 +211,8 @@ class Implementation : private virtual slsDetectorDefs {
int getReadNLines() const;
/* [Eiger] */
void setReadNLines(const int value);
/* [Eiger] */
void setRateCorrections(const std::vector<int64_t> &t);
readoutMode getReadoutMode() const;
/* [Ctb] */
void setReadoutMode(const readoutMode f);
@ -336,6 +338,7 @@ class Implementation : private virtual slsDetectorDefs {
bool activated;
bool deactivatedPaddingEnable;
int numLinesReadout;
std::vector<int64_t> rateCorrections;
readoutMode readoutType;
uint32_t adcEnableMaskOneGiga;
uint32_t adcEnableMaskTenGiga;

View File

@ -0,0 +1,566 @@
#pragma once
#include "ToString.h"
#include "logger.h"
#include "sls_detector_defs.h"
#ifdef HDF5C
#include "H5Cpp.h"
#ifndef H5_NO_NAMESPACE
using namespace H5;
#endif
#endif
#include <chrono>
using ns = std::chrono::nanoseconds;
// versions
#define HDF5_WRITER_VERSION (6.1) // 1 decimal places
#define BINARY_WRITER_VERSION (6.1) // 1 decimal places
struct MasterAttributes {
slsDetectorDefs::detectorType detType{slsDetectorDefs::GENERIC};
slsDetectorDefs::timingMode timingMode{slsDetectorDefs::AUTO_TIMING};
uint32_t imageSize{0};
slsDetectorDefs::xy nPixels{};
uint32_t maxFramesPerFile{0};
uint64_t totalFrames{0};
ns exptime{0};
ns period{0};
uint32_t dynamicRange{0};
uint32_t tenGiga{0};
int threshold{0};
ns subExptime{0};
ns subPeriod{0};
uint32_t quad{0};
std::vector<int64_t> ratecorr;
uint32_t adcmask{0};
uint32_t analog{0};
uint32_t digital{0};
uint32_t dbitoffset{0};
uint64_t dbitlist{0};
slsDetectorDefs::ROI roi{};
ns exptime1{0};
ns exptime2{0};
ns exptime3{0};
ns gateDelay1{0};
ns gateDelay2{0};
ns gateDelay3{0};
uint32_t gates;
MasterAttributes(){};
virtual ~MasterAttributes(){};
virtual void WriteMasterBinaryAttributes(FILE *fd) {
LOG(logERROR) << "WriteMasterBinaryAttributes should have been called "
"by a child class";
}
std::string GetBinaryMasterAttributes() {
time_t t = time(nullptr);
std::ostringstream oss;
oss << "Version : " << std::setprecision(2)
<< BINARY_WRITER_VERSION << '\n'
<< "TimeStamp : " << ctime(&t) << '\n'
<< "Detector Type : " << sls::ToString(detType) << '\n'
<< "Timing Mode : " << sls::ToString(timingMode)
<< '\n'
<< "Image Size : " << imageSize << " bytes" << '\n'
<< "Pixels : " << sls::ToString(nPixels) << '\n'
<< "Max Frames Per File : " << maxFramesPerFile << '\n'
<< "Total Frames : " << totalFrames << '\n';
return oss.str();
};
void WriteBinaryAttributes(FILE *fd, std::string message) {
message += std::string("\n#Frame Header\n"
"Frame Number : 8 bytes\n"
"SubFrame Number/ExpLength : 4 bytes\n"
"Packet Number : 4 bytes\n"
"Bunch ID : 8 bytes\n"
"Timestamp : 8 bytes\n"
"Module Id : 2 bytes\n"
"Row : 2 bytes\n"
"Column : 2 bytes\n"
"Reserved : 2 bytes\n"
"Debug : 4 bytes\n"
"Round Robin Number : 2 bytes\n"
"Detector Type : 1 byte\n"
"Header Version : 1 byte\n"
"Packets Caught Mask : 64 bytes\n");
if (fwrite((void *)message.c_str(), 1, message.length(), fd) !=
message.length()) {
throw sls::RuntimeError(
"Master binary file incorrect number of bytes written to file");
}
};
#ifdef HDF5C
virtual void WriteMasterHDF5Attributes(H5File *fd, Group *group) {
LOG(logERROR) << "WriteMasterHdf5Attributes should have been called "
"by a child class";
};
void WriteHDF5Attributes(H5File *fd, Group *group){
// clang-format off
// version
{
double version = BINARY_WRITER_VERSION;
DataSpace dataspace = DataSpace(H5S_SCALAR);
Attribute attribute = fd->createAttribute(
"version", PredType::NATIVE_DOUBLE, dataspace);
attribute.write(PredType::NATIVE_DOUBLE, &version);
}
// timestamp
{
time_t t = time(nullptr);
StrType strdatatype(PredType::C_S1, 256);
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group->createDataSet("timestamp", strdatatype, dataspace);
dataset.write(std::string(ctime(&t)), strdatatype);
}
// detector type
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("detector type", strdatatype, dataspace);
dataset.write(sls::ToString(detType), strdatatype);
}
// timing mode
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("timing mode", strdatatype, dataspace);
dataset.write(sls::ToString(timingMode), strdatatype);
}
// Image Size
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"image size", PredType::NATIVE_INT, dataspace);
dataset.write(&imageSize, PredType::NATIVE_INT);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("bytes"));
}
//TODO: make this into an array?
// x
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"number of pixels in x axis", PredType::NATIVE_INT, dataspace);
dataset.write(&nPixels.x, PredType::NATIVE_INT);
}
// y
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"number of pixels in y axis", PredType::NATIVE_INT, dataspace);
dataset.write(&nPixels.y, PredType::NATIVE_INT);
}
// Maximum frames per file
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"maximum frames per file", PredType::NATIVE_INT, dataspace);
dataset.write(&maxFramesPerFile, PredType::NATIVE_INT);
}
// Total Frames
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"total frames", PredType::STD_U64LE, dataspace);
dataset.write(&totalFrames, PredType::STD_U64LE);
}
};
void WriteHDF5Exptime(H5File *fd, Group *group) {
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("exposure time", strdatatype, dataspace);
dataset.write(sls::ToString(exptime), strdatatype);
};
void WriteHDF5Period(H5File *fd, Group *group) {
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("acquisition period", strdatatype, dataspace);
dataset.write(sls::ToString(period), strdatatype);
};
void WriteHDF5DynamicRange(H5File *fd, Group *group) {
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"dynamic range", PredType::NATIVE_INT, dataspace);
dataset.write(&dynamicRange, PredType::NATIVE_INT);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("bits"));
};
void WriteHDF5TenGiga(H5File *fd, Group *group) {
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"ten giga enable", PredType::NATIVE_INT, dataspace);
dataset.write(&tenGiga, PredType::NATIVE_INT);
};
#endif
};
// clang-format on
class GotthardMasterAttributes : public MasterAttributes {
public:
GotthardMasterAttributes(){};
void WriteMasterBinaryAttributes(FILE *fd) override {
std::ostringstream oss;
oss << MasterAttributes::GetBinaryMasterAttributes()
<< "Exptime : " << sls::ToString(exptime) << '\n'
<< "Period : " << sls::ToString(period) << '\n'
<< "Roi (xmin, xmax) : " << sls::ToString(roi) << '\n';
std::string message = oss.str();
MasterAttributes::WriteBinaryAttributes(fd, message);
};
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override {
MasterAttributes::WriteHDF5Attributes(fd, group);
MasterAttributes::WriteHDF5Exptime(fd, group);
MasterAttributes::WriteHDF5Period(fd, group);
// Roi xmin
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"roi xmin", PredType::NATIVE_INT, dataspace);
dataset.write(&roi.xmin, PredType::NATIVE_INT);
}
// Roi xmax
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"roi xmax", PredType::NATIVE_INT, dataspace);
dataset.write(&roi.xmax, PredType::NATIVE_INT);
}
};
#endif
};
class JungfrauMasterAttributes : public MasterAttributes {
public:
JungfrauMasterAttributes(){};
void WriteMasterBinaryAttributes(FILE *fd) override {
std::ostringstream oss;
oss << MasterAttributes::GetBinaryMasterAttributes()
<< "Exptime : " << sls::ToString(exptime) << '\n'
<< "Period : " << sls::ToString(period) << '\n';
std::string message = oss.str();
MasterAttributes::WriteBinaryAttributes(fd, message);
};
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override {
MasterAttributes::WriteHDF5Attributes(fd, group);
MasterAttributes::WriteHDF5Exptime(fd, group);
MasterAttributes::WriteHDF5Period(fd, group);
};
#endif
};
class EigerMasterAttributes : public MasterAttributes {
public:
EigerMasterAttributes(){};
void WriteMasterBinaryAttributes(FILE *fd) override {
std::ostringstream oss;
oss << MasterAttributes::GetBinaryMasterAttributes()
<< "Dynamic Range : " << dynamicRange << '\n'
<< "Ten Giga : " << tenGiga << '\n'
<< "Exptime : " << sls::ToString(exptime) << '\n'
<< "Period : " << sls::ToString(period) << '\n'
<< "SubExptime : " << sls::ToString(subExptime)
<< '\n'
<< "SubPeriod : " << sls::ToString(subPeriod)
<< '\n'
<< "Quad : " << quad << '\n'
<< "Rate Corrections : " << sls::ToString(ratecorr)
<< '\n';
std::string message = oss.str();
MasterAttributes::WriteBinaryAttributes(fd, message);
};
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override {
MasterAttributes::WriteHDF5Attributes(fd, group);
MasterAttributes::WriteHDF5DynamicRange(fd, group);
MasterAttributes::WriteHDF5TenGiga(fd, group);
MasterAttributes::WriteHDF5Exptime(fd, group);
MasterAttributes::WriteHDF5Period(fd, group);
// threshold
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"threshold", PredType::NATIVE_INT, dataspace);
dataset.write(&threshold, PredType::NATIVE_INT);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("eV"));
}
// SubExptime
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset = group->createDataSet("sub exposure time",
strdatatype, dataspace);
dataset.write(sls::ToString(subExptime), strdatatype);
}
// SubPeriod
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("sub period", strdatatype, dataspace);
dataset.write(sls::ToString(subPeriod), strdatatype);
}
// Quad
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group->createDataSet("quad", PredType::NATIVE_INT, dataspace);
dataset.write(&quad, PredType::NATIVE_INT);
}
// Rate corrections
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset = group->createDataSet("rate corrections",
strdatatype, dataspace);
dataset.write(sls::ToString(ratecorr), strdatatype);
}
};
#endif
};
class Mythen3MasterAttributes : public MasterAttributes {
public:
Mythen3MasterAttributes(){};
void WriteMasterBinaryAttributes(FILE *fd) override {
std::ostringstream oss;
oss << MasterAttributes::GetBinaryMasterAttributes()
<< "Dynamic Range : " << dynamicRange << '\n'
<< "Ten Giga : " << tenGiga << '\n'
<< "Period : " << sls::ToString(period) << '\n'
<< "Exptime1 : " << sls::ToString(exptime1)
<< '\n'
<< "Exptime2 : " << sls::ToString(exptime2)
<< '\n'
<< "Exptime3 : " << sls::ToString(exptime3)
<< '\n'
<< "GateDelay1 : " << sls::ToString(gateDelay1)
<< '\n'
<< "GateDelay2 : " << sls::ToString(gateDelay2)
<< '\n'
<< "GateDelay3 : " << sls::ToString(gateDelay3)
<< '\n'
<< "Gates : " << gates << '\n';
std::string message = oss.str();
MasterAttributes::WriteBinaryAttributes(fd, message);
};
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override {
MasterAttributes::WriteHDF5Attributes(fd, group);
MasterAttributes::WriteHDF5DynamicRange(fd, group);
MasterAttributes::WriteHDF5TenGiga(fd, group);
MasterAttributes::WriteHDF5Period(fd, group);
// Exptime1
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("exposure time1", strdatatype, dataspace);
dataset.write(sls::ToString(exptime1), strdatatype);
}
// Exptime2
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("exposure time2", strdatatype, dataspace);
dataset.write(sls::ToString(exptime2), strdatatype);
}
// Exptime3
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("exposure time3", strdatatype, dataspace);
dataset.write(sls::ToString(exptime3), strdatatype);
}
// GateDelay1
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("gate delay1", strdatatype, dataspace);
dataset.write(sls::ToString(gateDelay1), strdatatype);
}
// GateDelay2
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("gate delay2", strdatatype, dataspace);
dataset.write(sls::ToString(gateDelay2), strdatatype);
}
// GateDelay3
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256);
DataSet dataset =
group->createDataSet("gate delay3", strdatatype, dataspace);
dataset.write(sls::ToString(gateDelay3), strdatatype);
}
// Gates
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset =
group->createDataSet("gates", PredType::STD_U32LE, dataspace);
dataset.write(&gates, PredType::STD_U64LE);
}
};
#endif
};
class Gotthard2MasterAttributes : public MasterAttributes {
public:
Gotthard2MasterAttributes(){};
void WriteMasterBinaryAttributes(FILE *fd) override {
std::ostringstream oss;
oss << MasterAttributes::GetBinaryMasterAttributes()
<< "Exptime : " << sls::ToString(exptime) << '\n'
<< "Period : " << sls::ToString(period) << '\n';
std::string message = oss.str();
MasterAttributes::WriteBinaryAttributes(fd, message);
};
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override {
MasterAttributes::WriteHDF5Attributes(fd, group);
MasterAttributes::WriteHDF5Exptime(fd, group);
MasterAttributes::WriteHDF5Period(fd, group);
};
#endif
};
class MoenchMasterAttributes : public MasterAttributes {
public:
MoenchMasterAttributes(){};
void WriteMasterBinaryAttributes(FILE *fd) override {
std::ostringstream oss;
oss << MasterAttributes::GetBinaryMasterAttributes()
<< "Exptime : " << sls::ToString(exptime) << '\n'
<< "Period : " << sls::ToString(period) << '\n'
<< "Ten Giga : " << tenGiga << '\n'
<< "ADC Mask : " << sls::ToStringHex(adcmask)
<< '\n';
std::string message = oss.str();
MasterAttributes::WriteBinaryAttributes(fd, message);
};
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override {
MasterAttributes::WriteHDF5Attributes(fd, group);
MasterAttributes::WriteHDF5Exptime(fd, group);
MasterAttributes::WriteHDF5Period(fd, group);
MasterAttributes::WriteHDF5TenGiga(fd, group);
// ADC Mask
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"adc mask", PredType::NATIVE_INT, dataspace);
dataset.write(&adcmask, PredType::NATIVE_INT);
}
};
#endif
};
class CtbMasterAttributes : public MasterAttributes {
public:
CtbMasterAttributes(){};
void WriteMasterBinaryAttributes(FILE *fd) override {
std::ostringstream oss;
oss << MasterAttributes::GetBinaryMasterAttributes()
<< "Exptime : " << sls::ToString(exptime) << '\n'
<< "Period : " << sls::ToString(period) << '\n'
<< "Ten Giga : " << tenGiga << '\n'
<< "ADC Mask : " << sls::ToStringHex(adcmask)
<< '\n'
<< "Analog Flag : " << analog << '\n'
<< "Digital Flag : " << digital << '\n'
<< "Dbit Offset : " << dbitoffset << '\n'
<< "Dbit Bitset : " << dbitlist << '\n';
std::string message = oss.str();
MasterAttributes::WriteBinaryAttributes(fd, message);
};
#ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override {
MasterAttributes::WriteHDF5Attributes(fd, group);
MasterAttributes::WriteHDF5Exptime(fd, group);
MasterAttributes::WriteHDF5Period(fd, group);
MasterAttributes::WriteHDF5TenGiga(fd, group);
// ADC Mask
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"adc mask", PredType::NATIVE_INT, dataspace);
dataset.write(&adcmask, PredType::NATIVE_INT);
}
// Analog Flag
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"analog flag", PredType::NATIVE_INT, dataspace);
dataset.write(&analog, PredType::NATIVE_INT);
}
// Digital Flag
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"digital flag", PredType::NATIVE_INT, dataspace);
dataset.write(&digital, PredType::NATIVE_INT);
}
// Dbit Offset
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"dbit offset", PredType::NATIVE_INT, dataspace);
dataset.write(&dbitoffset, PredType::NATIVE_INT);
}
// Dbit List
{
DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group->createDataSet(
"dbit bitset list", PredType::STD_U64LE, dataspace);
dataset.write(&dbitlist, PredType::STD_U64LE);
}
};
#endif
};

View File

@ -39,10 +39,6 @@
// hdf5
#define MAX_CHUNKED_IMAGES (1)
// versions
#define HDF5_WRITER_VERSION (6.0) // 1 decimal places
#define BINARY_WRITER_VERSION (6.0) // 1 decimal places
// parameters to calculate fifo depth
#define SAMPLE_TIME_IN_NS (100000000) // 100ms
#define MAX_EIGER_ROWS_PER_READOUT (256)
@ -56,34 +52,3 @@
#define PROCESSOR_PRIORITY (70)
#define STREAMER_PRIORITY (10)
#define TCP_PRIORITY (10)
struct masterAttributes {
double version;
uint32_t detectorType;
uint32_t dynamicRange;
uint32_t tenGiga;
uint32_t imageSize;
uint32_t nPixelsX;
uint32_t nPixelsY;
uint32_t maxFramesPerFile;
uint64_t totalFrames;
uint64_t exptimeNs;
uint64_t subExptimeNs;
uint64_t subPeriodNs;
uint64_t periodNs;
uint32_t quadEnable;
uint32_t analogFlag;
uint32_t digitalFlag;
uint32_t adcmask;
uint32_t dbitoffset;
uint64_t dbitlist;
uint32_t roiXmin;
uint32_t roiXmax;
uint64_t exptime1Ns;
uint64_t exptime2Ns;
uint64_t exptime3Ns;
uint64_t gateDelay1Ns;
uint64_t gateDelay2Ns;
uint64_t gateDelay3Ns;
uint32_t gates;
};

View File

@ -39,6 +39,8 @@ std::string ToString(const std::vector<defs::dacIndex> &vec);
std::string ToString(const defs::burstMode s);
std::string ToString(const defs::timingSourceType s);
std::string ToString(const slsDetectorDefs::xy &coord);
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord);
std::string ToString(const slsDetectorDefs::ROI &roi);
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::ROI &roi);
std::string ToString(const slsDetectorDefs::rxParameters &r);

View File

@ -160,6 +160,8 @@ class slsDetectorDefs {
struct ROI {
int xmin{-1};
int xmax{-1};
ROI() = default;
ROI(int xmin, int xmax) : xmin(xmin), xmax(xmax){};
} __attribute__((packed));
#else
typedef struct {

View File

@ -309,6 +309,7 @@ enum detFuncs {
F_GET_RECEIVER_THREAD_IDS,
F_GET_RECEIVER_STREAMING_START_FNUM,
F_SET_RECEIVER_STREAMING_START_FNUM,
F_SET_RECEIVER_RATE_CORRECT,
NUM_REC_FUNCTIONS
};
@ -617,9 +618,9 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_RECEIVER_NUM_GATES: return "F_SET_RECEIVER_NUM_GATES";
case F_SET_RECEIVER_GATE_DELAY: return "F_SET_RECEIVER_GATE_DELAY";
case F_GET_RECEIVER_THREAD_IDS: return "F_GET_RECEIVER_THREAD_IDS";
case F_GET_RECEIVER_STREAMING_START_FNUM: return "F_GET_RECEIVER_STREAMING_START_FNUM";
case F_SET_RECEIVER_STREAMING_START_FNUM: return "F_SET_RECEIVER_STREAMING_START_FNUM";
case F_SET_RECEIVER_RATE_CORRECT: return "F_SET_RECEIVER_RATE_CORRECT";
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function";

View File

@ -3,6 +3,16 @@
namespace sls {
std::string ToString(const slsDetectorDefs::xy &coord) {
std::ostringstream oss;
oss << '[' << coord.x << ", " << coord.y << ']';
return oss.str();
}
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord) {
return os << ToString(coord);
}
std::string ToString(const slsDetectorDefs::ROI &roi) {
std::ostringstream oss;
oss << '[' << roi.xmin << ", " << roi.xmax << ']';
@ -492,7 +502,7 @@ std::string ToString(const defs::dacIndex s) {
case defs::TRIMBIT_SCAN:
return std::string("trimbit_scan");
case defs::HIGH_VOLTAGE:
return std::string("vhighvoltage");
return std::string("highvoltage");
case defs::IO_DELAY:
return std::string("iodelay");
default:
@ -850,7 +860,7 @@ template <> defs::dacIndex StringTo(const std::string &s) {
return defs::IBIAS_SFP;
if (s == "trimbit_scan")
return defs::TRIMBIT_SCAN;
if (s == "vhighvoltage")
if (s == "highvoltage")
return defs::HIGH_VOLTAGE;
if (s == "iodelay")
return defs::IO_DELAY;

View File

@ -221,13 +221,13 @@ TEST_CASE("Detector type") {
}
TEST_CASE("Formatting slsDetectorDefs::ROI") {
slsDetectorDefs::ROI roi{5, 159};
slsDetectorDefs::ROI roi(5, 159);
REQUIRE(ToString(roi) == "[5, 159]");
}
TEST_CASE("Streaming of slsDetectorDefs::ROI") {
using namespace sls;
slsDetectorDefs::ROI roi{-10, 1};
slsDetectorDefs::ROI roi(-10, 1);
std::ostringstream oss;
oss << roi;
REQUIRE(oss.str() == "[-10, 1]");