merge from 7.0.0

This commit is contained in:
maliakal_d 2023-02-24 10:39:51 +01:00
commit dc5db905d4
101 changed files with 4009 additions and 2128 deletions

279
README.md
View File

@ -1,102 +1,233 @@
### Note ## Dependencies
Before building from source make sure that you have the [software wiki](https://slsdetectorgroup.github.io/devdoc/dependencies.html) installed. If installing using conda, conda will manage the dependencies. Avoid also installing packages with pip.
Please do not update to any xxxx.xx.xx.dev0 tags. They are not releases, but tags for internal usage. ## Documentaion
Use only releases with tags such as x.x.x or x.x.x-rcx. Detailed documentation can be found in the [software wiki](https://slsdetectorgroup.github.io/devdoc/index.html) and on the [official site](https://www.psi.ch/en/detectors/software).
### Documentation ## Installation
##### 5.0.0 - Latest Release
Detailed documentation on the latest release can be found in the [software wiki](https://slsdetectorgroup.github.io/devdoc/index.html) and on the [official site](https://www.psi.ch/en/detectors/software).
##### Older Releases ### 1. Install binaries using conda
Documentation is found in the package. Conda is not only useful to manage python environments but can also
be used as a user space package manager. Dates in the tag (for eg. 2020.07.23.dev0)
are from the developer branch. Please use released tags for stability.
We have three different packages available:
* **slsdetlib** shared libraries and command line utilities
* **slsdetgui** GUI
* **slsdet** Python bindings
### Binaries
Binaries for the slsDetectorPackage are available through conda.
``` ```
#Add conda channels #Add channels for dependencies and our library
conda config --add channels conda-forge conda config --add channels conda-forge
conda config --add channels slsdetectorgroup conda config --add channels slsdetectorgroup
conda config --set channel_priority strict conda config --set channel_priority strict
conda install slsdetlib #only shared lib and command line #create and activate an environment with our library
conda install slsdet #python bindings (includes slsdetlib) #replace 6.1.1 with the required tag
conda install slsdetgui #gui (includes qt4) conda create -n myenv slsdetlib=6.1.1
conda activate myenv
#Install specific version
conda install slsdet=2020.03.02.dev0 #developer version from 3 March 2020
#ready to use
sls_detector_get exptime
etc ...
``` ```
### Source code
One can also obtain the source code from this repository and compile.
``` ```
git clone https://github.com/slsdetectorgroup/slsDetectorPackage.git # List available versions
# lib and binaries
conda search slsdetlib
# python
conda search slsdet
# gui
conda search slsdetgui
```
### 2. Build from source
##### 2.1 Download Source Code from github
```
git clone https://github.com/slsdetectorgroup/slsDetectorPackage.git --branch 7.0.0
```
**Pybind for Python**<br>
* **v7.0.0+**:
pybind11 packaged into 'libs/pybind'. No longer a submodule. No need for "recursive" or "submodule update".
* **Older versions**:
pybind11 is a submodule. Must be cloned using "recursive" and updated when switching between versions using the following commands.
``` ```
#### Dependencies # clone using recursive to get pybind11 submodule
git clone --recursive https://github.com/slsdetectorgroup/slsDetectorPackage.git
Refer [this page](https://slsdetectorgroup.github.io/devdoc/dependencies.html) for dependencies. # update submodule when switching between releases
cd slsDetectorPackage
git submodule update --init
#### Compilation
Compiling can be done in two ways. Either with the convenience script
cmk.sh or directly with cmake for more control.
**1. Compile using script cmk.sh**<br>
These are mainly aimed at those not familiar with using ccmake and cmake.
``` ```
The binaries are generated in slsDetectorPackage/build/bin directory.
Usage: ./cmk.sh [-c] [-b] [-p] [e] [t] [r] [g] [s] [u] [i] [m] [n] [-h] [z] [-d <HDF5 directory>] [-l Install directory] [-k <CMake command>] [-j <Number of threads>] ##### 2.2 Build from source
-[no option]: only make
-c: Clean
-b: Builds/Rebuilds CMake files normal mode ###### Build using CMake
-p: Builds/Rebuilds Python API
-h: Builds/Rebuilds Cmake files with HDF5 package ```
-d: HDF5 Custom Directory # outside slsDetecorPackage folder
-k: CMake command mkdir build && cd build
-l: Install directory
-t: Build/Rebuilds only text client # configure & generate Makefiles using cmake
-r: Build/Rebuilds only receiver # by listing all your options (alternately use ccmake described below)
-g: Build/Rebuilds only gui # cmake3 for some systems
-s: Simulator cmake ../slsDetectorPackage -DCMAKE_INSTALL_PREFIX=/your/install/path
-u: Chip Test Gui
-j: Number of threads to compile through # compiled to the build/bin directory
-e: Debug mode make -j12 #or whatever number of cores you are using to build
-i: Builds tests
-m: Manuals # install headers and libs in /your/install/path directory
-n: Manuals without compiling doxygen (only rst) make install
-z: Moench zmq processor ```
Instead of the cmake command, one can use ccmake to get a list of options to configure and generate Makefiles at ease.
```
# ccmake3 for some systems
ccmake ..
# choose the options
# first press [c] - configure
# then press [g] - generate
```
|Example cmake options|Comment|
|---|---|
| -DSLS_USE_PYTHON=ON | Python |
| -DPython_FIND_VIRTUALENV=ONLY | Python from only the conda environment |
| -DZeroMQ_HINT=/usr/lib64 | Use system zmq instead |
| -DSLS_USE_GUI=ON | GUI |
###### Build using in-built cmk.sh script
```
The binaries are generated in slsDetectorPackage/build/bin directory.
Usage: ./cmk.sh [-b] [-c] [-d <HDF5 directory>] [e] [g] [-h] [i] [-j <Number of threads>]
[-k <CMake command>] [-l <Install directory>] [m] [n] [-p] [-q <Zmq hint directory>]
[r] [s] [t] [u] [z]
-[no option]: only make
-b: Builds/Rebuilds CMake files normal mode
-c: Clean
-d: HDF5 Custom Directory
-e: Debug mode
-g: Build/Rebuilds gui
-h: Builds/Rebuilds Cmake files with HDF5 package
-i: Builds tests
-j: Number of threads to compile through
-k: CMake command
-l: Install directory
-m: Manuals
-n: Manuals without compiling doxygen (only rst)
-p: Builds/Rebuilds Python API
-q: Zmq hint directory
-r: Build/Rebuilds only receiver
-s: Simulator
-t: Build/Rebuilds only text client
-u: Chip Test Gui
-z: Moench zmq processor
# get all options # display all options
./cmk.sh -? ./cmk.sh -?
# new build and compile in parallel: # new build and compile in parallel (recommended basic option):
./cmk.sh -bj5 ./cmk.sh -cbj5
```
# new build, python and compile in parallel:
**2. Compile without script**<br> ./cmk.sh -cbpj5
Use cmake to create out-of-source builds, by creating a build folder parallel to source directory. This would create a debug build with address sanitizers.
``` #To use the system zmq (/usr/lib64) instead
$ mkdir build ./cmk.sh -cbj5 -q /usr/lib64
$ cd build
$ cmake ../slsDetectorPackage -DCMAKE_BUILD_TYPE=Debug -DSLS_USE_SANITIZER=ON
$ make -j12 #or whatever number of threads wanted
``` ```
To install binaries using CMake ###### Build on old distributions
If your linux distribution doesn't come with a C++11 compiler (gcc>4.8) then
it's possible to install a newer gcc using conda and build the slsDetectorPackage
using this compiler
``` ```
git clone --recursive https://github.com/slsdetectorgroup/slsDetectorPackage.git #Create an environment with the dependencies
mkdir build && cd build conda create -n myenv gxx_linux-64 cmake zmq
cmake ../slsDetectorPackage -DCMAKE_INSTALL_PREFIX=/your/install/path conda activate myenv
make -j12 #or whatever number of cores you are using to build
make install # outside slsDetecorPackage folder
mkdir build && cd build
cmake ../slsDetectorPackage -DCMAKE_PREFIX_PATH=$CONDA_PREFIX
make -j12
```
###### Build slsDetectorGui (Qt5)
1. Using pre-built binary on conda
```
conda create -n myenv slsdetgui=7.0.0
conda activate myenv
```
2. Using system installation on RHEL7
```
yum install qt5-qtbase-devel.x86_64
yum install qt5-qtsvg-devel.x86_64
```
3. Using conda
```
#Add channels for dependencies and our library
conda config --add channels conda-forge
conda config --add channels slsdetectorgroup
conda config --set channel_priority strict
# create environment to compile
# on rhel7
conda create -n slsgui zeromq gxx_linux-64 gxx_linux-64 mesa-libgl-devel-cos6-x86_64 qt
# on fedora or newer systems
conda create -n slsgui zeromq qt
# when using conda compilers, would also need libgl, but no need for it on fedora unless maybe using it with ROOT
# activate environment
conda activate slsgui
# compile with cmake outside slsDetecorPackage folder
mkdir build && cd build
cmake ../slsDetectorPackage -DSLS_USE_GUI=ON
make -j12
# or compile with cmk.sh
cd slsDetectorPackage
./cmk.sh -cbgj9
```
###### Build documentation from package
The documentation for the slsDetectorPackage is build using a combination
of Doxygen, Sphinx and Breathe. The easiest way to install the dependencies
is to use conda
```
conda create -n myenv python sphinx_rtd_theme breathe
```
```
# using cmake or ccmake to enable DSLS_BUILD_DOCS
# outside slsDetecorPackage folder
mkdir build && cd build
cmake ../slsDetectorPackage -DSLS_BUILD_DOCS=ON
make docs # generate API docs and build Sphinx RST
make rst # rst only, saves time in case the API did not change
``` ```
### Support ## Support
dhanya.thattil@psi.ch dhanya.thattil@psi.ch
erik.frojdh@psi.ch erik.frojdh@psi.ch

View File

@ -1,36 +1,39 @@
SLS Detector Package Minor Release 7.0.0.rc1 released on 12.12.2021 SLS Detector Package Major Release 7.x.x released on xx.xx.2023
=================================================================== ===============================================================
This document describes the differences between v7.0.0.rc1 and v6.1.2 This document describes the differences between v7.x.x and v7.0.0
CONTENTS CONTENTS
-------- --------
1. New, Changed or Resolved Features 1 New, Changed or Resolved Features
1.1. Compilation 1.1 Compilation
1.2. Callback 1.2 Callback
1.3. Python 1.3 Python
1.4. Client 1.4 Client
1.5. Detector Server 1.5 Detector Server
1.6. Simulator 1.6 Simulator
1.7. Receiver 1.7 Receiver
2. On-board Detector Server Compatibility 1.8 Gui
3. Firmware Requirements 2 On-board Detector Server Compatibility
4. Kernel Requirements 3 Firmware Requirements
5. Download, Documentation & Support 4 Kernel Requirements
5 Download, Documentation & Support
1. New or Changed Features 1 New, Changed or Resolved Features
========================== =====================================
- moench being made compatible with jungfrau 2.0 boards (jungfrau structure, away from ctb) - moench being made compatible with jungfrau 2.0 boards (jungfrau structure, away from ctb)
- eiger febl and feb in versions - eiger febl and feb in versions
2. On-board Detector Server Compatibility
2 On-board Detector Server Compatibility
========================================== ==========================================
@ -57,16 +60,16 @@ This document describes the differences between v7.0.0.rc1 and v6.1.2
3. Firmware Requirements 3 Firmware Requirements
======================== ========================
Eiger 17.02.2022 (v30) Eiger 20.02.2023 (v31)
Jungfrau 04.11.2022 (v1.4, HW v1.0) Jungfrau 04.11.2022 (v1.4, HW v1.0)
03.11.2022 (v2.4, HW v2.0) 03.11.2022 (v2.4, HW v2.0)
Mythen3 05.12.2022 (v1.4) Mythen3 24.01.2023 (v1.4)
Gotthard2 23.11.2022 (v0.3) Gotthard2 23.11.2022 (v0.3)
@ -106,22 +109,22 @@ This document describes the differences between v7.0.0.rc1 and v6.1.2
4. Kernel Requirements 4 Kernel Requirements
====================== ======================
Blackfin Blackfin
======== --------
Latest version: Fri Oct 29 00:00:00 2021 Latest version: Fri Oct 29 00:00:00 2021
Older ones will work, but might have issues with programming firmware via Older ones will work, but might have issues with programming firmware via
the package. the package.
Nios Nios
==== -----
Compatible version: Mon May 10 18:00:21 CEST 2021 Compatible version: Mon May 10 18:00:21 CEST 2021
Kernel Upgrade Kernel Upgrade
============== ---------------
Eiger via bit files Eiger via bit files
Others via command Others via command
@ -134,7 +137,7 @@ This document describes the differences between v7.0.0.rc1 and v6.1.2
5. Download, Documentation & Support 5 Download, Documentation & Support
==================================== ====================================
Download Download
@ -190,6 +193,9 @@ This document describes the differences between v7.0.0.rc1 and v6.1.2
https://slsdetectorgroup.github.io/devdoc/udpheader.html https://slsdetectorgroup.github.io/devdoc/udpheader.html
https://slsdetectorgroup.github.io/devdoc/udpdetspec.html https://slsdetectorgroup.github.io/devdoc/udpdetspec.html
slsReceiver Zmq Format:
https://slsdetectorgroup.github.io/devdoc/slsreceiver.html#zmq-json-header-format
TroubleShooting: TroubleShooting:
https://slsdetectorgroup.github.io/devdoc/troubleshooting.html https://slsdetectorgroup.github.io/devdoc/troubleshooting.html
https://slsdetectorgroup.github.io/devdoc/troubleshooting.html#receiver-pc-tuning-options https://slsdetectorgroup.github.io/devdoc/troubleshooting.html#receiver-pc-tuning-options
@ -206,4 +212,3 @@ This document describes the differences between v7.0.0.rc1 and v6.1.2
dhanya.thattil@psi.ch dhanya.thattil@psi.ch
erik.frojdh@psi.ch erik.frojdh@psi.ch

2
cmk.sh
View File

@ -33,7 +33,7 @@ Usage: $0 [-b] [-c] [-d <HDF5 directory>] [e] [g] [-h] [i] [-j <Number of thread
-c: Clean -c: Clean
-d: HDF5 Custom Directory -d: HDF5 Custom Directory
-e: Debug mode -e: Debug mode
-g: Build/Rebuilds only gui -g: Build/Rebuilds gui
-h: Builds/Rebuilds Cmake files with HDF5 package -h: Builds/Rebuilds Cmake files with HDF5 package
-i: Builds tests -i: Builds tests
-j: Number of threads to compile through -j: Number of threads to compile through

View File

@ -116,12 +116,16 @@ Program from console
# Always ensure that the client and server software are of the same release. # Always ensure that the client and server software are of the same release.
# copies server from tftp folder of pc, links new server to jungfrauDetectorServer, # copies server, links new server to jungfrauDetectorServer,
# removes old server from respawn, sets up new lnked server to respawn # removes old server from respawn, sets up new lnked server to respawn
# programs fpga, # programs fpga, reboots
# reboots
# v5.0.0 - 6.0.0 (copies server from tftp folder of the pc)
sls_detector_put update jungfrauDetectorServervxxx pcxxx xx.pof sls_detector_put update jungfrauDetectorServervxxx pcxxx xx.pof
# v6.1.1 - present (copies server from the full path provided)
sls_detector_put update jungfrauDetectorServervxxx xx.pof
# Or only program firmware # Or only program firmware
sls_detector_put programfpga xxx.pof sls_detector_put programfpga xxx.pof
@ -182,11 +186,16 @@ Program from console
# Always ensure that the client and server software are of the same release. # Always ensure that the client and server software are of the same release.
# copies server from tftp folder of pc, links new server to mythen3DetectorServer, # copies server, links new server to mythen3DetectorServer,
# programs fpga, # removes old server from respawn, sets up new lnked server to respawn
# reboots # programs fpga, reboots
# v5.0.0 - 6.0.0 (copies server from tftp folder of the pc)
sls_detector_put update mythen3DetectorServervxxx pcxxx xxx.rbf sls_detector_put update mythen3DetectorServervxxx pcxxx xxx.rbf
# v6.1.1 - present (copies server from the full path provided)
sls_detector_put update mythen3DetectorServervxxx xxx.rbf
# Or only program firmware # Or only program firmware
sls_detector_put programfpga xxx.rbf sls_detector_put programfpga xxx.rbf
@ -211,11 +220,16 @@ Program from console
# Always ensure that the client and server software are of the same release. # Always ensure that the client and server software are of the same release.
# copies server from tftp folder of pc, links new server to gotthard2DetectorServer, # copies server, links new server to gotthard2DetectorServer,
# programs fpga, # removes old server from respawn, sets up new lnked server to respawn
# reboots # programs fpga, reboots
# v5.0.0 - 6.0.0 (copies server from tftp folder of the pc)
sls_detector_put update gotthard2DetectorServervxxx pcxxx xxx.rbf sls_detector_put update gotthard2DetectorServervxxx pcxxx xxx.rbf
# v6.1.1 - present (copies server from the full path provided)
sls_detector_put update gotthard2DetectorServervxxx xxx.rbf
# Or only program firmware # Or only program firmware
sls_detector_put programfpga xxx.rbf sls_detector_put programfpga xxx.rbf
@ -257,12 +271,16 @@ Program from console
# Always ensure that the client and server software are of the same release. # Always ensure that the client and server software are of the same release.
# copies server from tftp folder of pc, links new server to moenchDetectorServer, # copies server, links new server to moenchDetectorServer,
# removes old server from respawn, sets up new lnked server to respawn # removes old server from respawn, sets up new lnked server to respawn
# programs fpga, # programs fpga, reboots
# reboots
# v5.0.0 - 6.0.0 (copies server from tftp folder of the pc)
sls_detector_put update moenchDetectorServervxxx pcxxx xx.pof sls_detector_put update moenchDetectorServervxxx pcxxx xx.pof
# v6.1.1 - present (copies server from the full path provided)
sls_detector_put update moenchDetectorServervxxx xx.pof
# Or only program firmware # Or only program firmware
sls_detector_put programfpga xxx.pof sls_detector_put programfpga xxx.pof
@ -288,12 +306,16 @@ Program from console
# Always ensure that the client and server software are of the same release. # Always ensure that the client and server software are of the same release.
# copies server from tftp folder of pc, links new server to ctbDetectorServer, # copies server, links new server to ctbDetectorServer,
# removes old server from respawn, sets up new lnked server to respawn # removes old server from respawn, sets up new lnked server to respawn
# programs fpga, # programs fpga, reboots
# reboots
# v5.0.0 - 6.0.0 (copies server from tftp folder of the pc)
sls_detector_put update ctbDetectorServervxxx pcxxx xx.pof sls_detector_put update ctbDetectorServervxxx pcxxx xx.pof
# v6.1.1 - present (copies server from the full path provided)
sls_detector_put update ctbDetectorServervxxx xx.pof
# Or only program firmware # Or only program firmware
sls_detector_put programfpga xxx.pof sls_detector_put programfpga xxx.pof

View File

@ -1,14 +1,3 @@
.. note ::
The default branch of our git repository is developer. It contains the
latest development version. It is expected to compile and work but
features might be added or tweaked. In some cases the API might also change
without being communicated. If absolute stability of the API is needed please
use one of the release versions.
.. warning :: .. warning ::
Before building from source make sure that you have the Before building from source make sure that you have the
@ -161,7 +150,7 @@ Build using in-built cmk.sh script
-c: Clean -c: Clean
-d: HDF5 Custom Directory -d: HDF5 Custom Directory
-e: Debug mode -e: Debug mode
-g: Build/Rebuilds only gui -g: Build/Rebuilds gui
-h: Builds/Rebuilds Cmake files with HDF5 package -h: Builds/Rebuilds Cmake files with HDF5 package
-i: Builds tests -i: Builds tests
-j: Number of threads to compile through -j: Number of threads to compile through
@ -178,17 +167,17 @@ Build using in-built cmk.sh script
-z: Moench zmq processor -z: Moench zmq processor
# get all options # display all options
./cmk.sh -? ./cmk.sh -?
# new build and compile in parallel: # new build and compile in parallel (recommended basic option):
./cmk.sh -bj5 ./cmk.sh -cbj5
# new build, python and compile in parallel: # new build, python and compile in parallel:
./cmk.sh -bpj5 ./cmk.sh -cbpj5
#To use the system zmq (/usr/lib64) instead #To use the system zmq (/usr/lib64) instead
./cmk.sh -bj5 -q /usr/lib64 ./cmk.sh -cbj5 -q /usr/lib64

View File

@ -86,6 +86,184 @@ Client Commands
sls_detector_get -h rx_framescaught sls_detector_get -h rx_framescaught
ZMQ: Json Header Format
------------------------
**Change in field names from slsDetectorPackage v6.x.x to v7.0.0**
* detSpec1 <- bunchId
* detSpec2 <- reserved
* detSpec3 <- debug
* detSpec4 <- roundRNumber
**Format**
.. code-block:: bash
{
"jsonversion": unsigned int,
"bitmode": unsigned int,
"fileIndex": unsigned long int,
"detshape": [
unsigned int,
unsigned int
],
"shape": [
unsigned int,
unsigned int
],
"size": unsigned int,
"acqIndex": unsigned long int,
"frameIndex": unsigned long int,
"progress": double,
"fname": string,
"data": unsigned int,
"completeImage": unsigned int,
"frameNumber": unsigned long long int,
"expLength": unsigned int,
"packetNumber": unsigned int,
"detSpec1": unsigned long int,
"timestamp": unsigned long int,
"modId": unsigned int,
"row": unsigned int,
"column": unsigned int,
"detSpec2": unsigned int,
"detSpec3": unsigned int,
"detSpec4": unsigned int,
"detType": unsigned int,
"version": unsigned int,
"flipRows": unsigned int,
"quad": unsigned int,
"addJsonHeader": {
string : string
}
}
+--------------+----------------------------------------------+
| Field | Description |
+--------------+----------------------------------------------+
| jsonversion | Version of the json header. |
| | Value at 4 for v6.x.x and v7.x.x |
+--------------+----------------------------------------------+
| bitmode | Bits per pixel [4|8|16|32] |
+--------------+----------------------------------------------+
| fileIndex | Current file acquisition index |
+--------------+----------------------------------------------+
| detshape | Geometry of the entire detector |
+--------------+----------------------------------------------+
| shape | Geometry of the current port streamed out |
+--------------+----------------------------------------------+
| size | Size of image of current port in bytesout |
+--------------+----------------------------------------------+
| acqIndex | Frame number from the detector (redundant) |
+--------------+----------------------------------------------+
| frameIndex | Frame number of current acquisition |
| | (Starting at 0) |
+--------------+----------------------------------------------+
| progress | Progress of current acquisition in % |
+--------------+----------------------------------------------+
| fname | Current file name |
+--------------+----------------------------------------------+
| data | 1 if there is data following |
| | 0 if dummy header |
+--------------+----------------------------------------------+
| completeImage| 1 if no missing packets for this frame |
| | in this port, else 0 |
+--------------+----------------------------------------------+
| frameNumber | Frame number |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| expLength | subframe number (32 bit eiger) |
| | or real time exposure time in 100ns (others) |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| packetNumber | Number of packets caught for that frame |
+--------------+----------------------------------------------+
| detSpec1 | See :ref:`here<Detector Specific Fields>` |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| timestamp | Timestamp with 10 MHz clock |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| modId | Module Id |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| row | Row number in detector |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| column | Column number in detector |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| detSpec2 | See :ref:`here<Detector Specific Fields>` |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| detSpec3 | See :ref:`here<Detector Specific Fields>` |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| detSpec4 | See :ref:`here<Detector Specific Fields>` |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| detType | Detector type enum |
| detSpec3 | See :ref:`Detector enum<Detector Enum>` |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| version | Detector header version. At 2 |
| | [From detector udp header] |
+--------------+----------------------------------------------+
| flipRows | 1 if rows should be flipped. |
| | Usually for Eiger bottom. |
+--------------+----------------------------------------------+
| quad | 1 if its an Eiger quad. |
+--------------+----------------------------------------------+
| addJsonHeader| Optional custom parameters that is required |
| | for processing code. |
+--------------+----------------------------------------------+
SLS Receiver Header Format
--------------------------
It is 112 bytes and consists of:
* 48 bytes of the SLS Detector Header (described in :ref:`the current detector header <detector udp header>`)
* 64 bytes of packet mask
.. code-block:: cpp
typedef struct {
uint64_t frameNumber;
uint32_t expLength;
uint32_t packetNumber;
uint64_t detSpec1;
uint64_t timestamp;
uint16_t modId;
uint16_t row;
uint16_t column;
uint16_t detSpec2;
uint32_t detSpec3;
uint16_t detSpec4;
uint8_t detType;
uint8_t version;
} sls_detector_header;
struct sls_receiver_header {
sls_detector_header detHeader; /**< is the detector header */
sls_bitset packetsMask; /**< is the packets caught bit mask */
};
.. note ::
| The packetNumber in the SLS Receiver Header will be modified to number of packets caught by receiver for that frame. For eg. Jungfrau will have 128 packets per frame. If it is less, then this is a partial frame due to missing packets.
| Furthermore, the bit mask will specify which packets have been received.
File format File format
-------------- --------------
@ -117,8 +295,6 @@ Some file name examples:
Each acquisition will create a master file that can be enabled/disabled using **fmaster**. This should have parameters relevant to the acquisition. Each acquisition will create a master file that can be enabled/disabled using **fmaster**. This should have parameters relevant to the acquisition.
SLS Receiver Header consist of SLS Detector Header + 64 bytes of bitmask, altogether 112 bytes. The packetNumber in the sls detector header part, will be updated to number of packets caught by receiver for that frame. Furthermore, the bit mask will specify which packets have been received.
**Binary file format** **Binary file format**
This is the default file format. This is the default file format.

View File

@ -11,7 +11,7 @@ Current Version
**v2.0 (slsDetectorPackage v7.0.0+)** **v2.0 (slsDetectorPackage v7.0.0+)**
.. table:: <---------------------------------------------------- 8 bytes ----------------------------------------------------> .. table:: <---------------------------------------------------- 8 bytes per row --------------------------------------------->
:align: center :align: center
:widths: 30,30,30,15,15 :widths: 30,30,30,15,15

6
examples/badchannel.txt Normal file
View File

@ -0,0 +1,6 @@
0
10, 30
40:45 50:52
1279
# all bad channels are applied for all counters in deector

View File

@ -1,18 +1,18 @@
# detector hostname # detector hostname
hostname localhost:1910 hostname localhost:1910
# receiver hostname
rx_hostname mpc1922:2010
# udp destination ports # udp destination ports
udp_dstport 50010 udp_dstport 50010
# udp destination ip from rx_hostname
udp_dstip auto
# udp source ip (same subnet as udp_dstip) # udp source ip (same subnet as udp_dstip)
udp_srcip 192.168.1.100 udp_srcip 192.168.1.100
# receiver hostname
rx_hostname mpc1922:2010
# udp destination ip from rx_hostname
udp_dstip auto
# output file directory # output file directory
fpath /tmp fpath /tmp
@ -27,418 +27,7 @@ dbitclk 40
# patterns # patterns
patword 0x0000 0x0000000000000000 pattern /tmp/pattern.pat
patword 0x0001 0x0000000000000000
patword 0x0002 0x0008000900080000
patword 0x0003 0x0008000900080000
patword 0x0004 0x0008000900080000
patword 0x0005 0x0008000900080000
patword 0x0006 0x0008000900080000
patword 0x0007 0x0008000900080000
patword 0x0008 0x0008000900080000
patword 0x0009 0x0008000900080000
patword 0x000a 0x0008000900080000
patword 0x000b 0x0008000900080000
patword 0x000c 0x0008000900080000
patword 0x000d 0x0008000900080000
patword 0x000e 0x0008000900080000
patword 0x000f 0x0008000900080000
patword 0x0010 0x0008000900080000
patword 0x0011 0x0008000900080000
patword 0x0012 0x0008000900080000
patword 0x0013 0x0008000900080000
patword 0x0014 0x0008000900080000
patword 0x0015 0x0008000900080000
patword 0x0016 0x0008400900080020
patword 0x0017 0x0008400900080020
patword 0x0018 0x0008599f0418503a
patword 0x0019 0x0008599f0418503a
patword 0x001a 0x0108599f0418503a
patword 0x001b 0x0108599f0418503a
patword 0x001c 0x0108599f0418503a
patword 0x001d 0x0108599f0418503a
patword 0x001e 0x0108599f0418503a
patword 0x001f 0x0108599f0418503a
patword 0x0020 0x0108599f0418503a
patword 0x0021 0x0108599f0418503a
patword 0x0022 0x0108599f0418503a
patword 0x0023 0x0108599f0418503a
patword 0x0024 0x0108599f0418503a
patword 0x0025 0x0108599f0418503a
patword 0x0026 0x0108599f0418503a
patword 0x0027 0x0108599f0418503a
patword 0x0028 0x0108599f0418503a
patword 0x0029 0x0108599f0418503a
patword 0x002a 0x0108599f0418503a
patword 0x002b 0x0108599f0418503a
patword 0x002c 0x0108599f0418503a
patword 0x002d 0x0108599f0418503a
patword 0x002e 0x0108599f0418503a
patword 0x002f 0x0108599f0418503a
patword 0x0030 0x0108599f0418503a
patword 0x0031 0x0108599f0418503a
patword 0x0032 0x0108599f0418503a
patword 0x0033 0x0108599f0418503a
patword 0x0034 0x0108599f0418503a
patword 0x0035 0x0108599f0418503a
patword 0x0036 0x0108599f0418503a
patword 0x0037 0x0108599f0418503a
patword 0x0038 0x0108599f0418503a
patword 0x0039 0x0108599f0418503a
patword 0x003a 0x0108599f0418503a
patword 0x003b 0x0108599f0418503a
patword 0x003c 0x0108599f0418503a
patword 0x003d 0x0108599f0418503a
patword 0x003e 0x0108599f0418503a
patword 0x003f 0x0108599f0418503a
patword 0x0040 0x0108599f0418503a
patword 0x0041 0x0108599f0418503a
patword 0x0042 0x0108599f0418503a
patword 0x0043 0x0108599f0418503a
patword 0x0044 0x0108599f0418503a
patword 0x0045 0x0108599f0418503a
patword 0x0046 0x0108599f0418503a
patword 0x0047 0x0108599f0418503a
patword 0x0048 0x0108599f0418503a
patword 0x0049 0x0108599f0418503a
patword 0x004a 0x0108599f0418503a
patword 0x004b 0x0108599f0418503a
patword 0x004c 0x0108599f0418503a
patword 0x004d 0x0108599f0418503a
patword 0x004e 0x0108599f0418503a
patword 0x004f 0x0108599f0418503a
patword 0x0050 0x0108599f0418503a
patword 0x0051 0x0108599f0418503a
patword 0x0052 0x0108599f0418503a
patword 0x0053 0x0108599f0418503a
patword 0x0054 0x0108599f0418503a
patword 0x0055 0x0108599f0418503a
patword 0x0056 0x0108599f0418503a
patword 0x0057 0x0108599f0418503a
patword 0x0058 0x0108599f0418503a
patword 0x0059 0x0108599f0418503a
patword 0x005a 0x0108599f0418503a
patword 0x005b 0x0108599f0418503a
patword 0x005c 0x0108599f0418503a
patword 0x005d 0x0108599f0418503a
patword 0x005e 0x0108599f0418503a
patword 0x005f 0x0108599f0418503a
patword 0x0060 0x0108599f0418503a
patword 0x0061 0x0108599f0418503a
patword 0x0062 0x0108599f0418503a
patword 0x0063 0x0108599f0418503a
patword 0x0064 0x0108599f0418503a
patword 0x0065 0x0108599f0418503a
patword 0x0066 0x0108599f0418503a
patword 0x0067 0x0108599f0418503a
patword 0x0068 0x0108599f0418503a
patword 0x0069 0x0108599f0418503a
patword 0x006a 0x0108599f0418503a
patword 0x006b 0x0108599f0418503a
patword 0x006c 0x0108599f0418503a
patword 0x006d 0x0108599f0418503a
patword 0x006e 0x0108599f0418503a
patword 0x006f 0x0108599f0418503a
patword 0x0070 0x0108599f0418503a
patword 0x0071 0x0108599f0418503a
patword 0x0072 0x0108599f0418503a
patword 0x0073 0x0108599f0418503a
patword 0x0074 0x0108599f0418503a
patword 0x0075 0x0108599f0418503a
patword 0x0076 0x0108599f0418503a
patword 0x0077 0x0108599f0418503a
patword 0x0078 0x0108599f0418503a
patword 0x0079 0x0108599f0418503a
patword 0x007a 0x0108599f0418503a
patword 0x007b 0x0108599f0418503a
patword 0x007c 0x0108599f0418503a
patword 0x007d 0x0108599f0418503a
patword 0x007e 0x010859960418503a
patword 0x007f 0x010859960418503a
patword 0x0080 0x010859960418503a
patword 0x0081 0x010859960418503a
patword 0x0082 0x010859960418503a
patword 0x0083 0x010859960418503a
patword 0x0084 0x010859960418503a
patword 0x0085 0x010859960418503a
patword 0x0086 0x010859960418503a
patword 0x0087 0x010859960418503a
patword 0x0088 0x010859960418503a
patword 0x0089 0x010859960418503a
patword 0x008a 0x010859960418503a
patword 0x008b 0x010859960418503a
patword 0x008c 0x010859960418503a
patword 0x008d 0x010859960418503a
patword 0x008e 0x010859960418503a
patword 0x008f 0x010859960418503a
patword 0x0090 0x010859960418503a
patword 0x0091 0x010859960418503a
patword 0x0092 0x010819960418501a
patword 0x0093 0x010819960418501a
patword 0x0094 0x010819960418501a
patword 0x0095 0x010819960418501a
patword 0x0096 0x030819960418501a
patword 0x0097 0x030819960418501a
patword 0x0098 0x030819960418501a
patword 0x0099 0x030819960418501a
patword 0x009a 0x030819960418501a
patword 0x009b 0x030819960418501a
patword 0x009c 0x030819960418501a
patword 0x009d 0x030819960418501a
patword 0x009e 0x030819960418501a
patword 0x009f 0x030819960418501a
patword 0x00a0 0x030819960418501a
patword 0x00a1 0x030819960418501a
patword 0x00a2 0x030819960418501a
patword 0x00a3 0x030819960418501a
patword 0x00a4 0x030819960418501a
patword 0x00a5 0x030819960418501a
patword 0x00a6 0x030819960418501a
patword 0x00a7 0x030819960418501a
patword 0x00a8 0x030819960418501a
patword 0x00a9 0x030819960418501a
patword 0x00aa 0x030819960418501a
patword 0x00ab 0x030819960418501a
patword 0x00ac 0x030819960008501a
patword 0x00ad 0x030819960008501a
patword 0x00ae 0x030819960008501a
patword 0x00af 0x030819960008501a
patword 0x00b0 0x030819960008501a
patword 0x00b1 0x030819960008501a
patword 0x00b2 0x030819960008501a
patword 0x00b3 0x030819960008501a
patword 0x00b4 0x030819960008501a
patword 0x00b5 0x030819960008501a
patword 0x00b6 0x030819960008501a
patword 0x00b7 0x030819960008501a
patword 0x00b8 0x030819960008501a
patword 0x00b9 0x030819960008501a
patword 0x00ba 0x030819960008501a
patword 0x00bb 0x030819960008501a
patword 0x00bc 0x030819960008501a
patword 0x00bd 0x030819960008501a
patword 0x00be 0x030819960008501a
patword 0x00bf 0x030819960008501a
patword 0x00c0 0x0308199f0008501a
patword 0x00c1 0x0308199f0008501a
patword 0x00c2 0x0308199f0008501a
patword 0x00c3 0x0308199f0008501a
patword 0x00c4 0x0308199f0008501a
patword 0x00c5 0x0308199f0008501a
patword 0x00c6 0x0308199f0008501a
patword 0x00c7 0x0308199f0008501a
patword 0x00c8 0x0308199f0008501a
patword 0x00c9 0x0308199f0008501a
patword 0x00ca 0x0308199f0008501a
patword 0x00cb 0x0308199f0008501a
patword 0x00cc 0x0308199f0008501a
patword 0x00cd 0x0308199f0008501a
patword 0x00ce 0x0308199f0008501a
patword 0x00cf 0x0308199f0008501a
patword 0x00d0 0x0308199f0008501a
patword 0x00d1 0x0308199f0008501a
patword 0x00d2 0x0308199f0008501a
patword 0x00d3 0x0308199f0008501a
patword 0x00d4 0x0308599f0008503a
patword 0x00d5 0x0308599f0008503a
patword 0x00d6 0x030c599f000850ba
patword 0x00d7 0x030c599f000850ba
patword 0x00d8 0x030c599f000850ba
patword 0x00d9 0x030c599f000850ba
patword 0x00da 0x030c599f000850ba
patword 0x00db 0x030c599f000850ba
patword 0x00dc 0x030c599f000850ba
patword 0x00dd 0x030c599f000850ba
patword 0x00de 0x030c599f000850ba
patword 0x00df 0x030c599f000850ba
patword 0x00e0 0x030c599f000850ba
patword 0x00e1 0x030c599f000850ba
patword 0x00e2 0x030c599f000850ba
patword 0x00e3 0x030c599f000850ba
patword 0x00e4 0x030c599f000850ba
patword 0x00e5 0x030c599f000850ba
patword 0x00e6 0x030c599f000850ba
patword 0x00e7 0x030c599f000850ba
patword 0x00e8 0x030c599f000850ba
patword 0x00e9 0x030c599f000850ba
patword 0x00ea 0x030c799f010858ba
patword 0x00eb 0x030c799f010858ba
patword 0x00ec 0x030c599f000850ba
patword 0x00ed 0x030c599f000850ba
patword 0x00ee 0x030c599f000850ba
patword 0x00ef 0x030c599f000850ba
patword 0x00f0 0x030c599f000850ba
patword 0x00f1 0x030c599f000850ba
patword 0x00f2 0x030c599f000850ba
patword 0x00f3 0x030c599f000850ba
patword 0x00f4 0x030c599f000850ba
patword 0x00f5 0x030c599f000850ba
patword 0x00f6 0x030c599f000850ba
patword 0x00f7 0x030c599f000850ba
patword 0x00f8 0x030c599f000850ba
patword 0x00f9 0x030c599f000850ba
patword 0x00fa 0x030c599f000850ba
patword 0x00fb 0x030c599f000850ba
patword 0x00fc 0x030c599f000850ba
patword 0x00fd 0x030c599f000850ba
patword 0x00fe 0x030c599f000850ba
patword 0x00ff 0x030c599f000850ba
patword 0x0100 0x030c599f000850ba
patword 0x0101 0x030c599f000850ba
patword 0x0102 0x030c599f400850ba
patword 0x0103 0x030c599f400850ba
patword 0x0104 0x030c599f600850ba
patword 0x0105 0x030c599f400850ba
patword 0x0106 0x030c599f400850ba
patword 0x0107 0x030c599f400850ba
patword 0x0108 0x870c599f682e50ba
patword 0x0109 0x870c599f482850ba
patword 0x010a 0x870c599f000e50ba
patword 0x010b 0x870c599f000850ba
patword 0x010c 0x870c599f000e50ba
patword 0x010d 0x870c599f000850ba
patword 0x010e 0x870c599f000e50ba
patword 0x010f 0x870c599f000850ba
patword 0x0110 0x870c599f000e50ba
patword 0x0111 0x870c599f000850ba
patword 0x0112 0x870c599f000e50ba
patword 0x0113 0x870c599f000850ba
patword 0x0114 0x870c599f000e50ba
patword 0x0115 0x870c599f000850ba
patword 0x0116 0x870c599f000e50ba
patword 0x0117 0x870c599f000850ba
patword 0x0118 0x870c599f000e50ba
patword 0x0119 0x870c599f000850ba
patword 0x011a 0x870c599f000e50ba
patword 0x011b 0x870c599f000850ba
patword 0x011c 0x870c599f000e50ba
patword 0x011d 0x870c599f000850ba
patword 0x011e 0x870c599f000e50ba
patword 0x011f 0x870c599f000850ba
patword 0x0120 0x870c599f000e50ba
patword 0x0121 0x870c599f000850ba
patword 0x0122 0x870c599f200e50ba
patword 0x0123 0x870c599f000850ba
patword 0x0124 0x870c599f000e50ba
patword 0x0125 0x870c599f000850ba
patword 0x0126 0x870c599f000e50ba
patword 0x0127 0x870c599f000850ba
patword 0x0128 0x870c599f000e50ba
patword 0x0129 0x870c599f000850ba
patword 0x012a 0x870c599f000e50ba
patword 0x012b 0x870c599f000850ba
patword 0x012c 0x870c599f000e50ba
patword 0x012d 0x870c599f000850ba
patword 0x012e 0x870c599f000e50ba
patword 0x012f 0x870c599f000850ba
patword 0x0130 0x870c599f000e50ba
patword 0x0131 0x870c599f000850ba
patword 0x0132 0x870c599f000e50ba
patword 0x0133 0x870c599f000850ba
patword 0x0134 0x870c599f000e50ba
patword 0x0135 0x870c599f000850ba
patword 0x0136 0x870c599f000e50ba
patword 0x0137 0x870c599f000850ba
patword 0x0138 0x870c599f000e50ba
patword 0x0139 0x870c599f000850ba
patword 0x013a 0x870c599f282e50ba
patword 0x013b 0x870c599f082850ba
patword 0x013c 0x870c599f000e50ba
patword 0x013d 0x870c599f000850ba
patword 0x013e 0x870c599f000e50ba
patword 0x013f 0x870c599f000850ba
patword 0x0140 0x870c599f000e50ba
patword 0x0141 0x870c599f000850ba
patword 0x0142 0x870c599f000e50ba
patword 0x0143 0x870c599f000850ba
patword 0x0144 0x870c599f000e50ba
patword 0x0145 0x870c599f000850ba
patword 0x0146 0x870c599f000e50ba
patword 0x0147 0x870c599f000850ba
patword 0x0148 0x870c599f000e50ba
patword 0x0149 0x870c599f000850ba
patword 0x014a 0x870c599f000e50ba
patword 0x014b 0x870c599f000850ba
patword 0x014c 0x870c599f000e50ba
patword 0x014d 0x870c599f000850ba
patword 0x014e 0x870c599f000e50ba
patword 0x014f 0x870c599f000850ba
patword 0x0150 0x870c599f000e50ba
patword 0x0151 0x870c599f000850ba
patword 0x0152 0x870c599f000e50ba
patword 0x0153 0x870c599f000850ba
patword 0x0154 0x870c599f200e50ba
patword 0x0155 0x870c599f000850ba
patword 0x0156 0x870c599f000e50ba
patword 0x0157 0x870c599f000850ba
patword 0x0158 0x870c599f000e50ba
patword 0x0159 0x870c599f000850ba
patword 0x015a 0x870c599f000e50ba
patword 0x015b 0x870c599f000850ba
patword 0x015c 0x870c599f000e50ba
patword 0x015d 0x870c599f000850ba
patword 0x015e 0x870c599f000e50ba
patword 0x015f 0x870c599f000850ba
patword 0x0160 0x870c599f000e50ba
patword 0x0161 0x870c599f000850ba
patword 0x0162 0x870c599f000e50ba
patword 0x0163 0x870c599f000850ba
patword 0x0164 0x870c599f000e50ba
patword 0x0165 0x870c599f000850ba
patword 0x0166 0x870c599f000e50ba
patword 0x0167 0x870c599f000850ba
patword 0x0168 0x870c599f000e50ba
patword 0x0169 0x870c599f000850ba
patword 0x016a 0x870c599f000e50ba
patword 0x016b 0x870c599f000850ba
patword 0x016c 0x070c599f000850ba
patword 0x016d 0x070c599f000850ba
patword 0x016e 0x000c599f000850ba
patword 0x016f 0x000c599f000850ba
patword 0x0170 0x0008599f200e503a
patword 0x0171 0x0008599f0008503a
patword 0x0172 0x0008599f200e503a
patword 0x0173 0x0008599f0008503a
patword 0x0174 0x0008599f0008503a
patword 0x0175 0x0008599f0008503a
patword 0x0176 0x0008599f0008503a
patword 0x0177 0x0008599f0008503a
patword 0x0178 0x0008599f0008503a
patword 0x0179 0x0008599f0008503a
patword 0x017a 0x0008599f0008503a
patword 0x017b 0x0008599f0008503a
patword 0x017c 0x0008599f0008503a
patword 0x017d 0x0008599f0008503a
patword 0x017e 0x0008599f0008503a
patword 0x017f 0x0008599f0008503a
patword 0x0180 0x0008599f0008503a
patword 0x0181 0x0008599f0008503a
patword 0x0182 0x0008599f0008503a
patword 0x0183 0x0008599f0008503a
patword 0x0184 0x0008599f0008503a
patword 0x0185 0x0008599f0008503a
patword 0x0186 0x0008599f0008503a
patword 0x0187 0x0008599f0008503a
patword 0x0188 0x0008599f0008503a
patword 0x0189 0x0008599f0008503a
patword 0x018a 0x0008599f0008503a
patword 0x018b 0x0008599f0008503a
patword 0x018c 0x0008599f0008503a
patword 0x018d 0x0008599f0008503a
patioctrl 0x8f0effff6dbffdbf
patlimits 0x0000 0x018c
patloop 0 0x013a 0x016b
patnloop 0 0x199
patloop 1 0x0400 0x0400
patnloop 1 0
patloop 2 0x0400 0x0400
patnloop 2 0
patwait 0 0x00aa
patwaittime 0 10000
patwait 1 0x0400
patwaittime 1 0
patwait 2 0x0400
patwaittime 2 0
# dacs # dacs
dac 6 800 dac 6 800

View File

@ -1,13 +1,13 @@
# detector hostname # detector hostname
hostname localhost:1900 hostname localhost:1900
# receiver hostname
rx_hostname mpc1922:2000
# udp destination ports # udp destination ports
udp_dstport 50000 udp_dstport 50000
udp_dstport2 50001 udp_dstport2 50001
# receiver hostname
rx_hostname mpc1922:2000
# udp destination ip from rx_hostname # udp destination ip from rx_hostname
udp_dstip auto udp_dstip auto

View File

@ -1,15 +1,15 @@
# detector hostname # detector hostname
hostname localhost:1900+localhost:1902+ hostname localhost:1900+localhost:1902+
# receiver hostname
rx_hostname mpc1922:2000+mpc1922:2001+
# udp destination ports # udp destination ports
0:udp_dstport 50000 0:udp_dstport 50000
0:udp_dstport2 50001 0:udp_dstport2 50001
1:udp_dstport 50002 1:udp_dstport 50002
1:udp_dstport2 50003 1:udp_dstport2 50003
# receiver hostname
rx_hostname mpc1922:2000+mpc1922:2001+
# udp destination ip from rx_hostname # udp destination ip from rx_hostname
udp_dstip auto udp_dstip auto

View File

@ -1,18 +1,18 @@
# detector hostname # detector hostname
hostname localhost:1904 hostname localhost:1904
# receiver hostname
rx_hostname mpc1922:2004
# udp destination ports # udp destination ports
udp_dstport 50004 udp_dstport 50004
# udp destination ip from rx_hostname
udp_dstip auto
# udp source ip (same subnet as udp_dstip) # udp source ip (same subnet as udp_dstip)
udp_srcip 192.168.1.100 udp_srcip 192.168.1.100
# receiver hostname
rx_hostname mpc1922:2004
# udp destination ip from rx_hostname
udp_dstip auto
# output file directory # output file directory
fpath /tmp fpath /tmp

View File

@ -1,24 +1,12 @@
# detector hostname # detector hostname
hostname localhost:1914 hostname localhost:1914
# receiver hostname
rx_hostname mpc1922:2014
# udp destination ports # udp destination ports
udp_dstport 50014 udp_dstport 50014
# udp destination ip from rx_hostname
udp_dstip auto
# udp source ip (same subnet as udp_dstip) # udp source ip (same subnet as udp_dstip)
udp_srcip 192.168.1.100 udp_srcip 192.168.1.100
# output file directory
fpath /tmp
# disable file writing
fwrite 0
# enable 2nd interface for veto debugging # enable 2nd interface for veto debugging
# udp destination port for veto # udp destination port for veto
udp_dstport2 50015 udp_dstport2 50015
@ -27,6 +15,18 @@ udp_dstip2 auto
# udp source ip (same subnet as udp_dstip) # udp source ip (same subnet as udp_dstip)
udp_srcip2 192.168.1.100 udp_srcip2 192.168.1.100
# receiver hostname
rx_hostname mpc1922:2014
# udp destination ip from rx_hostname
udp_dstip auto
# output file directory
fpath /tmp
# disable file writing
fwrite 0
# to enable 2nd interface for veto debugging # to enable 2nd interface for veto debugging
numinterfaces 2 numinterfaces 2

View File

@ -1,21 +1,21 @@
# detector hostname # detector hostname
hostname localhost:1906 hostname localhost:1906
# receiver hostname
rx_hostname mpc1922:2006
# udp destination ports # udp destination ports
udp_dstport 50006 udp_dstport 50006
udp_dstport2 50007 udp_dstport2 50007
# udp destination ip from rx_hostname
udp_dstip auto
udp_dstip2 auto
# udp source ip (same subnet as udp_dstip) # udp source ip (same subnet as udp_dstip)
udp_srcip 192.168.1.100 udp_srcip 192.168.1.100
udp_srcip2 192.168.1.100 udp_srcip2 192.168.1.100
# receiver hostname
rx_hostname mpc1922:2006
# udp destination ip from rx_hostname
udp_dstip auto
udp_dstip2 auto
# output file directory # output file directory
fpath /tmp fpath /tmp

View File

@ -4,13 +4,6 @@ detsize 2048 1024
# detector hostname # detector hostname
virtual 4 1952 virtual 4 1952
# receiver hostname and tcpports
0:rx_tcpport 1970
1:rx_tcpport 1971
2:rx_tcpport 1972
3:rx_tcpport 1973
rx_hostname mpc1922
# udp destination ports # udp destination ports
0:udp_dstport2 50001 0:udp_dstport2 50001
0:udp_dstport2 50002 0:udp_dstport2 50002
@ -21,14 +14,21 @@ rx_hostname mpc1922
3:udp_dstport 50007 3:udp_dstport 50007
3:udp_dstport2 50008 3:udp_dstport2 50008
# udp destination ip from rx_hostname
udp_dstip auto
udp_dstip2 auto
# udp source ip (same subnet as udp_dstip) # udp source ip (same subnet as udp_dstip)
udp_srcip 192.168.1.100 udp_srcip 192.168.1.100
udp_srcip2 192.168.1.100 udp_srcip2 192.168.1.100
# receiver hostname and tcpports
0:rx_tcpport 1970
1:rx_tcpport 1971
2:rx_tcpport 1972
3:rx_tcpport 1973
rx_hostname mpc1922
# udp destination ip from rx_hostname
udp_dstip auto
udp_dstip2 auto
# transmission delay frame # transmission delay frame
0:txndelay_frame 0 0:txndelay_frame 0
1:txndelay_frame 1 1:txndelay_frame 1

View File

@ -1,18 +1,18 @@
# detector hostname # detector hostname
hostname localhost:1908 hostname localhost:1908
# receiver hostname
rx_hostname mpc1922:2008
# udp destination ports # udp destination ports
udp_dstport 50008 udp_dstport 50008
# udp destination ip from rx_hostname
udp_dstip auto
# udp source ip (same subnet as udp_dstip) # udp source ip (same subnet as udp_dstip)
udp_srcip 192.168.1.100 udp_srcip 192.168.1.100
# receiver hostname
rx_hostname mpc1922:2008
# udp destination ip from rx_hostname
udp_dstip auto
# output file directory # output file directory
fpath /tmp fpath /tmp

View File

@ -1,18 +1,18 @@
# detector hostname # detector hostname
hostname localhost:1912 hostname localhost:1912
# receiver hostname
rx_hostname mpc1922:2012
# udp destination ports # udp destination ports
udp_dstport 50012 udp_dstport 50012
# udp destination ip from rx_hostname
udp_dstip auto
# udp source ip (same subnet as udp_dstip) # udp source ip (same subnet as udp_dstip)
udp_srcip 192.168.1.100 udp_srcip 192.168.1.100
# receiver hostname
rx_hostname mpc1922:2012
# udp destination ip from rx_hostname
udp_dstip auto
# output file directory # output file directory
fpath /tmp fpath /tmp

View File

@ -34,6 +34,7 @@ set( PYTHON_FILES
slsdet/eiger.py slsdet/eiger.py
slsdet/enums.py slsdet/enums.py
slsdet/errors.py slsdet/errors.py
slsdet/gaincaps.py
slsdet/gotthard.py slsdet/gotthard.py
slsdet/pattern.py slsdet/pattern.py
slsdet/gotthard2.py slsdet/gotthard2.py

View File

@ -2,7 +2,7 @@
# Copyright (C) 2021 Contributors to the SLS Detector Package # Copyright (C) 2021 Contributors to the SLS Detector Package
import subprocess import subprocess
import locale import locale
out = subprocess.run(['g', 'list'], stdout = subprocess.PIPE, encoding=locale.getpreferredencoding()) out = subprocess.run(['sls_detector_get', 'list'], stdout = subprocess.PIPE, encoding=locale.getpreferredencoding())
cmd = out.stdout.splitlines() cmd = out.stdout.splitlines()
cmd.pop(0) cmd.pop(0)
@ -99,7 +99,6 @@ intentionally_missing = [
'temp_slowadc', 'temp_slowadc',
'temp_sodl', 'temp_sodl',
'temp_sodr', 'temp_sodr',
'trigger', #use sendSoftwareTrigger
'update', #use updateServerAndFirmare 'update', #use updateServerAndFirmare
'udp_validate', #use validateUdpConfiguration 'udp_validate', #use validateUdpConfiguration
'udp_reconfigure', #use reconfigureUdpDestination 'udp_reconfigure', #use reconfigureUdpDestination

View File

@ -11,7 +11,7 @@ from .gotthard2 import Gotthard2
from .gotthard import Gotthard from .gotthard import Gotthard
from .moench import Moench from .moench import Moench
from .pattern import Pattern, patternParameters from .pattern import Pattern, patternParameters
from .gaincaps import Mythen3GainCapsWrapper
import _slsdet import _slsdet
xy = _slsdet.xy xy = _slsdet.xy

View File

@ -26,6 +26,7 @@ SHORT_STR_LENGTH=20
MAX_PATTERN_LENGTH=0x2000 MAX_PATTERN_LENGTH=0x2000
MAX_PATTERN_LEVELS=6 MAX_PATTERN_LEVELS=6
M3_MAX_PATTERN_LEVELS=3 M3_MAX_PATTERN_LEVELS=3
MAX_NUM_COUNTERS=3
DEFAULT_STREAMING_TIMER_IN_MS=500 DEFAULT_STREAMING_TIMER_IN_MS=500
NUM_RX_THREAD_IDS=9 NUM_RX_THREAD_IDS=9
MAX_NUM_PACKETS=512 MAX_NUM_PACKETS=512

View File

@ -16,6 +16,7 @@ defs = slsDetectorDefs
from .utils import element_if_equal, all_equal, get_set_bits, list_to_bitmask from .utils import element_if_equal, all_equal, get_set_bits, list_to_bitmask
from .utils import Geometry, to_geo, element, reduce_time, is_iterable, hostname_list from .utils import Geometry, to_geo, element, reduce_time, is_iterable, hostname_list
from _slsdet import xy from _slsdet import xy
from .gaincaps import Mythen3GainCapsWrapper
from . import utils as ut from . import utils as ut
from .proxy import JsonProxy, SlowAdcProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy from .proxy import JsonProxy, SlowAdcProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy
from .registers import Register, Adc_register from .registers import Register, Adc_register
@ -231,7 +232,7 @@ class Detector(CppDetectorApi):
""" """
[Jungfrau][Moench][Gotthard2][Myhten3][Gotthard][Ctb] Hardware version of detector. [Jungfrau][Moench][Gotthard2][Myhten3][Gotthard][Ctb] Hardware version of detector.
""" """
return ut.lhex(self.getHardwareVersion()) return self.getHardwareVersion()
@property @property
@element @element
@ -263,11 +264,17 @@ class Detector(CppDetectorApi):
"""Receiver version """ """Receiver version """
return self.getReceiverVersion() return self.getReceiverVersion()
@property
@element
def serialnumber(self):
"""Jungfrau][Gotthard][Mythen3][Gotthard2][CTB][Moench] Serial number of detector """
return ut.lhex(self.getSerialNumber())
@property @property
@element @element
def rx_threads(self): def rx_threads(self):
""" """
Get thread ids from the receiver in order of [parent, tcp, listener 0, processor 0, streamer 0, listener 1, processor 1, streamer 1, arping]. Get kernel thread ids from the receiver in order of [parent, tcp, listener 0, processor 0, streamer 0, listener 1, processor 1, streamer 1, arping].
Note Note
----- -----
@ -451,6 +458,56 @@ class Detector(CppDetectorApi):
def triggers(self, n_triggers): def triggers(self, n_triggers):
self.setNumberOfTriggers(n_triggers) self.setNumberOfTriggers(n_triggers)
def resetdacs(self, use_hardware_values):
self.resetToDefaultDacs(use_hardware_values)
def trigger(self):
self.sendSoftwareTrigger()
def blockingtrigger(self):
self.sendSoftwareTrigger(True)
@property
@element
def gaincaps(self):
"""
[Mythen3] Gain caps. Enum: M3_GainCaps \n
Note
----
Options: M3_GainCaps, M3_C15sh, M3_C30sh, M3_C50sh, M3_C225ACsh, M3_C15pre
Example
-------
>>> d.gaincaps
C15pre, C30sh
>>> d.gaincaps = M3_GainCaps.M3_C30sh
>>> d.gaincaps
C30sh
>>> d.gaincaps = M3_GainCaps.M3_C30sh | M3_GainCaps.M3_C15sh
>>> d.gaincaps
C15sh, C30sh
"""
res = [Mythen3GainCapsWrapper(it) for it in self.getGainCaps()]
return res
@gaincaps.setter
def gaincaps(self, caps):
#convert to int if called with Wrapper
if isinstance(caps, Mythen3GainCapsWrapper):
self.setGainCaps(caps.value)
elif isinstance(caps, dict):
corr = {}
for key, value in caps.items():
if isinstance(value, Mythen3GainCapsWrapper):
corr[key] = value.value
else:
corr[key] = value
ut.set_using_dict(self.setGainCaps, corr)
else:
self.setGainCaps(caps)
@property @property
def exptime(self): def exptime(self):
""" """
@ -498,7 +555,7 @@ class Detector(CppDetectorApi):
@exptime.setter @exptime.setter
def exptime(self, t): def exptime(self, t):
if self.type == detectorType.MYTHEN3 and is_iterable(t): if self.type == detectorType.MYTHEN3 and is_iterable(t) and not isinstance(t,dict):
for i, v in enumerate(t): for i, v in enumerate(t):
if isinstance(v, int): if isinstance(v, int):
v = float(v) v = float(v)
@ -507,8 +564,6 @@ class Detector(CppDetectorApi):
ut.set_time_using_dict(self.setExptime, t) ut.set_time_using_dict(self.setExptime, t)
@property @property
def period(self): def period(self):
""" """
@ -647,6 +702,10 @@ class Detector(CppDetectorApi):
"""Start detector acquisition. Status changes to RUNNING or WAITING and automatically returns to idle at the end of acquisition.""" """Start detector acquisition. Status changes to RUNNING or WAITING and automatically returns to idle at the end of acquisition."""
self.startDetector() self.startDetector()
def clearbusy(self):
"""If acquisition aborted during acquire command, use this to clear acquiring flag in shared memory before starting next acquisition"""
self.clearAcquiringFlag()
def rx_start(self): def rx_start(self):
"""Starts receiver listener for detector data packets and create a data file (if file write enabled).""" """Starts receiver listener for detector data packets and create a data file (if file write enabled)."""
self.startReceiver() self.startReceiver()
@ -1563,6 +1622,20 @@ class Detector(CppDetectorApi):
def trimval(self, value): def trimval(self, value):
ut.set_using_dict(self.setAllTrimbits, value) ut.set_using_dict(self.setAllTrimbits, value)
@property
@element
def fliprows(self):
"""
[Eiger] flips rows paramater sent to slsreceiver to stream as json parameter to flip rows in gui. \n
[Jungfrau] flips rows in the detector itself. For bottom module and number of interfaces must be set to 2. slsReceiver and slsDetectorGui does not handle.
"""
return self.getFlipRows()
@fliprows.setter
def fliprows(self, value):
ut.set_using_dict(self.setFlipRows, value)
@property @property
@element @element
def master(self): def master(self):
@ -1588,6 +1661,19 @@ class Detector(CppDetectorApi):
def sync(self, value): def sync(self, value):
ut.set_using_dict(self.setSynchronization, value) ut.set_using_dict(self.setSynchronization, value)
@property
@element
def badchannels(self):
"""
[fname|none|0]\n\t[Gotthard2][Mythen3] Sets the bad channels (from file of bad channel numbers) to be masked out. None or 0 unsets all the badchannels.\n
[Mythen3] Also does trimming
"""
return self.getBadChannels()
@badchannels.setter
def badchannels(self, value):
ut.set_using_dict(self.setBadChannels, value)
@property @property
@element @element
def lock(self): def lock(self):
@ -1696,6 +1782,11 @@ class Detector(CppDetectorApi):
"""Gets the list of timing modes (timingMode) for this detector.""" """Gets the list of timing modes (timingMode) for this detector."""
return self.getTimingModeList() return self.getTimingModeList()
@property
def readoutspeedlist(self):
"""List of readout speed levels implemented for this detector."""
return self.getReadoutSpeedList()
@property @property
def templist(self): def templist(self):
"""List of temperature enums (dacIndex) implemented for this detector.""" """List of temperature enums (dacIndex) implemented for this detector."""
@ -1797,25 +1888,24 @@ class Detector(CppDetectorApi):
@property @property
def versions(self): def versions(self):
if self.type == detectorType.EIGER: version_list = {'type': self.type,
return {'type': self.type,
'package': self.packageversion, 'package': self.packageversion,
'client': self.clientversion, 'client': self.clientversion,
'firmware (Beb)': self.firmwareversion,
'firmware(Febl)': self.getFrontEndFirmwareVersion(slsDetectorDefs.fpgaPosition.FRONT_LEFT),
'firmware (Febr)': self.getFrontEndFirmwareVersion(slsDetectorDefs.fpgaPosition.FRONT_RIGHT),
'detectorserver': self.detectorserverversion, 'detectorserver': self.detectorserverversion,
'kernel': self.kernelversion, 'kernel': self.kernelversion}
'receiver': self.rx_version}
return {'type': self.type, if self.type == detectorType.EIGER:
'package': self.packageversion, version_list ['firmware (Beb)'] = self.firmwareversion
'client': self.clientversion, version_list ['firmware(Febl)'] = self.getFrontEndFirmwareVersion(slsDetectorDefs.fpgaPosition.FRONT_LEFT)
'firmware': self.firmwareversion, version_list ['firmware (Febr)'] = self.getFrontEndFirmwareVersion(slsDetectorDefs.fpgaPosition.FRONT_RIGHT)
'detectorserver': self.detectorserverversion, else:
'hardware':self.hardwareversion, version_list ['firmware'] = self.firmwareversion
'kernel': self.kernelversion, version_list ['hardware'] = self.hardwareversion
'receiver': self.rx_version}
if self.use_receiver:
version_list ['receiver'] = self.rx_version
return version_list
@property @property
def virtual(self): def virtual(self):
@ -3103,6 +3193,17 @@ class Detector(CppDetectorApi):
def dbitclk(self, value): def dbitclk(self, value):
ut.set_using_dict(self.setDBITClock, value) ut.set_using_dict(self.setDBITClock, value)
@property
@element
def adcvpp(self):
"""[Ctb][Moench] Vpp of ADC. [0 -> 1V | 1 -> 1.14V | 2 -> 1.33V | 3 -> 1.6V | 4 -> 2V] \n
Advanced User function!"""
return self.getADCVpp(False)
@adcvpp.setter
def adcvpp(self, value):
ut.set_using_dict(self.setADCVpp, value, False)
@property @property
@element @element
def dbitpipeline(self): def dbitpipeline(self):
@ -3713,6 +3814,23 @@ class Detector(CppDetectorApi):
""" """
return self.getMeasuredCurrent(dacIndex.I_POWER_IO) return self.getMeasuredCurrent(dacIndex.I_POWER_IO)
@property
def clkphase(self):
"""
[Gotthard2][Mythen3] Phase shift of all clocks.
Example
-------
>>> d.clkphase[0] = 20
>>> d.clkphase
0: 20
1: 10
2: 20
3: 10
4: 10
5: 5
"""
return ClkPhaseProxy(self)
@property @property
def clkdiv(self): def clkdiv(self):

42
python/slsdet/gaincaps.py Normal file
View File

@ -0,0 +1,42 @@
import _slsdet
gc = _slsdet.slsDetectorDefs.M3_GainCaps
class Mythen3GainCapsWrapper:
"""Holds M3_GainCaps enums and facilitates printing"""
# 'M3_C10pre', 'M3_C15pre', 'M3_C15sh', 'M3_C225ACsh', 'M3_C30sh', 'M3_C50sh'
all_bits = gc.M3_C10pre | gc.M3_C15pre | gc.M3_C15sh | gc.M3_C225ACsh | gc.M3_C30sh | gc.M3_C50sh
all_caps = (gc.M3_C10pre, gc.M3_C15pre, gc.M3_C15sh, gc.M3_C225ACsh, gc.M3_C30sh, gc.M3_C50sh)
def __init__(self, value = 0):
self._validate(value)
self.value = value
def __eq__(self, other) -> bool:
if isinstance(other, Mythen3GainCapsWrapper):
return self.value == other.value
else:
return self.value == other
def __ne__(self, other) -> bool:
return not self.__eq__(other)
def __str__(self) -> str:
s = ', '.join(str(c).rsplit('_', 1)[1] for c in self.all_caps if self.value & c)
return s
def __repr__(self) -> str:
return self.__str__()
def _validate(self, value):
"""Check that only bits representing real capacitors are set"""
if isinstance(value, gc):
return True
elif isinstance(value, int):
if value & (~self.all_bits):
raise ValueError(f"The value: {value} is not allowed for Mythen3GainCapsWrapper")
else:
raise ValueError("GainCaps can only be initialized from int or M3_GainCaps enum")

View File

@ -13,6 +13,7 @@ from .detector import Detector, freeze
from .dacs import DetectorDacs from .dacs import DetectorDacs
import _slsdet import _slsdet
dacIndex = _slsdet.slsDetectorDefs.dacIndex dacIndex = _slsdet.slsDetectorDefs.dacIndex
gc_enums = _slsdet.slsDetectorDefs.M3_GainCaps
from .detector_property import DetectorProperty from .detector_property import DetectorProperty
@ -62,4 +63,6 @@ class Mythen3(Detector):
@property @property
def dacs(self): def dacs(self):
return self._dacs return self._dacs

View File

@ -4,6 +4,7 @@ from .utils import element_if_equal
from .enums import dacIndex from .enums import dacIndex
from .defines import M3_MAX_PATTERN_LEVELS, MAX_PATTERN_LEVELS from .defines import M3_MAX_PATTERN_LEVELS, MAX_PATTERN_LEVELS
from _slsdet import slsDetectorDefs from _slsdet import slsDetectorDefs
detectorType = slsDetectorDefs.detectorType
def set_proxy_using_dict(func, key, value, unpack = False): def set_proxy_using_dict(func, key, value, unpack = False):
@ -87,7 +88,10 @@ class ClkDivProxy:
def __repr__(self): def __repr__(self):
rstr = '' rstr = ''
for i in range(6): num_clocks = 6
if self.det.type == detectorType.MYTHEN3:
num_clocks = 5
for i in range(num_clocks):
r = element_if_equal(self.__getitem__(i)) r = element_if_equal(self.__getitem__(i))
if isinstance(r, list): if isinstance(r, list):
rstr += ' '.join(f'{item}' for item in r) rstr += ' '.join(f'{item}' for item in r)
@ -96,10 +100,35 @@ class ClkDivProxy:
return rstr.strip('\n') return rstr.strip('\n')
class ClkPhaseProxy:
"""
Proxy class to allow for more intuitive reading clock phase
"""
def __init__(self, det):
self.det = det
def __getitem__(self, key):
return element_if_equal(self.det.getClockPhase(key))
def __setitem__(self, key, value):
set_proxy_using_dict(self.det.setClockPhase, key, value)
def __repr__(self):
rstr = ''
if self.det.type == detectorType.MYTHEN3:
num_clocks = 5
for i in range(num_clocks):
r = element_if_equal(self.__getitem__(i))
if isinstance(r, list):
rstr += ' '.join(f'{item}' for item in r)
else:
rstr += f'{i}: {r}\n'
return rstr.strip('\n')
class MaxPhaseProxy: class MaxPhaseProxy:
""" """
Proxy class to allow for more intuitive reading clockdivider Proxy class to allow for more intuitive reading max clock phase shift
""" """
def __init__(self, det): def __init__(self, det):
self.det = det self.det = det
@ -109,7 +138,9 @@ class MaxPhaseProxy:
def __repr__(self): def __repr__(self):
rstr = '' rstr = ''
for i in range(5): if self.det.type == detectorType.MYTHEN3:
num_clocks = 5
for i in range(num_clocks):
r = element_if_equal(self.__getitem__(i)) r = element_if_equal(self.__getitem__(i))
if isinstance(r, list): if isinstance(r, list):
rstr += ' '.join(f'{item}' for item in r) rstr += ' '.join(f'{item}' for item in r)
@ -120,7 +151,7 @@ class MaxPhaseProxy:
class ClkFreqProxy: class ClkFreqProxy:
""" """
Proxy class to allow for more intuitive reading clockdivider Proxy class to allow for more intuitive reading clock frequency
""" """
def __init__(self, det): def __init__(self, det):
self.det = det self.det = det
@ -130,7 +161,9 @@ class ClkFreqProxy:
def __repr__(self): def __repr__(self):
rstr = '' rstr = ''
for i in range(5): if self.det.type == detectorType.MYTHEN3:
num_clocks = 5
for i in range(num_clocks):
r = element_if_equal(self.__getitem__(i)) r = element_if_equal(self.__getitem__(i))
if isinstance(r, list): if isinstance(r, list):
rstr += ' '.join(f'{item}' for item in r) rstr += ' '.join(f'{item}' for item in r)

View File

@ -224,6 +224,21 @@ void init_det(py::module &m) {
(void (Detector::*)(const std::string &, sls::Positions)) & (void (Detector::*)(const std::string &, sls::Positions)) &
Detector::setBadChannels, Detector::setBadChannels,
py::arg(), py::arg() = Positions{}); py::arg(), py::arg() = Positions{});
CppDetectorApi.def(
"getBadChannels",
(Result<std::vector<int>>(Detector::*)(sls::Positions) const) &
Detector::getBadChannels,
py::arg() = Positions{});
CppDetectorApi.def(
"setBadChannels",
(void (Detector::*)(const std::vector<int>, sls::Positions)) &
Detector::setBadChannels,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def(
"setBadChannels",
(void (Detector::*)(const std::vector<std::vector<int>>)) &
Detector::setBadChannels,
py::arg());
CppDetectorApi.def("isVirtualDetectorServer", CppDetectorApi.def("isVirtualDetectorServer",
(Result<bool>(Detector::*)(sls::Positions) const) & (Result<bool>(Detector::*)(sls::Positions) const) &
Detector::isVirtualDetectorServer, Detector::isVirtualDetectorServer,

View File

@ -0,0 +1,24 @@
import pytest
from slsdet import Mythen3GainCapsWrapper
from slsdet.enums import M3_GainCaps #this is the c++ enum
def test_comapre_with_int():
c = Mythen3GainCapsWrapper(128) #C10pre
assert c == 128
assert c != 5
assert c != 1280
def test_compare_with_other():
a = Mythen3GainCapsWrapper(128)
b = Mythen3GainCapsWrapper(1<<10)
c = Mythen3GainCapsWrapper(128)
assert a!=b
assert (a==b) == False
assert a==c
def test_can_be_default_constructed():
c = Mythen3GainCapsWrapper()
assert c == 0

View File

@ -0,0 +1 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv7.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv7.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv7.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv7.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv7.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv7.0.0

View File

@ -0,0 +1 @@
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServerv7.0.0

View File

@ -40,20 +40,31 @@ class jungfrauModuleData : public slsDetectorData<uint16_t> {
out by a module i.e. using the slsReceiver (160x160 pixels, 40 packets out by a module i.e. using the slsReceiver (160x160 pixels, 40 packets
1286 large etc.) \param c crosstalk parameter for the output buffer 1286 large etc.) \param c crosstalk parameter for the output buffer
*/ */
#ifndef ZMQ
#define off sizeof(jf_header)
#endif
#ifdef ZMQ
#define off 0
#endif
jungfrauModuleData() jungfrauModuleData()
: slsDetectorData<uint16_t>(1024, 512, : slsDetectorData<uint16_t>(1024, 512,
1024* 512 * 2 + sizeof(jf_header)) { 1024* 512 * 2 + off) {
for (int ix = 0; ix < 1024; ix++) { for (int ix = 0; ix < 1024; ix++) {
for (int iy = 0; iy < 512; iy++) { for (int iy = 0; iy < 512; iy++) {
dataMap[iy][ix] = sizeof(jf_header) + (1024 * iy + ix) * 2; dataMap[iy][ix] = off + (1024 * iy + ix) * 2;
#ifdef HIGHZ #ifdef HIGHZ
dataMask[iy][ix] = 0x3fff; dataMask[iy][ix] = 0x3fff;
#endif #endif
} }
} }
iframe = 0; iframe = 0;
// cout << "data struct created" << endl; // cout << "data struct created" << endl;
}; };

View File

@ -0,0 +1,64 @@
# SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package
#module add CBFlib/0.9.5
INCDIR=-I. -I../ -I../interpolations -I../interpolations/etaVEL -I../dataStructures -I../../slsSupportLib/include/ -I../../slsReceiverSoftware/include/ -I../tiffio/include
LDFLAG= ../tiffio/src/tiffIO.cpp -L/usr/lib64/ -lpthread -lm -lstdc++ -pthread -lrt -ltiff -O3 -std=c++11
MAIN=jungfrauClusterFinder.cpp
all: jungfrauRawDataProcess
jungfrauRawDataProcess: jungfrauRawDataProcess.cpp $(INCS) clean
g++ -o jungfrauRawDataProcess jungfrauRawDataProcess.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DSAVE_ALL -DMODULE
jungfrauRawDataProcessStrx: jungfrauRawDataProcess.cpp $(INCS) clean
g++ -o jungfrauRawDataProcessStrx jungfrauRawDataProcess.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DSAVE_ALL -DJFSTRX
jungfrauRawDataProcessStrxAldo: jungfrauRawDataProcess.cpp $(INCS) clean
g++ -o jungfrauRawDataProcessStrxAldo jungfrauRawDataProcess.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DSAVE_ALL -DJFSTRX -DALDO
jungfrauRawDataProcessStrxOld: jungfrauRawDataProcess.cpp $(INCS) clean
g++ -o jungfrauRawDataProcessStrxOld jungfrauRawDataProcess.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DSAVE_ALL -DJFSTRXOLD
jungfrauRawDataProcessStrxOldAldo: jungfrauRawDataProcess.cpp $(INCS) clean
g++ -o jungfrauRawDataProcessStrxOldAldo jungfrauRawDataProcess.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DSAVE_ALL -DJFSTRXOLD -DALDO
jungfrauClusterFinder: jungfrauClusterFinder.cpp $(INCS) clean
g++ -o jungfrauClusterFinder jungfrauClusterFinder.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DSAVE_ALL
jungfrauClusterFinderHighZ: jungfrauClusterFinder.cpp $(INCS) clean
g++ -o jungfrauClusterFinderHighZ jungfrauClusterFinder.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DSAVE_ALL -DHIGHZ
jungfrauMakeEta: jungfrauInterpolation.cpp $(INCS) clean
g++ -o jungfrauMakeEta jungfrauInterpolation.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DFF
jungfrauInterpolation: jungfrauInterpolation.cpp $(INCS) clean
g++ -o jungfrauInterpolation jungfrauInterpolation.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF)
jungfrauNoInterpolation: jungfrauNoInterpolation.cpp $(INCS) clean
g++ -o jungfrauNoInterpolation jungfrauNoInterpolation.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF)
jungfrauPhotonCounter: jungfrauPhotonCounter.cpp $(INCS) clean
g++ -o jungfrauPhotonCounter jungfrauPhotonCounter.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DNEWRECEIVER
jungfrauAnalog: jungfrauPhotonCounter.cpp $(INCS) clean
g++ -o jungfrauAnalog jungfrauPhotonCounter.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DNEWRECEIVER -DANALOG
jungfrauPhotonCounterHighZ: jungfrauPhotonCounter.cpp $(INCS) clean
g++ -o jungfrauPhotonCounterHighZ jungfrauPhotonCounter.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DNEWRECEIVER -DHIGHZ
jungfrauAnalogHighZ: jungfrauPhotonCounter.cpp $(INCS) clean
g++ -o jungfrauAnalogHighZ jungfrauPhotonCounter.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DNEWRECEIVER -DANALOG -DHIGHZ
clean:
rm -f jungfrauClusterFinder jungfrauMakeEta jungfrauInterpolation jungfrauNoInterpolation jungfrauPhotonCounter jungfrauAnalog

View File

@ -1,25 +1,19 @@
# 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
INCDIR= -I. -I../dataStructures ../tiffIO.cpp -I../ -I../interpolations/ -I../../slsSupportLib/include/ -I../../slsReceiverSoftware/include/ -I../../libs/rapidjson/ INCDIR= -I. -I../dataStructures ../tiffio/src/tiffIO.cpp -I../ -I../interpolations/ -I../../slsSupportLib/include/ -I../../slsReceiverSoftware/include/ -I../../libs/rapidjson/ -I../tiffio/include
LDFLAG= -L/usr/lib64/ -lpthread -lm -lstdc++ -lzmq -pthread -lrt -ltiff -O3 -std=c++11 -Wall -L../../build/bin/ -lSlsSupport LDFLAG= -L/usr/lib64/ -lpthread -lm -lstdc++ -lzmq -pthread -lrt -ltiff -O3 -std=c++11 -Wall -L../../build/bin/ -lSlsSupport
#-L../../bin -lhdf5 -L. #-L../../bin -lhdf5 -L.
#DESTDIR?=../bin #DESTDIR?=../bin
all: moenchZmqProcess moenchZmq04Process all: jungfrauZmqProcess
#moenchZmqProcessCtbGui #jungfrauZmqProcessCtbGui
moenchZmqProcess: moenchZmqProcess.cpp clean jungfrauZmqProcess: jungfrauZmqProcess.cpp clean
g++ -o moenchZmqProcess moenchZmqProcess.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DNEWZMQ -DINTERP g++ -o jungfrauZmqProcess jungfrauZmqProcess.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DNEWZMQ -DINTERP
moenchZmq04Process: moenchZmqProcess.cpp clean
g++ -o moench04ZmqProcess moenchZmqProcess.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DNEWZMQ -DINTERP -DMOENCH04
#moenchZmqProcessCtbGui: moenchZmqProcess.cpp clean
# g++ -o moenchZmqProcessCtbGui moenchZmqProcess.cpp $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF) -DNEWZMQ -DINTERP -DCTBGUI
clean: clean:
rm -f moenchZmqProcess rm -f jungfrauZmqProcess

View File

@ -0,0 +1,26 @@
ROOTSYS=/opt/cern/v6/root
#/afs/psi.ch/project/sls_det_sof/roottware/root_v5.34.23_sl6_64bit
LIBZMQDIR = $(PWD)
LIBZMQ = -L$(LIBZMQDIR) -lzmq
SHLIB_PATH=/opt/cern/v6/root/lib
CMAKE_PREFIX_PATH=/opt/cern/v6/root
DYLD_LIBRARY_PATH=/opt/cern/v6/root/lib
INCDIR= -I. -I../dataStructures ../tiffio/src/tiffIO.cpp -I../ -I../interpolations/ -I../../slsSupportLib/include/ -I../../slsReceiverSoftware/include/ -I../../libs/rapidjson/ -I../tiffio/include
LDFLAG= -L/usr/lib64/ -lpthread -lm -lstdc++ -lzmq -pthread -lrt -ltiff -O3 -std=c++11 -Wall -L../../build/bin/ -lSlsSupport
#-L../../bin -lhdf5 -L.
default: onlinedisp_zmq
onlinedisp_zmq: onlinedisp_zmq.cpp onlinedisp_zmq.h
# flags from root-config --cflags --glibs
g++ -o onlinedisp_zmq onlinedisp_zmq.cpp -I. -I$(ROOTSYS)/include -Wall -g -lm -L. -lzmq -pthread -lrt -L$(ROOTSYS)/lib -lGui -lCore -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -m64 $(LDFLAG) $(INCDIR) $(LIBHDF5) $(LIBRARYCBF)
#-lCint

View File

@ -0,0 +1,10 @@
sls_detector_put rx_jsonpara detectorMode counting
sls_detector_put rx_jsonpara frameMode newPedestal
sls_detector_put rx_jsonpara frameMode frame
sls_detector_put rx_jsonpara detectorMode analog
sls_detector_put rx_jsonpara threshold 150
sls_detector_put rx_jsonpara threshold 0
sls_detector_put rx_jsonpara threshold 300
sls_detector_put rx_zmqhwm 50

View File

@ -0,0 +1,418 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
//#include "sls/ansi.h"
#include <iostream>
#undef CORR
#define C_GHOST 0.0004
#define CM_ROWS 50
#define RAWDATA
#ifndef JFSTRX
#ifndef JFSTRXOLD
#ifndef MODULE
#include "jungfrauHighZSingleChipData.h"
#endif
#ifdef MODULE
#include "jungfrauModuleData.h"
#endif
#endif
#endif
#ifdef JFSTRX
#include "jungfrauLGADStrixelsData.h"
#endif
#ifdef JFSTRXOLD
#include "jungfrauStrixelsHalfModuleOldDesign.h"
#endif
#include "multiThreadedCountingDetector.h"
#include "singlePhotonDetector.h"
#include <fstream>
#include <map>
#include <stdio.h>
#include <sys/stat.h>
#include <ctime>
using namespace std;
int main(int argc, char *argv[]) {
if (argc < 5) {
cout << "Usage is " << argv[0]
<< "indir outdir fname(no extension) fextension [runmin] [runmax] [pedfile (raw or tiff)] [threshold] "
"[nframes] [xmin xmax ymin ymax] [gainmap]"
<< endl;
cout << "threshold <0 means analog; threshold=0 means cluster finder; "
"threshold>0 means photon counting"
<< endl;
cout << "nframes <0 means sum everything; nframes=0 means one file per "
"run; nframes>0 means one file every nframes"
<< endl;
return 1;
}
int fifosize = 1000;
int nthreads = 10;
int csize = 3;
int nsigma = 5;
int nped = 10000;
int cf = 0;
#ifndef JFSTRX
#ifndef JFSTRXOLD
#ifndef MODULE
jungfrauHighZSingleChipData *decoder = new jungfrauHighZSingleChipData();
int nx = 256, ny = 256;
#endif
#ifdef MODULE
jungfrauModuleData *decoder = new jungfrauModuleData();
int nx = 1024, ny = 512;
#endif
#endif
#endif
#ifdef JFSTRX
cout << "bbb" << endl;
jungfrauLGADStrixelsData *decoder = new jungfrauLGADStrixelsData();
int nx = 1024/5, ny = 512*5;
#endif
#ifdef JFSTRXOLD
cout << "ccc" << endl;
jungfrauStrixelsHalfModuleOldDesign *decoder = new jungfrauStrixelsHalfModuleOldDesign();
int nx = 1024*3, ny = 512/3;
#endif
decoder->getDetectorSize(nx, ny);
cout << "Detector size is " << nx << " " << ny << endl;
double *gainmap = NULL;
//float *gm;
int ff, np;
// cout << " data size is " << dsize;
ifstream filebin;
char *indir = argv[1];
char *outdir = argv[2];
char *fformat = argv[3];
char *fext = argv[4];
int runmin = 0;
// cout << "argc is " << argc << endl;
if (argc >= 6) {
runmin = atoi(argv[5]);
}
int runmax = runmin;
if (argc >= 7) {
runmax = atoi(argv[6]);
}
char *pedfile = NULL;
if (argc >= 8) {
pedfile = argv[7];
}
double thr = 0;
double thr1 = 1;
if (argc >= 9) {
thr = atof(argv[8]);
}
int nframes = 0;
if (argc >= 10) {
nframes = atoi(argv[9]);
}
int xmin = 0, xmax = nx, ymin = 0, ymax = ny;
if (argc >= 14) {
xmin = atoi(argv[10]);
xmax = atoi(argv[11]);
ymin = atoi(argv[12]);
ymax = atoi(argv[13]);
}
char *gainfname = NULL;
if (argc > 14) {
gainfname = argv[14];
cout << "Gain map file name is: " << gainfname << endl;
}
char ffname[10000];
char fname[10000];
char imgfname[10000];
char cfname[10000];
std::time_t end_time;
FILE *of = NULL;
cout << "input directory is " << indir << endl;
cout << "output directory is " << outdir << endl;
cout << "input file is " << fformat << endl;
cout << "runmin is " << runmin << endl;
cout << "runmax is " << runmax << endl;
if (pedfile)
cout << "pedestal file is " << pedfile << endl;
if (thr > 0)
cout << "threshold is " << thr << endl;
cout << "Nframes is " << nframes << endl;
uint32_t nnx, nny;
singlePhotonDetector *filter = new singlePhotonDetector(
decoder, csize, nsigma, 1, NULL, nped, 200, -1, -1, gainmap, NULL);
if (gainfname) {
if (filter->readGainMap(gainfname))
cout << "using gain map " << gainfname << endl;
else
cout << "Could not open gain map " << gainfname << endl;
} else
thr = 0.15 * thr;
filter->newDataSet();
//int dsize = decoder->getDataSize();
if (thr > 0) {
cout << "threshold is " << thr << endl;
filter->setThreshold(thr);
cf = 0;
} else
cf = 1;
filter->setROI(xmin, xmax, ymin, ymax);
std::time(&end_time);
cout << std::ctime(&end_time) << endl;
char *buff;
// multiThreadedAnalogDetector *mt=new
// multiThreadedAnalogDetector(filter,nthreads,fifosize);
multiThreadedCountingDetector *mt =
new multiThreadedCountingDetector(filter, nthreads, fifosize);
#ifndef ANALOG
mt->setDetectorMode(ePhotonCounting);
cout << "Counting!" << endl;
if (thr > 0) {
cf = 0;
}
#endif
//{
#ifdef ANALOG
mt->setDetectorMode(eAnalog);
cout << "Analog!" << endl;
cf = 0;
// thr1=thr;
#endif
// }
mt->StartThreads();
mt->popFree(buff);
// cout << "mt " << endl;
int ifr = 0;
char froot[1000];
double *ped=new double[nx * ny];//, *ped1;
int pos,pos1;
if (pedfile) {
if (string(pedfile).find(".dat") != std::string::npos) {
pos1=string(pedfile).rfind("/");
strcpy(froot,pedfile+pos1);
pos=string(froot).find(".dat");
froot[pos]='\0';
}
cout << "PEDESTAL " << endl;
// sprintf(imgfname, "%s/pedestals.tiff", outdir);
if (string(pedfile).find(".tif") == std::string::npos) {
sprintf(fname, "%s", pedfile);
cout << fname << endl;
std::time(&end_time);
//cout << "aaa" << std::ctime(&end_time) << endl;
mt->setFrameMode(ePedestal);
// sprintf(fn,fformat,irun);
filebin.open((const char *)(fname), ios::in | ios::binary);
// //open file
if (filebin.is_open()) {
ff = -1;
while (decoder->readNextFrame(filebin, ff, np, buff)) {
// if (np == 40) {
if ((ifr+1) % 100 == 0) {
cout << " ****" << decoder->getValue(buff,20,20);// << endl;
}
mt->pushData(buff);
mt->nextThread();
mt->popFree(buff);
ifr++;
if (ifr % 100 == 0) {
cout << " ****" << ifr << " " << ff << " " << np << endl;
} //else
//cout << ifr << " " << ff << " " << np << endl;
if (ifr>=1000)
break;
ff = -1;
}
filebin.close();
while (mt->isBusy()) {
;
}
sprintf(imgfname, "%s/%s_ped.tiff", outdir, froot);
mt->writePedestal(imgfname);
sprintf(imgfname, "%s/%s_rms.tiff", outdir, froot);
mt->writePedestalRMS(imgfname);
} else
cout << "Could not open pedestal file " << fname
<< " for reading " << endl;
} else {
float *pp = ReadFromTiff(pedfile, nny, nnx);
if (pp && (int)nnx == nx && (int)nny == ny) {
for (int i = 0; i < nx * ny; i++) {
ped[i] = pp[i];
}
delete[] pp;
mt->setPedestal(ped);
cout << "Pedestal set from tiff file " << pedfile << endl;
} else {
cout << "Could not open pedestal tiff file " << pedfile
<< " for reading " << endl;
}
}
std::time(&end_time);
cout << std::ctime(&end_time) << endl;
}
ifr = 0;
int ifile = 0;
mt->setFrameMode(eFrame);
for (int irun = runmin; irun <= runmax; irun++) {
cout << "DATA ";
// sprintf(fn,fformat,irun);
sprintf(ffname, "%s/%s.%s", indir, fformat, fext);
sprintf(fname, (const char*)ffname, irun);
sprintf(ffname, "%s/%s.tiff", outdir, fformat);
sprintf(imgfname, (const char*)ffname, irun);
sprintf(ffname, "%s/%s.clust", outdir, fformat);
sprintf(cfname, (const char*)ffname, irun);
cout << fname << " ";
cout << imgfname << endl;
std::time(&end_time);
cout << std::ctime(&end_time) << endl;
// cout << fname << " " << outfname << " " << imgfname << endl;
filebin.open((const char *)(fname), ios::in | ios::binary);
// //open file
ifile = 0;
if (filebin.is_open()) {
if (thr <= 0 && cf != 0) { // cluster finder
if (of == NULL) {
of = fopen(cfname, "w");
if (of) {
mt->setFilePointer(of);
cout << "file pointer set " << endl;
} else {
cout << "Could not open " << cfname << " for writing "
<< endl;
mt->setFilePointer(NULL);
return 1;
}
}
}
// //while read frame
ff = -1;
ifr = 0;
while (decoder->readNextFrame(filebin, ff, np, buff)) {
// if (np == 40) {
// //push
if ((ifr+1) % 100 == 0) {
cout << " ****" << decoder->getValue(buff,20,20);// << endl;
}
mt->pushData(buff);
// // //pop
mt->nextThread();
mt->popFree(buff);
ifr++;
if (ifr % 100 == 0)
cout << " " << ifr << " " << ff << endl;
if (nframes > 0) {
if (ifr % nframes == 0) {
sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat,
ifile);
sprintf(imgfname, (const char*)ffname, irun);
mt->writeImage(imgfname, thr1);
mt->clearImage();
ifile++;
}
}
// } else
// cout << ifr << " " << ff << " " << np << endl;
ff = -1;
}
cout << "--" << endl;
filebin.close();
while (mt->isBusy()) {
;
}
if (nframes >= 0) {
if (nframes > 0) {
sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat, ifile);
sprintf(imgfname, (const char*)ffname, irun);
} else {
sprintf(ffname, "%s/%s.tiff", outdir, fformat);
sprintf(imgfname, (const char*)ffname, irun);
}
cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
mt->writeImage(imgfname, thr1);
mt->clearImage();
if (of) {
fclose(of);
of = NULL;
mt->setFilePointer(NULL);
}
}
std::time(&end_time);
cout << std::ctime(&end_time) << endl;
} else
cout << "Could not open " << fname << " for reading " << endl;
}
if (nframes < 0) {
sprintf(ffname, "%s/%s.tiff", outdir, fformat);
strcpy(imgfname, ffname);
cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
mt->writeImage(imgfname, thr1);
}
return 0;
}

View File

@ -0,0 +1,679 @@
#include "onlinedisp_zmq.h"
bool hasallpede;
TH1F * his102;TH1F * his101;
int processedf;
sls::zmqHeader zHeader;
#define PEDEFNAME "current_pede.dat"
#define NPRO 50
#define NPRI 50
//#define JFSTRX
#ifdef JFSTRX
#include "jungfrauLGADStrixelsData.h"
#else
#include "jungfrauModuleData.h"
#endif
int main(int argc, char* argv[])
{
goout=1;
hasallpede=false;
dophotonmap=true; if ((argc<3)) {printf("USAGE: command photon_energy_(peakinADC) [rx_ip] [port] \n"); return -1 ;}
else {
phene=atoi(argv[1]);
if (phene<0) dophotonmap=false;
threshold=float (phene/2);
printf( " \n");
printf( "phene %d \n",phene);
}
if (argc>=3) {
strcpy(serverip,argv[2]);
printf("ip is %s ",serverip);
}
portnum=30001;
if (argc>=4 ){ portnum= atoi(argv[3]);
}
printf(", port number is %d ",portnum); printf(". \n");
#ifdef JFSTRX
cout << "JFSTRX" << endl;
jungfrauLGADStrixelsData *decoder = new jungfrauLGADStrixelsData();
nx = 1024/5; ny= 512*5;
#else
nx = 1024; ny= 512;
#endif
gain_flag=false;
pede_flag=false;
bw_flag=false;
HDraw_every=20;
fixranges=false;
hchptr = (short*) malloc(NCH*sizeof(short));
startsocket(); //create and connect ZMQ
for (ipx=0;ipx<NCH;ipx++) hchptr[(ipx)]=0;
// cout<< decoder->getValue((char*)(hchptr),279,130)<<endl;
nonblock(NB_ENABLE);
cout <<"opening the rootapp" <<endl;
rootapp = new TApplication("Online JF display",&argc, argv);
LoadPaletteFalse();
char hname[100];
his1000= new TH2F("his1000","2d , ev. pede corrected",nx,-0.5,nx-0.5,ny,-0.5,ny-0.5);
his1000->SetOption("colz");
his2000= new TH2F("his2000","2d gain ",nx,-0.5,nx-0.5,ny,-0.5,ny-0.5);
his2000->GetZaxis()->SetRangeUser(0,4);
if (dophotonmap) {
his3000= new TH2F("his3000"," photon map ",nx,-0.5,nx-0.5,ny,-0.5,ny-0.5);
}
else {
his3000= new TH2F("his3000"," raw adc ",nx,-0.5,nx-0.5,ny,-0.5,ny-0.5);
}
his4500= new TH2F("his45000","L vs R",101,-50,500,101,-50,500);
hchip=new TH1I*[8];
for (i=0;i<8;i++) {
sprintf(hname,"hchip%d",i);
hchip[i] = new TH1I(hname,hname,NBIN,MIN_POS,MAX_POS);
}
cout <<"end of histo booking" <<endl;
if (A2==NULL) A2 = new TCanvas("A2","Plotting Canvas gain",150,10,500,250);
if (A3==NULL) A3 = new TCanvas("A3","Plotting Canvas ADC",150,360,1200,550);
if (A4==NULL) A4 = new TCanvas("A4","Plotting Canvas PHs",750,300,1000,800);
A4->Clear();
A4->Divide(4,2,0.005,0.005);
if (A5==NULL) A5 = new TCanvas("A5","Plotting Canvas Photon Map",750,300,1000,600);
if (A6==NULL) A6 = new TCanvas("A6","Plotting Canvas LvsR",650,250,650,660);
gSystem->ProcessEvents();
int running=0;
char runc[15]="*\\-/|";
printhelp();
while (1==1) { // loop on streamed frames
if(!zmqSocket->ReceiveHeader(0,zHeader, SLS_DETECTOR_JSON_HEADER_VERSION)){
cout<< "Receiver stopped, waiting for new stream" << endl;
zmqSocket->Disconnect();
zmqSocket->Connect();
}
else {
// if (((icount++)%10)==0) cout <<"recived frameindex "<<zHeader.frameIndex <<endl;
//cout <<"there" <<endl;
zmqSocket->ReceiveData(0, (char *)(&image_data), NCH*2);
}
{
framesinstream++;
running++;
fill1Ds=true; //alway fill 1d and LR plots
//if (((framesinstream%(int(HDraw_every)))==(int (HDraw_every)-1))) {fill1Ds=true;}else{fill1Ds=false;}
if (((framesinstream%(HDraw_every))==(HDraw_every)-1)) {show2Ds=true;}else{show2Ds=false;}
if (((framesinstream%NPRI)==NPRI-1)) { cout<<"\r "<<"frame (from start): "<<framesinstream<<" " << runc[((running/NPRI)%5)]<< " discarded frames %=" << (1-float(processedf)/float(zHeader.frameIndex-frameIndex_old))*100 << " current framenumber= " <<zHeader.frameIndex << " "<<std::flush; processedf=0;frameIndex_old=zHeader.frameIndex;}
npacket=0;
if (show2Ds) {
his1000->Reset();
his2000->Reset();
if (!dophotonmap) his3000->Reset(); //FOR RAW ADC DISPLAY
}
if ((fill1Ds)or(show2Ds)or(dophotonmap)) { // do something, otherwise skip to the next
processedf++;
for (i=0 ;i<NCH;i++) {
adcvalue= (image_data[i]) & 0x3fff;
if ((image_data[i] & 0xc000)!=0){ gain = (image_data[i]>>14) & 0x3;} else {gain=0;}
if (pede_flag){
if (gain_flag)
{
if ((gain==0)||(!hasallpede)) adcpedecorr=(adcvalue&0x3fff)*fgaind[i]-fpeded[i]*fgaind[i];
if ((gain==1)&&hasallpede) adcpedecorr=(fpedeG1d[i]*fgaind[i]+G1Poffset-adcvalue*fgaind[i])*30.0;
if ((gain==3)&&hasallpede) adcpedecorr=(fpedeG2d[i]*fgaind[i]+G2Poffset-adcvalue*fgaind[i])*340.0;
}
else
{
if ((gain==0)||(!hasallpede)) adcpedecorr=(adcvalue&0x3fff)-fpeded[i];
if ((gain==1)&&hasallpede) adcpedecorr=(fpedeG1d[i]+G1Poffset-adcvalue)*30.0;
if ((gain==3)&&hasallpede) adcpedecorr=(fpedeG2d[i]+G2Poffset-adcvalue)*340.0;
}
} else {adcpedecorr=float (adcvalue);} //end of if pede
if ((adcpedecorr>threshold)&&(pede_flag)) hchptr[(i)]= hchptr[(i)]+(int)((adcpedecorr+threshold)/phene);
if (fill1Ds) {
if (((i%1024)<1004)&&((i%1024)>20)&&((i/1024)>20)) { //skip the pix near guardring for PH plots
ichip= i/(256*256*4)*4+((i/256)%4) ;
hchip[ichip]->Fill(adcpedecorr,1);
if (((i%256)<253)&&((i%256)>2)) his4500->Fill(adcpedecorrold,adcpedecorr,1);
adcpedecorrold=adcpedecorr;
}
}//if (fill1Ds)
if ((show2Ds)) {
factor=2.0;
value=adcpedecorr;
if ((i%256==0)||(i%256==255)) value=int(value/factor);
if ((i/1024==255)||(i/1024==256)||(i/1024==767)||(i/1024==768)) value=int(value/factor);
his1000->Fill(float(i%1024),float(int (i/1024)),value);
if (!dophotonmap) his3000->Fill(float(i%1024),float(int (i/1024)) ,adcvalue);
his2000->Fill(float(i%1024),float(int (i/1024)) ,gain);
value=(int)(hchptr[i]);
if ((i%256==0)||(i%256==255)) value=int(value/factor);
if ((i/1024==255)||(i/1024==256)||(i/1024==767)||(i/1024==768)) value=int(value/factor);
if (dophotonmap) his3000->Fill(float(i%1024),float(int (i/1024)),float(value));
}
}// for (i=0 ;i<NCH-0;i++)
}// /end of do something
if ((show2Ds)) {
for (ipx=0;ipx<NCH;ipx++) hchptr[(ipx)]=0;
Plot2DHistos(); Plot1DHistos();
}
ifp=kbhit();
processifp(ifp);
if (((framesinstream%NPRO))==NPRO-1) gSystem->ProcessEvents();
}
}// end of infinite loop
rootapp->Run();
nonblock(NB_DISABLE);
return 0;
}
void processifp(int ifp){
if (ifp!=0){
c=fgetc(stdin);
if (c=='s') {if (goout==0){goout=1;}else {myloop();}}
if (c=='S') SetRanges();
if (c=='+') { HDraw_every=HDraw_every*0.8;cout<< endl <<"Drawing every "<< HDraw_every<<" frames "<<endl; }
if (c=='-') { HDraw_every=HDraw_every*1.25;cout<< endl <<"Drawing every "<< HDraw_every<<" frames "<<endl;}
if (c=='G') {gain_flag=not gain_flag ;if (gain_flag) {cout<<"gain corr enab."<< endl;}else {cout<<"gain corr disab."<< endl;}}
if (c=='[') { G1Poffset=G1Poffset-10;cout<< endl <<"G1Poffset "<<G1Poffset<<endl; }
if (c==']') { G1Poffset=G1Poffset+10;cout<< endl <<"G1Poffset "<<G1Poffset<<endl; }
if (c=='{') { G2Poffset=G2Poffset-10;cout<< endl <<"G2Poffset "<<G2Poffset<<endl; }
if (c=='}') { G2Poffset=G2Poffset+10;cout<< endl <<"G2Poffset "<<G2Poffset<<endl; }
if (c=='p') { //stopsocket();
loadpede();//startsocket();
}
if (c=='b') {LoadPaletteBW(1.1111);bw_flag=true; }
if (c=='B') {LoadPaletteBW(0.9);bw_flag=true; }
if (c=='O') savepede();
if (c=='o') readpede();
if (c=='P') loadallpede();
if (c=='u') his1000->SetOption("surf2z");
if (c=='C') his1000->SetOption("colz");
if (c=='q') exit(0);
if (c=='r') historeset();
if (c=='R') axisreset();
}
}
void loadallpede(){
cout <<"not implemented "<< endl;
// hasallpede=true;
// system("./sls_detector_put setbit 0x5d 12 "); //setting to FSG1 ;
// loadpede();
// loadpede();
// for (i=0;i<NCH;i++) {fpedeG1d[i]=fpeded[i];}
// system("./sls_detector_put setbit 0x5d 13 "); //setting to FSG0 ;
// sleep(1);
// loadpede();
// loadpede();
// for (i=0;i<NCH;i++) {fpedeG2d[i]=fpeded[i];}
// system("./sls_detector_put clearbit 0x5d 12 "); //setting to G0;
// system("./sls_detector_put clearbit 0x5d 13 "); //setting to G0;
// sleep(2);
// loadpede();
// loadpede();
}
void loadpede(void){
//startsocket();
framesinstream=0;
pede_flag=true;
nframes=0;
for (ipx=0;ipx<NCH;ipx++) fpeded[ipx]=0;
while (framesinstream<50) { // loop on files
if (!zmqSocket->ReceiveHeader(0,zHeader, SLS_DETECTOR_JSON_HEADER_VERSION)){
return;
}
cout <<"received frameindex "<<zHeader.frameIndex << endl;
zmqSocket->ReceiveData(0, (char *)(&image_data), NCH*2);
framesinstream++;nframes++;
for (ipx=0;ipx<NCH;ipx++) fpeded[ipx]=(fpeded[ipx]*(nframes-1)+(float)(image_data[ipx]&0x3fff))/(float)(nframes);
}
for (ipx=0;ipx<NCH;ipx++) { ipeded[ipx]=(short)(fpeded[ipx]);
if (ipx%60033==0) printf("i=%d pede= %d %f .\n",ipx, ipeded[ipx],fpeded[ipx]);
}
printf("total frames for pede: %d \n",nframes);
//stopsocket();
printhelp();
}
int kbhit()
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
void myloop(void){ //wait doing nothing.
goout=0;
int ifp;
while (goout==0){
ifp=kbhit();
processifp(ifp);
gSystem->ProcessEvents();
usleep(5000);
}
}
void printhelp(){
cout<< endl << "s=start/pause| p/n=getnewpede/raw | o/O=read/save pede | n=nopede(raw) | r/R=rst His/Axis | +/- = faster/slower ref. |q=exit | U/C sUrf2/Colz " <<endl;
}
void historeset(){
his4500->Reset();
his3000->Reset();
for (i=0;i<8;i++) {
hchip[i]->Reset();
}
Plot2DHistos();
Plot1DHistos();
}
void SetRanges() {
string str;
std::cin.clear();
//cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout<< endl;
cout<< " adc min " <<endl;
//getline(cin, str);
// adcmin= stoi(str);
std::cin >> adcmin;
cout<< " adc max " <<endl;
std::cin >> adcmax;
cout<< " p.map min " <<endl;
std::cin >> pmmin;
cout<< " p.map max " <<endl;
std::cin >> pmmax;
fixranges=true;
}
void axisreset(){
fixranges=false;
his1000->GetXaxis()->UnZoom();
his1000->GetYaxis()->UnZoom();
his1000->GetZaxis()->UnZoom();
his2000->GetXaxis()->UnZoom();
his2000->GetYaxis()->UnZoom();
his3000->GetZaxis()->UnZoom();
for (i=0;i<8;i++) {
hchip[i]->GetXaxis()->UnZoom();
hchip[i]->GetYaxis()->UnZoom();
}
his4500->GetXaxis()->UnZoom();
his4500->GetYaxis()->UnZoom();
his4500->GetZaxis()->UnZoom();
Plot2DHistos();
Plot1DHistos();
}
void nonblock(int state)
{
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state==NB_ENABLE)
{
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state==NB_DISABLE)
{ //turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
void LoadPaletteFalse(){
const Int_t NRGBs = 5;
const Int_t NCont = 90;
Double_t stops[NRGBs] = { 0.00, 0.34, 0.61, 0.84, 1.00 };
Double_t red[NRGBs] = { 0.00, 0.00, 0.87, 1.00, 0.51 };
Double_t green[NRGBs] = { 0.00, 0.81, 1.00, 0.20, 0.00 };
Double_t blue[NRGBs] = { 0.51, 1.00, 0.12, 0.00, 0.00 };
TColor::CreateGradientColorTable(NRGBs, stops, red,green, blue, NCont);
gStyle->SetNumberContours(NCont);
TColor::CreateGradientColorTable(NRGBs, stops, red,green ,blue, NCont);
gStyle->SetNumberContours(NCont);
}
void LoadPaletteBW(float gammatune){
vgamma=vgamma*gammatune;
cout<< "gamma is "<<vgamma<<endl;
const Int_t NRGBs = 99;
const Int_t NCont = 990;
Double_t stops[NRGBs] ;
Double_t red[NRGBs] ;
Double_t green[NRGBs];
Double_t blue[NRGBs] ;
for (int iRGB=0;iRGB<NRGBs;iRGB++){
stops[iRGB] =(1/float(NRGBs)*float(iRGB));
red[iRGB] = pow(stops[iRGB],vgamma);
green[iRGB] = red[iRGB];
blue[iRGB] =red[iRGB];
// cout << iRGB<<" "<< stops[iRGB] <<" " << red[iRGB]<<endl;
}
TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, NCont);
gStyle->SetNumberContours(NCont);
// TColor::SetPalette(52,0,1);
}
void Plot1DHistos(void){
if (hchip[0]->GetXaxis()->GetLast()!=oldh0xlast){
oldh0xlast=hchip[0]->GetXaxis()->GetLast();
oldh0xfirst=hchip[0]->GetXaxis()->GetFirst();
for (int ipad=1; ipad<8;ipad++) {
hchip[ipad]->GetXaxis()->SetRange(oldh0xfirst,oldh0xlast);
}
}
for (int ipad=0; ipad<8;ipad++) {
A4->cd(ipad+1);
gStyle->SetOptStat(1); gPad->SetLogy();
hchip[ipad%4+(1-int(ipad/4))*4]->Draw();
}
A4->cd();
A4->Update();
}
void Plot2DHistos(void){
gStyle->SetOptStat(0);
A3->cd();
// if (bw_flag) LoadPaletteBW(1.0);
if (fixranges) {
his1000->GetZaxis()->SetRangeUser(float(adcmin),float(adcmax));
his3000->GetZaxis()->SetRangeUser(float(pmmin),float(pmmax));
}
his1000->SetMinimum(-200);
his1000->Draw();
A3->Update();
A2->cd();
// if (bw_flag) LoadPaletteFalse();
his2000->GetXaxis()->SetRange(his1000->GetXaxis()->GetFirst(),his1000->GetXaxis()->GetLast());
his2000->GetYaxis()->SetRange(his1000->GetYaxis()->GetFirst(),his1000->GetYaxis()->GetLast());
his2000->Draw("colz");
A2->Update();
A5->cd();
his3000->GetXaxis()->SetRange(his1000->GetXaxis()->GetFirst(),his1000->GetXaxis()->GetLast());
his3000->GetYaxis()->SetRange(his1000->GetYaxis()->GetFirst(),his1000->GetYaxis()->GetLast());
his3000->Draw("colz");
A5->Update();
A6->cd();
his4500->Draw("colz");
A6->Update();
}
void startsocket(void) {
try {
zmqSocket = new sls::ZmqSocket(serverip, portnum);
} catch (...) {
cprintf(RED,
"Error: Could not create Zmq socket on port %d with ip %s\n",
portnum, serverip);
delete zmqSocket;
return;
}
zmqSocket->SetReceiveHighWaterMark(3);
zmqSocket->SetReceiveBuffer(1024*1024);
zmqSocket->Connect();
cout<<"Zmq Client[] "<< zmqSocket->GetZmqServerAddress()<<endl;
haveconnection=true;
}
void tryconnect(void)
{
int itry=0;
cout<< endl;
while (haveconnection==false) {
sleep(1);
cout<<"\r trying to (re)connect " <<itry++ << " " << endl ;
startsocket();
}
}
void stopsocket(void) {
// cout<<" cfd " << cfd << endl;;
delete zmqSocket;
zmqSocket=0;
//zmqSocket->~ZmqSocket ();
haveconnection=false;
}
void savepede(void) {
int pfd;
pfd=open(PEDEFNAME,O_CREAT|O_WRONLY, 0666);
if (pfd==-1) perror("open pede file");
write(pfd,fpeded,2*NCH*sizeof(float));
write(pfd,fpedeG1d,2*NCH*sizeof(float));
write(pfd,fpedeG2d,2*NCH*sizeof(float));
close(pfd);
}
void readpede(void) {
int pfd;
pfd=open(PEDEFNAME,O_RDONLY);
if (pfd==-1) perror("open pede file");
read(pfd,fpeded,NCH*2*sizeof(float));
read(pfd,fpedeG1d,NCH*2*sizeof(float));
read(pfd,fpedeG2d,NCH*2*sizeof(float));
close(pfd);
pede_flag=true;
hasallpede=true;
}

View File

@ -0,0 +1,204 @@
/**************************************************************************/
/* Header files section needs cleanup */
/**************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "sls/ZmqSocket.h"
#include "sls/tiffIO.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h> /* exit() */
#include <string.h> /* memset(), memcpy() */
#include <sys/utsname.h> /* uname() */
#include <sys/types.h>
#include <sys/socket.h> /* socket(), bind(),
listen(), accept() */
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h> /* fork(), write(), close() */
#include <time.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <cmath>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <rapidjson/document.h> //json header in zmq stream
#include <omp.h>
#define NTHREADS 2
#include <chrono>
#include <cstdio>
#include <ctime> // time_t
using namespace std;
using namespace std::chrono;
using namespace sls;
#include "TCanvas.h"
#include "TH1F.h"
#include "TF1.h"
#include "TH2F.h"
#include "TMath.h"
#include "TFile.h"
#include "TStyle.h"
#include "TSystem.h"
#include "TTimer.h"
#include "TProfile.h"
#include "TColor.h"
#include <iostream>
#include <fstream>
#include <termios.h>
#include <TApplication.h>
#include <stdio.h>
#include <math.h>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <iostream>
#include "sls/ansi.h"
#define SLS_DETECTOR_JSON_HEADER_VERSION 0x4
#define PI 3.14159265
#define FALSE 0
#define OFFSET 0
#define NBIN 500
#define MIN_POS -500.5 // 400.5
#define MAX_POS 3499.5 //-100.5
#define NCH 524288
// #define NCH 262144 in case of half_frames
char serverip[256];
int portnum;
FILE * sfilefd;
short* hchptr; // photon counted map "histogram"
int value;
float factor=1.84;
int npacket=0;
int totalnpacket=0;
float vgamma;
struct sockaddr_in serveraddr;
struct sockaddr_in clientaddr;
struct in_addr inadr;
struct hostent *server;
int i=0;
int ipx=0;
bool haveconnection;
TStyle *gStyle;
TApplication* rootapp;
TCanvas *A2;
TCanvas *A3;
TCanvas *A4;
TCanvas *A5;
TCanvas *A6;
TH1I **hchip;
TH2F **h4500chip;
short image_data[NCH*2];
short imaged[NCH*2];
float fpeded[NCH*2];
float fpedeG2d[NCH*2];
float fpedeG1d[NCH*2];
short ipeded[NCH*2];
short pcimaged[NCH*2];
float fgaind[NCH*2];
float adcpedecorr,adcpedecorrold;
bool gain_flag;
bool bw_flag;
bool fill2Ds;
bool show2Ds;
bool fill1Ds;
bool pede_flag;
bool dophotonmap;
int nx, ny;
int nframes;
int goout;
int framesinstream;
int ifp;
float threshold;
int phene;
int adcvalue;
int gain;
int ichip;
int frameIndex_old;
char pedefilename[128];
int framenum,bunchid;
TH2F* his1000;
TH2F* his2000;
TH2F* his3000;
TH2F* his4500;
TH1I* hproj;
TH1I* hchcum;
using namespace std;
void printhelp(void);
void processifp(int ifp);
void historeset(void);
void SetRanges(void);
void startsocket(void);
void stopsocket(void);
void axisreset(void);
int kbhit(void);
void myloop(void);
void loadpede(void);
void loadallpede(void);
void loadgain(void);
void nonblock(int state);
void LoadPaletteFalse(void);
void LoadPaletteBW(float);
void Plot1DHistos(void);
void Plot2DHistos(void);
void savepede(void);
void readpede(void);
int findinterpoindex(int startindex);
int findclumax(int startindex);
void tryconnect(void) ;
#define NB_ENABLE 1
#define NB_DISABLE 0
char c;
int HDraw_every;
float oldh0xfirst,oldh0xlast;
int idx;
int GXPoffset,G1Poffset,G2Poffset;
int ix,iy;
int adcmin,adcmax;
int pmmin,pmmax; //min/mnx for the photon map
bool fixranges;
sls::ZmqSocket *zmqSocket= NULL;

View File

@ -59,6 +59,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
void ClonePlot(); void ClonePlot();
void SavePlot(); void SavePlot();
void SetGapPixels(bool enable); void SetGapPixels(bool enable);
void UpdatePlot();
protected: protected:
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
@ -67,7 +68,6 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
void Zoom1DGainPlot(const QRectF &rect); void Zoom1DGainPlot(const QRectF &rect);
void Zoom2DGainPlot(const QRectF &rect); void Zoom2DGainPlot(const QRectF &rect);
void SetSaveFileName(QString val); void SetSaveFileName(QString val);
void UpdatePlot();
signals: signals:
void AcquireFinishedSignal(); void AcquireFinishedSignal();

View File

@ -47,6 +47,7 @@ class qTabPlot : public QWidget, private Ui::TabPlotObject {
private: private:
void SetupWidgetWindow(); void SetupWidgetWindow();
void Initialization(); void Initialization();
bool VerifyGapPixelsAllowed();
void Select1DPlot(bool enable); void Select1DPlot(bool enable);
void GetGapPixels(); void GetGapPixels();
void GetStreamingFrequency(); void GetStreamingFrequency();
@ -60,7 +61,8 @@ class qTabPlot : public QWidget, private Ui::TabPlotObject {
Detector *det; Detector *det;
qDrawPlot *plot; qDrawPlot *plot;
bool is1d; bool is1d{false};
bool isGapPixelsAllowed{false};
/** default plot and axis titles */ /** default plot and axis titles */
static QString defaultPlotTitle; static QString defaultPlotTitle;

View File

@ -180,8 +180,10 @@ void qTabDataOutput::BrowseOutputDir() {
LOG(logDEBUG) << "Browsing output directory"; LOG(logDEBUG) << "Browsing output directory";
QString directory = QFileDialog::getExistingDirectory( QString directory = QFileDialog::getExistingDirectory(
this, tr("Choose Output Directory "), dispOutputDir->text()); this, tr("Choose Output Directory "), dispOutputDir->text());
if (!directory.isEmpty()) if (!directory.isEmpty()) {
dispOutputDir->setText(directory); dispOutputDir->setText(directory);
ForceSetOutputDir();
}
} }
void qTabDataOutput::SetOutputDir(bool force) { void qTabDataOutput::SetOutputDir(bool force) {

View File

@ -16,7 +16,7 @@ QString qTabPlot::defaultImageYAxisTitle("Pixel");
QString qTabPlot::defaultImageZAxisTitle("Intensity"); QString qTabPlot::defaultImageZAxisTitle("Intensity");
qTabPlot::qTabPlot(QWidget *parent, Detector *detector, qDrawPlot *p) qTabPlot::qTabPlot(QWidget *parent, Detector *detector, qDrawPlot *p)
: QWidget(parent), det(detector), plot(p), is1d(false) { : QWidget(parent), det(detector), plot(p) {
setupUi(this); setupUi(this);
SetupWidgetWindow(); SetupWidgetWindow();
LOG(logDEBUG) << "Plot ready"; LOG(logDEBUG) << "Plot ready";
@ -57,11 +57,7 @@ void qTabPlot::SetupWidgetWindow() {
chkGainPlot1D->setChecked(true); chkGainPlot1D->setChecked(true);
plot->EnableGainPlot(true); plot->EnableGainPlot(true);
break; break;
case slsDetectorDefs::EIGER:
chkGapPixels->setEnabled(true);
break;
case slsDetectorDefs::JUNGFRAU: case slsDetectorDefs::JUNGFRAU:
chkGapPixels->setEnabled(true);
chkGainPlot->setEnabled(true); chkGainPlot->setEnabled(true);
chkGainPlot->setChecked(true); chkGainPlot->setChecked(true);
plot->EnableGainPlot(true); plot->EnableGainPlot(true);
@ -74,6 +70,8 @@ void qTabPlot::SetupWidgetWindow() {
default: default:
break; break;
} }
isGapPixelsAllowed = VerifyGapPixelsAllowed();
chkGapPixels->setEnabled(isGapPixelsAllowed);
Select1DPlot(is1d); Select1DPlot(is1d);
Initialization(); Initialization();
@ -200,6 +198,29 @@ void qTabPlot::Initialization() {
connect(dispZMax, SIGNAL(editingFinished()), this, SLOT(isZMaxModified())); connect(dispZMax, SIGNAL(editingFinished()), this, SLOT(isZMaxModified()));
} }
bool qTabPlot::VerifyGapPixelsAllowed() {
try {
switch (det->getDetectorType().squash()) {
case slsDetectorDefs::JUNGFRAU:
return true;
case slsDetectorDefs::EIGER:
if (det->getQuad().squash(false)) {
return true;
}
// full modules
if (det->getModuleGeometry().y % 2 == 0) {
return true;
}
return false;
default:
return false;
}
}
CATCH_DISPLAY("Could not verify if gap pixels allowed.",
"qTabPlot::VerifyGapPixelsAllowed")
return false;
}
void qTabPlot::Select1DPlot(bool enable) { void qTabPlot::Select1DPlot(bool enable) {
LOG(logDEBUG) << "Selecting " << (enable ? "1" : "2") << "D Plot"; LOG(logDEBUG) << "Selecting " << (enable ? "1" : "2") << "D Plot";
is1d = enable; is1d = enable;
@ -492,6 +513,7 @@ void qTabPlot::SetXYRange() {
} }
plot->SetXYRangeChanged(disablezoom, xyRange, isRange); plot->SetXYRangeChanged(disablezoom, xyRange, isRange);
plot->UpdatePlot();
emit DisableZoomSignal(disablezoom); emit DisableZoomSignal(disablezoom);
} }
@ -629,6 +651,7 @@ void qTabPlot::SetZRange() {
zRange[1] = val; zRange[1] = val;
} }
plot->SetZRange(zRange, isZRange); plot->SetZRange(zRange, isZRange);
plot->UpdatePlot();
} }
void qTabPlot::GetStreamingFrequency() { void qTabPlot::GetStreamingFrequency() {
@ -775,15 +798,10 @@ void qTabPlot::Refresh() {
boxFrequency->setEnabled(true); boxFrequency->setEnabled(true);
GetStreamingFrequency(); GetStreamingFrequency();
GetHwm(); GetHwm();
// gain plot, gap pixels enable // gain plot
switch (det->getDetectorType().squash()) { switch (det->getDetectorType().squash()) {
case slsDetectorDefs::EIGER:
chkGapPixels->setEnabled(true);
GetGapPixels();
break;
case slsDetectorDefs::JUNGFRAU: case slsDetectorDefs::JUNGFRAU:
chkGainPlot->setEnabled(true); chkGainPlot->setEnabled(true);
chkGapPixels->setEnabled(true);
GetGapPixels(); GetGapPixels();
break; break;
case slsDetectorDefs::MOENCH: case slsDetectorDefs::MOENCH:
@ -795,6 +813,11 @@ void qTabPlot::Refresh() {
default: default:
break; break;
} }
// gap pixels
if (isGapPixelsAllowed) {
chkGapPixels->setEnabled(true);
GetGapPixels();
}
} else { } else {
boxFrequency->setEnabled(false); boxFrequency->setEnabled(false);
chkGainPlot->setEnabled(false); chkGainPlot->setEnabled(false);

View File

@ -3,12 +3,12 @@
# empty branch = developer branch in updateAPIVersion.sh # empty branch = developer branch in updateAPIVersion.sh
branch="" branch=""
det_list=("ctbDetectorServer" det_list=("ctbDetectorServer
"gotthardDetectorServer" gotthardDetectorServer
"gotthard2DetectorServer" gotthard2DetectorServer
"jungfrauDetectorServer" jungfrauDetectorServer
"mythen3DetectorServer" mythen3DetectorServer
"moenchDetectorServer" moenchDetectorServer"
) )
usage="\nUsage: compileAllServers.sh [server|all(opt)] [branch(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tNo 'branch' input means 'developer branch'" usage="\nUsage: compileAllServers.sh [server|all(opt)] [branch(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tNo 'branch' input means 'developer branch'"
@ -25,9 +25,11 @@ elif [ $# -eq 1 ] || [ $# -eq 2 ]; then
else else
# only one server # only one server
# arg not in list # arg not in list
if [[ $det_list != *$1* ]]; then echo $det_list | grep -w -q $1
#if [[ $det_list != *$1* ]]; then
if ! [[ $? ]] ; then
echo -e "Invalid argument 1: $1. $usage" echo -e "Invalid argument 1: $1. $usage"
return -1 return 1
fi fi
declare -a det=("${1}") declare -a det=("${1}")
#echo "Compiling only $1" #echo "Compiling only $1"
@ -37,14 +39,14 @@ elif [ $# -eq 1 ] || [ $# -eq 2 ]; then
# arg in list # arg in list
if [[ $det_list == *$2* ]]; then if [[ $det_list == *$2* ]]; then
echo -e "Invalid argument 2: $2. $usage" echo -e "Invalid argument 2: $2. $usage"
return -1 return 1
fi fi
branch+=$2 branch+=$2
#echo "with branch $branch" #echo "with branch $branch"
fi fi
else else
echo -e "Too many arguments.$usage" echo -e "Too many arguments.$usage"
return -1 return 1
fi fi
declare -a deterror=("OK" "OK" "OK" "OK" "OK" "OK") declare -a deterror=("OK" "OK" "OK" "OK" "OK" "OK")

View File

@ -99,7 +99,7 @@ void basictests() {
#endif #endif
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not map to memory. Dangerous to continue.\n"); "Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initError = FAIL; initError = FAIL;
return; return;
@ -109,8 +109,10 @@ void basictests() {
if ((!debugflag) && (!updateFlag) && if ((!debugflag) && (!updateFlag) &&
((checkType() == FAIL) || (testFpga() == FAIL) || ((checkType() == FAIL) || (testFpga() == FAIL) ||
(testBus() == FAIL))) { (testBus() == FAIL))) {
strcpy(initErrorMessage, "Could not pass basic tests of FPGA and bus. " sprintf(initErrorMessage,
"Dangerous to continue.\n"); "Could not pass basic tests of FPGA and bus. Cannot proceed. "
"Check Firmware. (Firmware version:0x%llx) \n",
getFirmwareVersion());
LOG(logERROR, ("%s\n\n", initErrorMessage)); LOG(logERROR, ("%s\n\n", initErrorMessage));
initError = FAIL; initError = FAIL;
return; return;
@ -446,7 +448,7 @@ void initStopServer() {
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
initError = FAIL; initError = FAIL;
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); "Stop Server: Map Fail. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initCheckDone = 1; initCheckDone = 1;
return; return;

View File

@ -1106,7 +1106,9 @@ int Beb_SetDetectorPosition(int pos[]) {
int posRight[2] = {Beb_top ? pos[X] + 1 : pos[X], pos[Y]}; int posRight[2] = {Beb_top ? pos[X] + 1 : pos[X], pos[Y]};
if (Beb_quadEnable) { if (Beb_quadEnable) {
posRight[Y] = 1; // right is next row posLeft[Y] = 1; // left is next row
posLeft[X] = 0; // left same first row
posRight[Y] = 0; // right same first row
posRight[X] = 0; // right same first column posRight[X] = 0; // right same first column
} }

View File

@ -25,7 +25,7 @@ target_include_directories(eigerDetectorServer_virtual
) )
target_compile_definitions(eigerDetectorServer_virtual target_compile_definitions(eigerDetectorServer_virtual
PUBLIC EIGERD PCCOMPILE STOP_SERVER PUBLIC EIGERD PCCOMPILE STOP_SERVER #TEST_MOD_GEOMETRY
PUBLIC VIRTUAL #VIRTUAL_9M PUBLIC VIRTUAL #VIRTUAL_9M
) )

View File

@ -1240,19 +1240,16 @@ int Feb_Control_GetDynamicRange(int *retval) {
int Feb_Control_Disable16bitConversion(int disable) { int Feb_Control_Disable16bitConversion(int disable) {
LOG(logINFO, ("%s 16 bit expansion\n", disable ? "Disabling" : "Enabling")); LOG(logINFO, ("%s 16 bit expansion\n", disable ? "Disabling" : "Enabling"));
uint32_t bitmask = DAQ_REG_HRDWRE_DSBL_16BIT_MSK;
unsigned int regval = 0; unsigned int regval = 0;
if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, &regval)) {
LOG(logERROR, ("Could not %s 16 bit expansion (bit mode)\n",
(disable ? "disable" : "enable")));
return 0;
}
if (disable) { if (disable) {
regval |= DAQ_REG_HRDWRE_DSBL_16BIT_MSK; regval |= bitmask;
} else { } else {
regval &= ~DAQ_REG_HRDWRE_DSBL_16BIT_MSK; regval &= ~bitmask;
} }
if (!Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval)) { if (!Feb_Control_WriteRegister_BitMask(DAQ_REG_HRDWRE, regval, bitmask)) {
LOG(logERROR, ("Could not %s 16 bit expansion (bit mode)\n", LOG(logERROR, ("Could not %s 16 bit expansion (bit mode)\n",
(disable ? "disable" : "enable"))); (disable ? "disable" : "enable")));
return 0; return 0;
@ -1262,11 +1259,12 @@ int Feb_Control_Disable16bitConversion(int disable) {
int Feb_Control_Get16bitConversionDisabled(int *ret) { int Feb_Control_Get16bitConversionDisabled(int *ret) {
unsigned int regval = 0; unsigned int regval = 0;
if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, &regval)) { if (!Feb_Control_ReadRegister_BitMask(DAQ_REG_HRDWRE, &regval,
DAQ_REG_HRDWRE_DSBL_16BIT_MSK)) {
LOG(logERROR, ("Could not get 16 bit expansion (bit mode)\n")); LOG(logERROR, ("Could not get 16 bit expansion (bit mode)\n"));
return 0; return 0;
} }
if (regval & DAQ_REG_HRDWRE_DSBL_16BIT_MSK) { if (regval) {
*ret = 1; *ret = 1;
} else { } else {
*ret = 0; *ret = 0;
@ -1667,6 +1665,15 @@ int Feb_Control_GetReadNRows() {
} }
int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) { int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
return Feb_Control_WriteRegister_BitMask(offset, data, BIT32_MSK);
}
int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval) {
return Feb_Control_ReadRegister_BitMask(offset, retval, BIT32_MASK);
}
int Feb_Control_WriteRegister_BitMask(uint32_t offset, uint32_t data,
uint32_t bitmask) {
uint32_t actualOffset = offset; uint32_t actualOffset = offset;
char side[2][10] = {"right", "left"}; char side[2][10] = {"right", "left"};
unsigned int addr[2] = {Feb_Control_rightAddress, Feb_Control_leftAddress}; unsigned int addr[2] = {Feb_Control_rightAddress, Feb_Control_leftAddress};
@ -1690,24 +1697,41 @@ int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
for (int iloop = 0; iloop < 2; ++iloop) { for (int iloop = 0; iloop < 2; ++iloop) {
if (run[iloop]) { if (run[iloop]) {
LOG(logDEBUG1, LOG(logDEBUG1, ("Writing 0x%x to %s 0x%x (mask:0x%x)\n", data,
("Writing 0x%x to %s 0x%x\n", data, side[iloop], actualOffset)); side[iloop], actualOffset, bitmask));
if (!Feb_Interface_WriteRegister(addr[iloop], actualOffset, data, 0,
0)) { uint32_t writeVal = 0;
LOG(logERROR, ("Could not write 0x%x to %s addr 0x%x\n", data, if (!Feb_Interface_ReadRegister(addr[iloop], actualOffset,
&writeVal)) {
LOG(logERROR, ("Could not read %s addr 0x%x register\n",
side[iloop], actualOffset)); side[iloop], actualOffset));
return 0; return 0;
} }
uint32_t regVal = 0; // set only the bits in the mask
if (!Feb_Interface_ReadRegister(addr[iloop], actualOffset, writeVal &= ~(bitmask);
&regVal)) { writeVal |= (data & bitmask);
LOG(logERROR, ("Could not read %s register\n", addr[iloop]));
LOG(logDEBUG1, ("writing 0x%x to 0x%x\n", writeVal, actualOffset));
if (!Feb_Interface_WriteRegister(addr[iloop], actualOffset,
writeVal, 0, 0)) {
LOG(logERROR, ("Could not write 0x%x to %s addr 0x%x\n",
writeVal, side[iloop], actualOffset));
return 0; return 0;
} }
if (regVal != data) { writeVal &= bitmask;
uint32_t readVal = 0;
if (!Feb_Interface_ReadRegister(addr[iloop], actualOffset,
&readVal)) {
return 0;
}
readVal &= bitmask;
if (writeVal != readVal) {
LOG(logERROR, LOG(logERROR,
("Could not write %s register. Write 0x%x, read 0x%x\n", ("Could not write %s addr 0x%x register. Wrote "
addr[iloop], data, regVal)); "0x%x, read 0x%x (mask:0x%x)\n",
side[iloop], actualOffset, writeVal, readVal, bitmask));
return 0; return 0;
} }
} }
@ -1716,7 +1740,8 @@ int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
return 1; return 1;
} }
int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval) { int Feb_Control_ReadRegister_BitMask(uint32_t offset, uint32_t *retval,
uint32_t bitmask) {
uint32_t actualOffset = offset; uint32_t actualOffset = offset;
char side[2][10] = {"right", "left"}; char side[2][10] = {"right", "left"};
unsigned int addr[2] = {Feb_Control_rightAddress, Feb_Control_leftAddress}; unsigned int addr[2] = {Feb_Control_rightAddress, Feb_Control_leftAddress};
@ -1746,8 +1771,9 @@ int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval) {
side[iloop], actualOffset)); side[iloop], actualOffset));
return 0; return 0;
} }
LOG(logDEBUG1, ("Read 0x%x from %s 0x%x\n", value[iloop], value[iloop] &= bitmask;
side[iloop], actualOffset)); LOG(logDEBUG1, ("Read 0x%x from %s 0x%x (mask:0x%x)\n",
value[iloop], side[iloop], actualOffset, bitmask));
*retval = value[iloop]; *retval = value[iloop];
// if not the other (left, not right OR right, not left), return the // if not the other (left, not right OR right, not left), return the
// value // value
@ -1758,7 +1784,7 @@ int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval) {
} }
// Inconsistent values when reading both registers // Inconsistent values when reading both registers
if ((run[0] & run[1]) & (value[0] != value[1])) { if ((run[0] & run[1]) & (value[0] != value[1])) {
LOG(logERROR, ("Inconsistent values read from %s 0x%x and %s 0x%x\n", LOG(logERROR, ("Inconsistent values read from %s: 0x%x and %s: 0x%x\n",
side[0], value[0], side[1], value[1])); side[0], value[0], side[1], value[1]));
return 0; return 0;
} }

View File

@ -95,7 +95,10 @@ int Feb_Control_SetReadNRows(int value);
int Feb_Control_GetReadNRows(); int Feb_Control_GetReadNRows();
int Feb_Control_WriteRegister(uint32_t offset, uint32_t data); int Feb_Control_WriteRegister(uint32_t offset, uint32_t data);
int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval); int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval);
int Feb_Control_WriteRegister_BitMask(uint32_t offset, uint32_t data,
uint32_t bitmask);
int Feb_Control_ReadRegister_BitMask(uint32_t offset, uint32_t *retval,
uint32_t bitmask);
// pulsing // pulsing
int Feb_Control_Pulse_Pixel(int npulses, int x, int y); int Feb_Control_Pulse_Pixel(int npulses, int x, int y);
int Feb_Control_PulsePixelNMove(int npulses, int inc_x_pos, int inc_y_pos); int Feb_Control_PulsePixelNMove(int npulses, int inc_x_pos, int inc_y_pos);

View File

@ -882,12 +882,15 @@ int setDynamicRange(int dr) {
LOG(logINFO, ("Setting dynamic range: %d\n", dr)); LOG(logINFO, ("Setting dynamic range: %d\n", dr));
#else #else
sharedMemory_lockLocalLink(); sharedMemory_lockLocalLink();
if (Feb_Control_SetDynamicRange(dr)) { if (!Feb_Control_SetDynamicRange(dr)) {
if (!Beb_SetUpTransferParameters(dr)) { LOG(logERROR, ("Could not set dynamic range in feb\n"));
LOG(logERROR, ("Could not set bit mode in the back end\n")); sharedMemory_unlockLocalLink();
sharedMemory_unlockLocalLink(); return FAIL;
return eiger_dynamicrange; }
} if (!Beb_SetUpTransferParameters(dr)) {
LOG(logERROR, ("Could not set bit mode in the back end\n"));
sharedMemory_unlockLocalLink();
return eiger_dynamicrange;
} }
sharedMemory_unlockLocalLink(); sharedMemory_unlockLocalLink();
#endif #endif
@ -1475,6 +1478,12 @@ int setHighVoltage(int val) {
sharedMemory_unlockLocalLink(); sharedMemory_unlockLocalLink();
return -3; return -3;
} }
// need to read the file twice to get the proper value
if (!Feb_Control_GetHighVoltage(&eiger_highvoltage)) {
LOG(logERROR, ("Could not read high voltage\n"));
sharedMemory_unlockLocalLink();
return -3;
}
sharedMemory_unlockLocalLink(); sharedMemory_unlockLocalLink();
// tolerance of 5 // tolerance of 5
@ -2685,6 +2694,10 @@ void *start_timer(void *arg) {
header->modId = eiger_virtual_module_id; header->modId = eiger_virtual_module_id;
header->row = row; header->row = row;
header->column = colLeft; header->column = colLeft;
if (eiger_virtual_quad_mode) {
header->row = 1; // left is next row
header->column = 0; // left same first column
}
char packetData2[packetsize]; char packetData2[packetsize];
memset(packetData2, 0, packetsize); memset(packetData2, 0, packetsize);
@ -2693,11 +2706,11 @@ void *start_timer(void *arg) {
header->version = SLS_DETECTOR_HEADER_VERSION; header->version = SLS_DETECTOR_HEADER_VERSION;
header->frameNumber = frameNr + iframes; header->frameNumber = frameNr + iframes;
header->packetNumber = i; header->packetNumber = i;
header->modId = eiger_virtual_module_id; header->modId = eiger_virtual_module_id + 1;
header->row = row; header->row = row;
header->column = colRight; header->column = colRight;
if (eiger_virtual_quad_mode) { if (eiger_virtual_quad_mode) {
header->row = 1; // right is next row header->row = 0; // right is next row
header->column = 0; // right same first column header->column = 0; // right same first column
} }

View File

@ -5,7 +5,7 @@
#define LINKED_SERVER_NAME "eigerDetectorServer" #define LINKED_SERVER_NAME "eigerDetectorServer"
#define REQUIRED_FIRMWARE_VERSION (30) #define REQUIRED_FIRMWARE_VERSION (31)
// virtual ones renamed for consistency // virtual ones renamed for consistency
// real ones keep previous name for compatibility (already in production) // real ones keep previous name for compatibility (already in production)
#ifdef VIRTUAL #ifdef VIRTUAL
@ -137,6 +137,7 @@ enum MASTERINDEX { MASTER_HARDWARE, OW_MASTER, OW_SLAVE };
#define UDP_HEADER_MAX_FRAME_VALUE (0xFFFFFFFFFFFF) #define UDP_HEADER_MAX_FRAME_VALUE (0xFFFFFFFFFFFF)
#define BIT16_MASK (0xFFFF) #define BIT16_MASK (0xFFFF)
#define BIT32_MSK (0xFFFFFFFF)
#define DAC_MIN_MV (0) #define DAC_MIN_MV (0)
#define DAC_MAX_MV (2048) #define DAC_MAX_MV (2048)

View File

@ -93,7 +93,7 @@ void basictests() {
#endif #endif
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not map to memory. Dangerous to continue.\n"); "Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initError = FAIL; initError = FAIL;
return; return;
@ -105,8 +105,8 @@ void basictests() {
(checkType() == FAIL) || (testFpga() == FAIL) || (checkType() == FAIL) || (testFpga() == FAIL) ||
(testBus() == FAIL))) { (testBus() == FAIL))) {
sprintf(initErrorMessage, sprintf(initErrorMessage,
"Could not pass basic tests of FPGA and bus. Dangerous to " "Could not pass basic tests of FPGA and bus. Cannot proceed. "
"continue. (Firmware version:0x%llx) \n", "Check Firmware. (Firmware version:0x%llx) \n",
getFirmwareVersion()); getFirmwareVersion());
LOG(logERROR, ("%s\n\n", initErrorMessage)); LOG(logERROR, ("%s\n\n", initErrorMessage));
initError = FAIL; initError = FAIL;
@ -396,7 +396,7 @@ void initStopServer() {
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
initError = FAIL; initError = FAIL;
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); "Stop Server: Map Fail. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initCheckDone = 1; initCheckDone = 1;
return; return;

View File

@ -87,7 +87,7 @@ void basictests() {
#endif #endif
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not map to memory. Dangerous to continue.\n"); "Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initError = FAIL; initError = FAIL;
} }
@ -97,7 +97,7 @@ void basictests() {
((checkType() == FAIL) || (testFpga() == FAIL) || ((checkType() == FAIL) || (testFpga() == FAIL) ||
(testBus() == FAIL))) { (testBus() == FAIL))) {
strcpy(initErrorMessage, "Could not pass basic tests of FPGA and bus. " strcpy(initErrorMessage, "Could not pass basic tests of FPGA and bus. "
"Dangerous to continue.\n"); "Cannot proceed. Check Firmware.\n");
LOG(logERROR, ("%s\n\n", initErrorMessage)); LOG(logERROR, ("%s\n\n", initErrorMessage));
initError = FAIL; initError = FAIL;
return; return;
@ -381,7 +381,7 @@ void initStopServer() {
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
initError = FAIL; initError = FAIL;
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); "Stop Server: Map Fail. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initCheckDone = 1; initCheckDone = 1;
return; return;

View File

@ -82,7 +82,7 @@ void basictests() {
#endif #endif
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not map to memory. Dangerous to continue.\n"); "Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initError = FAIL; initError = FAIL;
} }
@ -91,8 +91,10 @@ void basictests() {
if ((!debugflag) && (!updateFlag) && if ((!debugflag) && (!updateFlag) &&
((checkType() == FAIL) || (testFpga() == FAIL) || ((checkType() == FAIL) || (testFpga() == FAIL) ||
(testBus() == FAIL))) { (testBus() == FAIL))) {
strcpy(initErrorMessage, "Could not pass basic tests of FPGA and bus. " sprintf(initErrorMessage,
"Dangerous to continue.\n"); "Could not pass basic tests of FPGA and bus. Cannot proceed. "
"Check Firmware. (Firmware version:0x%llx) \n",
getFirmwareVersion());
LOG(logERROR, ("%s\n\n", initErrorMessage)); LOG(logERROR, ("%s\n\n", initErrorMessage));
initError = FAIL; initError = FAIL;
return; return;
@ -428,7 +430,7 @@ void initStopServer() {
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
initError = FAIL; initError = FAIL;
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); "Stop Server: Map Fail. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initCheckDone = 1; initCheckDone = 1;
return; return;
@ -2798,6 +2800,7 @@ int softwareTrigger(int block) {
LOG(logINFO, ("Sending Software Trigger\n")); LOG(logINFO, ("Sending Software Trigger\n"));
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_SOFTWARE_TRIGGER_MSK); bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_SOFTWARE_TRIGGER_MSK);
bus_w(CONTROL_REG, bus_r(CONTROL_REG) & ~CONTROL_SOFTWARE_TRIGGER_MSK);
#ifndef VIRTUAL #ifndef VIRTUAL
// block till frame is sent out // block till frame is sent out

View File

@ -82,8 +82,8 @@ void basictests() {
#endif #endif
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not map to memory. Dangerous to continue.\n"); "Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, ("%s\n\n", initErrorMessage));
initError = FAIL; initError = FAIL;
} }
#ifndef VIRTUAL #ifndef VIRTUAL
@ -91,8 +91,10 @@ void basictests() {
if ((!debugflag) && (!updateFlag) && if ((!debugflag) && (!updateFlag) &&
((checkType() == FAIL) || (testFpga() == FAIL) || ((checkType() == FAIL) || (testFpga() == FAIL) ||
(testBus() == FAIL))) { (testBus() == FAIL))) {
strcpy(initErrorMessage, "Could not pass basic tests of FPGA and bus. " sprintf(initErrorMessage,
"Dangerous to continue.\n"); "Could not pass basic tests of FPGA and bus. Cannot proceed. "
"Check Firmware. (Firmware version:0x%llx) \n",
getFirmwareVersion());
LOG(logERROR, ("%s\n\n", initErrorMessage)); LOG(logERROR, ("%s\n\n", initErrorMessage));
initError = FAIL; initError = FAIL;
return; return;
@ -432,7 +434,7 @@ void initStopServer() {
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
initError = FAIL; initError = FAIL;
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); "Stop Server: Map Fail. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initCheckDone = 1; initCheckDone = 1;
return; return;

View File

@ -89,7 +89,7 @@ void basictests() {
#endif #endif
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not map to memory. Dangerous to continue.\n"); "Could not map to memory. Cannot proceed. Check Firmware.\n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initError = FAIL; initError = FAIL;
} }
@ -99,8 +99,10 @@ void basictests() {
((validateKernelVersion(KERNEL_DATE_VRSN) == FAIL) || ((validateKernelVersion(KERNEL_DATE_VRSN) == FAIL) ||
(checkType() == FAIL) || (testFpga() == FAIL) || (checkType() == FAIL) || (testFpga() == FAIL) ||
(testBus() == FAIL))) { (testBus() == FAIL))) {
strcpy(initErrorMessage, "Could not pass basic tests of FPGA and bus. " sprintf(initErrorMessage,
"Dangerous to continue.\n"); "Could not pass basic tests of FPGA and bus. Cannot proceed. "
"Check Firmware. (Firmware version:0x%llx) \n",
getFirmwareVersion());
LOG(logERROR, ("%s\n\n", initErrorMessage)); LOG(logERROR, ("%s\n\n", initErrorMessage));
initError = FAIL; initError = FAIL;
return; return;
@ -388,7 +390,7 @@ void initStopServer() {
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
initError = FAIL; initError = FAIL;
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); "Stop Server: Map Fail. Cannot proceed. Check Firmware. \n");
LOG(logERROR, (initErrorMessage)); LOG(logERROR, (initErrorMessage));
initCheckDone = 1; initCheckDone = 1;
return; return;

View File

@ -3,7 +3,7 @@
#pragma once #pragma once
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#define REQRD_FRMWRE_VRSN (0x221205) #define REQRD_FRMWRE_VRSN (0x230124)
#define KERNEL_DATE_VRSN "Mon May 10 18:00:21 CEST 2021" #define KERNEL_DATE_VRSN "Mon May 10 18:00:21 CEST 2021"
#define ID_FILE "detid_mythen3.txt" #define ID_FILE "detid_mythen3.txt"
@ -57,10 +57,10 @@
#define DEFAULT_TRIMBIT_VALUE (0) #define DEFAULT_TRIMBIT_VALUE (0)
#define DEFAULT_COUNTER_DISABLED_VTH_VAL (2800) #define DEFAULT_COUNTER_DISABLED_VTH_VAL (2800)
#define DEFAULT_READOUT_C0 (12) //(083333333) // rdo_clk, 83.33 MHz #define DEFAULT_READOUT_C0 (10) //(100000000) // rdo_clk, 100 MHz
#define DEFAULT_READOUT_C1 (12) //(083333333) // rdo_smp_clk, 83.33 MHz #define DEFAULT_READOUT_C1 (10) //(100000000) // rdo_smp_clk, 100 MHz
#define DEFAULT_SYSTEM_C0 (20) //(050000000) // run_clk, 20 MHz #define DEFAULT_SYSTEM_C0 (10) //(100000000) // run_clk, 100 MHz
#define DEFAULT_SYSTEM_C1 (8) //(125000000) // str_clk, 125 MHz const #define DEFAULT_SYSTEM_C1 (6) //(166666666) // str_clk, 166 MHz const
#define DEFAULT_SYSTEM_C2 (5) //(200000000) // smp_clk, 200 MHz const #define DEFAULT_SYSTEM_C2 (5) //(200000000) // smp_clk, 200 MHz const
#define DEFAULT_TRIMMING_RUN_CLKDIV (40) // (25000000) // 25 MHz #define DEFAULT_TRIMMING_RUN_CLKDIV (40) // (25000000) // 25 MHz

View File

@ -548,8 +548,8 @@ int M_nofunc(int file_des) {
ret = FAIL; ret = FAIL;
memset(mess, 0, sizeof(mess)); memset(mess, 0, sizeof(mess));
sprintf(mess, "Unrecognized Function enum %d. Please do not proceed.\n", sprintf(mess, "%s Function enum %d. Please do not proceed.\n",
fnum); UNRECOGNIZED_FNUM_ENUM, fnum);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return Server_SendResult(file_des, OTHER, NULL, 0); return Server_SendResult(file_des, OTHER, NULL, 0);
} }
@ -5087,11 +5087,20 @@ int set_source_udp_mac(int file_des) {
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
if (check_detector_idle("configure mac") == OK) { if (check_detector_idle("configure mac") == OK) {
if (udpDetails[0].srcmac != arg) { if (udpDetails[0].srcmac != arg) {
for (int iRxEntry = 0; iRxEntry != MAX_UDP_DESTINATION; // multicast (LSB of first octet = 1)
++iRxEntry) { if ((arg >> 40) & 0x1) {
udpDetails[iRxEntry].srcmac = arg; ret = FAIL;
sprintf(mess,
"Cannot set source mac address. Must be a unicast "
"address (LSB of first octet should be 0).");
LOG(logERROR, (mess));
} else {
for (int iRxEntry = 0; iRxEntry != MAX_UDP_DESTINATION;
++iRxEntry) {
udpDetails[iRxEntry].srcmac = arg;
}
configure_mac();
} }
configure_mac();
} }
} }
} }
@ -5953,7 +5962,7 @@ int set_clock_divider(int file_des) {
#endif #endif
modeNotImplemented("clock index (divider set)", args[0]); modeNotImplemented("clock index (divider set)", args[0]);
} }
// TODO: if value between to set and num clocks, msg = "cannot set"
enum CLKINDEX c = 0; enum CLKINDEX c = 0;
int val = args[1]; int val = args[1];
if (ret == OK) { if (ret == OK) {

View File

@ -225,6 +225,17 @@ class Detector {
*/ */
void setBadChannels(const std::string &fname, Positions pos = {}); void setBadChannels(const std::string &fname, Positions pos = {});
/** [Gotthard2][Mythen3] */
Result<std::vector<int>> getBadChannels(Positions pos = {}) const;
/** [Gotthard2][Mythen3] Empty list resets bad channel list */
void setBadChannels(const std::vector<int> list, Positions pos = {});
/** [Gotthard2][Mythen3] Size of list should match number of modules. Each
* value is at module level and can start at 0. Empty vector resets bad
* channel list. */
void setBadChannels(const std::vector<std::vector<int>> list);
Result<bool> isVirtualDetectorServer(Positions pos = {}) const; Result<bool> isVirtualDetectorServer(Positions pos = {}) const;
///@} ///@}
@ -937,9 +948,10 @@ class Detector {
/** Client IP Address that last communicated with the receiver */ /** Client IP Address that last communicated with the receiver */
Result<IpAddr> getRxLastClientIP(Positions pos = {}) const; Result<IpAddr> getRxLastClientIP(Positions pos = {}) const;
/** Get thread ids from the receiver in order of [parent, tcp, listener 0, /** Get kernel thread ids from the receiver in order of [parent, tcp,
* processor 0, streamer 0, listener 1, processor 1, streamer 1, arping]. If * listener 0, processor 0, streamer 0, listener 1, processor 1, streamer 1,
* no streamer yet or there is no second interface, it gives 0 in its place. * arping]. If no streamer yet or there is no second interface, it gives 0
* in its place.
*/ */
Result<std::array<pid_t, NUM_RX_THREAD_IDS>> Result<std::array<pid_t, NUM_RX_THREAD_IDS>>
getRxThreadIds(Positions pos = {}) const; getRxThreadIds(Positions pos = {}) const;
@ -1469,8 +1481,9 @@ class Detector {
Result<int> getADCConfiguration(const int chipIndex, const int adcIndex, Result<int> getADCConfiguration(const int chipIndex, const int adcIndex,
Positions pos = {}) const; Positions pos = {}) const;
/** [Gotthard2] configures one chip at a time for specific adc, chipIndex /** [Gotthard2] configures one chip at a time for specific adc, chipIndex.
* and adcIndex is -1 for all */ * -1 for all. Setting specific chip index not implemented in hardware yet
*/
void setADCConfiguration(const int chipIndex, const int adcIndex, void setADCConfiguration(const int chipIndex, const int adcIndex,
const int value, Positions pos = {}); const int value, Positions pos = {});

View File

@ -7,6 +7,7 @@
#include "sls/ToString.h" #include "sls/ToString.h"
#include "sls/bit_utils.h" #include "sls/bit_utils.h"
#include "sls/container_utils.h" #include "sls/container_utils.h"
#include "sls/file_utils.h"
#include "sls/logger.h" #include "sls/logger.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
@ -278,7 +279,12 @@ std::string CmdProxy::Versions(int action) {
auto t = det->getFirmwareVersion(std::vector<int>{det_id}); auto t = det->getFirmwareVersion(std::vector<int>{det_id});
os << "\nType : " << OutString(det->getDetectorType()) os << "\nType : " << OutString(det->getDetectorType())
<< "\nRelease : " << det->getPackageVersion() << std::hex << "\nRelease : " << det->getPackageVersion() << std::hex
<< "\nClient : " << det->getClientVersion(); << "\nClient : " << det->getClientVersion()
<< "\nServer : "
<< OutString(det->getDetectorServerVersion(std::vector<int>{det_id}))
<< "\nKernel : "
<< OutString(det->getKernelVersion({std::vector<int>{det_id}}));
if (eiger) { if (eiger) {
os << "\nFirmware (Beb) : " os << "\nFirmware (Beb) : "
<< OutString(det->getFirmwareVersion(std::vector<int>{det_id})); << OutString(det->getFirmwareVersion(std::vector<int>{det_id}));
@ -291,16 +297,11 @@ std::string CmdProxy::Versions(int action) {
} else { } else {
os << "\nFirmware : " os << "\nFirmware : "
<< OutStringHex( << OutStringHex(
det->getFirmwareVersion(std::vector<int>{det_id})); det->getFirmwareVersion(std::vector<int>{det_id}))
} << "\nHardware : "
os << "\nServer : "
<< OutString(
det->getDetectorServerVersion(std::vector<int>{det_id}));
if (!eiger)
os << "\nHardware : "
<< OutString(det->getHardwareVersion(std::vector<int>{det_id})); << OutString(det->getHardwareVersion(std::vector<int>{det_id}));
os << "\nKernel : " }
<< OutString(det->getKernelVersion({std::vector<int>{det_id}}));
if (det->getUseReceiverFlag().squash(true)) { if (det->getUseReceiverFlag().squash(true)) {
os << "\nReceiver : " os << "\nReceiver : "
<< OutString(det->getReceiverVersion(std::vector<int>{det_id})); << OutString(det->getReceiverVersion(std::vector<int>{det_id}));
@ -557,9 +558,9 @@ std::string CmdProxy::BadChannels(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "[fname]\n\t[Gotthard2][Mythen3] Sets the bad channels (from " os << "[fname|none|0]\n\t[Gotthard2][Mythen3] Sets the bad channels "
"file of bad channel numbers) to be masked out." "(from file of bad channel numbers) to be masked out. None or 0 "
"\n\t[Mythen3] Also does trimming" "unsets all the badchannels.\n\t[Mythen3] Also does trimming"
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
if (args.size() != 1) { if (args.size() != 1) {
@ -568,10 +569,25 @@ std::string CmdProxy::BadChannels(int action) {
det->getBadChannels(args[0], std::vector<int>{det_id}); det->getBadChannels(args[0], std::vector<int>{det_id});
os << "successfully retrieved" << '\n'; os << "successfully retrieved" << '\n';
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
if (args.size() != 1) { bool parse = false;
if (args.size() == 0) {
WrongNumberOfParameters(1); WrongNumberOfParameters(1);
} else if (args.size() == 1) {
if (args[0] == "none" || args[0] == "0") {
det->setBadChannels(std::vector<int>{},
std::vector<int>{det_id});
} else if (args[0].find(".") != std::string::npos) {
det->setBadChannels(args[0], std::vector<int>{det_id});
} else {
parse = true;
}
}
// parse multi args or single one with range or single value
if (parse || args.size() > 1) {
// get channels
auto list = getChannelsFromStringList(args);
det->setBadChannels(list, std::vector<int>{det_id});
} }
det->setBadChannels(args[0], std::vector<int>{det_id});
os << "successfully loaded" << '\n'; os << "successfully loaded" << '\n';
} else { } else {
throw RuntimeError("Unknown action"); throw RuntimeError("Unknown action");
@ -1481,7 +1497,7 @@ std::string CmdProxy::Trigger(int action) {
/* Network Configuration (Detector<->Receiver) */ /* Network Configuration (Detector<->Receiver) */
IpAddr CmdProxy::getIpFromAuto() { IpAddr CmdProxy::getDstIpFromAuto() {
std::string rxHostname = std::string rxHostname =
det->getRxHostname(std::vector<int>{det_id}).squash("none"); det->getRxHostname(std::vector<int>{det_id}).squash("none");
// Hostname could be ip try to decode otherwise look up the hostname // Hostname could be ip try to decode otherwise look up the hostname
@ -1492,6 +1508,21 @@ IpAddr CmdProxy::getIpFromAuto() {
return val; return val;
} }
IpAddr CmdProxy::getSrcIpFromAuto() {
if (det->getDetectorType().squash() == defs::GOTTHARD) {
throw RuntimeError(
"Cannot use 'auto' for udp_srcip for GotthardI Detector.");
}
std::string hostname =
det->getHostname(std::vector<int>{det_id}).squash("none");
// Hostname could be ip try to decode otherwise look up the hostname
auto val = IpAddr{hostname};
if (val == 0) {
val = HostnameToIp(hostname.c_str());
}
return val;
}
UdpDestination CmdProxy::getUdpEntry() { UdpDestination CmdProxy::getUdpEntry() {
UdpDestination udpDestination{}; UdpDestination udpDestination{};
udpDestination.entry = rx_id; udpDestination.entry = rx_id;
@ -1502,7 +1533,7 @@ UdpDestination CmdProxy::getUdpEntry() {
std::string value = it.substr(pos + 1); std::string value = it.substr(pos + 1);
if (key == "ip") { if (key == "ip") {
if (value == "auto") { if (value == "auto") {
auto val = getIpFromAuto(); auto val = getDstIpFromAuto();
LOG(logINFO) << "Setting udp_dstip of detector " << det_id LOG(logINFO) << "Setting udp_dstip of detector " << det_id
<< " to " << val; << " to " << val;
udpDestination.ip = val; udpDestination.ip = val;
@ -1511,7 +1542,7 @@ UdpDestination CmdProxy::getUdpEntry() {
} }
} else if (key == "ip2") { } else if (key == "ip2") {
if (value == "auto") { if (value == "auto") {
auto val = getIpFromAuto(); auto val = getDstIpFromAuto();
LOG(logINFO) << "Setting udp_dstip2 of detector " << det_id LOG(logINFO) << "Setting udp_dstip2 of detector " << det_id
<< " to " << val; << " to " << val;
udpDestination.ip2 = val; udpDestination.ip2 = val;
@ -1586,8 +1617,9 @@ std::string CmdProxy::UDPSourceIP(int action) {
os << "[x.x.x.x] or auto\n\tIp address of the detector (source) udp " os << "[x.x.x.x] or auto\n\tIp address of the detector (source) udp "
"interface. Must be same subnet as destination udp " "interface. Must be same subnet as destination udp "
"ip.\n\t[Eiger] Set only for 10G. For 1G, detector will replace " "ip.\n\t[Eiger] Set only for 10G. For 1G, detector will replace "
"with its own DHCP IP address. If 'auto' used, then ip is set to " "with its own DHCP IP address. \n\tOne can also set this to "
"ip of rx_hostname." "'auto' for 1 GbE data and virtual detectors. It will set to IP "
"of detector. Not available for GotthardI"
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
auto t = det->getSourceUDPIP(std::vector<int>{det_id}); auto t = det->getSourceUDPIP(std::vector<int>{det_id});
@ -1601,7 +1633,7 @@ std::string CmdProxy::UDPSourceIP(int action) {
} }
IpAddr val; IpAddr val;
if (args[0] == "auto") { if (args[0] == "auto") {
val = getIpFromAuto(); val = getSrcIpFromAuto();
LOG(logINFO) << "Setting udp_srcip of detector " << det_id << " to " LOG(logINFO) << "Setting udp_srcip of detector " << det_id << " to "
<< val; << val;
} else { } else {
@ -1624,8 +1656,9 @@ std::string CmdProxy::UDPSourceIP2(int action) {
"of the " "of the "
"detector (source) udp interface 2. Must be same subnet as " "detector (source) udp interface 2. Must be same subnet as "
"destination udp ip2.\n\t [Jungfrau][Moench] top half or inner " "destination udp ip2.\n\t [Jungfrau][Moench] top half or inner "
"interface\n\t [Gotthard2] veto debugging. If 'auto' used, then " "interface\n\t [Gotthard2] veto debugging. \n\tOne can also set "
"ip is set to ip of rx_hostname." "this to 'auto' for 1 GbE data and virtual detectors. It will "
"set to IP of detector."
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
auto t = det->getSourceUDPIP2(std::vector<int>{det_id}); auto t = det->getSourceUDPIP2(std::vector<int>{det_id});
@ -1639,7 +1672,7 @@ std::string CmdProxy::UDPSourceIP2(int action) {
} }
IpAddr val; IpAddr val;
if (args[0] == "auto") { if (args[0] == "auto") {
val = getIpFromAuto(); val = getSrcIpFromAuto();
LOG(logINFO) << "Setting udp_srcip2 of detector " << det_id LOG(logINFO) << "Setting udp_srcip2 of detector " << det_id
<< " to " << val; << " to " << val;
} else { } else {
@ -1673,7 +1706,7 @@ std::string CmdProxy::UDPDestinationIP(int action) {
WrongNumberOfParameters(1); WrongNumberOfParameters(1);
} }
if (args[0] == "auto") { if (args[0] == "auto") {
auto val = getIpFromAuto(); auto val = getDstIpFromAuto();
LOG(logINFO) << "Setting udp_dstip of detector " << det_id << " to " LOG(logINFO) << "Setting udp_dstip of detector " << det_id << " to "
<< val; << val;
det->setDestinationUDPIP(val, std::vector<int>{det_id}); det->setDestinationUDPIP(val, std::vector<int>{det_id});
@ -1710,7 +1743,7 @@ std::string CmdProxy::UDPDestinationIP2(int action) {
WrongNumberOfParameters(1); WrongNumberOfParameters(1);
} }
if (args[0] == "auto") { if (args[0] == "auto") {
auto val = getIpFromAuto(); auto val = getDstIpFromAuto();
LOG(logINFO) << "Setting udp_dstip2 of detector " << det_id LOG(logINFO) << "Setting udp_dstip2 of detector " << det_id
<< " to " << val; << " to " << val;
det->setDestinationUDPIP2(val, std::vector<int>{det_id}); det->setDestinationUDPIP2(val, std::vector<int>{det_id});
@ -2381,7 +2414,7 @@ std::string CmdProxy::ConfigureADC(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "[chip index 0-10, -1 for all] [adc index 0-31, -1 for all] [12 " os << "[chip index 0-9, -1 for all] [adc index 0-31, -1 for all] [7 "
"bit configuration value in hex]\n\t[Gotthard2] Sets " "bit configuration value in hex]\n\t[Gotthard2] Sets "
"configuration for specific chip and adc, but configures 1 chip " "configuration for specific chip and adc, but configures 1 chip "
"(all adcs for that chip) at a time." "(all adcs for that chip) at a time."
@ -2860,6 +2893,8 @@ std::string CmdProxy::PatternLoopAddresses(int action) {
if (cmd != "patlimits") { if (cmd != "patlimits") {
GetLevelAndUpdateArgIndex(action, "patloop", level, iArg, nGetArgs, GetLevelAndUpdateArgIndex(action, "patloop", level, iArg, nGetArgs,
nPutArgs); nPutArgs);
if (cmd != "patloop0" && cmd != "patloop1" && cmd != "patloop2")
os << level << ' ';
} }
if (action == defs::GET_ACTION) { if (action == defs::GET_ACTION) {
auto t = auto t =
@ -2899,6 +2934,8 @@ std::string CmdProxy::PatternLoopCycles(int action) {
int level = -1, iArg = 0, nGetArgs = 0, nPutArgs = 1; int level = -1, iArg = 0, nGetArgs = 0, nPutArgs = 1;
GetLevelAndUpdateArgIndex(action, "patnloop", level, iArg, nGetArgs, GetLevelAndUpdateArgIndex(action, "patnloop", level, iArg, nGetArgs,
nPutArgs); nPutArgs);
if (cmd != "patnloop0" && cmd != "patnloop1" && cmd != "patnloop2")
os << level << ' ';
if (action == defs::GET_ACTION) { if (action == defs::GET_ACTION) {
auto t = det->getPatternLoopCycles(level, std::vector<int>{det_id}); auto t = det->getPatternLoopCycles(level, std::vector<int>{det_id});
os << OutString(t) << '\n'; os << OutString(t) << '\n';
@ -2933,6 +2970,8 @@ std::string CmdProxy::PatternWaitAddress(int action) {
int level = -1, iArg = 0, nGetArgs = 0, nPutArgs = 1; int level = -1, iArg = 0, nGetArgs = 0, nPutArgs = 1;
GetLevelAndUpdateArgIndex(action, "patwait", level, iArg, nGetArgs, GetLevelAndUpdateArgIndex(action, "patwait", level, iArg, nGetArgs,
nPutArgs); nPutArgs);
if (cmd != "patwait0" && cmd != "patwait1" && cmd != "patwait2")
os << level << ' ';
if (action == defs::GET_ACTION) { if (action == defs::GET_ACTION) {
auto t = det->getPatternWaitAddr(level, std::vector<int>{det_id}); auto t = det->getPatternWaitAddr(level, std::vector<int>{det_id});
os << OutStringHex(t, 4) << '\n'; os << OutStringHex(t, 4) << '\n';
@ -2966,6 +3005,9 @@ std::string CmdProxy::PatternWaitTime(int action) {
int level = -1, iArg = 0, nGetArgs = 0, nPutArgs = 1; int level = -1, iArg = 0, nGetArgs = 0, nPutArgs = 1;
GetLevelAndUpdateArgIndex(action, "patwaittime", level, iArg, nGetArgs, GetLevelAndUpdateArgIndex(action, "patwaittime", level, iArg, nGetArgs,
nPutArgs); nPutArgs);
if (cmd != "patwaittime0" && cmd != "patwaittime1" &&
cmd != "patwaittime2")
os << level << ' ';
if (action == defs::GET_ACTION) { if (action == defs::GET_ACTION) {
auto t = det->getPatternWaitTime(level, std::vector<int>{det_id}); auto t = det->getPatternWaitTime(level, std::vector<int>{det_id});
os << OutString(t) << '\n'; os << OutString(t) << '\n';

View File

@ -1155,7 +1155,8 @@ class CmdProxy {
std::string Scan(int action); std::string Scan(int action);
std::string Trigger(int action); std::string Trigger(int action);
/* Network Configuration (Detector<->Receiver) */ /* Network Configuration (Detector<->Receiver) */
IpAddr getIpFromAuto(); IpAddr getDstIpFromAuto();
IpAddr getSrcIpFromAuto();
UdpDestination getUdpEntry(); UdpDestination getUdpEntry();
std::string UDPDestinationList(int action); std::string UDPDestinationList(int action);
std::string UDPSourceIP(int action); std::string UDPSourceIP(int action);
@ -1782,11 +1783,12 @@ class CmdProxy {
rx_lastclient, getRxLastClientIP, rx_lastclient, getRxLastClientIP,
"\n\tClient IP Address that last communicated with the receiver."); "\n\tClient IP Address that last communicated with the receiver.");
GET_COMMAND(rx_threads, getRxThreadIds, GET_COMMAND(
"\n\tGet thread ids from the receiver in order of [parent, " rx_threads, getRxThreadIds,
"tcp, listener 0, processor 0, streamer 0, listener 1, " "\n\tGet kernel thread ids from the receiver in order of [parent, "
"processor 1, streamer 1, arping]. If no streamer yet or there " "tcp, listener 0, processor 0, streamer 0, listener 1, "
"is no second interface, it gives 0 in its place."); "processor 1, streamer 1, arping]. If no streamer yet or there "
"is no second interface, it gives 0 in its place.");
INTEGER_COMMAND_VEC_ID(rx_arping, getRxArping, setRxArping, StringTo<int>, INTEGER_COMMAND_VEC_ID(rx_arping, getRxArping, setRxArping, StringTo<int>,
"[0, 1]\n\tStarts a thread in slsReceiver to arping " "[0, 1]\n\tStarts a thread in slsReceiver to arping "

View File

@ -351,6 +351,29 @@ void Detector::setBadChannels(const std::string &fname, Positions pos) {
pimpl->setBadChannels(fname, pos); pimpl->setBadChannels(fname, pos);
} }
Result<std::vector<int>> Detector::getBadChannels(Positions pos) const {
return pimpl->Parallel(&Module::getBadChannels, pos);
}
void Detector::setBadChannels(const std::vector<std::vector<int>> list) {
if (list.size() != static_cast<size_t>(size())) {
std::stringstream ss;
ss << "Number of bad channel sets (" << list.size()
<< ") needs to match the number of modules (" << size() << ")";
throw RuntimeError(ss.str());
}
for (int idet = 0; idet < size(); ++idet) {
// TODO! Call in parallel since loading trimbits is slow?
pimpl->Parallel(&Module::setBadChannels, {idet}, list[idet]);
}
}
void Detector::setBadChannels(const std::vector<int> list, Positions pos) {
pimpl->setBadChannels(list, pos);
}
Result<bool> Detector::isVirtualDetectorServer(Positions pos) const { Result<bool> Detector::isVirtualDetectorServer(Positions pos) const {
return pimpl->Parallel(&Module::isVirtualDetectorServer, pos); return pimpl->Parallel(&Module::isVirtualDetectorServer, pos);
} }

View File

@ -253,14 +253,15 @@ void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) {
} }
void DetectorImpl::setHostname(const std::vector<std::string> &name) { void DetectorImpl::setHostname(const std::vector<std::string> &name) {
// this check is there only to allow the previous detsizechan command // do not free always to allow the previous detsize/ initialchecks command
if (shm()->totalNumberOfModules != 0) { if (shm.exists() && shm()->totalNumberOfModules != 0) {
LOG(logWARNING) << "There are already module(s) in shared memory." LOG(logWARNING) << "There are already module(s) in shared memory."
"Freeing Shared memory now."; "Freeing Shared memory now.";
bool initialChecks = shm()->initialChecks;
freeSharedMemory(); freeSharedMemory();
}
// could be called after freeing shm from API
if (!shm.exists()) {
setupDetector(); setupDetector();
shm()->initialChecks = initialChecks;
} }
for (const auto &hostname : name) { for (const auto &hostname : name) {
addModule(hostname); addModule(hostname);
@ -342,28 +343,32 @@ void DetectorImpl::updateDetectorSize() {
"updating detector size. "); "updating detector size. ");
} }
int maxx = shm()->numberOfChannels.x;
int maxy = shm()->numberOfChannels.y;
int nModx = 0, nMody = 0; int nModx = 0, nMody = 0;
// 1d, add modules along x axis // 1d, add modules along x axis
if (modSize.y == 1) { if (modSize.y == 1) {
if (maxx == 0) { int detSizeX = shm()->numberOfChannels.x;
maxx = modSize.x * size(); int maxChanX = modSize.x * size();
// user given detsizex used only within max value
if (detSizeX > 1 && detSizeX <= maxChanX) {
maxChanX = detSizeX;
} }
nModx = maxx / modSize.x; nModx = maxChanX / modSize.x;
nMody = size() / nModx; nMody = size() / nModx;
if ((maxx % modSize.x) > 0) { if ((maxChanX % modSize.x) > 0) {
++nMody; ++nMody;
} }
} }
// 2d, add modules along y axis (due to eiger top/bottom) // 2d, add modules along y axis (due to eiger top/bottom)
else { else {
if (maxy == 0) { int detSizeY = shm()->numberOfChannels.y;
maxy = modSize.y * size(); int maxChanY = modSize.y * size();
// user given detsizey used only within max value
if (detSizeY > 1 && detSizeY <= maxChanY) {
maxChanY = detSizeY;
} }
nMody = maxy / modSize.y; nMody = maxChanY / modSize.y;
nModx = size() / nMody; nModx = size() / nMody;
if ((maxy % modSize.y) > 0) { if ((maxChanY % modSize.y) > 0) {
++nModx; ++nModx;
} }
} }
@ -518,19 +523,18 @@ void DetectorImpl::setTransmissionDelay(int step) {
f.get(); f.get();
} }
int DetectorImpl::destroyReceivingDataSockets() { void DetectorImpl::destroyReceivingDataSockets() {
LOG(logINFO) << "Going to destroy data sockets"; LOG(logINFO) << "Going to destroy data sockets";
// close socket // close socket
zmqSocket.clear(); zmqSocket.clear();
client_downstream = false; client_downstream = false;
LOG(logINFO) << "Destroyed Receiving Data Socket(s)"; LOG(logINFO) << "Destroyed Receiving Data Socket(s)";
return OK;
} }
int DetectorImpl::createReceivingDataSockets() { void DetectorImpl::createReceivingDataSockets() {
if (client_downstream) { if (client_downstream) {
return OK; return;
} }
LOG(logINFO) << "Going to create data sockets"; LOG(logINFO) << "Going to create data sockets";
@ -557,24 +561,22 @@ int DetectorImpl::createReceivingDataSockets() {
int hwm = shm()->zmqHwm; int hwm = shm()->zmqHwm;
if (hwm >= 0) { if (hwm >= 0) {
zmqSocket[iSocket]->SetReceiveHighWaterMark(hwm); zmqSocket[iSocket]->SetReceiveHighWaterMark(hwm);
if (zmqSocket[iSocket]->GetReceiveHighWaterMark() != hwm) { // need not reconnect. cannot be connected (detector idle)
throw ZmqSocketError("Could not set zmq rcv hwm to " +
std::to_string(hwm));
}
} }
LOG(logINFO) << "Zmq Client[" << iSocket << "] at " LOG(logINFO) << "Zmq Client[" << iSocket << "] at "
<< zmqSocket.back()->GetZmqServerAddress() << "[hwm: " << zmqSocket.back()->GetZmqServerAddress() << "[hwm: "
<< zmqSocket.back()->GetReceiveHighWaterMark() << "]"; << zmqSocket.back()->GetReceiveHighWaterMark() << "]";
} catch (...) { } catch (std::exception &e) {
LOG(logERROR) << "Could not create Zmq socket on port " << portnum;
destroyReceivingDataSockets(); destroyReceivingDataSockets();
return FAIL; std::ostringstream oss;
oss << "Could not create zmq sub socket on port " << portnum;
oss << " [" << e.what() << ']';
throw RuntimeError(oss.str());
} }
} }
client_downstream = true; client_downstream = true;
LOG(logINFO) << "Receiving Data Socket(s) created"; LOG(logINFO) << "Receiving Data Socket(s) created";
return OK;
} }
void DetectorImpl::readFrameFromReceiver() { void DetectorImpl::readFrameFromReceiver() {
@ -1114,9 +1116,7 @@ void DetectorImpl::setDataStreamingToClient(bool enable) {
destroyReceivingDataSockets(); destroyReceivingDataSockets();
// create data threads // create data threads
} else { } else {
if (createReceivingDataSockets() == FAIL) { createReceivingDataSockets();
throw RuntimeError("Could not create data threads in client.");
}
} }
} }
@ -1149,11 +1149,7 @@ void DetectorImpl::setClientStreamingHwm(const int limit) {
if (limit >= 0) { if (limit >= 0) {
for (auto &it : zmqSocket) { for (auto &it : zmqSocket) {
it->SetReceiveHighWaterMark(limit); it->SetReceiveHighWaterMark(limit);
if (it->GetReceiveHighWaterMark() != limit) { // need not reconnect. cannot be connected (detector idle)
shm()->zmqHwm = -1;
throw ZmqSocketError("Could not set zmq rcv hwm to " +
std::to_string(limit));
}
} }
LOG(logINFO) << "Setting Client Zmq socket rcv hwm to " << limit; LOG(logINFO) << "Setting Client Zmq socket rcv hwm to " << limit;
} }
@ -1231,8 +1227,7 @@ int DetectorImpl::acquire() {
// let the progress thread (no callback) know acquisition is done // let the progress thread (no callback) know acquisition is done
if (dataReady == nullptr) { if (dataReady == nullptr) {
setJoinThreadFlag(true); setJoinThreadFlag(true);
} } else if (receiver) {
if (receiver) {
while (numZmqRunning != 0) { while (numZmqRunning != 0) {
Parallel(&Module::restreamStopFromReceiver, {}); Parallel(&Module::restreamStopFromReceiver, {});
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(200));
@ -1322,6 +1317,7 @@ void DetectorImpl::processData(bool receiver) {
} }
// only update progress // only update progress
else { else {
LOG(logINFO) << "Type 'q' and hit enter to stop acquisition";
double progress = 0; double progress = 0;
printProgress(progress); printProgress(progress);
@ -1778,6 +1774,10 @@ void DetectorImpl::setBadChannels(const std::string &fname, Positions pos) {
if (list.empty()) { if (list.empty()) {
throw RuntimeError("Bad channel file is empty."); throw RuntimeError("Bad channel file is empty.");
} }
setBadChannels(list, pos);
}
void DetectorImpl::setBadChannels(const std::vector<int> list, Positions pos) {
// update to multi values if multi modules // update to multi values if multi modules
if (isAllPositions(pos)) { if (isAllPositions(pos)) {
@ -1794,20 +1794,24 @@ void DetectorImpl::setBadChannels(const std::string &fname, Positions pos) {
" out of bounds."); " out of bounds.");
} }
int ch = badchannel % nchan; int ch = badchannel % nchan;
int imod = badchannel / nchan; size_t imod = badchannel / nchan;
if (imod >= (int)modules.size()) { if (imod >= modules.size()) {
throw RuntimeError("Invalid bad channel list. " + throw RuntimeError("Invalid bad channel list. " +
std::to_string(badchannel) + std::to_string(badchannel) +
" out of bounds."); " out of bounds.");
} }
if (badchannels.size() != imod + 1) {
if ((int)badchannels.size() != imod + 1) {
badchannels.push_back(std::vector<int>{}); badchannels.push_back(std::vector<int>{});
} }
badchannels[imod].push_back(ch); badchannels[imod].push_back(ch);
} }
for (int imod = 0; imod != (int)modules.size(); ++imod) { for (size_t imod = 0; imod != modules.size(); ++imod) {
Parallel(&Module::setBadChannels, {imod}, badchannels[imod]); // add empty vector if no bad channels in this module
if (badchannels.size() != imod + 1) {
badchannels.push_back(std::vector<int>{});
}
Parallel(&Module::setBadChannels, {static_cast<int>(imod)},
badchannels[imod]);
} }
} else if (pos.size() != 1) { } else if (pos.size() != 1) {

View File

@ -306,6 +306,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
void getBadChannels(const std::string &fname, Positions pos) const; void getBadChannels(const std::string &fname, Positions pos) const;
void setBadChannels(const std::string &fname, Positions pos); void setBadChannels(const std::string &fname, Positions pos);
void setBadChannels(const std::vector<int> list, Positions pos);
std::vector<std::string> getCtbDacNames() const; std::vector<std::string> getCtbDacNames() const;
std::string getCtbDacName(defs::dacIndex i) const; std::string getCtbDacName(defs::dacIndex i) const;
@ -348,8 +349,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
void updateDetectorSize(); void updateDetectorSize();
int destroyReceivingDataSockets(); void destroyReceivingDataSockets();
int createReceivingDataSockets(); void createReceivingDataSockets();
/** /**
* Reads frames from receiver through a constant socket * Reads frames from receiver through a constant socket

View File

@ -76,7 +76,7 @@ void Module::setHostname(const std::string &hostname,
initialDetectorServerChecks(); initialDetectorServerChecks();
checkDetectorVersionCompatibility(); checkDetectorVersionCompatibility();
LOG(logINFO) << "Module Version Compatibility - Success"; LOG(logINFO) << "Module Version Compatibility - Success";
} catch (const DetectorError &e) { } catch (const RuntimeError &e) {
if (!initialChecks) { if (!initialChecks) {
LOG(logWARNING) << "Bypassing Initial Checks at your own risk!"; LOG(logWARNING) << "Bypassing Initial Checks at your own risk!";
} else { } else {
@ -876,26 +876,25 @@ void Module::startReadout() {
} }
void Module::stopAcquisition() { void Module::stopAcquisition() {
// get status before stopping acquisition
runStatus s = ERROR, r = ERROR; // get det status before stopping acq
bool zmqstreaming = false; runStatus detStatus = ERROR;
try { try {
if (shm()->useReceiverFlag && getReceiverStreaming()) { detStatus = getRunStatus();
zmqstreaming = true;
s = getRunStatus();
r = getReceiverStatus();
}
} catch (...) { } catch (...) {
// if receiver crashed, stop detector in any case
zmqstreaming = false;
} }
sendToDetectorStop(F_STOP_ACQUISITION); sendToDetectorStop(F_STOP_ACQUISITION);
shm()->stoppedFlag = true; shm()->stoppedFlag = true;
// if rxr streaming and acquisition finished, restream dummy stop packet // restream dummy header, if rxr streaming and det idle before stop
if (zmqstreaming && (s == IDLE) && (r == IDLE)) { try {
restreamStopFromReceiver(); if (shm()->useReceiverFlag && getReceiverStreaming()) {
if (detStatus == IDLE && getReceiverStatus() == IDLE) {
restreamStopFromReceiver();
}
}
} catch (...) {
} }
} }

View File

@ -9,7 +9,15 @@
namespace sls { namespace sls {
Pattern::Pattern() = default; Pattern::Pattern() {
// initialize pattern addresses
for (int i = 0; i != MAX_PATTERN_LEVELS; ++i) {
pat->startloop[i] = MAX_PATTERN_LENGTH - 1;
pat->stoploop[i] = MAX_PATTERN_LENGTH - 1;
pat->wait[i] = MAX_PATTERN_LENGTH - 1;
}
}
Pattern::~Pattern() { delete pat; } Pattern::~Pattern() { delete pat; }
Pattern::Pattern(const Pattern &other) { Pattern::Pattern(const Pattern &other) {

View File

@ -33,7 +33,7 @@ namespace sls {
template <typename T> class SharedMemory { template <typename T> class SharedMemory {
static constexpr int NAME_MAX_LENGTH = 255; static constexpr int NAME_MAX_LENGTH = 255;
std::string name; std::string name;
T *shared_struct{}; T *shared_struct{nullptr};
public: public:
// moduleid of -1 creates a detector only shared memory // moduleid of -1 creates a detector only shared memory
@ -64,8 +64,18 @@ template <typename T> class SharedMemory {
unmapSharedMemory(); unmapSharedMemory();
} }
T *operator()() { return shared_struct; } T *operator()() {
const T *operator()() const { return shared_struct; } if (shared_struct)
return shared_struct;
throw SharedMemoryError(getNoShmAccessMessage());
}
const T *operator()() const {
if (shared_struct)
return shared_struct;
throw SharedMemoryError(getNoShmAccessMessage());
}
std::string getName() const { return name; } std::string getName() const { return name; }
bool exists() { bool exists() {
@ -204,6 +214,11 @@ template <typename T> class SharedMemory {
throw SharedMemoryError(msg); throw SharedMemoryError(msg);
} }
} }
const char *getNoShmAccessMessage() const {
return ("No shared memory to access. Create it first with "
"hostname or config command.");
};
}; };
} // namespace sls } // namespace sls

View File

@ -702,11 +702,11 @@ TEST_CASE("confadc", "[.cmd]") {
} }
} }
REQUIRE_THROWS(proxy.Call("confadc", {"11", "2", "0x3ff"}, -1, REQUIRE_THROWS(proxy.Call("confadc", {"11", "2", "0x7f"}, -1,
PUT)); // invalid chip index PUT)); // invalid chip index
REQUIRE_THROWS(proxy.Call("confadc", {"-1", "10", "0x3ff"}, -1, REQUIRE_THROWS(proxy.Call("confadc", {"-1", "32", "0x7f"}, -1,
PUT)); // invalid adc index PUT)); // invalid adc index
REQUIRE_THROWS(proxy.Call("confadc", {"-1", "10", "0x1fff"}, -1, REQUIRE_THROWS(proxy.Call("confadc", {"-1", "10", "0x80"}, -1,
PUT)); // invalid value PUT)); // invalid value
{ {
std::ostringstream oss; std::ostringstream oss;
@ -718,10 +718,11 @@ TEST_CASE("confadc", "[.cmd]") {
proxy.Call("confadc", {"2", "3"}, -1, GET, oss); proxy.Call("confadc", {"2", "3"}, -1, GET, oss);
REQUIRE(oss.str() == "confadc 0x11\n"); REQUIRE(oss.str() == "confadc 0x11\n");
} }
for (int i = 0; i != ndet; ++i) { for (int i = 0; i != ndet; ++i) {
for (int j = 0; j != nchip; ++j) { for (int j = 0; j != nchip; ++j) {
for (int k = 0; k != nadc; ++k) { for (int k = 0; k != nadc; ++k) {
det.setADCConfiguration(j, k, prev_val[i][j][k], {i}); det.setADCConfiguration(-1, k, prev_val[i][j][k], {i});
} }
} }
} }

View File

@ -181,12 +181,14 @@ TEST_CASE("patloop", "[.cmd]") {
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("patloop", {sLoop, "0x20", "0x5c"}, -1, PUT, oss); proxy.Call("patloop", {sLoop, "0x20", "0x5c"}, -1, PUT, oss);
REQUIRE(oss.str() == "patloop [0x0020, 0x005c]\n"); REQUIRE(oss.str() ==
"patloop " + sLoop + " [0x0020, 0x005c]\n");
} }
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("patloop", {sLoop}, -1, GET, oss); proxy.Call("patloop", {sLoop}, -1, GET, oss);
REQUIRE(oss.str() == "patloop [0x0020, 0x005c]\n"); REQUIRE(oss.str() ==
"patloop " + sLoop + " [0x0020, 0x005c]\n");
} }
for (int iDet = 0; iDet != det.size(); ++iDet) { for (int iDet = 0; iDet != det.size(); ++iDet) {
det.setPatternLoopAddresses(iLoop, prev_val[iDet][0], det.setPatternLoopAddresses(iLoop, prev_val[iDet][0],
@ -227,12 +229,12 @@ TEST_CASE("patnloop", "[.cmd]") {
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("patnloop", {sLoop, "5"}, -1, PUT, oss); proxy.Call("patnloop", {sLoop, "5"}, -1, PUT, oss);
REQUIRE(oss.str() == "patnloop 5\n"); REQUIRE(oss.str() == "patnloop " + sLoop + " 5\n");
} }
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("patnloop", {sLoop}, -1, GET, oss); proxy.Call("patnloop", {sLoop}, -1, GET, oss);
REQUIRE(oss.str() == "patnloop 5\n"); REQUIRE(oss.str() == "patnloop " + sLoop + " 5\n");
} }
for (int iDet = 0; iDet != det.size(); ++iDet) { for (int iDet = 0; iDet != det.size(); ++iDet) {
det.setPatternLoopCycles(iLoop, prev_val[iDet], {iDet}); det.setPatternLoopCycles(iLoop, prev_val[iDet], {iDet});
@ -272,12 +274,12 @@ TEST_CASE("patwait", "[.cmd]") {
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("patwait", {sLoop, "0x5c"}, -1, PUT, oss); proxy.Call("patwait", {sLoop, "0x5c"}, -1, PUT, oss);
REQUIRE(oss.str() == "patwait 0x005c\n"); REQUIRE(oss.str() == "patwait " + sLoop + " 0x005c\n");
} }
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("patwait", {sLoop}, -1, GET, oss); proxy.Call("patwait", {sLoop}, -1, GET, oss);
REQUIRE(oss.str() == "patwait 0x005c\n"); REQUIRE(oss.str() == "patwait " + sLoop + " 0x005c\n");
} }
for (int iDet = 0; iDet != det.size(); ++iDet) { for (int iDet = 0; iDet != det.size(); ++iDet) {
det.setPatternWaitAddr(iLoop, prev_val[iDet], {iDet}); det.setPatternWaitAddr(iLoop, prev_val[iDet], {iDet});
@ -317,12 +319,12 @@ TEST_CASE("patwaittime", "[.cmd]") {
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("patwaittime", {sLoop, "8589936640"}, -1, PUT, oss); proxy.Call("patwaittime", {sLoop, "8589936640"}, -1, PUT, oss);
REQUIRE(oss.str() == "patwaittime 8589936640\n"); REQUIRE(oss.str() == "patwaittime " + sLoop + " 8589936640\n");
} }
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("patwaittime", {sLoop}, -1, GET, oss); proxy.Call("patwaittime", {sLoop}, -1, GET, oss);
REQUIRE(oss.str() == "patwaittime 8589936640\n"); REQUIRE(oss.str() == "patwaittime " + sLoop + " 8589936640\n");
} }
for (int iDet = 0; iDet != det.size(); ++iDet) { for (int iDet = 0; iDet != det.size(); ++iDet) {
det.setPatternWaitTime(iLoop, prev_val[iDet], {iDet}); det.setPatternWaitTime(iLoop, prev_val[iDet], {iDet});

View File

@ -145,7 +145,8 @@ TEST_CASE("rx_missingpackets", "[.cmd][.rx]") {
REQUIRE(oss.str() != "rx_missingpackets [0, 0]\n"); REQUIRE(oss.str() != "rx_missingpackets [0, 0]\n");
} }
} }
{ auto det_type = det.getDetectorType().squash();
if (det_type != defs::CHIPTESTBOARD && det_type != defs::MOENCH) {
// 0 missing packets (takes into account that acquisition is stopped) // 0 missing packets (takes into account that acquisition is stopped)
det.startReceiver(); det.startReceiver();
det.startDetector(); det.startDetector();

View File

@ -517,8 +517,19 @@ TEST_CASE("gappixels", "[.cmd]") {
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU || det_type == defs::MOENCH || // test eiger(quad or full module only)
det_type == defs::EIGER) { bool gapPixelTest = false;
if (det_type == defs:: || det_type == defs::MOENCH)
gapPixelTest = true;
else if (det_type == defs::EIGER) {
bool quad = det.getQuad().squash(false);
bool fullModule = (det.getModuleGeometry().y % 2 == 0);
if (quad || fullModule) {
gapPixelTest = true;
}
}
if (gapPixelTest) {
auto prev_val = det.getGapPixelsinCallback(); auto prev_val = det.getGapPixelsinCallback();
{ {
std::ostringstream oss; std::ostringstream oss;
@ -637,6 +648,8 @@ TEST_CASE("badchannels", "[.cmd]") {
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2 || det_type == defs::MYTHEN3) { if (det_type == defs::GOTTHARD2 || det_type == defs::MYTHEN3) {
auto prev = det.getBadChannels();
REQUIRE_THROWS(proxy.Call("badchannels", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("badchannels", {}, -1, GET));
std::string fname_put = std::string fname_put =
@ -649,6 +662,51 @@ TEST_CASE("badchannels", "[.cmd]") {
std::vector<int> expected = {0, 12, 15, 40, 41, 42, 43, 44, 1279}; std::vector<int> expected = {0, 12, 15, 40, 41, 42, 43, 44, 1279};
REQUIRE(list == expected); REQUIRE(list == expected);
REQUIRE_NOTHROW(proxy.Call("badchannels", {"none"}, 0, PUT));
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
list = getChannelsFromFile(fname_get);
REQUIRE(list.empty());
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_put}, 0, PUT));
REQUIRE_NOTHROW(proxy.Call("badchannels", {"0"}, 0, PUT));
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
list = getChannelsFromFile(fname_get);
REQUIRE(list.empty());
REQUIRE_NOTHROW(proxy.Call("badchannels", {"12"}, 0, PUT));
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
list = getChannelsFromFile(fname_get);
expected = {12};
REQUIRE(list == expected);
REQUIRE_NOTHROW(proxy.Call(
"badchannels", {"0", "12,", "15", "43", "40:45", "1279"}, 0, PUT));
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
list = getChannelsFromFile(fname_get);
expected = {0, 12, 15, 40, 41, 42, 43, 44, 1279};
REQUIRE(list == expected);
REQUIRE_NOTHROW(proxy.Call("badchannels", {"40:45"}, 0, PUT));
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
list = getChannelsFromFile(fname_get);
expected = {40, 41, 42, 43, 44};
REQUIRE(list == expected);
REQUIRE_NOTHROW(proxy.Call("badchannels", {"5,6,7"}, 0, PUT));
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
list = getChannelsFromFile(fname_get);
expected = {5, 6, 7};
REQUIRE(list == expected);
REQUIRE_NOTHROW(proxy.Call("badchannels", {"1:5,6,7"}, 0, PUT));
REQUIRE_NOTHROW(proxy.Call("badchannels", {fname_get}, 0, GET));
list = getChannelsFromFile(fname_get);
expected = {1, 2, 3, 4, 6, 7};
REQUIRE(list == expected);
det.setBadChannels(prev);
} else { } else {
REQUIRE_THROWS(proxy.Call("badchannels", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("badchannels", {}, -1, GET));
} }
@ -1216,7 +1274,7 @@ TEST_CASE("clkphase", "[.cmd]") {
} }
std::string s_deg_val = "15"; std::string s_deg_val = "15";
if (det_type == defs::MYTHEN3) { if (det_type == defs::MYTHEN3) {
s_deg_val = "15"; s_deg_val = "14";
} else if (det_type == defs::GOTTHARD2) { } else if (det_type == defs::GOTTHARD2) {
s_deg_val = "23"; s_deg_val = "23";
} }

View File

@ -101,7 +101,8 @@ TEST_CASE("Move SharedMemory", "[detector]") {
shm2 = std::move(shm); // shm is now a moved from object! shm2 = std::move(shm); // shm is now a moved from object!
CHECK(shm2()->x == 9); CHECK(shm2()->x == 9);
CHECK(shm() == nullptr); REQUIRE_THROWS(
shm()); // trying to access should throw instead of returning a nullptr
CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") + CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") +
std::to_string(shm_id)); std::to_string(shm_id));
shm2.removeSharedMemory(); shm2.removeSharedMemory();

View File

@ -4,6 +4,8 @@
#include "Arping.h" #include "Arping.h"
#include <chrono> #include <chrono>
#include <signal.h>
#include <thread>
#include <unistd.h> #include <unistd.h>
namespace sls { namespace sls {
@ -18,7 +20,7 @@ Arping::Arping() {}
Arping::~Arping() { Arping::~Arping() {
if (IsRunning()) { if (IsRunning()) {
StopThread(); StopProcess();
} }
} }
@ -33,59 +35,66 @@ void Arping::SetInterfacesAndIps(const int index, const std::string &interface,
// create commands to arping // create commands to arping
std::ostringstream os; std::ostringstream os;
os << "arping -c 1 -U -I " << interface << " " << ip; os << "arping -c 1 -U -I " << interface << " " << ip;
// to read error messages
os << " 2>&1";
std::string cmd = os.str(); std::string cmd = os.str();
commands[index] = cmd; commands[index] = cmd;
} }
pid_t Arping::GetThreadId() const { return threadId; } pid_t Arping::GetProcessId() const { return childPid; }
bool Arping::IsRunning() const { return runningFlag; } bool Arping::IsRunning() const { return runningFlag; }
void Arping::StartThread() { void Arping::StartProcess() {
TestCommands(); TestCommands();
try {
t = std::thread(&Arping::ThreadExecution, this); // to prevent zombies from child processes being killed
} catch (...) { signal(SIGCHLD, SIG_IGN);
throw RuntimeError("Could not start arping thread");
// Needs to be a fork and udp socket deleted after Listening threads
// done running to prevent udp socket cannot bind because of popen
// that forks
childPid = fork();
// child process
if (childPid == 0) {
LOG(logINFOBLUE) << "Created [ Arping Process, Tid: " << gettid()
<< " ]";
ProcessExecution();
}
// parent process
else if (childPid > 0) {
runningFlag = true;
}
// error
else {
throw RuntimeError("Could not start arping Process");
} }
runningFlag = true;
} }
void Arping::StopThread() { void Arping::StopProcess() {
LOG(logINFOBLUE) << "Exiting [ Arping Process ]";
if (kill(childPid, SIGTERM)) {
throw RuntimeError("Could not kill the arping Process");
}
runningFlag = false; runningFlag = false;
t.join();
} }
void Arping::ThreadExecution() { void Arping::ProcessExecution() {
threadId = gettid(); while (true) {
LOG(logINFOBLUE) << "Created [ Arping Thread, Tid: " << threadId << " ]";
while (runningFlag) {
std::string error = ExecuteCommands(); std::string error = ExecuteCommands();
// just print (was already tested at thread start) // just print (was already tested at Process start)
if (!error.empty()) { if (!error.empty()) {
LOG(logERROR) << error; LOG(logERROR) << error;
} }
const auto interval = std::chrono::seconds(60);
// wait for 60s as long as thread not killed std::this_thread::sleep_for(interval);
int nsecs = 0;
while (runningFlag && nsecs != 60) {
std::this_thread::sleep_for(std::chrono::seconds(1));
++nsecs;
}
} }
LOG(logINFOBLUE) << "Exiting [ Arping Thread, Tid: " << threadId << " ]";
threadId = 0;
} }
void Arping::TestCommands() { void Arping::TestCommands() {
// 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(
"Could not arping. Interface not set up in apring thread"); "Could not arping. Interface not set up in arping Process");
} }
// test if arping commands throw an error // test if arping commands throw an error
std::string error = ExecuteCommands(); std::string error = ExecuteCommands();
@ -101,7 +110,7 @@ std::string Arping::ExecuteCommands() {
if (cmd.empty()) if (cmd.empty())
continue; continue;
LOG(logDEBUG) << "Executing Arping Command: " << cmd; LOG(logDEBUG1) << "Executing Arping Command: " << cmd;
// execute command // execute command
FILE *sysFile = popen(cmd.c_str(), "r"); FILE *sysFile = popen(cmd.c_str(), "r");

View File

@ -2,15 +2,15 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once #pragma once
/** /**
*@short creates/destroys an ARPing thread to arping the interfaces slsReceiver *@short creates/destroys an ARPing child process to arping the interfaces
is listening to. slsReceiver is listening to.
*/ */
#include "receiver_defs.h" #include "receiver_defs.h"
#include "sls/logger.h" #include "sls/logger.h"
#include <atomic> #include <atomic>
#include <thread> #include <unistd.h>
namespace sls { namespace sls {
@ -22,21 +22,20 @@ class Arping {
void SetInterfacesAndIps(const int index, const std::string &interface, void SetInterfacesAndIps(const int index, const std::string &interface,
const std::string &ip); const std::string &ip);
pid_t GetThreadId() const; pid_t GetProcessId() const;
bool IsRunning() const; bool IsRunning() const;
void StartThread(); void StartProcess();
void StopThread(); void StopProcess();
private: private:
void TestCommands(); void TestCommands();
std::string ExecuteCommands(); std::string ExecuteCommands();
void ThreadExecution(); void ProcessExecution();
std::vector<std::string> commands = std::vector<std::string> commands =
std::vector<std::string>(MAX_NUMBER_OF_LISTENING_THREADS); std::vector<std::string>(MAX_NUMBER_OF_LISTENING_THREADS);
std::atomic<bool> runningFlag{false}; std::atomic<bool> runningFlag{false};
std::thread t; std::atomic<pid_t> childPid{0};
std::atomic<pid_t> threadId{0};
}; };
} // namespace sls } // namespace sls

View File

@ -234,8 +234,7 @@ int ClientInterface::decodeFunction(Interface &socket) {
socket.Receive(fnum); socket.Receive(fnum);
socket.setFnum(fnum); socket.setFnum(fnum);
if (fnum <= NUM_DET_FUNCTIONS || fnum >= NUM_REC_FUNCTIONS) { if (fnum <= NUM_DET_FUNCTIONS || fnum >= NUM_REC_FUNCTIONS) {
throw RuntimeError("Unrecognized Function enum " + throw RuntimeError(UNRECOGNIZED_FNUM_ENUM + std::to_string(fnum));
std::to_string(fnum) + "\n");
} else { } else {
LOG(logDEBUG1) << "calling function fnum: " << fnum << " (" LOG(logDEBUG1) << "calling function fnum: " << fnum << " ("
<< getFunctionNameFromEnum((enum detFuncs)fnum) << ")"; << getFunctionNameFromEnum((enum detFuncs)fnum) << ")";
@ -320,164 +319,121 @@ int ClientInterface::setup_receiver(Interface &socket) {
auto arg = socket.Receive<rxParameters>(); auto arg = socket.Receive<rxParameters>();
LOG(logDEBUG) << ToString(arg); LOG(logDEBUG) << ToString(arg);
// if object exists, verify unlocked and idle, else only verify lock
// (connecting first time)
if (receiver != nullptr) {
verifyIdle(socket);
}
// basic setup
setDetectorType(arg.detType);
impl()->setDetectorSize(arg.numberOfModule);
impl()->setModulePositionId(arg.moduleIndex);
impl()->setDetectorHostname(arg.hostname);
// udp setup
// update retvals only if detmac is not the same as in detector
MacAddr retvals[2]; MacAddr retvals[2];
if (arg.udp_dstip != 0) { try {
MacAddr r = setUdpIp(IpAddr(arg.udp_dstip)); // if object exists, verify unlocked and idle, else only verify lock
MacAddr detMac{arg.udp_dstmac}; // (connecting first time)
if (detMac != r) { if (receiver != nullptr) {
retvals[0] = r; verifyIdle(socket);
} }
}
if (arg.udp_dstip2 != 0) {
MacAddr r = setUdpIp2(IpAddr(arg.udp_dstip2));
MacAddr detMac{arg.udp_dstmac2};
if (detMac != r) {
retvals[1] = r;
}
}
impl()->setUDPPortNumber(arg.udp_dstport);
impl()->setUDPPortNumber2(arg.udp_dstport2);
if (detType == JUNGFRAU || detType == MOENCH || detType == GOTTHARD2) {
try {
impl()->setNumberofUDPInterfaces(arg.udpInterfaces);
} catch (const RuntimeError &e) {
throw RuntimeError("Failed to set number of interfaces to " +
std::to_string(arg.udpInterfaces));
}
}
impl()->setUDPSocketBufferSize(0);
// acquisition parameters // basic setup
impl()->setNumberOfFrames(arg.frames); setDetectorType(arg.detType);
impl()->setNumberOfTriggers(arg.triggers); impl()->setDetectorSize(arg.numberOfModule);
if (detType == GOTTHARD2) { impl()->setModulePositionId(arg.moduleIndex);
impl()->setNumberOfBursts(arg.bursts); impl()->setDetectorHostname(arg.hostname);
}
if (detType == JUNGFRAU) { // udp setup
impl()->setNumberOfAdditionalStorageCells(arg.additionalStorageCells); // update retvals only if detmac is not the same as in detector
} if (arg.udp_dstip != 0) {
if (detType == CHIPTESTBOARD) { MacAddr r = setUdpIp(IpAddr(arg.udp_dstip));
try { MacAddr detMac{arg.udp_dstmac};
if (detMac != r) {
retvals[0] = r;
}
}
if (arg.udp_dstip2 != 0) {
MacAddr r = setUdpIp2(IpAddr(arg.udp_dstip2));
MacAddr detMac{arg.udp_dstmac2};
if (detMac != r) {
retvals[1] = r;
}
}
impl()->setUDPPortNumber(arg.udp_dstport);
impl()->setUDPPortNumber2(arg.udp_dstport2);
if (detType == JUNGFRAU || detType == MOENCH || detType == GOTTHARD2) {
impl()->setNumberofUDPInterfaces(arg.udpInterfaces);
}
impl()->setUDPSocketBufferSize(0);
// acquisition parameters
impl()->setNumberOfFrames(arg.frames);
impl()->setNumberOfTriggers(arg.triggers);
if (detType == GOTTHARD2) {
impl()->setNumberOfBursts(arg.bursts);
}
if (detType == JUNGFRAU) {
impl()->setNumberOfAdditionalStorageCells(
arg.additionalStorageCells);
}
if (detType == CHIPTESTBOARD) {
impl()->setNumberofAnalogSamples(arg.analogSamples); impl()->setNumberofAnalogSamples(arg.analogSamples);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set num analog samples to " +
std::to_string(arg.analogSamples) +
" due to fifo structure memory allocation.");
} }
} if (detType == CHIPTESTBOARD) {
if (detType == CHIPTESTBOARD) {
try {
impl()->setNumberofDigitalSamples(arg.digitalSamples); impl()->setNumberofDigitalSamples(arg.digitalSamples);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set num digital samples to " +
std::to_string(arg.analogSamples) +
" due to fifo structure memory allocation.");
} }
} if (detType != MYTHEN3) {
if (detType != MYTHEN3) { impl()->setAcquisitionTime(std::chrono::nanoseconds(arg.expTimeNs));
impl()->setAcquisitionTime(std::chrono::nanoseconds(arg.expTimeNs)); }
} impl()->setAcquisitionPeriod(std::chrono::nanoseconds(arg.periodNs));
impl()->setAcquisitionPeriod(std::chrono::nanoseconds(arg.periodNs)); if (detType == EIGER) {
if (detType == EIGER) { impl()->setSubExpTime(std::chrono::nanoseconds(arg.subExpTimeNs));
impl()->setSubExpTime(std::chrono::nanoseconds(arg.subExpTimeNs)); impl()->setSubPeriod(std::chrono::nanoseconds(arg.subExpTimeNs) +
impl()->setSubPeriod(std::chrono::nanoseconds(arg.subExpTimeNs) + std::chrono::nanoseconds(arg.subDeadTimeNs));
std::chrono::nanoseconds(arg.subDeadTimeNs)); impl()->setActivate(static_cast<bool>(arg.activate));
impl()->setActivate(static_cast<bool>(arg.activate)); impl()->setDetectorDataStream(LEFT, arg.dataStreamLeft);
impl()->setDetectorDataStream(LEFT, arg.dataStreamLeft); impl()->setDetectorDataStream(RIGHT, arg.dataStreamRight);
impl()->setDetectorDataStream(RIGHT, arg.dataStreamRight);
try {
impl()->setQuad(arg.quad == 0 ? false : true); impl()->setQuad(arg.quad == 0 ? false : true);
} catch (const RuntimeError &e) { impl()->setThresholdEnergy(arg.thresholdEnergyeV[0]);
throw RuntimeError("Could not set quad to " +
std::to_string(arg.quad) +
" due to fifo strucutre memory allocation");
} }
impl()->setThresholdEnergy(arg.thresholdEnergyeV[0]); if (detType == EIGER || detType == JUNGFRAU || detType == MOENCH) {
} impl()->setReadNRows(arg.readNRows);
if (detType == EIGER || detType == JUNGFRAU || detType == MOENCH) {
impl()->setReadNRows(arg.readNRows);
}
if (detType == MYTHEN3) {
std::array<int, 3> val;
for (int i = 0; i < 3; ++i) {
val[i] = arg.thresholdEnergyeV[i];
} }
impl()->setThresholdEnergy(val); if (detType == MYTHEN3) {
} std::array<int, 3> val;
if (detType == EIGER || detType == MYTHEN3) { for (int i = 0; i < 3; ++i) {
try { val[i] = arg.thresholdEnergyeV[i];
}
impl()->setThresholdEnergy(val);
}
if (detType == EIGER || detType == MYTHEN3) {
impl()->setDynamicRange(arg.dynamicRange); impl()->setDynamicRange(arg.dynamicRange);
} catch (const RuntimeError &e) {
throw RuntimeError(
"Could not set dynamic range. Could not allocate "
"memory for fifo or could not start listening/writing threads");
} }
} impl()->setTimingMode(arg.timMode);
impl()->setTimingMode(arg.timMode); if (detType == EIGER || detType == CHIPTESTBOARD || detType == MYTHEN3) {
if (detType == EIGER || detType == CHIPTESTBOARD || detType == MYTHEN3) {
try {
impl()->setTenGigaEnable(arg.tenGiga); impl()->setTenGigaEnable(arg.tenGiga);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10GbE.");
} }
} if (detType == CHIPTESTBOARD) {
if (detType == CHIPTESTBOARD) {
try {
impl()->setReadoutMode(arg.roMode); impl()->setReadoutMode(arg.roMode);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set read out mode "
"due to fifo memory allocation.");
}
}
if (detType == CHIPTESTBOARD) {
try {
impl()->setADCEnableMask(arg.adcMask); impl()->setADCEnableMask(arg.adcMask);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set adc enable mask "
"due to fifo memory allcoation");
}
try {
impl()->setTenGigaADCEnableMask(arg.adc10gMask); impl()->setTenGigaADCEnableMask(arg.adc10gMask);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10Gb adc enable mask "
"due to fifo memory allcoation");
} }
} if (detType == GOTTHARD) {
if (detType == GOTTHARD) {
try {
impl()->setDetectorROI(arg.roi); impl()->setDetectorROI(arg.roi);
} catch (const RuntimeError &e) {
throw RuntimeError("Could not set ROI");
} }
if (detType == MYTHEN3) {
impl()->setCounterMask(arg.countermask);
impl()->setAcquisitionTime1(
std::chrono::nanoseconds(arg.expTime1Ns));
impl()->setAcquisitionTime2(
std::chrono::nanoseconds(arg.expTime2Ns));
impl()->setAcquisitionTime3(
std::chrono::nanoseconds(arg.expTime3Ns));
impl()->setGateDelay1(std::chrono::nanoseconds(arg.gateDelay1Ns));
impl()->setGateDelay2(std::chrono::nanoseconds(arg.gateDelay2Ns));
impl()->setGateDelay3(std::chrono::nanoseconds(arg.gateDelay3Ns));
impl()->setNumberOfGates(arg.gates);
}
if (detType == GOTTHARD2) {
impl()->setBurstMode(arg.burstType);
}
impl()->setScan(arg.scanParams);
} catch (std::exception &e) {
throw RuntimeError("Could not setup receiver [" +
std::string(e.what()) + ']');
} }
if (detType == MYTHEN3) {
impl()->setCounterMask(arg.countermask);
impl()->setAcquisitionTime1(std::chrono::nanoseconds(arg.expTime1Ns));
impl()->setAcquisitionTime2(std::chrono::nanoseconds(arg.expTime2Ns));
impl()->setAcquisitionTime3(std::chrono::nanoseconds(arg.expTime3Ns));
impl()->setGateDelay1(std::chrono::nanoseconds(arg.gateDelay1Ns));
impl()->setGateDelay2(std::chrono::nanoseconds(arg.gateDelay2Ns));
impl()->setGateDelay3(std::chrono::nanoseconds(arg.gateDelay3Ns));
impl()->setNumberOfGates(arg.gates);
}
if (detType == GOTTHARD2) {
impl()->setBurstMode(arg.burstType);
}
impl()->setScan(arg.scanParams);
return socket.sendResult(retvals); return socket.sendResult(retvals);
} }
@ -501,13 +457,10 @@ void ClientInterface::setDetectorType(detectorType arg) {
detType = GENERIC; detType = GENERIC;
receiver = make_unique<Implementation>(arg); receiver = make_unique<Implementation>(arg);
detType = arg; detType = arg;
} catch (std::exception &e) { } catch (const std::exception &e) {
std::ostringstream os; throw RuntimeError("Could not set detector type in the receiver. [" +
os << "Could not set detector type in the receiver. "; std::string(e.what()) + ']');
os << e.what();
throw RuntimeError(os.str());
} }
// callbacks after (in setdetectortype, the object is reinitialized) // callbacks after (in setdetectortype, the object is reinitialized)
if (startAcquisitionCallBack != nullptr) if (startAcquisitionCallBack != nullptr)
impl()->registerCallBackStartAcquisition(startAcquisitionCallBack, impl()->registerCallBackStartAcquisition(startAcquisitionCallBack,
@ -535,8 +488,8 @@ int ClientInterface::set_detector_roi(Interface &socket) {
verifyIdle(socket); verifyIdle(socket);
try { try {
impl()->setDetectorROI(arg); impl()->setDetectorROI(arg);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not set ROI"); throw RuntimeError("Could not set ROI [" + std::string(e.what()) + ']');
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -615,10 +568,10 @@ int ClientInterface::set_num_analog_samples(Interface &socket) {
} }
try { try {
impl()->setNumberofAnalogSamples(value); impl()->setNumberofAnalogSamples(value);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not set num analog samples to " + throw RuntimeError("Could not set number of analog samples to " +
std::to_string(value) + std::to_string(value) + " [" +
" due to fifo structure memory allocation."); std::string(e.what()) + ']');
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -631,11 +584,12 @@ int ClientInterface::set_num_digital_samples(Interface &socket) {
} }
try { try {
impl()->setNumberofDigitalSamples(value); impl()->setNumberofDigitalSamples(value);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not set num digital samples to " + throw RuntimeError("Could not set number of digital samples to " +
std::to_string(value) + std::to_string(value) + " [" +
" due to fifo structure memory allocation."); std::string(e.what()) + ']');
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -742,9 +696,9 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
} else { } else {
try { try {
impl()->setDynamicRange(dr); impl()->setDynamicRange(dr);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not allocate memory for fifo or " throw RuntimeError("Could not set dynamic range [" +
"could not start listening/writing threads"); std::string(e.what()) + ']');
} }
} }
} }
@ -780,7 +734,12 @@ int ClientInterface::get_status(Interface &socket) {
int ClientInterface::start_receiver(Interface &socket) { int ClientInterface::start_receiver(Interface &socket) {
if (impl()->getStatus() == IDLE) { if (impl()->getStatus() == IDLE) {
LOG(logDEBUG1) << "Starting Receiver"; LOG(logDEBUG1) << "Starting Receiver";
impl()->startReceiver(); try {
impl()->startReceiver();
} catch (const std::exception &e) {
throw RuntimeError("Could not start reciever [" +
std::string(e.what()) + ']');
}
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -790,12 +749,16 @@ int ClientInterface::stop_receiver(Interface &socket) {
if (impl()->getStatus() == RUNNING) { if (impl()->getStatus() == RUNNING) {
LOG(logDEBUG1) << "Stopping Receiver"; LOG(logDEBUG1) << "Stopping Receiver";
impl()->setStoppedFlag(static_cast<bool>(arg)); impl()->setStoppedFlag(static_cast<bool>(arg));
impl()->stopReceiver(); try {
impl()->stopReceiver();
} catch (const std::exception &e) {
throw RuntimeError("Could not stop receiver [" +
std::string(e.what()) + ']');
}
} }
auto s = impl()->getStatus(); auto s = impl()->getStatus();
if (s != IDLE) if (s != IDLE)
throw RuntimeError("Could not stop receiver. It as it is: " + throw RuntimeError("Could not stop receiver. Status: " + ToString(s));
ToString(s));
return socket.Send(OK); return socket.Send(OK);
} }
@ -810,7 +773,12 @@ int ClientInterface::set_file_dir(Interface &socket) {
throw RuntimeError("Receiver path needs to be absolute path"); throw RuntimeError("Receiver path needs to be absolute path");
LOG(logDEBUG1) << "Setting file path: " << fpath; LOG(logDEBUG1) << "Setting file path: " << fpath;
impl()->setFilePath(fpath); try {
impl()->setFilePath(fpath);
} catch (const std::exception &e) {
throw RuntimeError("Could not set file path [" + std::string(e.what()) +
']');
}
return socket.Send(OK); return socket.Send(OK);
} }
@ -892,7 +860,12 @@ int ClientInterface::set_file_write(Interface &socket) {
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting File write enable:" << enable; LOG(logDEBUG1) << "Setting File write enable:" << enable;
impl()->setFileWriteEnable(enable); try {
impl()->setFileWriteEnable(enable);
} catch (const std::exception &e) {
throw RuntimeError("Could not enable/disable file write [" +
std::string(e.what()) + ']');
}
return socket.Send(OK); return socket.Send(OK);
} }
@ -946,8 +919,9 @@ int ClientInterface::enable_tengiga(Interface &socket) {
LOG(logDEBUG1) << "Setting 10GbE:" << val; LOG(logDEBUG1) << "Setting 10GbE:" << val;
try { try {
impl()->setTenGigaEnable(val); impl()->setTenGigaEnable(val);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not set 10GbE."); throw RuntimeError("Could not set 10GbE. [" +
std::string(e.what()) + ']');
} }
} }
int retval = impl()->getTenGigaEnable(); int retval = impl()->getTenGigaEnable();
@ -963,9 +937,9 @@ int ClientInterface::set_fifo_depth(Interface &socket) {
LOG(logDEBUG1) << "Setting fifo depth:" << value; LOG(logDEBUG1) << "Setting fifo depth:" << value;
try { try {
impl()->setFifoDepth(value); impl()->setFifoDepth(value);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not set fifo depth due to fifo structure " throw RuntimeError("Could not set fifo depth [" +
"memory allocation."); std::string(e.what()) + ']');
} }
} }
int retval = impl()->getFifoDepth(); int retval = impl()->getFifoDepth();
@ -1000,10 +974,12 @@ int ClientInterface::set_streaming(Interface &socket) {
LOG(logDEBUG1) << "Setting data stream enable:" << index; LOG(logDEBUG1) << "Setting data stream enable:" << index;
try { try {
impl()->setDataStreamEnable(index); impl()->setDataStreamEnable(index);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not set data stream enable to " + throw RuntimeError("Could not set data stream enable to " +
std::to_string(index)); std::to_string(index) + " [" +
std::string(e.what()) + ']');
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -1062,7 +1038,12 @@ int ClientInterface::set_file_format(Interface &socket) {
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting file format:" << f; LOG(logDEBUG1) << "Setting file format:" << f;
impl()->setFileFormat(f); try {
impl()->setFileFormat(f);
} catch (const std::exception &e) {
throw RuntimeError("Could not set file format to " + ToString(f) +
" [" + std::string(e.what()) + ']');
}
auto retval = impl()->getFileFormat(); auto retval = impl()->getFileFormat();
validate(f, retval, "set file format", DEC); validate(f, retval, "set file format", DEC);
@ -1183,7 +1164,13 @@ int ClientInterface::set_udp_socket_buffer_size(Interface &socket) {
"Receiver socket buffer size exceeded max (INT_MAX/2)"); "Receiver socket buffer size exceeded max (INT_MAX/2)");
} }
LOG(logDEBUG1) << "Setting UDP Socket Buffer size: " << size; LOG(logDEBUG1) << "Setting UDP Socket Buffer size: " << size;
impl()->setUDPSocketBufferSize(size); try {
impl()->setUDPSocketBufferSize(size);
} catch (const std::exception &e) {
throw RuntimeError("Could not set udp socket buffer size to " +
std::to_string(size) + " [" +
std::string(e.what()) + ']');
}
} }
int retval = impl()->getUDPSocketBufferSize(); int retval = impl()->getUDPSocketBufferSize();
if (size != 0) if (size != 0)
@ -1262,9 +1249,9 @@ int ClientInterface::set_readout_mode(Interface &socket) {
LOG(logDEBUG1) << "Setting readout mode: " << arg; LOG(logDEBUG1) << "Setting readout mode: " << arg;
try { try {
impl()->setReadoutMode(arg); impl()->setReadoutMode(arg);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError( throw RuntimeError("Could not set read out mode [" +
"Could not set read out mode due to fifo memory allocation."); std::string(e.what()) + ']');
} }
} }
auto retval = impl()->getReadoutMode(); auto retval = impl()->getReadoutMode();
@ -1280,10 +1267,11 @@ int ClientInterface::set_adc_mask(Interface &socket) {
LOG(logDEBUG1) << "Setting 1Gb ADC enable mask: " << arg; LOG(logDEBUG1) << "Setting 1Gb ADC enable mask: " << arg;
try { try {
impl()->setADCEnableMask(arg); impl()->setADCEnableMask(arg);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError( throw RuntimeError("Could not set adc enable mask [" +
"Could not set adc enable mask due to fifo memory allcoation"); std::string(e.what()) + ']');
} }
auto retval = impl()->getADCEnableMask(); auto retval = impl()->getADCEnableMask();
if (retval != arg) { if (retval != arg) {
std::ostringstream os; std::ostringstream os;
@ -1347,10 +1335,10 @@ int ClientInterface::set_quad_type(Interface &socket) {
LOG(logDEBUG1) << "Setting quad:" << quadEnable; LOG(logDEBUG1) << "Setting quad:" << quadEnable;
try { try {
impl()->setQuad(quadEnable == 0 ? false : true); impl()->setQuad(quadEnable == 0 ? false : true);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not set quad to " + throw RuntimeError("Could not set quad to " +
std::to_string(quadEnable) + std::to_string(quadEnable) + " [" +
" due to fifo strucutre memory allocation"); std::string(e.what()) + ']');
} }
} }
int retval = impl()->getQuad() ? 1 : 0; int retval = impl()->getQuad() ? 1 : 0;
@ -1486,10 +1474,12 @@ int ClientInterface::set_num_interfaces(Interface &socket) {
LOG(logDEBUG1) << "Setting Number of UDP Interfaces:" << arg; LOG(logDEBUG1) << "Setting Number of UDP Interfaces:" << arg;
try { try {
impl()->setNumberofUDPInterfaces(arg); impl()->setNumberofUDPInterfaces(arg);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Failed to set number of interfaces to " + throw RuntimeError("Could not set number of interfaces to " +
std::to_string(arg)); std::to_string(arg) + " [" + std::string(e.what()) +
']');
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -1499,10 +1489,11 @@ int ClientInterface::set_adc_mask_10g(Interface &socket) {
LOG(logDEBUG1) << "Setting 10Gb ADC enable mask: " << arg; LOG(logDEBUG1) << "Setting 10Gb ADC enable mask: " << arg;
try { try {
impl()->setTenGigaADCEnableMask(arg); impl()->setTenGigaADCEnableMask(arg);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError( throw RuntimeError("Could not set 10Gb adc enable mask [" +
"Could not set 10Gb adc enable mask due to fifo memory allcoation"); std::string(e.what()) + ']');
} }
auto retval = impl()->getTenGigaADCEnableMask(); auto retval = impl()->getTenGigaADCEnableMask();
if (retval != arg) { if (retval != arg) {
std::ostringstream os; std::ostringstream os;
@ -1518,7 +1509,12 @@ int ClientInterface::set_counter_mask(Interface &socket) {
auto arg = socket.Receive<uint32_t>(); auto arg = socket.Receive<uint32_t>();
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting counters: " << arg; LOG(logDEBUG1) << "Setting counters: " << arg;
impl()->setCounterMask(arg); try {
impl()->setCounterMask(arg);
} catch (const std::exception &e) {
throw RuntimeError("Could not set counter mask [" +
std::string(e.what()) + ']');
}
return socket.Send(OK); return socket.Send(OK);
} }
@ -1714,7 +1710,12 @@ int ClientInterface::set_arping(Interface &socket) {
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Starting/ Killing arping thread:" << value; LOG(logDEBUG1) << "Starting/ Killing arping thread:" << value;
impl()->setArping(value, udpips); try {
impl()->setArping(value, udpips);
} catch (const std::exception &e) {
throw RuntimeError("Could not start/kill arping thread [" +
std::string(e.what()) + ']');
}
return socket.Send(OK); return socket.Send(OK);
} }
@ -1732,9 +1733,11 @@ int ClientInterface::set_receiver_roi(Interface &socket) {
verifyIdle(socket); verifyIdle(socket);
try { try {
impl()->setReceiverROI(arg); impl()->setReceiverROI(arg);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not set ReceiverROI"); throw RuntimeError("Could not set Receiver ROI [" +
std::string(e.what()) + ']');
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -1746,9 +1749,11 @@ int ClientInterface::set_receiver_roi_metadata(Interface &socket) {
verifyIdle(socket); verifyIdle(socket);
try { try {
impl()->setReceiverROIMetadata(arg); impl()->setReceiverROIMetadata(arg);
} catch (const RuntimeError &e) { } catch (const std::exception &e) {
throw RuntimeError("Could not set ReceiverROI metadata"); throw RuntimeError("Could not set ReceiverROI metadata [" +
std::string(e.what()) + ']');
} }
return socket.Send(OK); return socket.Send(OK);
} }

View File

@ -87,19 +87,18 @@ void DataStreamer::CreateZmqSockets(uint32_t port, const IpAddr ip, int hwm) {
std::string sip = ip.str(); std::string sip = ip.str();
try { try {
zmqSocket = new ZmqSocket(portnum, (ip != 0 ? sip.c_str() : nullptr)); zmqSocket = new ZmqSocket(portnum, (ip != 0 ? sip.c_str() : nullptr));
// set if custom // set if custom
if (hwm >= 0) { if (hwm >= 0) {
zmqSocket->SetSendHighWaterMark(hwm); zmqSocket->SetSendHighWaterMark(hwm);
if (zmqSocket->GetSendHighWaterMark() != hwm) { // needed, or HWL is not taken
throw RuntimeError( zmqSocket->Rebind();
"Could not set zmq send high water mark to " +
std::to_string(hwm));
}
} }
} catch (...) { } catch (std::exception &e) {
LOG(logERROR) << "Could not create Zmq socket on port " << portnum std::ostringstream oss;
<< " for Streamer " << index; oss << "Could not create zmq pub socket on port " << portnum;
throw; oss << " [" << e.what() << ']';
throw RuntimeError(oss.str());
} }
LOG(logINFO) << index << " Streamer: Zmq Server started at " LOG(logINFO) << index << " Streamer: Zmq Server started at "
<< zmqSocket->GetZmqServerAddress() << zmqSocket->GetZmqServerAddress()

View File

@ -78,11 +78,12 @@ void Implementation::SetupFifoStructure() {
try { try {
fifo.push_back( fifo.push_back(
sls::make_unique<Fifo>(i, datasize, generalData->fifoDepth)); sls::make_unique<Fifo>(i, datasize, generalData->fifoDepth));
} catch (...) { } catch (const std::exception &e) {
fifo.clear(); fifo.clear();
generalData->fifoDepth = 0; generalData->fifoDepth = 0;
throw RuntimeError("Could not allocate memory for fifo structure " + std::ostringstream oss;
std::to_string(i) + ". FifoDepth is now 0."); oss << e.what() << ". Fifo depth is now 0";
throw RuntimeError(oss.str());
} }
// set the listener & dataprocessor threads to point to the right fifo // set the listener & dataprocessor threads to point to the right fifo
if (listener.size()) if (listener.size())
@ -165,12 +166,10 @@ void Implementation::setDetectorType(const detectorType d) {
SetupListener(i); SetupListener(i);
dataProcessor.push_back(sls::make_unique<DataProcessor>(i)); dataProcessor.push_back(sls::make_unique<DataProcessor>(i));
SetupDataProcessor(i); SetupDataProcessor(i);
} catch (...) { } catch (const std::exception &e) {
listener.clear(); listener.clear();
dataProcessor.clear(); dataProcessor.clear();
throw RuntimeError( throw;
"Could not create listener/dataprocessor threads (index:" +
std::to_string(i) + ")");
} }
} }
@ -212,6 +211,7 @@ void Implementation::SetupDataStreamer(int i) {
streamingHwm); streamingHwm);
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader); dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader);
dataStreamer[i]->SetFileIndex(fileIndex); dataStreamer[i]->SetFileIndex(fileIndex);
dataStreamer[i]->SetQuadEnable(quadEnable);
dataStreamer[i]->SetFlipRows(flipRows); dataStreamer[i]->SetFlipRows(flipRows);
dataStreamer[i]->SetNumberofPorts(numPorts); dataStreamer[i]->SetNumberofPorts(numPorts);
dataStreamer[i]->SetQuadEnable(quadEnable); dataStreamer[i]->SetQuadEnable(quadEnable);
@ -351,19 +351,21 @@ std::array<pid_t, NUM_RX_THREAD_IDS> Implementation::getThreadIds() const {
retval[id++] = 0; retval[id++] = 0;
} }
} }
retval[NUM_RX_THREAD_IDS - 1] = arping.GetThreadId(); retval[NUM_RX_THREAD_IDS - 1] = arping.GetProcessId();
return retval; return retval;
} }
bool Implementation::getArping() const { return arping.IsRunning(); } bool Implementation::getArping() const { return arping.IsRunning(); }
pid_t Implementation::getArpingThreadId() const { return arping.GetThreadId(); } pid_t Implementation::getArpingProcessId() const {
return arping.GetProcessId();
}
void Implementation::setArping(const bool i, void Implementation::setArping(const bool i,
const std::vector<std::string> ips) { const std::vector<std::string> ips) {
if (i != arping.IsRunning()) { if (i != arping.IsRunning()) {
if (!i) { if (!i) {
arping.StopThread(); arping.StopProcess();
} else { } else {
// setup interface // setup interface
for (int i = 0; i != generalData->numUDPInterfaces; ++i) { for (int i = 0; i != generalData->numUDPInterfaces; ++i) {
@ -374,7 +376,7 @@ void Implementation::setArping(const bool i,
} }
arping.SetInterfacesAndIps(i, eth[i], ips[i]); arping.SetInterfacesAndIps(i, eth[i], ips[i]);
} }
arping.StartThread(); arping.StartProcess();
} }
} }
} }
@ -665,8 +667,9 @@ void Implementation::startReceiver() {
startAcquisitionCallBack(filePath, fileName, fileIndex, imageSize, startAcquisitionCallBack(filePath, fileName, fileIndex, imageSize,
pStartAcquisition); pStartAcquisition);
} catch (const std::exception &e) { } catch (const std::exception &e) {
throw RuntimeError("Start Acquisition Callback Error: " + std::ostringstream oss;
std::string(e.what())); oss << "Start Acquisition Callback Error: " << e.what();
throw RuntimeError(oss.str());
} }
if (rawDataReadyCallBack != nullptr) { if (rawDataReadyCallBack != nullptr) {
LOG(logINFO) << "Data Write has been defined externally"; LOG(logINFO) << "Data Write has been defined externally";
@ -713,6 +716,10 @@ void Implementation::stopReceiver() {
std::this_thread::sleep_for(std::chrono::milliseconds(5)); std::this_thread::sleep_for(std::chrono::milliseconds(5));
} }
// delete the udp sockets
for (const auto &it : listener)
it->DeleteUDPSocket();
if (fileWriteEnable && modulePos == 0) { if (fileWriteEnable && modulePos == 0) {
// master and virtual file (hdf5) // master and virtual file (hdf5)
StartMasterWriter(); StartMasterWriter();
@ -777,8 +784,9 @@ void Implementation::stopReceiver() {
status = IDLE; status = IDLE;
LOG(logINFO) << "Receiver Stopped"; LOG(logINFO) << "Receiver Stopped";
LOG(logINFO) << "Status: " << ToString(status); LOG(logINFO) << "Status: " << ToString(status);
throw RuntimeError("Acquisition Finished Callback Error: " + std::ostringstream oss;
std::string(e.what())); oss << "Acquisition Finished Callback Error: " << e.what();
throw RuntimeError(oss.str());
} }
} }
} }
@ -859,7 +867,7 @@ void Implementation::CreateUDPSockets() {
} }
} catch (const RuntimeError &e) { } catch (const RuntimeError &e) {
shutDownUDPSockets(); shutDownUDPSockets();
throw RuntimeError("Could not create UDP Socket(s)."); throw;
} }
LOG(logDEBUG) << "UDP socket(s) created successfully."; LOG(logDEBUG) << "UDP socket(s) created successfully.";
} }
@ -879,7 +887,9 @@ void Implementation::SetupWriter() {
shutDownUDPSockets(); shutDownUDPSockets();
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->CloseFiles(); it->CloseFiles();
throw RuntimeError("Could not create first data file."); std::ostringstream oss;
oss << "Could not set up writer: " << e.what();
throw RuntimeError(oss.str());
} }
} }
@ -968,10 +978,9 @@ void Implementation::StartMasterWriter() {
} }
} }
#endif #endif
} catch (std::exception &e) { } catch (const std::exception &e) {
// ignore it and just print it // ignore it and just print it
LOG(logWARNING) << "Caught exception when handling virtual hdf5 file [" LOG(logWARNING) << "Error creating master/virtualfiles: " << e.what();
<< e.what() << "]";
} }
} }
@ -1032,12 +1041,10 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
SetupListener(i); SetupListener(i);
dataProcessor.push_back(sls::make_unique<DataProcessor>(i)); dataProcessor.push_back(sls::make_unique<DataProcessor>(i));
SetupDataProcessor(i); SetupDataProcessor(i);
} catch (...) { } catch (const std::exception &e) {
listener.clear(); listener.clear();
dataProcessor.clear(); dataProcessor.clear();
throw RuntimeError( throw;
"Could not create listener/dataprocessor threads (index:" +
std::to_string(i) + ")");
} }
// streamer threads // streamer threads
@ -1045,16 +1052,14 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
try { try {
dataStreamer.push_back(sls::make_unique<DataStreamer>(i)); dataStreamer.push_back(sls::make_unique<DataStreamer>(i));
SetupDataStreamer(i); SetupDataStreamer(i);
} catch (...) { } catch (const std::exception &e) {
if (dataStreamEnable) { if (dataStreamEnable) {
dataStreamer.clear(); dataStreamer.clear();
dataStreamEnable = false; dataStreamEnable = false;
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetDataStreamEnable(dataStreamEnable); it->SetDataStreamEnable(dataStreamEnable);
} }
throw RuntimeError( throw;
"Could not create datastreamer threads (index:" +
std::to_string(i) + ")");
} }
} }
} }
@ -1165,12 +1170,12 @@ void Implementation::setDataStreamEnable(const bool enable) {
try { try {
dataStreamer.push_back(sls::make_unique<DataStreamer>(i)); dataStreamer.push_back(sls::make_unique<DataStreamer>(i));
SetupDataStreamer(i); SetupDataStreamer(i);
} catch (...) { } catch (const std::exception &e) {
dataStreamer.clear(); dataStreamer.clear();
dataStreamEnable = false; dataStreamEnable = false;
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetDataStreamEnable(dataStreamEnable); it->SetDataStreamEnable(dataStreamEnable);
throw RuntimeError("Could not set data stream enable."); throw;
} }
} }
SetThreadPriorities(); SetThreadPriorities();

View File

@ -54,7 +54,7 @@ class Implementation : private virtual slsDetectorDefs {
void setThreadIds(const pid_t parentTid, const pid_t tcpTid); void setThreadIds(const pid_t parentTid, const pid_t tcpTid);
std::array<pid_t, NUM_RX_THREAD_IDS> getThreadIds() const; std::array<pid_t, NUM_RX_THREAD_IDS> getThreadIds() const;
bool getArping() const; bool getArping() const;
pid_t getArpingThreadId() const; pid_t getArpingProcessId() const;
void setArping(const bool i, const std::vector<std::string> ips); void setArping(const bool i, const std::vector<std::string> ips);
ROI getReceiverROI() const; ROI getReceiverROI() const;
void setReceiverROI(const ROI arg); void setReceiverROI(const ROI arg);
@ -323,7 +323,7 @@ class Implementation : private virtual slsDetectorDefs {
// acquisition // acquisition
std::atomic<runStatus> status{IDLE}; std::atomic<runStatus> status{IDLE};
bool stoppedFlag{false}; std::atomic<bool> stoppedFlag{false};
scanParameters scanParams{}; scanParameters scanParams{};
// network configuration (UDP) // network configuration (UDP)

View File

@ -148,30 +148,34 @@ void Listener::RecordFirstIndex(uint64_t fnum) {
} }
void Listener::CreateUDPSocket(int &actualSize) { void Listener::CreateUDPSocket(int &actualSize) {
if (disabledPort) {
return;
}
uint32_t packetSize = generalData->packetSize;
if (generalData->detType == GOTTHARD2 && index != 0) {
packetSize = generalData->vetoPacketSize;
}
try { try {
if (disabledPort) {
return;
}
uint32_t packetSize = generalData->packetSize;
if (generalData->detType == GOTTHARD2 && index != 0) {
packetSize = generalData->vetoPacketSize;
}
udpSocket = nullptr; udpSocket = nullptr;
udpSocket = make_unique<UdpRxSocket>( udpSocket = make_unique<UdpRxSocket>(
udpPortNumber, packetSize, udpPortNumber, packetSize,
(eth.length() ? InterfaceNameToIp(eth).str().c_str() : nullptr), (eth.length() ? InterfaceNameToIp(eth).str().c_str() : nullptr),
generalData->udpSocketBufferSize); generalData->udpSocketBufferSize);
LOG(logINFO) << index << ": UDP port opened at port " << udpPortNumber; LOG(logINFO) << index << ": UDP port opened at port " << udpPortNumber;
} catch (...) {
throw RuntimeError("Could not create UDP socket on port " + udpSocketAlive = true;
std::to_string(udpPortNumber));
// doubled due to kernel bookkeeping (could also be less due to
// permissions)
actualSize = udpSocket->getBufferSize();
} catch (std::exception &e) {
std::ostringstream oss;
oss << "Could not create UDP socket on port " << udpPortNumber << " ["
<< e.what() << ']';
throw RuntimeError(oss.str());
} }
udpSocketAlive = true;
// doubled due to kernel bookkeeping (could also be less due to permissions)
actualSize = udpSocket->getBufferSize();
} }
void Listener::ShutDownUDPSocket() { void Listener::ShutDownUDPSocket() {
@ -184,6 +188,13 @@ void Listener::ShutDownUDPSocket() {
} }
} }
void Listener::DeleteUDPSocket() {
if (udpSocket) {
udpSocket.reset();
LOG(logINFO) << "Closed UDP port " << udpPortNumber;
}
}
void Listener::CreateDummySocketForUDPSocketBufferSize(int s, int &actualSize) { void Listener::CreateDummySocketForUDPSocketBufferSize(int s, int &actualSize) {
// custom setup (s != 0) // custom setup (s != 0)
// default setup at startup (s = 0) // default setup at startup (s = 0)

View File

@ -50,6 +50,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
void ResetParametersforNewAcquisition(); void ResetParametersforNewAcquisition();
void CreateUDPSocket(int &actualSize); void CreateUDPSocket(int &actualSize);
void ShutDownUDPSocket(); void ShutDownUDPSocket();
void DeleteUDPSocket();
/** to set & get actual buffer size */ /** to set & get actual buffer size */
void CreateDummySocketForUDPSocketBufferSize(int s, int &actualSize); void CreateDummySocketForUDPSocketBufferSize(int s, int &actualSize);

View File

@ -31,6 +31,11 @@ namespace sls {
// #define ZMQ_DETAIL // #define ZMQ_DETAIL
#define ROIVERBOSITY #define ROIVERBOSITY
// high water mark for gui
#define DEFFAULT_LOW_ZMQ_HWM (25)
#define DEFAULT_LOW_ZMQ_HWM_BUFFERSIZE (1024 * 1024) // 1MB
#define DEFAULT_ZMQ_BUFFERSIZE (-1) // os default
/** zmq header structure */ /** zmq header structure */
struct zmqHeader { struct zmqHeader {
/** true if incoming data, false if end of acquisition */ /** true if incoming data, false if end of acquisition */
@ -108,15 +113,29 @@ class ZmqSocket {
/** Returns high water mark for outbound messages */ /** Returns high water mark for outbound messages */
int GetSendHighWaterMark(); int GetSendHighWaterMark();
/** Sets high water mark for outbound messages. Default 1000 (zmqlib) */ /** Sets high water mark for outbound messages. Default 1000 (zmqlib). Also
* changes send buffer size depending on hwm. Must rebind. */
void SetSendHighWaterMark(int limit); void SetSendHighWaterMark(int limit);
/** Returns high water mark for inbound messages */ /** Returns high water mark for inbound messages */
int GetReceiveHighWaterMark(); int GetReceiveHighWaterMark();
/** Sets high water mark for inbound messages. Default 1000 (zmqlib) */ /** Sets high water mark for inbound messages. Default 1000 (zmqlib). Also
* changes receiver buffer size depending on hwm. Must reconnect */
void SetReceiveHighWaterMark(int limit); void SetReceiveHighWaterMark(int limit);
/** Gets kernel buffer for outbound messages. Default 0 (os) */
int GetSendBuffer();
/** Sets kernel buffer for outbound messages. Default 0 (os) */
void SetSendBuffer(int limit);
/** Gets kernel buffer for inbound messages. Default 0 (os) */
int GetReceiveBuffer();
/** Sets kernel buffer for inbound messages. Default 0 (os) */
void SetReceiveBuffer(int limit);
/** /**
* Returns Port Number * Returns Port Number
* @returns Port Number * @returns Port Number
@ -129,6 +148,9 @@ class ZmqSocket {
*/ */
std::string GetZmqServerAddress() { return sockfd.serverAddress; } std::string GetZmqServerAddress() { return sockfd.serverAddress; }
/** unbinds and rebind, to apply changes of HWM */
void Rebind();
/** /**
* Connect client socket to server socket * Connect client socket to server socket
* @returns 1 for fail, 0 for success * @returns 1 for fail, 0 for success

View File

@ -148,6 +148,18 @@ Squash(const Container &c, typename Container::value_type default_value = {}) {
return default_value; return default_value;
} }
template <typename T>
typename std::enable_if<is_container<T>::value, bool>::type
removeDuplicates(T &c) {
auto containerSize = c.size();
std::sort(c.begin(), c.end());
c.erase(std::unique(c.begin(), c.end()), c.end());
if (c.size() != containerSize) {
return true;
}
return false;
}
} // namespace sls } // namespace sls
#endif // CONTAINER_UTILS_H #endif // CONTAINER_UTILS_H

View File

@ -50,6 +50,8 @@ ssize_t getFileSize(FILE *fd, const std::string &prependErrorString);
std::string getFileNameFromFilePath(const std::string &fpath); std::string getFileNameFromFilePath(const std::string &fpath);
std::vector<int> getChannelsFromStringList(const std::vector<std::string> list);
/** File can have # for comments. /** File can have # for comments.
* Channels can be separated by spaces, commas * Channels can be separated by spaces, commas
* and ranges provided using ':', eg. 23:29 * and ranges provided using ':', eg. 23:29

View File

@ -10,6 +10,8 @@
*@short functions indices to call on server (detector/receiver) *@short functions indices to call on server (detector/receiver)
*/ */
#define UNRECOGNIZED_FNUM_ENUM "Unrecognized Function enum"
enum detFuncs { enum detFuncs {
F_EXEC_COMMAND = 0, F_EXEC_COMMAND = 0,
F_GET_DETECTOR_TYPE, F_GET_DETECTOR_TYPE,

View File

@ -1,6 +1,7 @@
// 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 */
<<<<<<< HEAD
#define RELEASE "developer" #define RELEASE "developer"
#define APILIB "developer 0x221213" #define APILIB "developer 0x221213"
#define APIRECEIVER "developer 0x221213" #define APIRECEIVER "developer 0x221213"
@ -11,3 +12,15 @@
#define APIMOENCH "developer 0x221215" #define APIMOENCH "developer 0x221215"
#define APIGOTTHARD "developer 0x230117" #define APIGOTTHARD "developer 0x230117"
#define APIMYTHEN3 "developer 0x230117" #define APIMYTHEN3 "developer 0x230117"
=======
#define RELEASE "7.0.0"
#define APICTB "7.0.0 0x230222"
#define APIGOTTHARD "7.0.0 0x230222"
#define APIGOTTHARD2 "7.0.0 0x230222"
#define APIJUNGFRAU "7.0.0 0x230222"
#define APIMYTHEN3 "7.0.0 0x230222"
#define APIMOENCH "7.0.0 0x230222"
#define APIEIGER "7.0.0 0x230222"
#define APILIB "7.0.0 0x230223"
#define APIRECEIVER "7.0.0 0x230222"
>>>>>>> 7.0.0.rc

View File

@ -4,6 +4,7 @@
#include "sls/logger.h" #include "sls/logger.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "sls/sls_detector_exceptions.h" #include "sls/sls_detector_exceptions.h"
#include "sls/sls_detector_funcs.h"
#include <arpa/inet.h> #include <arpa/inet.h>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
@ -76,9 +77,7 @@ void ClientSocket::readReply(int &ret, void *retval, size_t retval_size) {
try { try {
Receive(&ret, sizeof(ret)); Receive(&ret, sizeof(ret));
if (ret == slsDetectorDefs::FAIL) { if (ret == slsDetectorDefs::FAIL) {
char mess[MAX_STR_LENGTH]{}; std::string mess = readErrorMessage();
// get error message
Receive(mess, sizeof(mess));
// Do we need to know hostname here? // Do we need to know hostname here?
// In that case save it??? // In that case save it???
if (socketType == "Receiver") { if (socketType == "Receiver") {
@ -107,6 +106,9 @@ void ClientSocket::readReply(int &ret, void *retval, size_t retval_size) {
std::string ClientSocket::readErrorMessage() { std::string ClientSocket::readErrorMessage() {
std::string error_msg(MAX_STR_LENGTH, '\0'); std::string error_msg(MAX_STR_LENGTH, '\0');
Receive(&error_msg[0], error_msg.size()); Receive(&error_msg[0], error_msg.size());
if (error_msg.find(UNRECOGNIZED_FNUM_ENUM) != std::string::npos) {
error_msg.insert(0, "Software version mismatch. ");
}
return error_msg; return error_msg;
} }

View File

@ -27,15 +27,18 @@ UdpRxSocket::UdpRxSocket(int port, ssize_t packet_size, const char *hostname,
const std::string portname = std::to_string(port); const std::string portname = std::to_string(port);
if (getaddrinfo(hostname, portname.c_str(), &hints, &res)) { if (getaddrinfo(hostname, portname.c_str(), &hints, &res)) {
throw RuntimeError("Failed at getaddrinfo with " + throw RuntimeError("Failed at getaddrinfo with " +
std::string(hostname)); std::string(hostname) + " [" +
std::string(strerror(errno)) + ']');
} }
sockfd_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol); sockfd_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd_ == -1) { if (sockfd_ == -1) {
throw RuntimeError("Failed to create UDP RX socket"); throw RuntimeError("Failed to create UDP RX socket [" +
std::string(strerror(errno)) + ']');
} }
if (bind(sockfd_, res->ai_addr, res->ai_addrlen) == -1) { if (bind(sockfd_, res->ai_addr, res->ai_addrlen) == -1) {
close(sockfd_); close(sockfd_);
throw RuntimeError("Failed to bind UDP RX socket"); throw RuntimeError("Failed to bind UDP RX socket [" +
std::string(strerror(errno)) + ']');
} }
freeaddrinfo(res); freeaddrinfo(res);
@ -74,13 +77,15 @@ int UdpRxSocket::getBufferSize() const {
int ret = 0; int ret = 0;
socklen_t optlen = sizeof(ret); socklen_t optlen = sizeof(ret);
if (getsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &ret, &optlen) == -1) if (getsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &ret, &optlen) == -1)
throw RuntimeError("Could not get socket buffer size"); throw RuntimeError("Could not get socket buffer size [" +
std::string(strerror(errno)) + ']');
return ret; return ret;
} }
void UdpRxSocket::setBufferSize(int size) { void UdpRxSocket::setBufferSize(int size) {
if (setsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size))) if (setsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)))
throw RuntimeError("Could not set socket buffer size"); throw RuntimeError("Could not set socket buffer size [" +
std::string(strerror(errno)) + ']');
} }
void UdpRxSocket::Shutdown() { void UdpRxSocket::Shutdown() {

View File

@ -102,6 +102,16 @@ void ZmqSocket::SetSendHighWaterMark(int limit) {
PrintError(); PrintError();
throw ZmqSocketError("Could not set ZMQ_SNDHWM"); throw ZmqSocketError("Could not set ZMQ_SNDHWM");
} }
if (GetSendHighWaterMark() != limit) {
throw ZmqSocketError("Could not set ZMQ_SNDHWM to " +
std::to_string(limit));
}
int bufsize = DEFAULT_ZMQ_BUFFERSIZE;
if (limit < DEFFAULT_LOW_ZMQ_HWM) {
bufsize = DEFAULT_LOW_ZMQ_HWM_BUFFERSIZE;
}
SetSendBuffer(bufsize);
} }
int ZmqSocket::GetReceiveHighWaterMark() { int ZmqSocket::GetReceiveHighWaterMark() {
@ -110,7 +120,7 @@ int ZmqSocket::GetReceiveHighWaterMark() {
if (zmq_getsockopt(sockfd.socketDescriptor, ZMQ_RCVHWM, &value, if (zmq_getsockopt(sockfd.socketDescriptor, ZMQ_RCVHWM, &value,
&value_size)) { &value_size)) {
PrintError(); PrintError();
throw ZmqSocketError("Could not get ZMQ_SNDHWM"); throw ZmqSocketError("Could not get ZMQ_RCVHWM");
} }
return value; return value;
} }
@ -119,7 +129,77 @@ void ZmqSocket::SetReceiveHighWaterMark(int limit) {
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_RCVHWM, &limit, if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_RCVHWM, &limit,
sizeof(limit))) { sizeof(limit))) {
PrintError(); PrintError();
throw ZmqSocketError("Could not set ZMQ_SNDHWM"); throw ZmqSocketError("Could not set ZMQ_RCVHWM");
}
if (GetReceiveHighWaterMark() != limit) {
throw ZmqSocketError("Could not set ZMQ_RCVHWM to " +
std::to_string(limit));
}
int bufsize = DEFAULT_ZMQ_BUFFERSIZE;
if (limit < DEFFAULT_LOW_ZMQ_HWM) {
bufsize = DEFAULT_LOW_ZMQ_HWM_BUFFERSIZE;
}
SetReceiveBuffer(bufsize);
}
int ZmqSocket::GetSendBuffer() {
int value = 0;
size_t value_size = sizeof(value);
if (zmq_getsockopt(sockfd.socketDescriptor, ZMQ_SNDBUF, &value,
&value_size)) {
PrintError();
throw ZmqSocketError("Could not get ZMQ_SNDBUF");
}
return value;
}
void ZmqSocket::SetSendBuffer(int limit) {
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_SNDBUF, &limit,
sizeof(limit))) {
PrintError();
throw ZmqSocketError("Could not set ZMQ_SNDBUF");
}
if (GetSendBuffer() != limit) {
throw ZmqSocketError("Could not set ZMQ_SNDBUF to " +
std::to_string(limit));
}
}
int ZmqSocket::GetReceiveBuffer() {
int value = 0;
size_t value_size = sizeof(value);
if (zmq_getsockopt(sockfd.socketDescriptor, ZMQ_RCVBUF, &value,
&value_size)) {
PrintError();
throw ZmqSocketError("Could not get ZMQ_RCVBUF");
}
return value;
}
void ZmqSocket::SetReceiveBuffer(int limit) {
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_RCVBUF, &limit,
sizeof(limit))) {
PrintError();
throw ZmqSocketError("Could not set ZMQ_RCVBUF");
}
if (GetReceiveBuffer() != limit) {
throw ZmqSocketError("Could not set ZMQ_RCVBUF to " +
std::to_string(limit));
}
}
void ZmqSocket::Rebind() { // the purpose is to apply HWL changes, which are
// frozen at bind, which is in the constructor.
// unbbind
if (zmq_unbind(sockfd.socketDescriptor, sockfd.serverAddress.c_str())) {
PrintError();
throw ZmqSocketError("Could not unbind socket");
}
// bind address
if (zmq_bind(sockfd.socketDescriptor, sockfd.serverAddress.c_str())) {
PrintError();
throw ZmqSocketError("Could not bind socket");
} }
} }

View File

@ -2,6 +2,7 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#include "sls/file_utils.h" #include "sls/file_utils.h"
#include "sls/ToString.h" #include "sls/ToString.h"
#include "sls/container_utils.h"
#include "sls/logger.h" #include "sls/logger.h"
#include "sls/sls_detector_exceptions.h" #include "sls/sls_detector_exceptions.h"
@ -165,6 +166,63 @@ ssize_t getFileSize(FILE *fd, const std::string &prependErrorString) {
return fileSize; return fileSize;
} }
std::vector<int>
getChannelsFromStringList(const std::vector<std::string> list) {
std::vector<int> channels;
for (auto line : list) {
// replace comma with space
std::replace_if(
begin(line), end(line), [](char c) { return (c == ','); }, ' ');
// split line (delim space)
std::vector<std::string> vec = split(line, ' ');
// for every channel separated by space
for (auto it : vec) {
// find range and replace with sequence of x to y
auto result = it.find(':');
if (result != std::string::npos) {
try {
int istart = StringTo<int>(it.substr(0, result));
int istop = StringTo<int>(
it.substr(result + 1, it.length() - result - 1));
LOG(logDEBUG1) << "istart:" << istart << " istop:" << istop;
std::vector<int> range(istop - istart);
std::generate(range.begin(), range.end(),
[n = istart]() mutable { return n++; });
for (auto range_it : range) {
channels.push_back(range_it);
}
} catch (std::exception &e) {
throw RuntimeError(
"Could not load channels. Invalid channel range: " +
it);
}
}
// else convert to int
else {
int ival = 0;
try {
ival = StringTo<int>(it);
} catch (std::exception &e) {
throw RuntimeError(
"Could not load channels. Invalid channel number: " +
it);
}
channels.push_back(ival);
}
}
}
if (removeDuplicates(channels)) {
LOG(logWARNING) << "Removed duplicates from channel file";
}
LOG(logDEBUG1) << "list:" << ToString(channels);
return channels;
}
std::vector<int> getChannelsFromFile(const std::string &fname) { std::vector<int> getChannelsFromFile(const std::string &fname) {
// read bad channels file // read bad channels file
std::ifstream input_file(fname); std::ifstream input_file(fname);
@ -172,73 +230,19 @@ std::vector<int> getChannelsFromFile(const std::string &fname) {
throw RuntimeError("Could not open bad channels file " + fname + throw RuntimeError("Could not open bad channels file " + fname +
" for reading"); " for reading");
} }
std::vector<int> list; std::vector<std::string> lines;
for (std::string line; std::getline(input_file, line);) { for (std::string line; std::getline(input_file, line);) {
// ignore comments // ignore comments
if (line.find('#') != std::string::npos) { if (line.find('#') != std::string::npos) {
line.erase(line.find('#')); line.erase(line.find('#'));
} }
// ignore empty lines
// replace comma with space if (line.empty()) {
std::replace_if( continue;
begin(line), end(line), [](char c) { return (c == ','); }, ' ');
// replace x:y with a sequence of x to y
auto result = line.find(':');
while (result != std::string::npos) {
auto start = line.rfind(' ', result);
if (start == std::string::npos) {
start = 0;
} else
++start;
int istart = StringTo<int>(line.substr(start, result - start));
auto stop = line.find(' ', result);
if (stop == std::string::npos) {
stop = line.length();
}
int istop =
StringTo<int>(line.substr(result + 1, stop - result - 1));
std::vector<int> v(istop - istart);
std::generate(v.begin(), v.end(),
[n = istart]() mutable { return n++; });
line.replace(start, stop - start, ToString(v));
LOG(logDEBUG1) << line;
result = line.find(':');
}
// remove punctuations including [ and ]
line.erase(std::remove_if(begin(line), end(line), ispunct), end(line));
LOG(logDEBUG) << "\nline: [" << line << ']';
// split line (delim space) and push to list
std::vector<std::string> vec = split(line, ' ');
for (auto it : vec) {
int ival = 0;
try {
ival = StringTo<int>(it);
} catch (std::exception &e) {
throw RuntimeError("Could not load channels from file. Invalid "
"channel number: " +
it);
}
list.push_back(ival);
} }
lines.push_back(line);
} }
return getChannelsFromStringList(lines);
// remove duplicates from list
auto listSize = list.size();
std::sort(list.begin(), list.end());
list.erase(unique(list.begin(), list.end()), list.end());
if (list.size() != listSize) {
LOG(logWARNING) << "Removed duplicates from channel file";
}
LOG(logDEBUG1) << "list:" << ToString(list);
return list;
} }
std::string getAbsolutePathFromCurrentProcess(const std::string &fname) { std::string getAbsolutePathFromCurrentProcess(const std::string &fname) {

Some files were not shown because too many files have changed in this diff Show More