mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-14 22:07:12 +02:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
f761046bfc | |||
1a859b83db | |||
70bfc875a6 | |||
c0755308a4 | |||
ab5509e10c | |||
004cb26646 | |||
a4f47a5945 | |||
312f3f473d | |||
5871086cd6 | |||
6a0fe823b3 | |||
5912aae53e | |||
8833ccf5cc | |||
77c558a7be | |||
378fc301b8 | |||
87d6e16090 | |||
2ef021041c | |||
574127b5ac |
@ -2,7 +2,7 @@
|
|||||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||||
cmake_minimum_required(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.12)
|
||||||
project(slsDetectorPackage)
|
project(slsDetectorPackage)
|
||||||
set(PROJECT_VERSION 7.0.0)
|
set(PROJECT_VERSION 7.0.2)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
|
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
|
||||||
|
|
||||||
|
951
RELEASE.txt
951
RELEASE.txt
@ -1,935 +1,78 @@
|
|||||||
SLS Detector Package Major Release 7.0.0 released on 24.02.2023
|
SLS Detector Package Major Release 7.0.2 released on 12.07.2023
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
This document describes the differences between v7.0.0 and v6.1.2
|
This document describes the differences between v7.0.2 and v7.0.1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CONTENTS
|
CONTENTS
|
||||||
--------
|
--------
|
||||||
1 New, Changed or Resolved Features
|
1 Resolved Issues
|
||||||
1.1 Compilation
|
2 On-board Detector Server Compatibility
|
||||||
1.2 Callback
|
3 Firmware Requirements
|
||||||
1.3 Python
|
4 Kernel Requirements
|
||||||
1.4 Client
|
5 Download, Documentation & Support
|
||||||
1.5 Detector Server
|
|
||||||
1.6 Simulator
|
|
||||||
1.7 Receiver
|
|
||||||
1.8 Gui
|
|
||||||
2 On-board Detector Server Compatibility
|
|
||||||
3 Firmware Requirements
|
|
||||||
4 Kernel Requirements
|
|
||||||
5 Download, Documentation & Support
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1 Resolved Issues
|
||||||
1 New, Changed or Resolved Features
|
=================
|
||||||
=====================================
|
|
||||||
|
|
||||||
|
|
||||||
1.1 Compilation
|
Firmware
|
||||||
==================
|
|
||||||
|
|
||||||
|
|
||||||
General:
|
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
* [Jungfrau] Stopping acquisition in sync mode
|
||||||
|
Previously, stopping acquisition in sync mode would result in the slave
|
||||||
|
status remaining in Running status for next acquisition and framesl (frames
|
||||||
|
left) would be stuck from the previous acquisition. This is fixed in firmware.
|
||||||
|
|
||||||
* Custom location to find ZeroMQ
|
|
||||||
Option to provide a custom location to look for ZeroMQ, if not found
|
|
||||||
using FindZeroMQ.cmake
|
|
||||||
|
|
||||||
For example, to use the system installed zmq:
|
|
||||||
Using cmake: -DZeroMQ_HINT=/usr/lib64
|
|
||||||
Using cmk.sh script: -q /usr/lib64
|
|
||||||
|
|
||||||
|
Detector Server
|
||||||
|
---------------
|
||||||
|
|
||||||
* Support external build
|
* [Jungfrau] Changing master to slave in sync mode
|
||||||
Assuming already installed version of the slsDetectorPacakge exists,
|
When in sync mode, changing from master to slave would change the status
|
||||||
external build of python bindings, gui, ctbgui and moench has been added.
|
to Running in firmware. A workaround in the detector server fixes this.
|
||||||
|
|
||||||
|
* [Jungfrau] Row and column for multi module Jungfrau
|
||||||
|
This mainly affected only the GUI, unless one was using the row and column
|
||||||
|
sent out by the detector. Row and column values were mixed up, but fixed now.
|
||||||
|
|
||||||
* Catch updated to latest 2.x version due to build failure in fedora
|
* [Jungfrau] Timing in sync mode
|
||||||
|
When sync is enabled, setting or getting timing would give an error. This
|
||||||
|
is fixed now.
|
||||||
|
|
||||||
|
|
||||||
|
Client
|
||||||
Gui:
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
* Qt5 and in-built compressed Qwt 6.1.5
|
|
||||||
Ported from Qt4 to Qt5. Minimum requirement: Qt 5.9
|
|
||||||
Compressed Qwt 6.1.5 added into the package in libs. It is unpacked and built
|
|
||||||
as a static library.This allows us to remove qwt as an external dependency
|
|
||||||
and reduces the risk of picking up the wrong version.
|
|
||||||
|
|
||||||
|
|
||||||
Python:
|
|
||||||
-------
|
|
||||||
|
|
||||||
|
|
||||||
* Install python extension
|
|
||||||
Option to copy the python extension (slsdet folder and _slsdet-..so)
|
|
||||||
to CMAKE_INSTALL_PREFIX/python using
|
|
||||||
-DSLS_INSTALL_PYTHONEXT
|
|
||||||
|
|
||||||
|
|
||||||
* Pybind11 (v2.10.0)
|
|
||||||
Pybind11 is removed as a submodule and instead built into package to
|
|
||||||
simplify for users. Now, there is no more need to clone with the '--recursive'
|
|
||||||
argument or to update submodule when switching to this package version
|
|
||||||
and above.
|
|
||||||
|
|
||||||
|
|
||||||
* Conda packages
|
|
||||||
Removed conda packages for python 3.6 and 3.7. Added for python 3.11.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1.2 Callback
|
|
||||||
=============
|
|
||||||
|
|
||||||
|
|
||||||
* Datatype of Metadata [registerCallBackRawDataReady,
|
|
||||||
registerCallBackRawDataModifyReady]
|
|
||||||
Datatype changed from char* to sls_receiver_header.
|
|
||||||
|
|
||||||
|
|
||||||
* Datatype of Size [registerCallBackRawDataReady,
|
|
||||||
registerCallBackRawDataModifyReady]
|
|
||||||
Datatype changed from uint32_t to size_t
|
|
||||||
|
|
||||||
|
|
||||||
* Datatype of file name and file path [registerCallBackStartAcquisition]
|
|
||||||
Datatype changed from string to const string reference.
|
|
||||||
|
|
||||||
|
|
||||||
* Incorrect image size [registerCallBackStartAcquisition]
|
|
||||||
Fixed. It used to give +120 bytes.
|
|
||||||
|
|
||||||
|
|
||||||
* [Gotthard2] 25um Image reconstruction for 2 modules
|
|
||||||
First module (master) interleaves with second modules(slave). First channel
|
|
||||||
of master is first channel of detector.
|
|
||||||
|
|
||||||
Requires firmware update to reverse channels of slaves.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1.3 Python
|
|
||||||
===========
|
|
||||||
|
|
||||||
|
|
||||||
* Python sub-microsecond resolution
|
|
||||||
Reading back sub-microsecond exposure times from the Python API fixed by
|
|
||||||
addig Python datetime supports only micro seconds as lowest unit.
|
|
||||||
|
|
||||||
This is fixed by introducing a new C++ type (DurationWrapper), which
|
|
||||||
holds number of nanoseconds as a uint64_t (only in python bindings) and
|
|
||||||
custom typecaster to convert to and from std::chrono::nanoseconds.
|
|
||||||
|
|
||||||
A get using API now returns in DurationWrapper, instead of datetime.
|
|
||||||
Refer exptime help for examples.
|
|
||||||
|
|
||||||
|
|
||||||
* Defines in sls_detector_defs
|
|
||||||
sls_detetor_defs parsed and #defines extracted into defines.py
|
|
||||||
For exmaple, one can use slsdet.LOCALHOST_IP
|
|
||||||
|
|
||||||
|
|
||||||
* Concatenated hostnames
|
|
||||||
Hostnames concatenated using '+' was not split up in Python API. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* Added many commands to python API
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1.4 Client
|
|
||||||
===========
|
|
||||||
|
|
||||||
|
|
||||||
Breaking API:
|
|
||||||
-------------
|
|
||||||
|
|
||||||
|
|
||||||
* Versioning
|
|
||||||
The client, receiver and detector servers now have semantic Versioning
|
|
||||||
along with the date and are managed with the Version class.
|
|
||||||
|
|
||||||
--version argument to the executable gives the complete versioning with date.
|
|
||||||
|
|
||||||
Using the client to get versions gives only the semantic version. An older
|
|
||||||
server will still give date. Hence, the return type is a string, breaking API.
|
|
||||||
|
|
||||||
Compatibility checks at hostname or rx_hostname command will only be for
|
|
||||||
backwards compatibility (ie. it only checks for the major version number).
|
|
||||||
If its an old server, then its expected to have the exact same date (as
|
|
||||||
before)
|
|
||||||
|
|
||||||
Setting intitialchecks to 0 also bypasses the receiver compatibility check.
|
|
||||||
|
|
||||||
|
|
||||||
* Detector Specific fields
|
|
||||||
bunchid ->detSpec1
|
|
||||||
reserved->detSpec2
|
|
||||||
debug->detSpec3
|
|
||||||
roundRnumber->detSpec4
|
|
||||||
|
|
||||||
Header version number stays the same in the UDP header as there is no
|
|
||||||
difference in the format from the detector. Only the structure memeber names
|
|
||||||
have changed in sls_detector_defs.h
|
|
||||||
|
|
||||||
Further details about each detector specific field can be found at:
|
|
||||||
https://slsdetectorgroup.github.io/devdoc/udpdetspec.html
|
|
||||||
|
|
||||||
|
|
||||||
* Namespace sls
|
|
||||||
All files in slsSupportLib and tests have now been moved to sls namespace
|
|
||||||
including macros. Using the LOG, for example, will require the sls qualifier.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger] Number of UDP interfaces
|
|
||||||
Command line: numinterfaces, API: getNumberofUDPInterfaces
|
|
||||||
This command now reflects the actual number of udp interfaces for Eiger,
|
|
||||||
which is 2.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger][Jungfrau] Row column
|
|
||||||
[Jungfrau] Fixed row column indexing for multi module 2 interfaces
|
|
||||||
|
|
||||||
[Eiger] The row indicies were switched across the Y axis for the callback
|
|
||||||
only for Eiger. This is now changed and kept similar to the other detectors.
|
|
||||||
The row indices would be in the order of the half modules in the hostname
|
|
||||||
command. Therefore, to keep the image from callback, invert the hostname
|
|
||||||
order in the config file.
|
|
||||||
|
|
||||||
* Deprecated CopyDetectorServer
|
|
||||||
Command line: copydetectorserver, API: copydetectorserver
|
|
||||||
Removed. Use updatedetectorserver
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger][Jugfrau][Mythen3] Deprecated specific transmission delay commands
|
|
||||||
txndelay_frame -> txdelay_frame
|
|
||||||
txndelay_left -> txdelay_left
|
|
||||||
txndelay_right -> txdelay_right
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger] Datastream only for 10GbE
|
|
||||||
Command line: datastream, API: getDataStream/ setDataStream
|
|
||||||
|
|
||||||
This command to enable/ disable data stream from left or right port
|
|
||||||
is now allowed only for 10GbE. Previously, it incorrectly allowed to do so.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger][Jungfrau][Moench][Ctb] Stop command effect on next frame number
|
|
||||||
Stopping acquisition sometimes results in different next frame numbers
|
|
||||||
for different moduels. Hence, after a stop, if the next frame numbers are
|
|
||||||
different, they are all set to their maximum value + 1.
|
|
||||||
|
|
||||||
|
|
||||||
* Missing packets
|
|
||||||
Command line: rx_missingpackets, API: getNumMissingPackets
|
|
||||||
This now returns a signed 64 bit instead of unsigned. The negative polarity
|
|
||||||
depicts extra packets instead of missing packets and also takes care of
|
|
||||||
disabled ports.
|
|
||||||
|
|
||||||
|
|
||||||
* Frames caught and frame index
|
|
||||||
Command line rx_framescaught, rx_frameindex, API: getFramesCaught/ getRxCurrentFrameIndex
|
|
||||||
They now return a vector for each port when there are 2 udp interfaces
|
|
||||||
in the receiver.
|
|
||||||
|
|
||||||
|
|
||||||
* [Gotthard][Gotthard2] Num modules
|
|
||||||
Only 2 modules allowed maximum in a detector shared memory.
|
|
||||||
|
|
||||||
|
|
||||||
* [Moench][Ctb][Mythen3] Deprecated commands
|
|
||||||
Patloopx, patnloopx, patwaitx, patwaittimex
|
|
||||||
Please use instead patloop, patnloop, patwait and patwaittime commands
|
|
||||||
with the level as an argument.
|
|
||||||
|
|
||||||
Old commands work with warning, but the server expects the new ones
|
|
||||||
such as a default pattern file to be loaded at startup for Moench.
|
|
||||||
|
|
||||||
Renamed patternParameters struct member from 'loop' to 'startloop' and
|
|
||||||
'stoploop'.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Clock Divider 4 and 5
|
|
||||||
Cannot be set anymore. Only read back.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
New commands:
|
|
||||||
-------------
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger][Gotthard][Gotthard2][Mythen3][Jungfrau] Master
|
|
||||||
|
|
||||||
Setting up from client:
|
|
||||||
[Eiger][Gotthard2][Jungfrau]
|
|
||||||
Command line: master, API: getMaster/ setMaster
|
|
||||||
All of them can get master mode from the client.
|
|
||||||
|
|
||||||
This can also be set up on the detector server. Please refer to notes
|
|
||||||
on that section.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger] Top
|
|
||||||
Command line: top, API: getTop/ setTop
|
|
||||||
Sets the half module to top or bottom from the client.
|
|
||||||
|
|
||||||
This can also be set up on the detector server. Please refer to notes
|
|
||||||
on that section.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3][Eiger] Save settings file
|
|
||||||
Command line: trimbits (sls_detector_get), API: saveTrimbits
|
|
||||||
Added
|
|
||||||
|
|
||||||
|
|
||||||
* [Gotthard2] Parallel readout added
|
|
||||||
Command line: parallel, API: getParallelMode/ setParallelMode
|
|
||||||
Default for Gotthard2 is parallel. Non parallel mode only works in
|
|
||||||
continuous mode.
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau] Software trigger added
|
|
||||||
Command line: trigger, API: sendSoftwareTrigger
|
|
||||||
Send software trigger instead of harware trigger.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger][Jungfrau] Blocking trigger
|
|
||||||
Commandline: blockingtrigger, API: sendSoftwareTrigger with argument true
|
|
||||||
Sends software trigger signal to detector and blocks until the frames
|
|
||||||
are sent out for that trigger.
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau] Sync
|
|
||||||
Command line: sync, API: getSynchronization/ setSynchronization
|
|
||||||
Enables or disables synchronization between modules
|
|
||||||
|
|
||||||
|
|
||||||
* [Gotthard2][Mythen3] Temperature readout
|
|
||||||
Command line: temp_fpga, API: getTemperature with TEMPERATURE_FPGA enum
|
|
||||||
Added
|
|
||||||
|
|
||||||
|
|
||||||
* [Gotthard2][Mythen3] Round robin added
|
|
||||||
Command line: udp_dstlist, API: getDestinationUDPList/ setDestinationUDPList
|
|
||||||
Command line: udp_numdst, API: getNumberofUDPDestinations
|
|
||||||
One can set up to 32 (64 for Mythen3) entries in the destination list.
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau] Module Id
|
|
||||||
Command line: moduleid, API: getModuleId
|
|
||||||
16 bit value (ideally unique) that is streamed out in the udp header of
|
|
||||||
the detector. The on-board detector server picks it up from a file
|
|
||||||
(if it exists) called detid_jungfrau.txt.
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau][[Gotthard2][Myhten3][Gotthard][Ctb][Moench] Hardware version
|
|
||||||
Command line: hardwareversion, API: getHardwareVersion
|
|
||||||
Gets the board or hardware version.
|
|
||||||
For example, Jungfrau returns 1.0 or 2.0.
|
|
||||||
It is also printed at on-board detector server start up.
|
|
||||||
Also printed before starting FPGA programming.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger][Jugfrau][Mythen3] Transmission Delay
|
|
||||||
Command line: tx_delay, API: getTransmissionDelay/ setTransmissionDelay
|
|
||||||
Sets transmission delay for all modules in the detector using the step
|
|
||||||
size provided. Sets up for every module:
|
|
||||||
[Eiger] txdelay_left to (2 * mod_index * n_delay)
|
|
||||||
[Eiger] txdelay_right to ((2 * mod_index + 1) * n_delay)
|
|
||||||
[Eiger] txdelay_frame to (2 *num_modules * n_delay)
|
|
||||||
[Jungfrau][Mythen3] txdelay_frame to (num_modules * n_delay)
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Bad channels
|
|
||||||
Command line: badchannels, API: getBadChannels/ setBadChannels
|
|
||||||
Set bad channels from file with a list of channels, which will be masked
|
|
||||||
out. Also does trimming. A detector level command will require the channel
|
|
||||||
numbers accordingly. The file and the command line is also extended to
|
|
||||||
include commas, colons range and removes duplicates.
|
|
||||||
|
|
||||||
API allows badchannels as a 2D vector (for every module) or
|
|
||||||
a 1D vector with positions.
|
|
||||||
|
|
||||||
Command line: Setting it to "none" or "0" will reset all the bad channels.
|
|
||||||
API: Empty vector will reset all the bad channels.
|
|
||||||
|
|
||||||
|
|
||||||
* [Moench][Ctb] Starting frame number
|
|
||||||
Command line: nextframenumber, API: getNextFrameNumber/ setNextFrameNumber
|
|
||||||
Added and default set up on detector server start up.
|
|
||||||
|
|
||||||
|
|
||||||
* [Ctb] DAC names
|
|
||||||
Command line: daclist, API: getDacNames/ setDacNames
|
|
||||||
Can set and get dac names in the dac list now.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Polarity, interpolation, pump probe, analog pulsing, digital pulsing
|
|
||||||
Command line: polarity, interpolation, pumpprobe, apulse, dpulse
|
|
||||||
API: getPolarity/ setPolarity, getInterpolation/ setInterpolation,
|
|
||||||
getPumpProbe/ setPumpProbe, getAnalogPulsing/ setAnalogPulsing,
|
|
||||||
getDigitalPulsing/ setDigitalPulsing
|
|
||||||
|
|
||||||
Added these commands.
|
|
||||||
|
|
||||||
Enabling interpolation will also enable all counters and disable vth3.
|
|
||||||
Disabling sets to previous counter mask and previous vth values.
|
|
||||||
|
|
||||||
In pump probe mode, only vth2 enabled. Disabling sets vth2 to prevevious
|
|
||||||
value.
|
|
||||||
|
|
||||||
Setting counter mask will check interpolation and pump probe mode
|
|
||||||
requirements, else sets vthx dacs according to counter mask.
|
|
||||||
|
|
||||||
Direct overwrite of any dac (including vthx) allowed using dac command
|
|
||||||
(as before).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
New commands for Receiver only:
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
* Arping for 10GbE
|
|
||||||
Command line: rx_arping API: getRxArping/ setRxArping
|
|
||||||
Starts a thread in the receiver to arping the interface it is listening
|
|
||||||
to in 10GbE mode every 60 s.
|
|
||||||
Changes NUM_RX_THREAD_IDS (sls_detector_defs.h) from 8 to 9.
|
|
||||||
|
|
||||||
|
|
||||||
* Receiver Region of Interest
|
|
||||||
Command line: rx_roi, API: getRxROI/ setRxROI
|
|
||||||
Command line: rx_clearroi, API: clearRxROI
|
|
||||||
One can set an ROI in the receiver to write to file. 1D detectors can set
|
|
||||||
xmin and xmax, whereas the 2D can also set ymin and ymax. -1 values signify
|
|
||||||
no ROI.
|
|
||||||
|
|
||||||
This is not at network level and can only be used to reduce size of file.
|
|
||||||
Virtual HDF5 files not created when this is enabled and also no link in
|
|
||||||
master file. No file created if module not in ROI.
|
|
||||||
|
|
||||||
There can only be one ROI per detector. Therefore, can be set only at
|
|
||||||
detector level, but can be retrieved at module level as well.
|
|
||||||
|
|
||||||
The GUI still shows the entire image, but has a yellow border around the
|
|
||||||
ROI. Status bar displays a message when Rx ROI enabled.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Additonal Features:
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
|
|
||||||
* Non-blocking start
|
|
||||||
Allowing non-blocking start at modular level again.
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau][Moench][Ctb] Additional programming checks
|
|
||||||
Also checks if the drive to write to is a special file or a normal
|
|
||||||
file. If its a normal file, it throws asking to redo the command with a
|
|
||||||
'--please-delete' argument to delete the normal file and create the device
|
|
||||||
drive and restart FPGA programming.
|
|
||||||
|
|
||||||
More readable error message insetad of "programfpga not implemented for
|
|
||||||
this detector'. This happens when 'hostname' command fails due to
|
|
||||||
server-firmware/client compatibility and the detector type becomes
|
|
||||||
'GENERIC'. Fixed to suggest if 'hostname' executed properly.
|
|
||||||
|
|
||||||
|
|
||||||
* Udp Source IP
|
|
||||||
Command line: udp_srcip(2), API: getSourceUDPIP(2)/ setSourceUDPIP(2)
|
|
||||||
One can also set this to 'auto' for 1 GbE data and virtual detectors.
|
|
||||||
It will set to IP of detector. Not available for GotthardI.
|
|
||||||
|
|
||||||
* Incrementing default receiver tcp port
|
|
||||||
Automatically incrementing the default receiver tcp port for every module
|
|
||||||
when creating shared memory.
|
|
||||||
|
|
||||||
|
|
||||||
* Command line pattern commands also prints level index at output now.
|
|
||||||
|
|
||||||
|
|
||||||
* Zmq High water mark (hwm) and buffer size
|
|
||||||
When switching to the gui, hwm for the gui and the reciver was set to 2.
|
|
||||||
Now, if hwm is less than 25, the zmq receive buffer size is set to 1Mb
|
|
||||||
in the gui, else to 0 (os default). Similarly, zmq send buffer size is
|
|
||||||
also set for the receiver. These functions and option to rebind the zmq
|
|
||||||
publisher socket is also available now.
|
|
||||||
|
|
||||||
|
|
||||||
Changes or Fixes:
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau][Gotthard2][Mythen3][Gotthard][Moench][Ctb] Can't stop
|
|
||||||
This bug was introduced in 6.1.1, when stopping an acquisition saying it
|
|
||||||
cannot stop, even though it was successful. It is fixed now.
|
|
||||||
|
|
||||||
Note: Only if the detector is not in idle or stopped status, will the
|
|
||||||
command to stop acquisition go to the detector. This was introduced in 6.1.2
|
|
||||||
to handle multiple modules getting asynchronous start and stops from
|
|
||||||
different processes.
|
|
||||||
|
|
||||||
|
|
||||||
* [Gotthard] Set delay exception
|
|
||||||
Set delay threw an exception as it adds master delay in verification
|
|
||||||
even if it was not a master. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* Shared memory access failure
|
|
||||||
After a free, one could get seg fault if one called a function accessing
|
|
||||||
the shared memory structure without first loading the config file that
|
|
||||||
creates the shared memory. Fixed, a proper exception thrown if one tries
|
|
||||||
to access shared memory without creating it first.
|
|
||||||
|
|
||||||
|
|
||||||
* Stop detector when receiver is stuck
|
|
||||||
If receiver was stuck or crashed, stop acquisition command should
|
|
||||||
stop detector first before checking receiver status to restream
|
|
||||||
dummy header. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* Free and config command fail
|
|
||||||
Free and config command checked mismatch of size of shared memory before
|
|
||||||
freeing or loading new config. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* Incorrect user provided detector size
|
|
||||||
Command line: detsize, API: getDetectorSize/ setDetectorSize
|
|
||||||
If a user sets an incorrect detector size that is greater than the actual
|
|
||||||
detector size, then it would have set an incorrect number of modules,
|
|
||||||
affecting number of ports in the receiver. This has been fixed and now
|
|
||||||
the user can only set less than or equal to the maximum dimension
|
|
||||||
it could have.
|
|
||||||
|
|
||||||
|
|
||||||
* sls_detector_help or sls_detector_get -h
|
|
||||||
Should not create Detector object. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau] Storage cells in running receiver
|
|
||||||
Allowing the possibility to set this when receiver in running state.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger] Vtr
|
|
||||||
Allow Vtrim to be interpolated for settings.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Incorrect gain caps when setting threshold energy
|
|
||||||
Gain caps overwritten with settings enum. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Non blocking start acquisition
|
|
||||||
Non-blocking start acquisition was sent out twice to the master. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Threshold
|
|
||||||
When settings trimbits or threshold, counter mask is set and hence,
|
|
||||||
vthx dacs are set accordingly.
|
|
||||||
|
|
||||||
setAllThresholdEnergy takes 3 values for each counter and if one of them
|
|
||||||
is -1, the trimbits and setings for that counter is picked up from the
|
|
||||||
detector.
|
|
||||||
|
|
||||||
|
|
||||||
* [Moench][Ctb] Pattern levels
|
|
||||||
Changed from 3 to 6.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3][Moench][Ctb] Default patwait and patloop addresses
|
|
||||||
Set default wait and loop addresses to 0x1fff (max value) for all levels
|
|
||||||
before loading pattern. Please use the pattern command instead of parameters.
|
|
||||||
This ensures defaults are set up and is faster.
|
|
||||||
|
|
||||||
|
|
||||||
* [Moench] Patsetbit and patsetmask
|
|
||||||
Command line: patsetbit API: getPatternBitMask/ setPatternBitMask
|
|
||||||
Command line: patmask API: getPatternMask/ setPatternMask
|
|
||||||
|
|
||||||
Exchanging the help and masks for patsetbit and patsetmask in the detector
|
|
||||||
server, especially in loading settings.
|
|
||||||
|
|
||||||
|
|
||||||
* [Moench][Ctb] ADC Vpp
|
|
||||||
Command line: adcvpp, API: getADCVpp/ setADCVpp
|
|
||||||
Moved from SetDAC function into into its own. One can use mV values or
|
|
||||||
option numbers as before.
|
|
||||||
|
|
||||||
|
|
||||||
* [Ctb] ADC command goes back to control server
|
|
||||||
Slow ADCs, slow ADC temperature, get measured current and voltage values
|
|
||||||
are requested via the control server again insetad of the stop server
|
|
||||||
due to configuration and definitions in the control server.
|
|
||||||
|
|
||||||
|
|
||||||
* UDP Source Mac addresses
|
|
||||||
Only allowing unicast addresses (LSB of first octet must be 0).
|
|
||||||
|
|
||||||
|
|
||||||
1.5 Detector Server
|
|
||||||
====================
|
|
||||||
|
|
||||||
|
|
||||||
Config file:
|
|
||||||
------------
|
|
||||||
|
|
||||||
* [Eiger][Gotthard2][Gotthard] Master
|
|
||||||
Using config file with 'master' with argument (master=1, slave=0)
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger] Top
|
|
||||||
Using config file with 'top' with argument (top=1, bottom=0)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Command line arguments:
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* They have precedence over config files.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger][Gotthard2 Virtual][Mythen3 Virtual][Gotthard Virtual] Master
|
|
||||||
Using command line '--master = 1' or '-m = 1' with argument
|
|
||||||
(master = 1, slave = 0)
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger] Top
|
|
||||||
Using command line '--top = 1' or '-t = 1' with argument (top=1, bottom=0)
|
|
||||||
|
|
||||||
|
|
||||||
* Ignore config file
|
|
||||||
The config files can also be ignored by an argument from the command line,
|
|
||||||
'--ignore-config' or '-i'.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
------
|
------
|
||||||
|
|
||||||
|
* [Jungfrau] Multi module sync mode
|
||||||
|
For start, stop and trigger acquisition, the procedure to start the slaves
|
||||||
|
(or the master for stop acquisition) first had to be obeyed. This is fixed
|
||||||
|
now.
|
||||||
|
|
||||||
* [Jungfrau][Eiger] Clear UDP destination
|
|
||||||
Command line: udp_cleardst, API: clearUDPDestinations
|
|
||||||
Clearing udp destination also clears it in the FPGA now.
|
|
||||||
|
|
||||||
|
ZMQ
|
||||||
|
---
|
||||||
|
|
||||||
* [Eiger] Incorrect next frame number
|
* [Jungfrau][Gotthard2] Client ZMQ port when using 2 interfaces
|
||||||
Command line: nextframenumber, API: getNextFrameNumber/ setNextFrameNumber
|
When switching between 1 and 2 interfaces, the client or gui zmq port
|
||||||
Get next frame number for 10g was connected to 1g registers and gave
|
was not set properly and resulted in dummy streaming forever. This is
|
||||||
incorrect values. Fixed.
|
fixed now.
|
||||||
|
|
||||||
|
* Rx_roi
|
||||||
|
This parameter is now also streamed in the zmq header to be able to use in
|
||||||
|
external GUIs.
|
||||||
|
|
||||||
* [Eiger] Quad Dynamic range
|
|
||||||
Could not set dyanamic range in an Eiger Quad. Fixed.
|
|
||||||
|
|
||||||
|
GUI
|
||||||
|
---
|
||||||
|
|
||||||
* [Eiger] Stop before first acquisition after power on
|
* [Jungfrau] Show Fix_G0 in expert mode
|
||||||
Firmware fixed to handle a stop command before first acquisition after
|
Fix_G0 was only shown when expert mode was enabled from Settings Tab. Now,
|
||||||
the module is powered on.
|
fixed to show when expert mode enabled from any tab.
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3][Gotthard2] System clock change effects
|
|
||||||
When changing the system clock (clkdiv 2), time settings should also be
|
|
||||||
affected (exptime, period etc.). Fixed.
|
|
||||||
|
|
||||||
[Gotthard2] System frequency should be same irrespective of timing source.
|
|
||||||
Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Kernel version compatibility test
|
|
||||||
Fix added to parse properly the kernel version with CET for corrected
|
|
||||||
version compatibility test.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Server crash for setting vthrehsold
|
|
||||||
Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] trimming
|
|
||||||
Fixed deserializing in trimming.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Incorrect gaincaps
|
|
||||||
Setting threshold energy was overwriting gaincaps with settings enum. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* [Ctb][Moench] Hostname fail in update mode.
|
|
||||||
Fixed
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Changes:
|
|
||||||
--------
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau] Temporary fix for stop in 6.1.1
|
|
||||||
Temporary fix introduced in 6.1.1 for not being able to start after a
|
|
||||||
stop command has been issued is removed. Reset core right after also has
|
|
||||||
been removed. It has been fixed in firmware instead.
|
|
||||||
|
|
||||||
|
|
||||||
* [Gotthard2] Clock Divider defaults
|
|
||||||
When chancing burst mode, clock dividers (2, 3 and 4) set to their
|
|
||||||
defaults according to burst mode.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Change in default clock dividers.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] DAC check for settings
|
|
||||||
Verify DAC values for each setting has been temporarily switched off
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] DAC min and max values
|
|
||||||
Vtrim minimum of 600 has been removed.
|
|
||||||
The threshold dacs minimum is 200 and maximum is 2400.
|
|
||||||
The other DACs minimum is 0 and maximum is 2800.
|
|
||||||
When out of range, will not throw, just a warning.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Vicin Dac changed to 800
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau][Moench][Ctb] PLL reset at server start up
|
|
||||||
PLL reset now at server start up.
|
|
||||||
|
|
||||||
|
|
||||||
* [Moench] ADC9257 Vref
|
|
||||||
ADC Vref voltage modified from 1.33V to 2V
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* [Ctb] Allow all clock dividers for PLL
|
|
||||||
Fixed. For example, 133 MHz would not really be set previously. Fixed by
|
|
||||||
changing totaldiv from float to an integer.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Additional Features:
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
|
|
||||||
* Stop server startup errors
|
|
||||||
Stop servers now also check for errors at startup (including version
|
|
||||||
compatibility) and like the control server, it will translate to the
|
|
||||||
client when connecting for the first time (hostname command).
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau][Moench][Ctb] Additional server update process
|
|
||||||
Removes old server binary or target of linked file when updating
|
|
||||||
detector server for blackfin detectors as there is less space on blackfin.
|
|
||||||
|
|
||||||
Clearing up absolute and respawn path (removing double '/')
|
|
||||||
|
|
||||||
Raise error if server name to be copied is the same as final soft link name.
|
|
||||||
|
|
||||||
|
|
||||||
* [Moench][Ctb] 1 GbE Non blocking acquisition
|
|
||||||
Previously non blocking acquisition in 1 GbE would not send data.
|
|
||||||
This feature added now.
|
|
||||||
|
|
||||||
|
|
||||||
* [Gotthard2] Adapted to new HDI version
|
|
||||||
HDI module ID written to FPGA register
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1.6 Simulator
|
|
||||||
==============
|
|
||||||
|
|
||||||
|
|
||||||
* Command line arguments. Please refer to previous section on Detector Server.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger] Only one executable
|
|
||||||
Only one executable for an Eiger virtual server. Master and top mode
|
|
||||||
can be provided via command line or config file to the detector server,
|
|
||||||
as well as via the client. See in Other New Features for more details.
|
|
||||||
|
|
||||||
One can start a module using:
|
|
||||||
eigerDetectorServer_virtual # reads default config file (top master)
|
|
||||||
eigerDetectorServer_virtual -i #ignores the config file (bottom slave)
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger][Junfrau][Gotthard2][Mythen3] Module Id
|
|
||||||
Added into udp header
|
|
||||||
|
|
||||||
|
|
||||||
* Minimum Configuration
|
|
||||||
One can setup with just:
|
|
||||||
hostname localhost
|
|
||||||
rx_hostname localhost
|
|
||||||
udp_dstip auto
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Packet size
|
|
||||||
Fixed packet size calculation. Previously, sending only header with no data.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1.7 Receiver
|
|
||||||
=============
|
|
||||||
|
|
||||||
|
|
||||||
Breaking API:
|
|
||||||
-------------
|
|
||||||
|
|
||||||
|
|
||||||
* Namespace sls
|
|
||||||
All the receiver source files have also been added to namespace sls.
|
|
||||||
|
|
||||||
|
|
||||||
* HDF5 and Binary writer version
|
|
||||||
Changed from 6.3 to 6.4
|
|
||||||
|
|
||||||
|
|
||||||
* Master file format to json
|
|
||||||
The format has been changed from ASCII to json.
|
|
||||||
|
|
||||||
|
|
||||||
* Geometry metadata
|
|
||||||
Added geometry (number of modules in each direction) to metadata in file.
|
|
||||||
|
|
||||||
|
|
||||||
* HDF5 Dataset name
|
|
||||||
Changed to just "data" to simplify for user
|
|
||||||
|
|
||||||
|
|
||||||
* File write
|
|
||||||
File write is disabled by default.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
------
|
|
||||||
|
|
||||||
|
|
||||||
* Refactored and fixed minor issues
|
|
||||||
Including memory structure and udp sockets.
|
|
||||||
Fixed progress also in discard partial packaets mode and deactivated ports.
|
|
||||||
Fixed 200% progress.
|
|
||||||
Completely padded images now have detector type or version in metadata.
|
|
||||||
Fixed getting stuck at stop receiver when using zmq
|
|
||||||
Fixed clang compiler warnings
|
|
||||||
|
|
||||||
|
|
||||||
* Multiple files
|
|
||||||
This bug was introduced in v6.0.0, where 1 file was created per frame
|
|
||||||
after the first file. Fixed by resetting the number of frames in
|
|
||||||
current file when creating a new one.
|
|
||||||
|
|
||||||
|
|
||||||
* [Eiger] Datastream command order
|
|
||||||
The order of commands to set datastream from client mattered previously.
|
|
||||||
Datastream had to be set before 10GbE enable. Order does not matter anymore.
|
|
||||||
|
|
||||||
|
|
||||||
* Udp destination MAC
|
|
||||||
If it has been set before, changing udp_dstip will not update udp_dstmac.
|
|
||||||
Fixed to always set it in detector even if it had a value before.
|
|
||||||
Udp_dstmac can still be used to overwrite again. This is useful when
|
|
||||||
using a router for example.
|
|
||||||
|
|
||||||
|
|
||||||
* Stuck when using zmq
|
|
||||||
More often in 6.1.1, gets stuck at stop receiver.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Incorrect number of packets calculated or tengiga not set up
|
|
||||||
Runnig config second time (with tengiga=0, dr !=32, counters !=0x7)
|
|
||||||
calculated incorrect image size expected due to inconsistent copy of
|
|
||||||
detector parameters. Fixed
|
|
||||||
|
|
||||||
|
|
||||||
* Storage cells in receiver
|
|
||||||
Previously not updated in receiver. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* Virtual HDF5 Parameter datasets
|
|
||||||
Corner case bug when frames caught is not a multiple of frames per file.
|
|
||||||
Not found in virtual image datasets. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Changes:
|
|
||||||
--------
|
|
||||||
|
|
||||||
|
|
||||||
* Master file created at end of acquisition
|
|
||||||
The file is now written at the end of acquisition. So if any metadata
|
|
||||||
is changed during an acquisition, it will reflect the last value.
|
|
||||||
|
|
||||||
|
|
||||||
* File name prefix
|
|
||||||
Slash '/' not allowed.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Additional Features:
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
|
|
||||||
* [Gotthard2] 25um image reconstruction in virtual HDF5
|
|
||||||
Virtual HDF5 reconstructs complete image by interleaving first module
|
|
||||||
(master) with second module (slave). First channel of master is first
|
|
||||||
channel of detector.
|
|
||||||
|
|
||||||
Requires firmware update to reverse channels of slaves.
|
|
||||||
|
|
||||||
|
|
||||||
* Memory size
|
|
||||||
Increased an internal fifo header by 8 bytes to align memory allocated for
|
|
||||||
to receive images for efficiency.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1.8 Gui
|
|
||||||
========
|
|
||||||
|
|
||||||
|
|
||||||
* Refer Compilation topic for changes.
|
|
||||||
|
|
||||||
|
|
||||||
* [Jungfrau][Eiger] Gap pixels
|
|
||||||
Enabled by default in the gui.
|
|
||||||
|
|
||||||
|
|
||||||
* High voltage
|
|
||||||
Moved from Developer tab to Settings tab.
|
|
||||||
|
|
||||||
|
|
||||||
* Gain plot zooming
|
|
||||||
Zooming disabled. Instead, it automatically zooms in when you zoom in
|
|
||||||
the main plot or if min and max of x and y axis set up in plot tab.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3] Inconsistent timing mode
|
|
||||||
Timing mode of the slaves should be discarded before squashing. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* [Mythen3][Gotthard2] Crashes
|
|
||||||
Additional locking Added
|
|
||||||
|
|
||||||
|
|
||||||
* File path set in detector after choosing a directory in dialog (without
|
|
||||||
pressing enter). Before, it was only set in the display box, but lost
|
|
||||||
when switching tabs.
|
|
||||||
|
|
||||||
|
|
||||||
* X, Y, Z axis limits
|
|
||||||
Did not reflect on the current plot. Fixed.
|
|
||||||
|
|
||||||
|
|
||||||
* Refer 'Client' notes on Zmq High water mark and Zmq buffer size for
|
|
||||||
fast detectors.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -939,7 +82,7 @@ This document describes the differences between v7.0.0 and v6.1.2
|
|||||||
|
|
||||||
|
|
||||||
Eiger 7.0.0
|
Eiger 7.0.0
|
||||||
Jungfrau 7.0.0
|
Jungfrau 7.0.2
|
||||||
Mythen3 7.0.0
|
Mythen3 7.0.0
|
||||||
Gotthard2 7.0.0
|
Gotthard2 7.0.0
|
||||||
Gotthard 7.0.0
|
Gotthard 7.0.0
|
||||||
@ -967,8 +110,8 @@ This document describes the differences between v7.0.0 and v6.1.2
|
|||||||
|
|
||||||
Eiger 20.02.2023 (v31)
|
Eiger 20.02.2023 (v31)
|
||||||
|
|
||||||
Jungfrau 04.11.2022 (v1.4, HW v1.0)
|
Jungfrau 16.05.2023 (v1.4.1, HW v1.0)
|
||||||
03.11.2022 (v2.4, HW v2.0)
|
15.05.2023 (v2.4.1, HW v2.0)
|
||||||
|
|
||||||
Mythen3 24.01.2023 (v1.4)
|
Mythen3 24.01.2023 (v1.4)
|
||||||
|
|
||||||
|
@ -140,14 +140,21 @@ ZMQ: Json Header Format
|
|||||||
"quad": unsigned int,
|
"quad": unsigned int,
|
||||||
"addJsonHeader": {
|
"addJsonHeader": {
|
||||||
string : string
|
string : string
|
||||||
}
|
},
|
||||||
|
"rx_roi": [
|
||||||
|
unsigned int,
|
||||||
|
unsigned int,
|
||||||
|
unsigned int,
|
||||||
|
unsigned int
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
+--------------+----------------------------------------------+
|
+--------------+----------------------------------------------+
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
+--------------+----------------------------------------------+
|
+--------------+----------------------------------------------+
|
||||||
| jsonversion | Version of the json header. |
|
| jsonversion | Version of the json header. |
|
||||||
| | Value at 4 for v6.x.x and v7.x.x |
|
| | Value at 4 for v6.x.x - v7.0.1 |
|
||||||
|
| | Value at 5 for v7.0.2 |
|
||||||
+--------------+----------------------------------------------+
|
+--------------+----------------------------------------------+
|
||||||
| bitmode | Bits per pixel [4|8|16|32] |
|
| bitmode | Bits per pixel [4|8|16|32] |
|
||||||
+--------------+----------------------------------------------+
|
+--------------+----------------------------------------------+
|
||||||
@ -222,7 +229,10 @@ ZMQ: Json Header Format
|
|||||||
| addJsonHeader| Optional custom parameters that is required |
|
| addJsonHeader| Optional custom parameters that is required |
|
||||||
| | for processing code. |
|
| | for processing code. |
|
||||||
+--------------+----------------------------------------------+
|
+--------------+----------------------------------------------+
|
||||||
|
| rx_roi | ROI in the receiver per port (xmin, xmax, |
|
||||||
|
| | ymin, ymax). For external guis to know |
|
||||||
|
| | what is saved |
|
||||||
|
+--------------+----------------------------------------------+
|
||||||
|
|
||||||
SLS Receiver Header Format
|
SLS Receiver Header Format
|
||||||
--------------------------
|
--------------------------
|
||||||
|
@ -1 +0,0 @@
|
|||||||
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.0
|
|
1
serverBin/jungfrauDetectorServerv7.0.2
Symbolic link
1
serverBin/jungfrauDetectorServerv7.0.2
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2
|
@ -132,7 +132,7 @@ void qTabSettings::SetupWidgetWindow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void qTabSettings::SetExportMode(bool exportMode) {
|
void qTabSettings::SetExportMode(bool exportMode) {
|
||||||
if (comboGainMode->isVisible()) {
|
if (comboGainMode->isEnabled()) {
|
||||||
ShowFixG0(exportMode);
|
ShowFixG0(exportMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
BIN
slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2
Executable file
BIN
slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.2
Executable file
Binary file not shown.
@ -1388,14 +1388,18 @@ int setMaster(enum MASTERINDEX m) {
|
|||||||
char *master_names[] = {MASTER_NAMES};
|
char *master_names[] = {MASTER_NAMES};
|
||||||
LOG(logINFOBLUE, ("Setting up as %s in (%s server)\n", master_names[m],
|
LOG(logINFOBLUE, ("Setting up as %s in (%s server)\n", master_names[m],
|
||||||
(isControlServer ? "control" : "stop")));
|
(isControlServer ? "control" : "stop")));
|
||||||
|
|
||||||
|
int prevSync = getSynchronization();
|
||||||
|
setSynchronization(0);
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
int retMaster = OK;
|
||||||
switch (m) {
|
switch (m) {
|
||||||
case OW_MASTER:
|
case OW_MASTER:
|
||||||
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_MASTER_MSK);
|
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_MASTER_MSK);
|
||||||
isMaster(&retval);
|
isMaster(&retval);
|
||||||
if (retval != 1) {
|
if (retval != 1) {
|
||||||
LOG(logERROR, ("Could not set master\n"));
|
LOG(logERROR, ("Could not set master\n"));
|
||||||
return FAIL;
|
retMaster = FAIL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OW_SLAVE:
|
case OW_SLAVE:
|
||||||
@ -1403,15 +1407,16 @@ int setMaster(enum MASTERINDEX m) {
|
|||||||
isMaster(&retval);
|
isMaster(&retval);
|
||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
LOG(logERROR, ("Could not set slave\n"));
|
LOG(logERROR, ("Could not set slave\n"));
|
||||||
return FAIL;
|
retMaster = FAIL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG(logERROR, ("Cannot reset to hardware settings from client. Restart "
|
LOG(logERROR, ("Cannot reset to hardware settings from client. Restart "
|
||||||
"detector server.\n"));
|
"detector server.\n"));
|
||||||
return FAIL;
|
retMaster = FAIL;
|
||||||
}
|
}
|
||||||
return OK;
|
setSynchronization(prevSync);
|
||||||
|
return retMaster;
|
||||||
}
|
}
|
||||||
|
|
||||||
int isMaster(int *retval) {
|
int isMaster(int *retval) {
|
||||||
@ -1449,7 +1454,7 @@ void setTiming(enum timingMode arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum timingMode getTiming() {
|
enum timingMode getTiming() {
|
||||||
if (bus_r(EXT_SIGNAL_REG) == EXT_SIGNAL_MSK)
|
if ((bus_r(EXT_SIGNAL_REG) & EXT_SIGNAL_MSK) >> EXT_SIGNAL_OFST)
|
||||||
return TRIGGER_EXPOSURE;
|
return TRIGGER_EXPOSURE;
|
||||||
return AUTO_TIMING;
|
return AUTO_TIMING;
|
||||||
}
|
}
|
||||||
@ -1736,40 +1741,40 @@ int setDetectorPosition(int pos[]) {
|
|||||||
detPos[2] = outerPos[X];
|
detPos[2] = outerPos[X];
|
||||||
detPos[3] = outerPos[Y];
|
detPos[3] = outerPos[Y];
|
||||||
|
|
||||||
// row
|
// row [Y]
|
||||||
// outer
|
// outer
|
||||||
uint32_t addr = COORD_ROW_REG;
|
uint32_t addr = COORD_ROW_REG;
|
||||||
bus_w(addr,
|
bus_w(addr,
|
||||||
(bus_r(addr) & ~COORD_ROW_OUTER_MSK) |
|
(bus_r(addr) & ~COORD_ROW_OUTER_MSK) |
|
||||||
((outerPos[X] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK));
|
((outerPos[Y] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK));
|
||||||
if (((bus_r(addr) & COORD_ROW_OUTER_MSK) >> COORD_ROW_OUTER_OFST) !=
|
if (((bus_r(addr) & COORD_ROW_OUTER_MSK) >> COORD_ROW_OUTER_OFST) !=
|
||||||
outerPos[X])
|
|
||||||
ret = FAIL;
|
|
||||||
// inner
|
|
||||||
bus_w(addr,
|
|
||||||
(bus_r(addr) & ~COORD_ROW_INNER_MSK) |
|
|
||||||
((innerPos[X] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK));
|
|
||||||
if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) !=
|
|
||||||
innerPos[X])
|
|
||||||
ret = FAIL;
|
|
||||||
|
|
||||||
// col
|
|
||||||
// outer
|
|
||||||
addr = COORD_COL_REG;
|
|
||||||
bus_w(addr,
|
|
||||||
(bus_r(addr) & ~COORD_COL_OUTER_MSK) |
|
|
||||||
((outerPos[Y] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK));
|
|
||||||
if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) !=
|
|
||||||
outerPos[Y])
|
outerPos[Y])
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
// inner
|
// inner
|
||||||
bus_w(addr,
|
bus_w(addr,
|
||||||
(bus_r(addr) & ~COORD_COL_INNER_MSK) |
|
(bus_r(addr) & ~COORD_ROW_INNER_MSK) |
|
||||||
((innerPos[Y] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK));
|
((innerPos[Y] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK));
|
||||||
if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) !=
|
if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) !=
|
||||||
innerPos[Y])
|
innerPos[Y])
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
|
|
||||||
|
// col [X]
|
||||||
|
// outer
|
||||||
|
addr = COORD_COL_REG;
|
||||||
|
bus_w(addr,
|
||||||
|
(bus_r(addr) & ~COORD_COL_OUTER_MSK) |
|
||||||
|
((outerPos[X] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK));
|
||||||
|
if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) !=
|
||||||
|
outerPos[X])
|
||||||
|
ret = FAIL;
|
||||||
|
// inner
|
||||||
|
bus_w(addr,
|
||||||
|
(bus_r(addr) & ~COORD_COL_INNER_MSK) |
|
||||||
|
((innerPos[X] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK));
|
||||||
|
if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) !=
|
||||||
|
innerPos[X])
|
||||||
|
ret = FAIL;
|
||||||
|
|
||||||
if (ret == OK) {
|
if (ret == OK) {
|
||||||
if (getNumberofUDPInterfaces() == 1) {
|
if (getNumberofUDPInterfaces() == 1) {
|
||||||
LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n",
|
LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n",
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#include "sls/sls_detector_defs.h"
|
#include "sls/sls_detector_defs.h"
|
||||||
|
|
||||||
#define MIN_REQRD_VRSN_T_RD_API 0x171220
|
#define MIN_REQRD_VRSN_T_RD_API 0x171220
|
||||||
#define REQRD_FRMWRE_VRSN_BOARD2 0x221104 // 1.0 pcb (version = 010)
|
#define REQRD_FRMWRE_VRSN_BOARD2 0x230516 // 1.0 pcb (version = 010)
|
||||||
#define REQRD_FRMWRE_VRSN 0x221103 // 2.0 pcb (version = 011)
|
#define REQRD_FRMWRE_VRSN 0x230515 // 2.0 pcb (version = 011)
|
||||||
|
|
||||||
#define NUM_HARDWARE_VERSIONS (2)
|
#define NUM_HARDWARE_VERSIONS (2)
|
||||||
#define HARDWARE_VERSION_NUMBERS \
|
#define HARDWARE_VERSION_NUMBERS \
|
||||||
|
@ -855,7 +855,7 @@ void Detector::stopDetector(Positions pos) {
|
|||||||
throw RuntimeError(
|
throw RuntimeError(
|
||||||
"Could not stop detector. Returned error status.");
|
"Could not stop detector. Returned error status.");
|
||||||
}
|
}
|
||||||
pimpl->Parallel(&Module::stopAcquisition, pos);
|
pimpl->stopDetector(pos);
|
||||||
status = getDetectorStatus().squash(defs::runStatus::RUNNING);
|
status = getDetectorStatus().squash(defs::runStatus::RUNNING);
|
||||||
++retries;
|
++retries;
|
||||||
|
|
||||||
@ -914,7 +914,7 @@ void Detector::setNextFrameNumber(uint64_t value, Positions pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Detector::sendSoftwareTrigger(const bool block, Positions pos) {
|
void Detector::sendSoftwareTrigger(const bool block, Positions pos) {
|
||||||
pimpl->Parallel(&Module::sendSoftwareTrigger, pos, block);
|
pimpl->sendSoftwareTrigger(block, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<defs::scanParameters> Detector::getScan(Positions pos) const {
|
Result<defs::scanParameters> Detector::getScan(Positions pos) const {
|
||||||
@ -951,18 +951,23 @@ void Detector::setNumberofUDPInterfaces(int n, Positions pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Detector::setNumberofUDPInterfaces_(int n, Positions pos) {
|
void Detector::setNumberofUDPInterfaces_(int n, Positions pos) {
|
||||||
|
if (!size()) {
|
||||||
|
throw RuntimeError("No modules added.");
|
||||||
|
}
|
||||||
bool previouslyClientStreaming = pimpl->getDataStreamingToClient();
|
bool previouslyClientStreaming = pimpl->getDataStreamingToClient();
|
||||||
|
int clientStartingPort = getClientZmqPort({0}).squash(0);
|
||||||
bool useReceiver = getUseReceiverFlag().squash(false);
|
bool useReceiver = getUseReceiverFlag().squash(false);
|
||||||
bool previouslyReceiverStreaming = false;
|
bool previouslyReceiverStreaming = false;
|
||||||
int startingPort = 0;
|
int rxStartingPort = 0;
|
||||||
if (useReceiver) {
|
if (useReceiver) {
|
||||||
previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true);
|
previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true);
|
||||||
startingPort = getRxZmqPort({0}).squash(0);
|
rxStartingPort = getRxZmqPort({0}).squash(0);
|
||||||
}
|
}
|
||||||
pimpl->Parallel(&Module::setNumberofUDPInterfaces, pos, n);
|
pimpl->Parallel(&Module::setNumberofUDPInterfaces, pos, n);
|
||||||
// ensure receiver zmq socket ports are multiplied by 2 (2 interfaces)
|
// ensure receiver zmq socket ports are multiplied by 2 (2 interfaces)
|
||||||
if (getUseReceiverFlag().squash(false) && size()) {
|
setClientZmqPort(clientStartingPort, -1);
|
||||||
setRxZmqPort(startingPort, -1);
|
if (getUseReceiverFlag().squash(false)) {
|
||||||
|
setRxZmqPort(rxStartingPort, -1);
|
||||||
}
|
}
|
||||||
// redo the zmq sockets if enabled
|
// redo the zmq sockets if enabled
|
||||||
if (previouslyClientStreaming) {
|
if (previouslyClientStreaming) {
|
||||||
|
@ -769,7 +769,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
|||||||
int nDetActualPixelsY = nDetPixelsY;
|
int nDetActualPixelsY = nDetPixelsY;
|
||||||
|
|
||||||
if (gapPixels) {
|
if (gapPixels) {
|
||||||
int n = InsertGapPixels(multiframe.get(), multigappixels,
|
int n = insertGapPixels(multiframe.get(), multigappixels,
|
||||||
quadEnable, dynamicRange,
|
quadEnable, dynamicRange,
|
||||||
nDetActualPixelsX, nDetActualPixelsY);
|
nDetActualPixelsX, nDetActualPixelsY);
|
||||||
callbackImage = multigappixels;
|
callbackImage = multigappixels;
|
||||||
@ -808,7 +808,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
|||||||
delete[] multigappixels;
|
delete[] multigappixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DetectorImpl::InsertGapPixels(char *image, char *&gpImage, bool quadEnable,
|
int DetectorImpl::insertGapPixels(char *image, char *&gpImage, bool quadEnable,
|
||||||
int dr, int &nPixelsx, int &nPixelsy) {
|
int dr, int &nPixelsx, int &nPixelsy) {
|
||||||
|
|
||||||
LOG(logDEBUG) << "Insert Gap pixels:"
|
LOG(logDEBUG) << "Insert Gap pixels:"
|
||||||
@ -1256,43 +1256,104 @@ int DetectorImpl::acquire() {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectorImpl::startAcquisition(bool blocking, std::vector<int> positions) {
|
bool DetectorImpl::handleSynchronization(Positions pos) {
|
||||||
// handle Mythen3 synchronization
|
bool handleSync = false;
|
||||||
if (shm()->detType == defs::MYTHEN3 && size() > 1) {
|
// multi module m3 or multi module sync enabled jungfrau
|
||||||
std::vector<int> master;
|
if (size() > 1) {
|
||||||
std::vector<int> slaves;
|
switch (shm()->detType) {
|
||||||
if (positions.empty() ||
|
case defs::MYTHEN3:
|
||||||
(positions.size() == 1 && positions[0] == -1)) {
|
case defs::GOTTHARD2:
|
||||||
positions.resize(modules.size());
|
case defs::GOTTHARD:
|
||||||
std::iota(begin(positions), end(positions), 0);
|
handleSync = true;
|
||||||
}
|
break;
|
||||||
// could be all slaves in positions
|
case defs::JUNGFRAU:
|
||||||
slaves.reserve(positions.size());
|
if (Parallel(&Module::getSynchronizationFromStopServer, pos)
|
||||||
auto is_master = Parallel(&Module::isMaster, positions);
|
.tsquash("Inconsistent synchronization among modules")) {
|
||||||
for (size_t i : positions) {
|
handleSync = true;
|
||||||
if (is_master[i])
|
}
|
||||||
master.push_back(i);
|
break;
|
||||||
else
|
default:
|
||||||
slaves.push_back(i);
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return handleSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetectorImpl::getMasterSlaveList(std::vector<int> positions,
|
||||||
|
std::vector<int> &masters,
|
||||||
|
std::vector<int> &slaves) {
|
||||||
|
// expand positions list
|
||||||
|
if (positions.empty() || (positions.size() == 1 && positions[0] == -1)) {
|
||||||
|
positions.resize(modules.size());
|
||||||
|
std::iota(begin(positions), end(positions), 0);
|
||||||
|
}
|
||||||
|
// could be all slaves in positions
|
||||||
|
slaves.reserve(positions.size());
|
||||||
|
auto is_master = Parallel(&Module::isMaster, positions);
|
||||||
|
for (size_t i : positions) {
|
||||||
|
if (is_master[i])
|
||||||
|
masters.push_back(i);
|
||||||
|
else
|
||||||
|
slaves.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetectorImpl::startAcquisition(const bool blocking, Positions pos) {
|
||||||
|
|
||||||
|
// slaves first
|
||||||
|
if (handleSynchronization(pos)) {
|
||||||
|
std::vector<int> masters;
|
||||||
|
std::vector<int> slaves;
|
||||||
|
getMasterSlaveList(pos, masters, slaves);
|
||||||
if (!slaves.empty()) {
|
if (!slaves.empty()) {
|
||||||
Parallel(&Module::startAcquisition, slaves);
|
Parallel(&Module::startAcquisition, slaves);
|
||||||
}
|
}
|
||||||
if (!master.empty()) {
|
if (!masters.empty()) {
|
||||||
if (blocking) {
|
Parallel((blocking ? &Module::startAndReadAll
|
||||||
Parallel(&Module::startAndReadAll, master);
|
: &Module::startAcquisition),
|
||||||
} else {
|
masters);
|
||||||
Parallel(&Module::startAcquisition, master);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (blocking) {
|
|
||||||
Parallel(&Module::startAndReadAll, positions);
|
|
||||||
} else {
|
|
||||||
Parallel(&Module::startAcquisition, positions);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// all in parallel
|
||||||
|
else {
|
||||||
|
Parallel(
|
||||||
|
(blocking ? &Module::startAndReadAll : &Module::startAcquisition),
|
||||||
|
pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetectorImpl::sendSoftwareTrigger(const bool block, Positions pos) {
|
||||||
|
// slaves first
|
||||||
|
if (handleSynchronization(pos)) {
|
||||||
|
std::vector<int> masters;
|
||||||
|
std::vector<int> slaves;
|
||||||
|
getMasterSlaveList(pos, masters, slaves);
|
||||||
|
if (!slaves.empty())
|
||||||
|
Parallel(&Module::sendSoftwareTrigger, slaves, false);
|
||||||
|
if (!masters.empty())
|
||||||
|
Parallel(&Module::sendSoftwareTrigger, masters, block);
|
||||||
|
}
|
||||||
|
// all in parallel
|
||||||
|
else {
|
||||||
|
Parallel(&Module::sendSoftwareTrigger, pos, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetectorImpl::stopDetector(Positions pos) {
|
||||||
|
// masters first
|
||||||
|
if (handleSynchronization(pos)) {
|
||||||
|
std::vector<int> masters;
|
||||||
|
std::vector<int> slaves;
|
||||||
|
getMasterSlaveList(pos, masters, slaves);
|
||||||
|
if (!masters.empty())
|
||||||
|
Parallel(&Module::stopAcquisition, masters);
|
||||||
|
if (!slaves.empty())
|
||||||
|
Parallel(&Module::stopAcquisition, slaves);
|
||||||
|
}
|
||||||
|
// all in parallel
|
||||||
|
else {
|
||||||
|
Parallel(&Module::stopAcquisition, pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectorImpl::printProgress(double progress) {
|
void DetectorImpl::printProgress(double progress) {
|
||||||
@ -1324,7 +1385,7 @@ void DetectorImpl::processData(bool receiver) {
|
|||||||
if (fgetc(stdin) == 'q') {
|
if (fgetc(stdin) == 'q') {
|
||||||
LOG(logINFO)
|
LOG(logINFO)
|
||||||
<< "Caught the command to stop acquisition";
|
<< "Caught the command to stop acquisition";
|
||||||
Parallel(&Module::stopAcquisition, {});
|
stopDetector({});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// get and print progress
|
// get and print progress
|
||||||
@ -1397,7 +1458,8 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
|||||||
default:
|
default:
|
||||||
throw RuntimeError(
|
throw RuntimeError(
|
||||||
"Unknown detector type. Did the 'hostname' command execute "
|
"Unknown detector type. Did the 'hostname' command execute "
|
||||||
"successfully? Or use update mode in the detector server side.");
|
"successfully? Or use update mode in the detector server "
|
||||||
|
"side.");
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(logINFO) << "This can take awhile. Please be patient.";
|
LOG(logINFO) << "This can take awhile. Please be patient.";
|
||||||
@ -1425,10 +1487,9 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
|||||||
int dst = mkstemp(destfname); // create temporary file and open it in r/w
|
int dst = mkstemp(destfname); // create temporary file and open it in r/w
|
||||||
if (dst == -1) {
|
if (dst == -1) {
|
||||||
fclose(src);
|
fclose(src);
|
||||||
throw RuntimeError(
|
throw RuntimeError(std::string("Could not create destination file "
|
||||||
std::string(
|
"in /tmp for programming: ") +
|
||||||
"Could not create destination file in /tmp for programming: ") +
|
destfname);
|
||||||
destfname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert src to dst rawbin
|
// convert src to dst rawbin
|
||||||
@ -1480,8 +1541,8 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
|||||||
}
|
}
|
||||||
// validate pof: read less than footer offset
|
// validate pof: read less than footer offset
|
||||||
if (isPof && dstFilePos < pofFooterOfst) {
|
if (isPof && dstFilePos < pofFooterOfst) {
|
||||||
throw RuntimeError(
|
throw RuntimeError("Could not convert programming file. EOF "
|
||||||
"Could not convert programming file. EOF before end of flash");
|
"before end of flash");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fclose(src) != 0) {
|
if (fclose(src) != 0) {
|
||||||
|
@ -278,7 +278,13 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
int acquire();
|
int acquire();
|
||||||
|
|
||||||
/** also takes care of master and slave for multi module mythen */
|
/** also takes care of master and slave for multi module mythen */
|
||||||
void startAcquisition(bool blocking, std::vector<int> positions);
|
void startAcquisition(const bool blocking, Positions pos);
|
||||||
|
|
||||||
|
/** also takes care of master and slave for multi module mythen */
|
||||||
|
void sendSoftwareTrigger(const bool block, Positions pos);
|
||||||
|
|
||||||
|
/** also takes care of master and slave for multi module mythen */
|
||||||
|
void stopDetector(Positions pos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines data from all readouts and gives it to the gui
|
* Combines data from all readouts and gives it to the gui
|
||||||
@ -368,9 +374,14 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
* @param nPixelsy number of pixels in Y axis (updated)
|
* @param nPixelsy number of pixels in Y axis (updated)
|
||||||
* @returns total data bytes for updated image
|
* @returns total data bytes for updated image
|
||||||
*/
|
*/
|
||||||
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
|
int insertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
|
||||||
int &nPixelsx, int &nPixelsy);
|
int &nPixelsx, int &nPixelsy);
|
||||||
|
|
||||||
|
bool handleSynchronization(Positions pos);
|
||||||
|
void getMasterSlaveList(std::vector<int> positions,
|
||||||
|
std::vector<int> &masters,
|
||||||
|
std::vector<int> &slaves);
|
||||||
|
|
||||||
void printProgress(double progress);
|
void printProgress(double progress);
|
||||||
|
|
||||||
void startProcessingThread(bool receiver);
|
void startProcessingThread(bool receiver);
|
||||||
|
@ -73,8 +73,8 @@ void Module::setHostname(const std::string &hostname,
|
|||||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||||
client.close();
|
client.close();
|
||||||
try {
|
try {
|
||||||
initialDetectorServerChecks();
|
|
||||||
checkDetectorVersionCompatibility();
|
checkDetectorVersionCompatibility();
|
||||||
|
initialDetectorServerChecks();
|
||||||
LOG(logINFO) << "Module Version Compatibility - Success";
|
LOG(logINFO) << "Module Version Compatibility - Success";
|
||||||
} catch (const RuntimeError &e) {
|
} catch (const RuntimeError &e) {
|
||||||
if (!initialChecks) {
|
if (!initialChecks) {
|
||||||
@ -93,9 +93,28 @@ int64_t Module::getFirmwareVersion() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string Module::getControlServerLongVersion() const {
|
std::string Module::getControlServerLongVersion() const {
|
||||||
char retval[MAX_STR_LENGTH]{};
|
try {
|
||||||
sendToDetector(F_GET_SERVER_VERSION, nullptr, retval);
|
char retval[MAX_STR_LENGTH]{};
|
||||||
return retval;
|
sendToDetector(F_GET_SERVER_VERSION, nullptr, retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
// throw with old server version (sends 8 bytes)
|
||||||
|
catch (RuntimeError &e) {
|
||||||
|
std::string emsg = std::string(e.what());
|
||||||
|
if (emsg.find(F_GET_SERVER_VERSION) && emsg.find("8 bytes")) {
|
||||||
|
throwDeprecatedServerVersion();
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::throwDeprecatedServerVersion() const {
|
||||||
|
uint64_t res = sendToDetectorStop<int64_t>(F_GET_SERVER_VERSION);
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Detector Server (Control) version (0x" << std::hex << res
|
||||||
|
<< ") is incompatible with this client. Please update detector server!";
|
||||||
|
throw RuntimeError(os.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Module::getStopServerLongVersion() const {
|
std::string Module::getStopServerLongVersion() const {
|
||||||
@ -519,8 +538,15 @@ bool Module::getSynchronization() const {
|
|||||||
return sendToDetector<int>(F_GET_SYNCHRONIZATION);
|
return sendToDetector<int>(F_GET_SYNCHRONIZATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Module::getSynchronizationFromStopServer() const {
|
||||||
|
return sendToDetectorStop<int>(F_GET_SYNCHRONIZATION);
|
||||||
|
}
|
||||||
|
|
||||||
void Module::setSynchronization(const bool value) {
|
void Module::setSynchronization(const bool value) {
|
||||||
sendToDetector(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr);
|
sendToDetector(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr);
|
||||||
|
// to deal with virtual servers as well
|
||||||
|
// (get sync from stop server during blocking acquisition)
|
||||||
|
sendToDetectorStop(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> Module::getBadChannels() const {
|
std::vector<int> Module::getBadChannels() const {
|
||||||
|
@ -92,6 +92,7 @@ class Module : public virtual slsDetectorDefs {
|
|||||||
int64_t getFirmwareVersion() const;
|
int64_t getFirmwareVersion() const;
|
||||||
std::string getControlServerLongVersion() const;
|
std::string getControlServerLongVersion() const;
|
||||||
std::string getStopServerLongVersion() const;
|
std::string getStopServerLongVersion() const;
|
||||||
|
void throwDeprecatedServerVersion() const;
|
||||||
std::string getDetectorServerVersion() const;
|
std::string getDetectorServerVersion() const;
|
||||||
std::string getHardwareVersion() const;
|
std::string getHardwareVersion() const;
|
||||||
std::string getKernelVersion() const;
|
std::string getKernelVersion() const;
|
||||||
@ -128,6 +129,7 @@ class Module : public virtual slsDetectorDefs {
|
|||||||
bool isMaster() const;
|
bool isMaster() const;
|
||||||
void setMaster(const bool master);
|
void setMaster(const bool master);
|
||||||
bool getSynchronization() const;
|
bool getSynchronization() const;
|
||||||
|
bool getSynchronizationFromStopServer() const;
|
||||||
void setSynchronization(const bool value);
|
void setSynchronization(const bool value);
|
||||||
std::vector<int> getBadChannels() const;
|
std::vector<int> getBadChannels() const;
|
||||||
void setBadChannels(std::vector<int> list);
|
void setBadChannels(std::vector<int> list);
|
||||||
|
@ -523,6 +523,28 @@ TEST_CASE("sync", "[.cmd]") {
|
|||||||
proxy.Call("sync", {"1"}, -1, PUT, oss);
|
proxy.Call("sync", {"1"}, -1, PUT, oss);
|
||||||
REQUIRE(oss.str() == "sync 1\n");
|
REQUIRE(oss.str() == "sync 1\n");
|
||||||
}
|
}
|
||||||
|
// setting to master or slave when synced
|
||||||
|
{
|
||||||
|
// get previous master
|
||||||
|
int prevMaster = 0;
|
||||||
|
auto previous = det.getMaster();
|
||||||
|
for (int i = 0; i != det.size(); ++i) {
|
||||||
|
if (previous[i] == 1) {
|
||||||
|
prevMaster = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
proxy.Call("master", {"1"}, 0, PUT);
|
||||||
|
proxy.Call("master", {"0"}, 0, PUT);
|
||||||
|
std::ostringstream oss;
|
||||||
|
proxy.Call("status", {}, -1, GET, oss);
|
||||||
|
REQUIRE(oss.str() != "status running\n");
|
||||||
|
// set all to slaves, and then master
|
||||||
|
for (int i = 0; i != det.size(); ++i) {
|
||||||
|
det.setMaster(0, {i});
|
||||||
|
}
|
||||||
|
det.setMaster(1, prevMaster);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
proxy.Call("sync", {}, -1, GET, oss);
|
proxy.Call("sync", {}, -1, GET, oss);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -16,6 +17,8 @@ namespace sls {
|
|||||||
#define gettid() syscall(SYS_gettid)
|
#define gettid() syscall(SYS_gettid)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void func(int signum) { wait(NULL); }
|
||||||
|
|
||||||
Arping::Arping() {}
|
Arping::Arping() {}
|
||||||
|
|
||||||
Arping::~Arping() {
|
Arping::~Arping() {
|
||||||
@ -44,10 +47,11 @@ pid_t Arping::GetProcessId() const { return childPid; }
|
|||||||
bool Arping::IsRunning() const { return runningFlag; }
|
bool Arping::IsRunning() const { return runningFlag; }
|
||||||
|
|
||||||
void Arping::StartProcess() {
|
void Arping::StartProcess() {
|
||||||
TestCommands();
|
|
||||||
|
|
||||||
// to prevent zombies from child processes being killed
|
// to prevent zombies from child processes being killed
|
||||||
signal(SIGCHLD, SIG_IGN);
|
signal(SIGCHLD, func);
|
||||||
|
|
||||||
|
// test once to throw exception if arping failed
|
||||||
|
TestForErrors();
|
||||||
|
|
||||||
// Needs to be a fork and udp socket deleted after Listening threads
|
// Needs to be a fork and udp socket deleted after Listening threads
|
||||||
// done running to prevent udp socket cannot bind because of popen
|
// done running to prevent udp socket cannot bind because of popen
|
||||||
@ -90,7 +94,7 @@ void Arping::ProcessExecution() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Arping::TestCommands() {
|
void Arping::TestForErrors() {
|
||||||
// atleast one interface must be set up
|
// atleast one interface must be set up
|
||||||
if (commands[0].empty()) {
|
if (commands[0].empty()) {
|
||||||
throw RuntimeError(
|
throw RuntimeError(
|
||||||
@ -116,7 +120,8 @@ std::string Arping::ExecuteCommands() {
|
|||||||
FILE *sysFile = popen(cmd.c_str(), "r");
|
FILE *sysFile = popen(cmd.c_str(), "r");
|
||||||
if (sysFile == NULL) {
|
if (sysFile == NULL) {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "Could not Arping [" << cmd << " ] : Popen fail";
|
os << "Could not Arping (" << cmd << " ) : Popen fail ("
|
||||||
|
<< strerror(errno) << ')';
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +133,7 @@ std::string Arping::ExecuteCommands() {
|
|||||||
// check exit status of command
|
// check exit status of command
|
||||||
if (pclose(sysFile)) {
|
if (pclose(sysFile)) {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "Could not arping[" << cmd << "] : " << output;
|
os << "Could not arping (" << cmd << ") : " << strerror(errno);
|
||||||
return os.str();
|
return os.str();
|
||||||
} else {
|
} else {
|
||||||
LOG(logDEBUG) << output;
|
LOG(logDEBUG) << output;
|
||||||
|
@ -28,7 +28,7 @@ class Arping {
|
|||||||
void StopProcess();
|
void StopProcess();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void TestCommands();
|
void TestForErrors();
|
||||||
std::string ExecuteCommands();
|
std::string ExecuteCommands();
|
||||||
void ProcessExecution();
|
void ProcessExecution();
|
||||||
|
|
||||||
|
@ -56,6 +56,8 @@ void DataStreamer::SetAdditionalJsonHeader(
|
|||||||
isAdditionalJsonUpdated = true;
|
isAdditionalJsonUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataStreamer::SetReceiverROI(ROI roi) { receiverRoi = roi; }
|
||||||
|
|
||||||
void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
|
void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
|
||||||
StopRunning();
|
StopRunning();
|
||||||
startedFlag = false;
|
startedFlag = false;
|
||||||
@ -249,6 +251,7 @@ int DataStreamer::SendDataHeader(sls_detector_header header, uint32_t size,
|
|||||||
isAdditionalJsonUpdated = false;
|
isAdditionalJsonUpdated = false;
|
||||||
}
|
}
|
||||||
zHeader.addJsonHeader = localAdditionalJsonHeader;
|
zHeader.addJsonHeader = localAdditionalJsonHeader;
|
||||||
|
zHeader.rx_roi = receiverRoi.getIntArray();
|
||||||
|
|
||||||
return zmqSocket->SendHeader(index, zHeader);
|
return zmqSocket->SendHeader(index, zHeader);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
|||||||
void SetNumberofTotalFrames(uint64_t value);
|
void SetNumberofTotalFrames(uint64_t value);
|
||||||
void
|
void
|
||||||
SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
|
SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
|
||||||
|
void SetReceiverROI(ROI roi);
|
||||||
|
|
||||||
void ResetParametersforNewAcquisition(const std::string &fname);
|
void ResetParametersforNewAcquisition(const std::string &fname);
|
||||||
/**
|
/**
|
||||||
@ -92,6 +93,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
|||||||
uint64_t fileIndex{0};
|
uint64_t fileIndex{0};
|
||||||
bool flipRows{false};
|
bool flipRows{false};
|
||||||
std::map<std::string, std::string> additionalJsonHeader;
|
std::map<std::string, std::string> additionalJsonHeader;
|
||||||
|
ROI receiverRoi{};
|
||||||
|
|
||||||
/** Used by streamer thread to update local copy (reduce number of locks
|
/** Used by streamer thread to update local copy (reduce number of locks
|
||||||
* during streaming) */
|
* during streaming) */
|
||||||
|
@ -14,14 +14,14 @@ HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib)
|
|||||||
"frame number",
|
"frame number",
|
||||||
"exp length or sub exposure time",
|
"exp length or sub exposure time",
|
||||||
"packets caught",
|
"packets caught",
|
||||||
"bunch id",
|
"detector specific 1",
|
||||||
"timestamp",
|
"timestamp",
|
||||||
"mod id",
|
"mod id",
|
||||||
"row",
|
"row",
|
||||||
"column",
|
"column",
|
||||||
"reserved",
|
"detector specific 2",
|
||||||
"debug",
|
"detector specific 3",
|
||||||
"round robin number",
|
"detector specific 4",
|
||||||
"detector type",
|
"detector type",
|
||||||
"detector header version",
|
"detector header version",
|
||||||
"packets caught bit mask",
|
"packets caught bit mask",
|
||||||
@ -317,7 +317,7 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
|
|||||||
dataSetPara[2]->write(&header.packetNumber, parameterDataTypes[2],
|
dataSetPara[2]->write(&header.packetNumber, parameterDataTypes[2],
|
||||||
memspace, *dataSpacePara);
|
memspace, *dataSpacePara);
|
||||||
i = 3;
|
i = 3;
|
||||||
dataSetPara[3]->write(&header.bunchId, parameterDataTypes[3], memspace,
|
dataSetPara[3]->write(&header.detSpec1, parameterDataTypes[3], memspace,
|
||||||
*dataSpacePara);
|
*dataSpacePara);
|
||||||
i = 4;
|
i = 4;
|
||||||
dataSetPara[4]->write(&header.timestamp, parameterDataTypes[4],
|
dataSetPara[4]->write(&header.timestamp, parameterDataTypes[4],
|
||||||
@ -332,13 +332,13 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
|
|||||||
dataSetPara[7]->write(&header.column, parameterDataTypes[7], memspace,
|
dataSetPara[7]->write(&header.column, parameterDataTypes[7], memspace,
|
||||||
*dataSpacePara);
|
*dataSpacePara);
|
||||||
i = 8;
|
i = 8;
|
||||||
dataSetPara[8]->write(&header.reserved, parameterDataTypes[8], memspace,
|
dataSetPara[8]->write(&header.detSpec2, parameterDataTypes[8], memspace,
|
||||||
*dataSpacePara);
|
*dataSpacePara);
|
||||||
i = 9;
|
i = 9;
|
||||||
dataSetPara[9]->write(&header.debug, parameterDataTypes[9], memspace,
|
dataSetPara[9]->write(&header.detSpec3, parameterDataTypes[9], memspace,
|
||||||
*dataSpacePara);
|
*dataSpacePara);
|
||||||
i = 10;
|
i = 10;
|
||||||
dataSetPara[10]->write(&header.roundRNumber, parameterDataTypes[10],
|
dataSetPara[10]->write(&header.detSpec4, parameterDataTypes[10],
|
||||||
memspace, *dataSpacePara);
|
memspace, *dataSpacePara);
|
||||||
i = 11;
|
i = 11;
|
||||||
dataSetPara[11]->write(&header.detType, parameterDataTypes[11],
|
dataSetPara[11]->write(&header.detType, parameterDataTypes[11],
|
||||||
|
@ -216,6 +216,8 @@ void Implementation::SetupDataStreamer(int i) {
|
|||||||
dataStreamer[i]->SetNumberofPorts(numPorts);
|
dataStreamer[i]->SetNumberofPorts(numPorts);
|
||||||
dataStreamer[i]->SetQuadEnable(quadEnable);
|
dataStreamer[i]->SetQuadEnable(quadEnable);
|
||||||
dataStreamer[i]->SetNumberofTotalFrames(numberOfTotalFrames);
|
dataStreamer[i]->SetNumberofTotalFrames(numberOfTotalFrames);
|
||||||
|
dataStreamer[i]->SetReceiverROI(
|
||||||
|
portRois[i].completeRoi() ? GetMaxROIPerPort() : portRois[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
slsDetectorDefs::xy Implementation::getDetectorSize() const {
|
slsDetectorDefs::xy Implementation::getDetectorSize() const {
|
||||||
@ -231,6 +233,11 @@ const slsDetectorDefs::xy Implementation::GetPortGeometry() const {
|
|||||||
return portGeometry;
|
return portGeometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const slsDetectorDefs::ROI Implementation::GetMaxROIPerPort() const {
|
||||||
|
return slsDetectorDefs::ROI{0, (int)generalData->nPixelsX - 1, 0,
|
||||||
|
(int)generalData->nPixelsY - 1};
|
||||||
|
}
|
||||||
|
|
||||||
void Implementation::setDetectorSize(const slsDetectorDefs::xy size) {
|
void Implementation::setDetectorSize(const slsDetectorDefs::xy size) {
|
||||||
xy portGeometry = GetPortGeometry();
|
xy portGeometry = GetPortGeometry();
|
||||||
|
|
||||||
@ -458,6 +465,10 @@ void Implementation::setReceiverROI(const slsDetectorDefs::ROI arg) {
|
|||||||
listener[i]->SetNoRoi(portRois[i].noRoi());
|
listener[i]->SetNoRoi(portRois[i].noRoi());
|
||||||
for (size_t i = 0; i != dataProcessor.size(); ++i)
|
for (size_t i = 0; i != dataProcessor.size(); ++i)
|
||||||
dataProcessor[i]->SetReceiverROI(portRois[i]);
|
dataProcessor[i]->SetReceiverROI(portRois[i]);
|
||||||
|
for (size_t i = 0; i != dataStreamer.size(); ++i) {
|
||||||
|
dataStreamer[i]->SetReceiverROI(
|
||||||
|
portRois[i].completeRoi() ? GetMaxROIPerPort() : portRois[i]);
|
||||||
|
}
|
||||||
LOG(logINFO) << "receiver roi: " << ToString(receiverRoi);
|
LOG(logINFO) << "receiver roi: " << ToString(receiverRoi);
|
||||||
if (generalData->numUDPInterfaces == 2 &&
|
if (generalData->numUDPInterfaces == 2 &&
|
||||||
generalData->detType != slsDetectorDefs::GOTTHARD2) {
|
generalData->detType != slsDetectorDefs::GOTTHARD2) {
|
||||||
|
@ -282,6 +282,7 @@ class Implementation : private virtual slsDetectorDefs {
|
|||||||
void SetupFifoStructure();
|
void SetupFifoStructure();
|
||||||
|
|
||||||
const xy GetPortGeometry() const;
|
const xy GetPortGeometry() const;
|
||||||
|
const ROI GetMaxROIPerPort() const;
|
||||||
void ResetParametersforNewAcquisition();
|
void ResetParametersforNewAcquisition();
|
||||||
void CreateUDPSockets();
|
void CreateUDPSockets();
|
||||||
void SetupWriter();
|
void SetupWriter();
|
||||||
|
@ -19,8 +19,8 @@ namespace sls {
|
|||||||
// files
|
// files
|
||||||
|
|
||||||
// versions
|
// versions
|
||||||
#define HDF5_WRITER_VERSION (6.5) // 1 decimal places
|
#define HDF5_WRITER_VERSION (6.6) // 1 decimal places
|
||||||
#define BINARY_WRITER_VERSION (7.1) // 1 decimal places
|
#define BINARY_WRITER_VERSION (7.2) // 1 decimal places
|
||||||
|
|
||||||
#define MAX_FRAMES_PER_FILE 20000
|
#define MAX_FRAMES_PER_FILE 20000
|
||||||
#define SHORT_MAX_FRAMES_PER_FILE 100000
|
#define SHORT_MAX_FRAMES_PER_FILE 100000
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "sls/container_utils.h"
|
#include "sls/container_utils.h"
|
||||||
#include "sls/sls_detector_exceptions.h"
|
#include "sls/sls_detector_exceptions.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -83,6 +84,8 @@ struct zmqHeader {
|
|||||||
bool completeImage{false};
|
bool completeImage{false};
|
||||||
/** additional json header */
|
/** additional json header */
|
||||||
std::map<std::string, std::string> addJsonHeader;
|
std::map<std::string, std::string> addJsonHeader;
|
||||||
|
/** (xmin, xmax, ymin, ymax) roi only in files written */
|
||||||
|
std::array<int, 4> rx_roi{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class ZmqSocket {
|
class ZmqSocket {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
#define MAX_UDP_DESTINATION 32
|
#define MAX_UDP_DESTINATION 32
|
||||||
|
|
||||||
#define SLS_DETECTOR_HEADER_VERSION 0x2
|
#define SLS_DETECTOR_HEADER_VERSION 0x2
|
||||||
#define SLS_DETECTOR_JSON_HEADER_VERSION 0x4
|
#define SLS_DETECTOR_JSON_HEADER_VERSION 0x5
|
||||||
|
|
||||||
// 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)
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||||
/** API versions */
|
/** API versions */
|
||||||
#define RELEASE "7.0.0"
|
#define RELEASE "7.0.2"
|
||||||
#define APICTB "7.0.0 0x230222"
|
#define APICTB "7.0.0 0x230222"
|
||||||
#define APIGOTTHARD "7.0.0 0x230222"
|
#define APIGOTTHARD "7.0.0 0x230222"
|
||||||
#define APIGOTTHARD2 "7.0.0 0x230222"
|
#define APIGOTTHARD2 "7.0.0 0x230222"
|
||||||
#define APIJUNGFRAU "7.0.0 0x230222"
|
|
||||||
#define APIMYTHEN3 "7.0.0 0x230222"
|
#define APIMYTHEN3 "7.0.0 0x230222"
|
||||||
#define APIMOENCH "7.0.0 0x230222"
|
#define APIMOENCH "7.0.0 0x230222"
|
||||||
#define APIEIGER "7.0.0 0x230222"
|
#define APIEIGER "7.0.0 0x230222"
|
||||||
#define APILIB "7.0.0 0x230223"
|
#define APIJUNGFRAU "7.0.2 0x230710"
|
||||||
#define APIRECEIVER "7.0.0 0x230222"
|
#define APILIB "7.0.2 0x230712"
|
||||||
|
#define APIRECEIVER "7.0.2 0x230712"
|
||||||
|
@ -254,6 +254,8 @@ int ZmqSocket::SendHeader(int index, zmqHeader header) {
|
|||||||
}
|
}
|
||||||
oss << " } ";
|
oss << " } ";
|
||||||
}
|
}
|
||||||
|
oss << ", \"rx_roi\":[" << header.rx_roi[0] << ", " << header.rx_roi[1]
|
||||||
|
<< ", " << header.rx_roi[2] << ", " << header.rx_roi[3] << "]";
|
||||||
oss << "}\n";
|
oss << "}\n";
|
||||||
std::string message = oss.str();
|
std::string message = oss.str();
|
||||||
int length = message.length();
|
int length = message.length();
|
||||||
@ -375,6 +377,11 @@ int ZmqSocket::ParseHeader(const int index, int length, char *buff,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Value &a = document["rx_roi"].GetArray();
|
||||||
|
for (SizeType i = 0; i != a.Size(); ++i) {
|
||||||
|
zHeader.rx_roi[i] = a[i].GetInt();
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user