Compare commits

...

131 Commits

Author SHA1 Message Date
27b2a607c8 binaries in 2020-08-10 12:05:37 +02:00
8e2bd17704 updated client script 2020-08-10 12:04:31 +02:00
0e011a77b5 array init fix for old gcc 2020-08-10 10:35:26 +02:00
d56b2134ef updated client versions 2020-08-10 09:58:57 +02:00
8af1183220 house keeping 2020-08-06 16:50:29 +02:00
78fdf5b60a removed casts 2020-08-06 12:33:43 +02:00
132043a70d static_assert enum size 2020-08-06 11:50:35 +02:00
b51290d0fe avoid conversions 2020-08-05 16:49:23 +02:00
0369413201 rename fix 2020-08-05 15:22:47 +02:00
04d6644753 Merge pull request #128 from slsdetectorgroup/rxrchrono
rxr chrono
2020-08-05 13:58:08 +02:00
949c6a81ce vector to array 2020-08-05 13:54:56 +02:00
aa0c36713c Utility function to get a vector of set bits
Template function to return a vector with the positions of all set bits in a variable.
2020-08-05 13:42:57 +02:00
4aee113dda temp fix 2020-08-05 13:27:19 +02:00
6c3f0d18ec rxr:removed delte and initialize memebers 2020-08-05 13:23:45 +02:00
7b6f4d0b5b rxr chrono 2020-08-05 12:07:45 +02:00
6db5954d21 Merge pull request #127 from slsdetectorgroup/configuremac
Configuremac
2020-08-05 10:22:20 +02:00
69d9680034 mior 2020-08-05 10:17:47 +02:00
bbf8ab4b88 binary in 2020-08-05 09:49:13 +02:00
79f010a438 renamed is_configurable to is_udp_configured 2020-08-05 09:37:58 +02:00
ab05da4d0e clean up 2020-08-05 09:13:53 +02:00
6e67ff9f90 tests 2020-08-04 17:54:40 +02:00
321ed13659 merge from developer 2020-08-04 17:43:38 +02:00
de39310a9c Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into developer 2020-08-04 17:40:27 +02:00
e1de2f72ba partial clean2 2020-08-04 17:40:17 +02:00
f6172f9b9e binary in 2020-08-04 17:36:49 +02:00
5616d4aeeb m3: deserializers reg also have to updated when changing dr, #counters 2020-08-04 17:32:34 +02:00
857aa47ee7 partial clean 2020-08-04 17:00:20 +02:00
bb3951c201 binaries in 2020-08-04 16:57:06 +02:00
380b062216 configure mac 2020-08-04 16:55:31 +02:00
a70d4e1e5d Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into developer 2020-08-04 15:38:45 +02:00
3301a80d99 send string 2020-08-04 15:38:38 +02:00
ce25b3018c Merge pull request #126 from slsdetectorgroup/m3
M3
2020-08-04 15:21:30 +02:00
d25f9093d5 binary in 2020-08-04 12:02:37 +02:00
d24edd52e1 m3: optimizing 1g and 10g digitizing by setting number of packets depending on 10/1g, dr and #counters 2020-08-04 12:01:28 +02:00
7b1ede32b1 m3: optimizing 1g and 10g digitizing by setting number of packets depending on 10/1g, dr and #counters 2020-08-04 11:58:20 +02:00
4174d193b4 removed exec_command from ClientInterface 2020-08-04 10:50:57 +02:00
0514f00552 m3: update deserializers except for deserializer reg 2020-08-03 17:23:04 +02:00
8631f5e2b0 m3: counter mask in master file 2020-08-03 16:39:31 +02:00
540a203139 Merge pull request #125 from slsdetectorgroup/eiger
Eiger
2020-08-03 15:04:25 +02:00
57c3cb0849 class to struct: review 2020-08-03 14:48:27 +02:00
e82bcafb76 moved class to struct masterattributes 2020-08-03 14:36:35 +02:00
3cdf98b230 Merge branch 'eiger' of github.com:slsdetectorgroup/slsDetectorPackage into eiger 2020-08-03 14:29:23 +02:00
acc43842eb code reviewe 2020-08-03 14:29:16 +02:00
63a5b4d61f send vector for ratecorr 2020-08-03 13:05:36 +02:00
3083260b28 changed clkdiv to speed in python 2020-08-03 11:13:47 +02:00
6e4b7f5bd7 fixed space in python enums 2020-08-03 11:10:01 +02:00
ddd562f8b5 fix 2020-08-03 10:27:06 +02:00
e2f1fd076a rate correction updated in rxr also when chanign exptime, subexptime, default rate correction 2020-08-03 10:07:00 +02:00
6a084e99b4 eiger manual for 5.0 2020-07-31 21:03:22 +02:00
885b22eca8 ratecorrectiosn addded to master file 2020-07-31 18:38:27 +02:00
bea4ba131a eiger rxr added threshold to master file 2020-07-31 17:45:33 +02:00
09fa8a3ba5 timing mode into receiver master file 2020-07-31 17:37:04 +02:00
874092a9d0 gui sub frame index now shows 2020-07-31 17:26:53 +02:00
5c4d355d57 minor 2020-07-31 17:18:15 +02:00
4702a76235 Merge branch 'developer' into eiger 2020-07-31 17:15:07 +02:00
fd503e84af m3: gui: when counters change, the npixelsx also changes 2020-07-31 16:50:17 +02:00
1211d02428 hdf5 dependant master attributes 2020-07-31 16:19:34 +02:00
ec27d35d6d refactor 2020-07-31 14:09:21 +02:00
ea2e7839d0 binary master attributes done, hdf5 WIP 2020-07-31 13:59:06 +02:00
d5b893e452 readErrorMessage 2020-07-31 13:32:53 +02:00
68c0f76bd9 created detector dependant master file attributes 2020-07-31 12:15:38 +02:00
4eaa9588ba created detector dependant master file attributes 2020-07-31 12:15:28 +02:00
459a715b9c minor 2020-07-31 12:15:02 +02:00
40d0430f2e get type from detector 2020-07-31 12:02:12 +02:00
0cb38a9c51 simplified sending 2020-07-31 11:51:06 +02:00
caef8c111c added overload to send vector 2020-07-31 11:05:39 +02:00
02d5cf14e4 removed extra decltype 2020-07-31 09:17:04 +02:00
bd221fefe5 Merge branch 'eiger' of github.com:slsdetectorgroup/slsDetectorPackage into eiger 2020-07-31 08:51:04 +02:00
c683f62452 Merge branch 'developer' into eiger 2020-07-31 08:50:51 +02:00
1177e54602 Remove VLAs (#124)
Removing the use of VLAs in the client and receiver side code. In addition cleaning up sending jsonheader
2020-07-30 18:22:39 +02:00
85c958facf WIP det dependant master file attribtes 2020-07-30 18:05:47 +02:00
87c33c8e81 gotthard2: bug fix: reversed list, but gain indices not reversed 2020-07-30 15:39:26 +02:00
7492f7dbfa m3: numpackets to 2 or 20 depending on ten giga enable (#123) 2020-07-30 15:02:33 +02:00
c2b586a333 eiger: virtual server more print minor 2020-07-30 14:07:02 +02:00
d31839e80e roi constructor added 2020-07-30 14:04:50 +02:00
b47f751d66 Merge branch 'm3' into eiger 2020-07-30 12:04:34 +02:00
aa52028690 Merge branch 'developer' into m3 2020-07-30 12:04:14 +02:00
6f5635a402 gotthard2: vetoref taken as decimal and not hex in server 2020-07-30 12:03:36 +02:00
5b9c7c4105 python vhighvoltage to highvoltage 2020-07-30 11:52:22 +02:00
98ffe350f3 changing command from vhighvoltage to highvoltage 2020-07-30 11:50:56 +02:00
7dfeb987db changing command from vhighvoltage to highvoltage 2020-07-30 11:50:03 +02:00
7899c5faef Merge branch 'm3' into eiger 2020-07-30 11:31:55 +02:00
17fb497774 Merge branch 'developer' into m3 2020-07-30 11:20:57 +02:00
e9c03c6eaf Merge pull request #122 from slsdetectorgroup/g2
G2
2020-07-30 11:18:56 +02:00
f497177022 fixes fro review 2020-07-30 11:18:40 +02:00
984b43545e Merge branch 'm3' into eiger 2020-07-29 17:26:20 +02:00
327218cb2b Merge branch 'g2' into m3 2020-07-29 17:26:04 +02:00
cdfd3934ee Merge branch 'developer' into g2 2020-07-29 17:25:45 +02:00
4cebefbc55 Merge branch 'm3' into eiger 2020-07-29 17:21:14 +02:00
24c4cd8d84 Merge branch 'g2' into m3 2020-07-29 17:15:37 +02:00
f358492e09 all binaries in 2020-07-29 16:53:21 +02:00
86d3fc7e55 fixes from review, moving from array to vector to avoid VLA 2020-07-29 16:52:22 +02:00
89da671ae2 m3: numpackets to 2 or 20 depending on ten giga enable 2020-07-29 15:10:54 +02:00
24e44d56fe Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into developer 2020-07-29 15:02:22 +02:00
b13d04dd89 eiger manual in 5.x 2020-07-29 15:02:11 +02:00
d19530b3d4 Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into developer 2020-07-29 14:39:44 +02:00
5ba3a414d6 Warn on the use of VLAs 2020-07-29 14:39:34 +02:00
54ad92a2bf binarires in 2020-07-29 13:26:55 +02:00
74a7ca9b71 gotthard2: vetophoton now has gain thresholds for each row and the get writes to file gain indices and adu for each channel, adus written in dec instead of hex, veto file in server removed and uses vetophoton instead 2020-07-29 13:24:42 +02:00
6846939f92 eiger rxr: space between subperiod(ns) in master file 2020-07-29 09:56:03 +02:00
99ec7f0046 eiger: always change speed when changing dr 2020-07-28 17:06:46 +02:00
df3ae7f409 gotthard2: reversing order of adc channels to chip 2020-07-28 15:08:13 +02:00
410f38c804 jungfrau calibrated settings in 2020-07-28 09:26:20 +02:00
91652df5b1 minor 2020-07-28 08:41:45 +02:00
02bda7c533 using GET_FLAG directly 2020-07-27 16:55:26 +02:00
9204a56ff7 Merge pull request #121 from slsdetectorgroup/checkargs
Check args for sending to detector/receiver
2020-07-27 15:49:19 +02:00
3ec637601d Merge branch 'developer' into checkargs 2020-07-27 15:49:08 +02:00
dc33f1a5da const 2020-07-27 09:14:58 +02:00
879b2c8864 clean getThresholdTemp 2020-07-27 08:58:33 +02:00
b1a4723028 WIP 2020-07-27 08:53:10 +02:00
bad7fd3906 Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into developer 2020-07-24 15:48:44 +02:00
21c8b77e2c fixed tests 2020-07-24 15:45:21 +02:00
097acf8086 renamed function to checkArgs 2020-07-24 14:26:58 +02:00
799f540d71 Update change_request.md 2020-07-24 11:32:51 +02:00
a412b465c6 Create change_request.md 2020-07-24 11:32:09 +02:00
bb2f70beb5 Update feature_request.md 2020-07-24 11:27:01 +02:00
096e94562a Update bug_report.md 2020-07-24 11:25:54 +02:00
9063a8d4ed Update feature_request.md 2020-07-24 11:25:02 +02:00
b1d3cbb25e Create feature_request.md 2020-07-24 11:23:50 +02:00
1fefc001f9 added const methods for detector 2020-07-24 11:17:45 +02:00
e8556abbe7 WIP 2020-07-24 10:57:54 +02:00
f8da057735 Update bug_report.md 2020-07-24 10:57:00 +02:00
df0b52604f Update bug_report.md 2020-07-24 10:55:39 +02:00
f792d59682 Update bug_report.md 2020-07-24 10:55:05 +02:00
98d061a032 Create bug_report.md 2020-07-24 10:51:43 +02:00
2bb9629f14 Create config.yml 2020-07-24 10:50:32 +02:00
cf2e1c1dfc Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into developer 2020-07-24 07:57:20 +02:00
cb54bf6225 docs 2020-07-24 07:57:12 +02:00
3b0f68c3c4 gotthard2: fix of ext burst mode global settings 2020-07-23 17:05:43 +02:00
5faf3c7336 format 2020-07-23 14:01:59 +02:00
3ddb264875 minor 2020-07-23 14:01:13 +02:00
101 changed files with 3170 additions and 2704 deletions

60
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,60 @@
---
name: Bug Report
about: Create a report to help us improve
title: New Bug Report
labels: action - Bug, priority - Unclassified, status - Pending
template: bug_report.md
---
<!-- Check an option by - [x], Uncheck an option by - [ ] -->
<!-- Please preview to see your option has been selected -->
<!-- Please fill out everything with an *, as this report will be discarded otherwise -->
##### *Distribution:
- [x] RHEL7
- [ ] RHEL6
- [ ] Fedora
- [ ] Other
##### *Detector type:
- [x] Not applicable
- [ ] Eiger
- [ ] Jungfrau
- [ ] Mythen3
- [ ] Gotthard2
- [ ] Gotthard
- [ ] Moench
- [ ] ChipTestBoard
##### *Software Package Version:
- [ ] developer
- [ ] 4.2.0
- [ ] 4.1.1
<!-- If others, please describe -->
##### Priority:
- [ ] Super Low
- [ ] Low
- [ ] Medium
- [ ] High
- [ ] Super High
##### *Describe the bug
<!-- A clear and concise description of what the bug is -->
##### Expected behavior
<!-- A clear and concise description of what you expected to happen. -->
##### To Reproduce
<!-- Steps to reproduce the behavior: -->
<!-- 1. Go to '...' -->
<!-- 2. Click on '....' -->
<!-- 3. Scroll down to '....' -->
<!-- 4. See error -->
##### Screenshots
<!-- If applicable, add screenshots to help explain your problem. -->
##### Additional context
<!-- Add any other context about the problem here. -->

View File

@ -0,0 +1,44 @@
---
name: Change Request
about: Suggest a change to an existing feature
title: New Change Request
labels: action - Change, priority - Unclassified, status - Pending
template: change_request.md
---
<!-- Check an option by - [x], Uncheck an option by - [ ] -->
<!-- Please preview to see your option has been selected -->
<!-- Please fill out everything with an *, as this report will be discarded otherwise -->
##### *Detector type:
- [x] Not applicable
- [ ] Eiger
- [ ] Jungfrau
- [ ] Mythen3
- [ ] Gotthard2
- [ ] Gotthard
- [ ] Moench
- [ ] ChipTestBoard
##### *Software Package Version:
- [ ] developer
- [ ] 4.2.0
- [ ] 4.1.1
<!-- If others, please describe -->
##### Priority:
- [ ] Super Low
- [ ] Low
- [ ] Medium
- [ ] High
- [ ] Super High
##### *State the change request:
<!-- A clear and concise description of what the change is to an existing feature -->
##### Is your change request related to a problem. Please describe:
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
##### Additional context:
<!-- Add any other context about the feature here -->

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -0,0 +1,50 @@
---
name: Feature Request
about: Suggest a feature
title: New Feature Request
labels: action - Enhancement, priority - Unclassified, status - Pending
template: feature_request.md
---
<!-- Check an option by - [x], Uncheck an option by - [ ] -->
<!-- Please preview to see your option has been selected -->
<!-- Please fill out everything with an *, as this report will be discarded otherwise -->
##### *Detector type:
- [x] Not applicable
- [ ] Eiger
- [ ] Jungfrau
- [ ] Mythen3
- [ ] Gotthard2
- [ ] Gotthard
- [ ] Moench
- [ ] ChipTestBoard
##### *Software Package Version:
- [ ] developer
- [ ] 4.2.0
- [ ] 4.1.1
<!-- If others, please describe -->
##### Priority:
- [ ] Super Low
- [ ] Low
- [ ] Medium
- [ ] High
- [ ] Super High
##### *State the feature:
<!-- A clear and concise description of what the feature is -->
##### Is your feature request related to a problem. Please describe:
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
##### Describe the solution you'd like:
<!-- A clear and concise description of what you want to happen -->
##### Describe alternatives you've considered:
<!-- A clear and concise description of any alternative solutions or features you've considered -->
##### Additional context:
<!-- Add any other context about the feature here -->

View File

@ -97,6 +97,7 @@ target_compile_options(slsProjectWarnings INTERFACE
-Wformat=2
-Wredundant-decls
# -Wconversion
-Wvla
-Wdouble-promotion
-Werror=return-type

View File

@ -42,7 +42,7 @@ The documentation that you are reading now is built with
* Doxygen (to extract C++ classes etc.)
* Breathe (Sphinx plugin to handle doxygen xml)
* Sphinx
* Sphinx with sphinx_rtd_theme
-----------------------
Packaged in libs/

View File

@ -1,9 +1,5 @@
Installation
==============================================
Build from source using CMake
---------------------------------
.. note ::
@ -13,17 +9,54 @@ Build from source using CMake
without being communicated. If absolute stability of the API is needed please
use one of the release versions.
.. warning ::
Before building from source make sure that you have the
:doc:`dependencies <../dependencies>` installed. If installing using conda, conda will
manage the dependencies.
Installation
==============================================
Build from source using CMake
---------------------------------
Note that on some systems, for example RH7, cmake v3+ is available under the cmake3 alias.
It is also required to clone with the option --recursive to get the git submodules used
in the package.
.. code-block:: bash
git clone https://github.com/slsdetectorgroup/slsDetectorPackage.git
git clone --recursive https://github.com/slsdetectorgroup/slsDetectorPackage.git
mkdir build && cd build
cmake ../slsDetectorPackage -DCMAKE_INSTALL_PREFIX=/your/install/path
make -j12
make -j12 #or whatever number of cores you are using to build
make install
The easiest way to configure options is to use the ccmake utility.
.. code-block:: bash
#from the build directory
ccmake .
Install binaries using conda
--------------------------------
Conda is not only useful to manage python environments but can also
be used as a user space package manager.
We have three different packages available:
* **slsdetlib**, shared libraries and command line utilities
* **slsdetgui**, GUI
* **slsdet**, Python bindings
.. code-block:: bash
#Add channels for dependencies and our library
@ -32,14 +65,19 @@ Install binaries using conda
conda config --set channel_priority strict
#cerate an environment with our library, then activate
conda create -n myenv slsdetlib=2020.03.18.dev2
codna activate myenv
conda create -n myenv slsdetlib=2020.07.23.dev0
conda activate myenv
#ready to use
sls_detector_get exptime
etc ...
.. code-block:: bash
#List available versions
conda search slsdet
Build from source on old distributions
-----------------------------------------
@ -66,4 +104,11 @@ is to use conda
.. code-block:: bash
conda create -n myenv python sphinx sphinx_rtd_theme
conda create -n myenv python sphinx sphinx_rtd_theme
Then enable the option SLS_BUILD_DOCS to create the targets
.. code-block:: bash
make docs # generate API docs and build Sphinx RST
make rst # rst only, saves time in case the API did not change

View File

@ -7,6 +7,52 @@ exposed to Python through pybind11.
.. py:currentmodule:: slsdet
.. autoclass:: runStatus
:members:
:undoc-members:
:show-inheritance:
.. autoclass:: detectorType
:undoc-members:
.. autoclass:: frameDiscardPolicy
:undoc-members:
.. autoclass:: fileFormat
:undoc-members:
.. autoclass:: dimension
:undoc-members:
.. autoclass:: externalSignalFlag
:undoc-members:
.. autoclass:: timingMode
:undoc-members:
.. autoclass:: dacIndex
:undoc-members:
.. autoclass:: detectorSettings
:undoc-members:
.. autoclass:: clockIndex
:undoc-members:
.. autoclass:: speedLevel
:undoc-members:
.. autoclass:: readoutMode
:undoc-members:
.. autoclass:: masterFlags
:undoc-members:
.. autoclass:: frameModeType
:undoc-members:
.. autoclass:: detectorModeType
:undoc-members:
.. autoclass:: burstMode
:undoc-members:
.. autoclass:: timingSourceType
:undoc-members:

View File

@ -1,6 +1,6 @@
Receiver
==============================================
.. doxygenclass:: slsReceiver
.. doxygenclass:: Receiver
:members:
.. :undoc-members:

View File

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

View File

@ -0,0 +1,129 @@
#Gain index ADU value (12 bit)
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655
1 3655

View File

@ -1,132 +1,129 @@
#G1 Energy #G2 Energy
300 7000
#G0 pedestal G1 pedestal G2 pedestal G0 gain G1 gain G2 gain (for every channel) ADU
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
100 100 100 10 1 0.1
#G0 pedestal G1 pedestal G2 pedestal G0 gain G1 gain G2 gain #G1 Energy #G2 Energy
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000
100 100 100 10 1 0.1 300 7000

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -99,7 +99,7 @@ If one desires to set the zmqport manually, he offset has to be taken into accou
{\tt{slsMultiReceiver}} uses two or more receivers in one single terminal: {\tt{./slsMultiReceiver startTCPPort numReceivers withCallback}}, where startTCPPort assumes the other ports are consecutively increased.
The command {\tt{r\_framesperfile}} sets the number of frames written in the same file. By default now it is 10000. It can be changes. It needs to be lowered particularly if one wants to parallelize the following conversion of the files.
The command {\tt{r\_framesperfile}} (\tt{\textcolor{red}{rx\_framesperfile}}) sets the number of frames written in the same file. By default now it is 10000. It can be changes. It needs to be lowered particularly if one wants to parallelize the following conversion of the files.
\subsection{Mandatory setup - Client}
@ -122,7 +122,23 @@ To do that:
sls_detector_put 0-config mydetector.config
\end{verbatim}
In the config file, if client, receiver and detector are using \textbf{1GbE} the following lines are mandatory (see slsDetectorsPackage/examples/eiger\_1Gb.config):
In the config file, if client, receiver and detector are using \textbf{1GbE} the following lines are mandatory (see slsDetectorsPackage/examples/eiger\_1Gb.config). It has been adapted to the the new 5.0 major release change:
\begin{verbatim}
detsize 1024 512 #detector geometry, long side of the module first
hostname beb059+beb058+ #1Gb detector hostname for controls
#1Gb receiver pc hostname to be inserted immediately and tcp\_ports to be stated immediately
rx_hostname x12sa-vcons:1991+pc1875:1992+
0:udp_dstport 50011 #udp port first quadrant, first halfmodule
0:udp_dstport2 50012 #udp port second quadrant, first halfmodule
1:udp_dstport 50013 #udp port first quadrant, second halfmodule
1:udp_dstport2 50014 #udp port second quadrant, second halfmodule
0:udp_srcip 129.129.202.237
0:udp_dstip auto
1:udp_srcip 129.129.202.236
1:udp_dstip auto
fpath /sls/X12SA/data/x12saop/Data10/Eiger0.5M
\end{verbatim}
In the old 3.x and 4.x release it was:
\begin{verbatim}
detsizechan 1024 512 #detector geometry, long side of the module first
hostname beb059+beb058+ #1Gb detector hostname for controls
@ -172,24 +188,25 @@ configuremac 0
rx_udpmac xx:xx:...
\end{verbatim}
Now we will give general communication commands. Commands with a diffent name in the \textcolor{red}{5.x} realease will be highlighted in \textcolor{red}{red}.
One can configure all the detector settings in a parameter file {\tt{setup.det}}, which is loaded by doing:
\begin{verbatim}
sls_detector_put 0-parameters setup.det
\end{verbatim}
Note that the parameter file for any realease before 4.1.1 has not the possibility to understand parameters to be set differently for different half modules, i.e. {\tt{0:txndelay\_left xxxxx},\tt{1:txndelay\_left yyyyy}}.
In the case of \E, the proper bias voltage of the sensor has to be setup, i.e. the {\tt{setup.det}} file needs to contain the line {\tt{vhighvoltage 150}}. Other detector functionality, which are rarely changed can be setup here.
In the case of \E, the proper bias voltage of the sensor has to be setup, i.e. the {\tt{setup.det}} file needs to contain the line {\tt{highvoltage 150}}. Other detector functionality, which are rarely changed can be setup here.
Other important settings that are configured in the {\tt{setup.det}} file are:
\begin{itemize}
\item {\tt{tengiga 0/1}}, which sets whether the detector is enabled to send data through the 1~or the 10~Gb Ethernet.
\item {\tt{flags parallel/nonparallel}}, which sets whether the detector is set in parallel acquisition and readout or in sequential mode. This changes the readout time of the chip and affects the frame rate capability (faster is {\tt{parallel}}, with higher noise but needed when the frame rate is $>2$~kHz.
\item {\tt{flags parallel/nonparallel}} or {\tt{\textcolor{red}{parallel 1/0}}}, which sets whether the detector is set in parallel acquisition and readout or in sequential mode. This changes the readout time of the chip and affects the frame rate capability (faster is {\tt{parallel}}).
\item {\tt{dr 32/16/8/4}} sets the detector in autosumming mode (32 bit counter or not autosumming, 12 bit out of the chip). This is strictly connected to what is required for the readout clock of chip. See next point.
\item {\tt{clkdivider 0/1/2}}. Changes the readout clock: 200, 100, 50~MHz (also referred to as full, half, quarter speed). Note that autosumming mode ({\tt{dr 32}} only works at {clkdivider 2}=quarter speed). By selecting Refer to readout timing specifications in~section\ref{timing} for how to set the detector.
\item {\tt{clkdivider 0/1/2}} or {\tt{\textcolor{red}{speed full\_speed/half\_speed/quart\_speed}}}. Changes the readout clock: 200, 100, 50~MHz (also referred to as full, half, quarter speed). Note that autosumming mode ({\tt{dr 32}} only works at \tt{clkdivider 2}=\tt{quart\_speed}). By selecting Refer to readout timing specifications in~section\ref{timing} for how to set the detector.
\item {\tt{flags continuous/storeinram}}. Allows to take frame continuously or storing them on memory. Users should use the {\tt{continuous}} flags. Enabling the {\tt{stroreinram}} flag makes the data to be sent out all at the end of the acquisition. Refer to readout timing specifications in section~\ref{timing} for how to set the detector. Examples will be given in section~\ref{}.
\end{itemize}
One should notice that, by default, by choosing the option {\tt{dr 32}}, then the software automatically sets the detector to {\tt{clkdivider 2}}. By choosing the option {\tt{dr 16}}, the software automatically sets the detector to {\tt{clkdivider 1}}. One needs to choose {\tt{clkdivider 0}} after setting the {\tt{dr 16}} option to have the fastest frame rate.
We would recommend expert users (beamline people) to write their parameters file for the users.
One should notice that, by default, by choosing the option {\tt{dr 32}}, then the software automatically sets the detector to {\tt{clkdivider 2}} ({\tt{\textcolor{red}{quart\_speed}}}). By choosing the option {\tt{dr 16}}, the software automatically sets the detector to {\tt{clkdivider 1}} ({\tt{\textcolor{red}{speed quart\_speed}}}). From release 5.x,
\section{API versioning} \label{api}
The eigerDetectorServer running on the boards has a versioning API scheme that will make it crash if used with a wrong firmware.
@ -210,10 +227,18 @@ Killing and starting the server on the boards allows you to check the firmware v
\section{Setting up the threshold}
\begin{verbatim}
sls_detector_put 0-settingsdir /path
sls_detector_put 0-trimen N xxxx yyyy zzzz
sls_detector_put 0-settings standard
sls_detector_put 0-threshold energy_in_eV standard
\end{verbatim}
or in \textcolor{red}{5.x}:
\begin{verbatim}
sls_detector_put 0-settingspath /path}
sls_detector_put 0-trimen N xxxx yyyy zzzz}
sls_detector_put 0-threshold energy_in_eV standard
\end{verbatim}
The first line requires to specify how many ({\tt{N}}) and at which energies in eV {\{tt{xxxx}}, {\tt{yyyy}}, {\tt{zzzz}} and so on) trimmed files were generated (to allow for an interpolation). This line should normally be included into the {\tt{mydetector.config}} file and should be set for you by one of the detector group.
NORMALLY, in this new calibration scheme, only {\tt{settings standard}} will be provided to you, unless specific cases to be discussed.
The threshold at 6000 eV , for example would be set as:{\tt{sls\_detector\_put 0-threshold 6000 standard}}.
@ -267,12 +292,13 @@ sls_detector_get receiver
There is a more complex way of performing an acquisition, that is useful for debugging and in case one wants a non blocking behavior:
You can then reset to zero the number of frames caught, then start the receiver and the detector:
You can then reset to zero the number of frames caught (in releases<5.0), then start the receiver and the detector:
\begin{enumerate}
\item {\tt{sls\_detector\_put 0-resetframescaught 0}}
\item {\tt{sls\_detector\_put 0-receiver start}}
\item {\tt{sls\_detector\_put 0-status start}}
\end{enumerate}
In release \textcolor{red}{5.0} it is not needed to reset the frames caughts.
You can poll the detector status using:
\begin{verbatim}
@ -347,8 +373,11 @@ col : 257 pixels
\end{verbatim}
\section{Readout timing- maximum frame rate}\label{timing}
IMPORTANT: to have faster readout and smaller dead time, one can configure {\tt{clkdivider}}, i.e. the speed at which the data are read, i.e. 200/100/50~MHz for {\tt{clkdivider 0/1/2}} and the dead time between frames through {\tt{flags parallel}}, i.e. acquire and read at the same time or acquire and then read out.
The configuration of this timing variables allows to achieve different frame rates. NOTE THAT IN EIGER, WHATEVER YOU DO, THE FRAME RATE LIMITATIONS COME FROM THE NETWORK BOTTLENECK AS THE HARDWARE GOES FASTER THAN THE DATA OUT.
IMPORTANT: to have faster readout and smaller dead time, one can configure {\tt{clkdivider}}, i.e. the {\tt{textcolor}{red}{speed} at which the data are read, i.e. 200/100/50~MHz for {\tt{clkdivider 0/1/2}} ({\tt{
\textcolor{red}{speed full\_speed/half\_speed/quart\_speed}}) and the dead time between frames through {\tt{flags parallel}} or {\tt{\textcolor{red}{parallel 1}}}, i.e. acquire and read at the same time or acquire and then read out.
The configuration of this timing variables allows to achieve different frame rates. NOTE THAT IN EIGER, WHATEVER YOU DO, THE FRAME RATE LIMITATIONS COME FROM THE NETWORK BOTTLENECK AS THE HARDWARE GOES FASTER THAN THE DATA OUT. WE recconmmend using the detector in \tt{dr 4/8/16}, \tt{\textcolor{red}{speed full\_speed}}, \tt{parallel 1} or \tt{dr 32}, \tt{\textcolor{red}{speed quart\_speed}}, \tt{parallel 1. All those options are now the defaults options starting from version 5.x.
In the case of REAL CONTINUOUS readout, i.e. continuous acquire and readout from the boards (independent on how the chip is set), the continuous frame rates are listed in table~\ref{tcont}. The time to send out the frame out of the board
\begin{table}
@ -384,11 +413,11 @@ dynamic range & images\\
16 & 7600\\
\hline
\end{tabular}
\caption{Amount of images that can be stored on board. As while we store them, we start to send them out, the effective number of images could be larger than this, but it will depend on the network setup (how fats you stream out images).}
\caption{Amount of images that can be stored on board. As while we store them, we start to send them out, the effective number of images could be larger than this, but it will depend on the network setup (how fast you stream out images).}
\label{timgs}
\end{table}
The maximum frame rate achievable with 10~GbE, {\tt{dr 16}}, {\tt{flags continuous}}, {\tt{flags parallel}},{\tt{clkdivider 0}}, \textbf{6.1~kHz}. This is currently limited by the connection between the Front End Board and the Backend board. We expect the 32 bit mode limit, internally, to be \textbf{2~kHz} ({\tt{clkdivider 2}}).
The maximum frame rate achievable with 10~GbE, {\tt{dr 16}}, {\tt{flags continuous}}, {\tt{flags parallel}} ({\tt{\textcolor{red}{parallel 1}}}),{\tt{clkdivider 0}} ({\tt{\textcolor{red}{speed full\_speed}}}), \textbf{6.1~kHz}. This is currently limited by the connection between the Front End Board and the Backend board. We expect the 32 bit mode limit, internally, to be \textbf{2~kHz} ({\tt{clkdivider 2}}).
In dynamic range {\tt{dr 8}} the frame rate is \textbf{11~kHz} and for{\tt{dr 4}} is \textbf{22~kHz}. For 4 and 8 bit mode the frame rate are directly limited by the speed of the detector chip and not by the readout boards.
\subsection{Minimum time between frames and Maximum frame rate}
@ -459,6 +488,23 @@ where the 'minimum time between frames' and the minimum period will be discussed
\textbf{From software version 4.0.0, there is a very useful function {\tt{sls\_detector\_get measuredperiod}} which return the measured period AFTER the acquisition. This is important to check that the settings to obtain the targeted frame rate was correct.}
In release \textcolor{red}{5.0} in 4-bit modes one can set a sort of ROI in the detector such to read half of the module (the central part) or a quarter of it with almost double or four times the frame rate. By default the \tt{\textcolor{red}{readnlines}} is set to \tt{256} meaning the whole chip. With \tt{\textcolor{red}{readnlines 128}} or \tt{\textcolor{red}{readnlines 64}} one sets to read half/quarter rows from the chip. In table~\ref{table:hfrpartial} the maximum frame rates, exposure time and period for the partial readout.\\
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline
readnlines & \# pixels & Active area (cm$^2$) & Max frame rate (kHz) & Period ($\mu$s) & Dead time ($\mu$s) & \# buffered images\\
\hline
256 &1024 $\times$ 512 & 8 $\times$ 3.8 & 22.7 & 44.0 &4.1 & 30k\\
\hline
128 &1024 $\times$ 256 & 8 $\times$ 1.9 & 42.1 & 23.7 &4.2 & 60k\\
\hline
64 & 1024 $\times$ 128 & 8 $\times$ 0.95 & 73.5 & 13.6 &4.2 & 120k\\
\hline
\end{tabular}
\label{table:hfrpartial}
\textbf{If you run too fast, the detector could become noisier (see problem shooting), it is important to match the detector settings to your frame rate. This can be done having more parameters files and load the one suitable with your experiment.} We experienced that with low energy settings could not reach 6~kHz and no noise.
In 16 bit mode, it could make sense, in case of noise and low threshold to either reduce the frame rate:
\begin{equation}
@ -579,10 +625,10 @@ The number of subframes composing a single 32bit acquisition can be calculated a
\end{equation}
This also means that {\tt{exptime}}$<${\tt{subexptime}} will be rounded to{\tt{subexptime}}. If you want shorter acquisitions, either reduce the {\tt{subexptime}} or switch two 16-bit mode (you can always sum offline if needed).
From release 4.0.0, an extra {\tt{flag overflow/nooverflow}} is added, with {\tt{nooverflow}} default:
From release 4.0.0, an extra {\tt{flag overflow/nooverflow}} is added (\tt{\textcolor{red}{overflow 0/1}}), with {\tt{nooverflow}} (\tt{\textcolor{red}{overflow 0}}) default:
\begin{itemize}
\item {\tt{nooverflow}}: the internal 12-bit result is summed, even if there was saturation of the 12-bit counter (4095) in any of the subframes. Note that if there is saturation for every subframe, you might get as a result a value of the counter equal to (4095$\times$~number~of~subframes), which you need to correctly identify. On the other hand if the saturation occurred only one time, you will get something "close'' to the real number.
\item {\tt{overflow}}: In this case, even if a pixel saturate only 1 time in a subframe, you will be returned as a value of the counter for that pixel: $2^{32}-1$, i.e. 4294967295.
\item {\tt{nooverflow}} (\tt{\textcolor{red}{overflow 0}}): the internal 12-bit result is summed, even if there was saturation of the 12-bit counter (4095) in any of the subframes. Note that if there is saturation for every subframe, you might get as a result a value of the counter equal to (4095$\times$~number~of~subframes), which you need to correctly identify. On the other hand if the saturation occurred only one time, you will get something "close'' to the real number.
\item {\tt{overflow}} (\tt{\textcolor{red}{overflow 1}})): In this case, even if a pixel saturate only 1 time in a subframe, you will be returned as a value of the counter for that pixel: $2^{32}-1$, i.e. 4294967295.
\end{itemize}
The UDP header will contain, after you receive the data, the effective number of subframe per image (see section~\ref{UDP}) as "SubFrame Num or Exp Time", i.e. the number of subframes recorded (32 bit eiger).
@ -610,17 +656,17 @@ The detector can be setup such to receive external triggers. Connect a LEMO sign
\begin{verbatim}
sls_detector_put 0-timing [auto/trigger/burst_trigger/gating]
sls_detector_put 0-frames x
sls_detector_put 0-cycles y
sls_detector_put 0-cycles y (\textcolor{red}{triggers})
sls_detector_acquire 0-
\end{verbatim}
No timeout is expected between the start of the acquisition and the arrival of the first trigger.
Here are the implemented options so far:
\begin{itemize}
\item {\tt{auto}} is the software controlled acquisition (does not use triggers), where {\tt{exptime}} and {\tt{period}} have to be set. Set number of cycles (i.e. triggers) to 1 using {\tt{cycles}}. Set number of frames using {\tt{frames}}.
\item {\tt{trigger}} 1 frame taken for 1 trigger. Your {\tt{frames}} needs to be 1 always, {\tt{cycles}} can be changed and defines how many triggers are considered. {\tt{exptime}} needs to be set. In the GUI this is called trigger exposure series.
\item {\tt{burst\_trigger}} gets only 1 trigger, but allows to take many frames. With {\tt{frames}} one can change the number of frames. {\tt{cycles}} needs to be 1. {\tt{exptime}} and {\tt{period}} have to be set. In the gui it is called trigger readout.
\item{\tt{gating}} allows to get a frame only when the trigger pulse is gating. Note that in this case the exp time and period only depend on the gating signal. {\tt{cycles}} allows to select how many gates to consider. Set number of frames to 1 using {\tt{frames}}. IMPORTANT: Up to firmware 23, the last subframe is oblige to finish being taken, despite the gate signal going down. This will be configurable from later fw and software version. Also, in gating mode, due to timimg of the state machine, you need to leave 500~$\mu$s deadtime between the end on an acquisition and the next. This is as the state machine is unable to check for changes in the status in the first 500~$\mu$s. ATTENTION: if you are in 16 bit mode and you are applying online rate corrections, as now the exptime is generated by the trigger, you might not have correct rate corrections. If you know what the exposure time is in the gating signal, then you can set the {\tt{exptime}} once and the rate corrections will be correct. In 32 bit mode, it does not matter as the rate corrections depends on the {\tt{subexptime}} which is software set independently from the gate exptime.
\item {\tt{auto}} is the software controlled acquisition (does not use triggers), where {\tt{exptime}} and {\tt{period}} have to be set. Set number of {\tt{cycles}} (\textcolor{red}{triggers}) to 1. Set number of frames using {\tt{frames}}.
\item {\tt{trigger}} 1 frame taken for 1 trigger. Your {\tt{frames}} needs to be 1 always, {\tt{cycles}} ({\tt{\textcolor{red}{triggers}}}) can be changed and defines how many triggers are considered. {\tt{exptime}} needs to be set. In the GUI this is called trigger exposure series.
\item {\tt{burst\_trigger}} gets only 1 trigger, but allows to take many frames. With {\tt{frames}} one can change the number of frames. {\tt{cycles}} ({\tt{\textcolor{red}{triggers}}}) needs to be 1. {\tt{exptime}} and {\tt{period}} have to be set. In the gui it is called trigger readout.
\item{\tt{gating}} allows to get a frame only when the trigger pulse is gating. Note that in this case the exp time and period only depend on the gating signal. {\tt{cycles}} (\tt{\textcolor{red}{triggers}}) allows to select how many gates to consider. Set number of frames to 1 using {\tt{frames}}. IMPORTANT: Up to firmware 23, the last subframe is oblige to finish being taken, despite the gate signal going down. This will be configurable from later fw and software version. Also, in gating mode, due to timimg of the state machine, you need to leave 500~$\mu$s deadtime between the end on an acquisition and the next. This is as the state machine is unable to check for changes in the status in the first 500~$\mu$s. ATTENTION: if you are in 16 bit mode and you are applying online rate corrections, as now the exptime is generated by the trigger, you might not have correct rate corrections. If you know what the exposure time is in the gating signal, then you can set the {\tt{exptime}} once and the rate corrections will be correct. In 32 bit mode, it does not matter as the rate corrections depends on the {\tt{subexptime}} which is software set independently from the gate exptime.
ATTENTION: From release 4.1.1 with the {\tt{trigger}} option it is possible to have software triggers as a debugging tool (instead of the hardware trigger signal. One should start the acquisition (with the blocking {\tt{sls\_detector\_acquire}} if wanted and with another client one can send the softare trigger {\tt{sls\_detector\_put status trigger}}. This option allows for example to perform a motor scan (moving a motor in between single images) and still writing all images to the same file.
When using 32-bit mode, by default the acquisition ends the last complete subframe that was started when still the acquisition time was valid. This has been chosen as many people wants to know the exact acquisition time for when the detector was taking data and also, if {\tt{ratecorr}} are active, the last subframe will be correctly corrected, while otherwise it will be corrected with a wrong subdeadtime.
@ -630,13 +676,13 @@ However, from 4.1.0, in gating mode, an option to immediately terminate the subf
Hardware-wise, the ENABLE OUT signal outputs when the chips are really acquiring. This means that the single subframes will be output in 32 bit mode. The TRIGGER OUT outputs the sum-up-signal at the moment (which is useless). This will be changed in the future to output the envelop of the enable signal.
We are planning to change some functionality, i.e. unify the {\tt{trigger}} and {\tt{burst\_trigger}} trigger modes and make both {\tt{frames}} and {\tt{cycles}} configurable at the same time.
We are planning to change some functionality, i.e. unify the {\tt{trigger}} and {\tt{burst\_trigger}} trigger modes and make both {\tt{frames}} and {\tt{cycles}} (\tt{\textcolor{red}{triggers}}) configurable at the same time.
There is the possibility to use {\tt{timing trigger/burst\_trigger}} and send software single commands to fake the trigger. This is done with:
\begin{verbatim}
sls_detector_put 0-timing [trigger/burst_trigger]
sls_detector_put 0-frames x
sls_detector_put 0-cycles y
sls_detector_put 0-cycles y (\textcolor{red}{triggers})
sls_detector_status trigger
\end{verbatim}
Note that this functionality is very (!) useful if you need to do something between and acquisition and the next. This can be used to do a fast threshold scan for example. See section~\ref{sec:fastthresholdscan}.
@ -716,8 +762,8 @@ If \textbf{dr} is 32 and \textbf{clkdivider} is not 2, whatever the detector get
Here is a list of parameters that should be reset:
\begin{enumerate}
\item \textbf{resetframescaught} should be reset to zero after every acquisition taken with {\tt{receiver start}},{\tt{status start}},{\tt{receiver stop}}. If the acquisition is taken with {\tt{sls\_detector\_acquire}}, there is no need to reset this.
\item After changing the {\tt{timing}} mode of the detector, one should reset to '1' the unused value, in that specific timing mode, between \textbf{frames} and \textbf{cycles}. See section~\ref{triggering} for how to use the timing. At the present moment the detector will acquire more frames than planned if the variable not used between \textbf{frames} and \textbf{cycles} is not reset. In future releases, the unused variable will be ignored. Still resetting is a good practice.
\item \textbf{resetframescaught} (only for releases < 5.x) should be reset to zero after every acquisition taken with {\tt{receiver start}},{\tt{status start}},{\tt{receiver stop}}. If the acquisition is taken with {\tt{sls\_detector\_acquire}}, there is no need to reset this.
\item After changing the {\tt{timing}} mode of the detector, one should reset to '1' the unused value, in that specific timing mode, between \textbf{frames} and \textbf{cycles} (\tt{\textcolor{red}{triggers}}). See section~\ref{triggering} for how to use the timing. At the present moment the detector will acquire more frames than planned if the variable not used between \textbf{frames} and \textbf{cycles} (\tt{\textcolor{red}{trigger}}) is not reset. In future releases, the unused variable will be ignored. Still resetting is a good practice.
\end{enumerate}
@ -1128,10 +1174,10 @@ In 500k--2M pixel systems there is a hardware temperature safety switch, which w
The HV can also be set and read through the software:
\begin{verbatim}
./sls_detector_put vhighvoltage 150
./sls_detector_get vhighvoltage
./sls_detector_put highvoltage 150
./sls_detector_get highvoltage
\end{verbatim}
Note that the get {\tt{vhighvoltage}} would return the measured HV from the master module only. If getting the vhighvoltage for individual halfmodules, only the master will have a value different from -999.
Note that the get {\tt{highvoltage}} would return the measured HV from the master module only. If getting the highvoltage for individual halfmodules, only the master will have a value different from -999.
\appendix
@ -1213,13 +1259,21 @@ do the same for the other boards. You can program in parallel many boards, but y
There are two ways to pulse the detector:
\begin{itemize}
\item \textbf{Pulse digitally:} when you are interested to the output readout and do not care about the analog response from the pixels:
\begin{verbatim}
\begin{verbatim}
sls_detector_put vthreshold 4000
sls_detector_put vtr 4000
sls_detector_put pulsechip N #to pulse N
sls_detector_put pulsechip -1 #to get out of testing mode
\end{verbatim}
Note that the answer will be $2 \cdot \textrm{{\tt{N}}} +2$ in this case.
Or in \textcolor{red}{5.x}:
\begin{verbatim}
sls_detector_put vthreshold 4000
sls_detector_put vtrim 4000
sls_detector_put pulsechip N #to pulse N
sls_detector_put pulsechip -1 #to get out of testing mode
\end{verbatim}
Note that the answer will be $2 \cdot \textrm{{\tt{N}}} +4$ in this case.
\item \textbf{Pulse analogically:} You want to really check the analogical part of the detector, not just the readout.
@ -1238,8 +1292,25 @@ sls_detector_put resmat 0
sls_detector_acquire
\end{verbatim}
You read {\tt{N}} in every pixel if you are setup correctly.
or in realese \textcolor{red}{5.x}:
\begin{verbatim}
sls_detector_put vcal 3600
sls_detector_put vthreshold 1700
sls_detector_put vrpreamp 3100
for i in $(seq 0 7) ;
do px=$((-255+i));
sls_detector_put pulse 0 $px 0;
for j in $(seq 0 255) ; do
sls_detector_put pulsenmove 100 0 1;
done;
done;
sls_detector_put partialreset 1
\end{verbatim}
\end{itemize}
\section{Load a noise pattern with shape}
For debug purposes, we have created a noise pattern with a shape. If you reconstruct correctly your image, you should be able to read ".EIGER'' in the same direction for both the top and bottom in normal human readable orientation.
To load the special noise file look at {\tt{settingsdir/eiger/standard/eigernoise.sn0xx}} in the package.
@ -1265,7 +1336,7 @@ We have also been requested if we could speed up the threshold scan. At the mome
./sls_detector_put enablefwrite 0
./sls_detector_put resetframescaught 0
./sls_detector_put index 0
./sls_detector_put cycles 21
./sls_detector_put cycles 21 (\textcolor{red}{triggers})
./sls_detector_put receiver start
./sls_detector_put status start
for i in $(seq 0 20);
@ -1383,7 +1454,7 @@ Environment variable SLSDETNAME can be set for using 2 different detectors from
\subsection{Measure the HV}
For every system:
\begin{itemize}
\item Software-wise measure it (now the software returns the measured value), with {\tt{sls\_detector\_get vhighvoltage}}. The returned value is the HV (for proper Eiger setting is approximately 150~V) if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:vhighvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
\item Software-wise measure it (now the software returns the measured value), with {\tt{sls\_detector\_get highvoltage}}. The returned value is the HV (for proper Eiger setting is approximately 150~V) if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:highvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
\item Hardware-wise (opening the detector) measure value of HV on C14 on the power distribution board. Check also that the small HV connector cable is really connected.
\end{itemize}
@ -1434,7 +1505,7 @@ Scroll up in the terminal till you find:\\
There is also an easier way, that is that only the master module will return the real value of the HV. If you have more than 1 detector system, then you will have more than 1 physical master, as the HV needs to be applied to all the systems.
\begin{verbatim}
for i in $(seq 0 36); do sls_detector_put $i:vhighvoltage; done
for i in $(seq 0 36); do sls_detector_put $i:highvoltage; done
\end{verbatim}
Only the master will return to you a sensible number (150 normally). the others will return -999.
@ -1595,10 +1666,10 @@ ratecorr number
where {\tt{number}} is a string that should be interpreted as a float in s. 0.000000 means correction off. Values above zero are the value of $\tau$ in ns.
\item \begin{verbatim}
sls_detector_get vhighvoltage
vhighvoltage number
sls_detector_get highvoltage
highvoltage number
\end{verbatim}
where {\tt{number}} is a string that should be interpreted as an int and for proper Eiger setting is approximately 150~V if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:vhighvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
where {\tt{number}} is a string that should be interpreted as an int and for proper Eiger setting is approximately 150~V if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:highvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned.
\item \begin{verbatim}
sls_detector_get busy

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1 +1 @@
vhighvoltage 200
highvoltage 200

View File

@ -13,11 +13,25 @@ import _slsdet
defs = _slsdet.slsDetectorDefs
runStatus = _slsdet.slsDetectorDefs.runStatus
speedLevel = _slsdet.slsDetectorDefs.speedLevel
detectorType = _slsdet.slsDetectorDefs.detectorType
frameDiscardPolicy = _slsdet.slsDetectorDefs.frameDiscardPolicy
fileFormat = _slsdet.slsDetectorDefs.fileFormat
dimension = _slsdet.slsDetectorDefs.dimension
externalSignalFlag = _slsdet.slsDetectorDefs.externalSignalFlag
timingMode = _slsdet.slsDetectorDefs.timingMode
dacIndex = _slsdet.slsDetectorDefs.dacIndex
detectorType = _slsdet.slsDetectorDefs.detectorType
detectorSettings = _slsdet.slsDetectorDefs.detectorSettings
clockIndex = _slsdet.slsDetectorDefs.clockIndex
readoutMode = _slsdet.slsDetectorDefs.readoutMode
masterFlags = _slsdet.slsDetectorDefs.masterFlags
frameModeType = _slsdet.slsDetectorDefs.frameModeType
detectorModeType = _slsdet.slsDetectorDefs.detectorModeType
burstMode = _slsdet.slsDetectorDefs.burstMode
timingSourceType = _slsdet.slsDetectorDefs.timingSourceType
IpAddr = _slsdet.IpAddr
MacAddr = _slsdet.MacAddr

View File

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

View File

@ -49,14 +49,14 @@ void init_enums(py::module &m) {
py::enum_<slsDetectorDefs::fileFormat>(Defs, "fileFormat")
.value("BINARY", slsDetectorDefs::fileFormat::BINARY)
.value(" HDF5", slsDetectorDefs::fileFormat::HDF5)
.value(" NUM_FILE_FORMATS",
.value("HDF5", slsDetectorDefs::fileFormat::HDF5)
.value("NUM_FILE_FORMATS",
slsDetectorDefs::fileFormat::NUM_FILE_FORMATS)
.export_values();
py::enum_<slsDetectorDefs::dimension>(Defs, "dimension")
.value("X", slsDetectorDefs::dimension::X)
.value(" Y", slsDetectorDefs::dimension::Y)
.value("Y", slsDetectorDefs::dimension::Y)
.export_values();
py::enum_<slsDetectorDefs::externalSignalFlag>(Defs, "externalSignalFlag")
@ -176,6 +176,7 @@ void init_enums(py::module &m) {
slsDetectorDefs::dacIndex::TEMPERATURE_FPGA2)
.value("TEMPERATURE_FPGA3",
slsDetectorDefs::dacIndex::TEMPERATURE_FPGA3)
.value("TRIMBIT_SCAN", slsDetectorDefs::dacIndex::TRIMBIT_SCAN)
.value("V_POWER_A", slsDetectorDefs::dacIndex::V_POWER_A)
.value("V_POWER_B", slsDetectorDefs::dacIndex::V_POWER_B)
.value("V_POWER_C", slsDetectorDefs::dacIndex::V_POWER_C)
@ -234,42 +235,42 @@ void init_enums(py::module &m) {
py::enum_<slsDetectorDefs::clockIndex>(Defs, "clockIndex")
.value("ADC_CLOCK", slsDetectorDefs::clockIndex::ADC_CLOCK)
.value(" DBIT_CLOCK", slsDetectorDefs::clockIndex::DBIT_CLOCK)
.value(" RUN_CLOCK", slsDetectorDefs::clockIndex::RUN_CLOCK)
.value(" SYNC_CLOCK", slsDetectorDefs::clockIndex::SYNC_CLOCK)
.value("DBIT_CLOCK", slsDetectorDefs::clockIndex::DBIT_CLOCK)
.value("RUN_CLOCK", slsDetectorDefs::clockIndex::RUN_CLOCK)
.value("SYNC_CLOCK", slsDetectorDefs::clockIndex::SYNC_CLOCK)
.export_values();
py::enum_<slsDetectorDefs::readoutMode>(Defs, "readoutMode")
.value("ANALOG_ONLY", slsDetectorDefs::readoutMode::ANALOG_ONLY)
.value(" DIGITAL_ONLY", slsDetectorDefs::readoutMode::DIGITAL_ONLY)
.value(" ANALOG_AND_DIGITAL",
.value("DIGITAL_ONLY", slsDetectorDefs::readoutMode::DIGITAL_ONLY)
.value("ANALOG_AND_DIGITAL",
slsDetectorDefs::readoutMode::ANALOG_AND_DIGITAL)
.export_values();
py::enum_<slsDetectorDefs::speedLevel>(Defs, "speedLevel")
.value("FULL_SPEED", slsDetectorDefs::speedLevel::FULL_SPEED)
.value(" HALF_SPEED", slsDetectorDefs::speedLevel::HALF_SPEED)
.value(" QUARTER_SPEED", slsDetectorDefs::speedLevel::QUARTER_SPEED)
.value("HALF_SPEED", slsDetectorDefs::speedLevel::HALF_SPEED)
.value("QUARTER_SPEED", slsDetectorDefs::speedLevel::QUARTER_SPEED)
.export_values();
py::enum_<slsDetectorDefs::masterFlags>(Defs, "masterFlags")
.value("NO_MASTER", slsDetectorDefs::masterFlags::NO_MASTER)
.value(" IS_MASTER", slsDetectorDefs::masterFlags::IS_MASTER)
.value(" IS_SLAVE", slsDetectorDefs::masterFlags::IS_SLAVE)
.value("IS_MASTER", slsDetectorDefs::masterFlags::IS_MASTER)
.value("IS_SLAVE", slsDetectorDefs::masterFlags::IS_SLAVE)
.export_values();
py::enum_<slsDetectorDefs::frameModeType>(Defs, "frameModeType")
.value("PEDESTAL", slsDetectorDefs::frameModeType::PEDESTAL)
.value(" NEW_PEDESTAL", slsDetectorDefs::frameModeType::NEW_PEDESTAL)
.value(" FLATFIELD", slsDetectorDefs::frameModeType::FLATFIELD)
.value(" NEW_FLATFIELD", slsDetectorDefs::frameModeType::NEW_FLATFIELD)
.value("NEW_PEDESTAL", slsDetectorDefs::frameModeType::NEW_PEDESTAL)
.value("FLATFIELD", slsDetectorDefs::frameModeType::FLATFIELD)
.value("NEW_FLATFIELD", slsDetectorDefs::frameModeType::NEW_FLATFIELD)
.export_values();
py::enum_<slsDetectorDefs::detectorModeType>(Defs, "detectorModeType")
.value("COUNTING", slsDetectorDefs::detectorModeType::COUNTING)
.value(" INTERPOLATING",
.value("INTERPOLATING",
slsDetectorDefs::detectorModeType::INTERPOLATING)
.value(" ANALOG", slsDetectorDefs::detectorModeType::ANALOG)
.value("ANALOG", slsDetectorDefs::detectorModeType::ANALOG)
.export_values();
py::enum_<slsDetectorDefs::burstMode>(Defs, "burstMode")
@ -282,7 +283,7 @@ void init_enums(py::module &m) {
py::enum_<slsDetectorDefs::timingSourceType>(Defs, "timingSourceType")
.value("TIMING_INTERNAL",
slsDetectorDefs::timingSourceType::TIMING_INTERNAL)
.value(" TIMING_EXTERNAL",
.value("TIMING_EXTERNAL",
slsDetectorDefs::timingSourceType::TIMING_EXTERNAL)
.export_values();
}

View File

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

View File

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

View File

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

View File

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

View File

@ -747,6 +747,35 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
LOG(logDEBUG) << "[ Progress:" << progress << ", Frame:" << currentFrame
<< " ]";
// 1d check if npixelX has changed (m3 for different counters enabled)
if (is1d && static_cast<int>(nPixelsX) != data->nx) {
nPixelsX = data->nx;
LOG(logINFO) << "Change in Detector Shape:\n\tnPixelsX:" << nPixelsX;
delete[] datax1d;
datax1d = new double[nPixelsX];
for (unsigned int px = 0; px < nPixelsX; ++px) {
datax1d[px] = px;
}
if (datay1d.size()) {
for (auto &it : datay1d) {
delete[] it;
}
datay1d.clear();
}
datay1d.push_back(new double[nPixelsX]);
for (unsigned int px = 0; px < nPixelsX; ++px) {
datax1d[px] = px;
datay1d[0][px] = 0;
}
currentPersistency = 0;
if (gainDatay1d) {
delete[] gainDatay1d;
gainDatay1d = new double[nPixelsX];
std::fill(gainDatay1d, gainDatay1d + nPixelsX, 0);
}
}
// 2d (only image, not gain data, not pedestalvals),
// check if npixelsX and npixelsY is the same (quad is different)
if (!is1d && (static_cast<int>(nPixelsX) != data->nx ||
@ -784,7 +813,7 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
plotTitlePrefix + QString(data->fileName.c_str()).section('/', -1);
indexTitle = QString("%1").arg(frameIndex);
if ((int)subFrameIndex != -1) {
indexTitle = QString("%1 %2").arg(frameIndex, subFrameIndex);
indexTitle = QString("%1 %2").arg(frameIndex).arg(subFrameIndex);
}
completeImage = data->completeImage;

View File

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

View File

@ -2048,7 +2048,7 @@ void *start_timer(void *arg) {
int colRight = top ? eiger_virtual_detPos[1] + 1 : eiger_virtual_detPos[1];
int ntotpixels = 256 * 256 * 4;
LOG(logINFO, (" dr:%d\n bytesperpixel:%f\n tgenable:%d\n datasize:%d\n "
LOG(logDEBUG1, (" dr:%d\n bytesperpixel:%f\n tgenable:%d\n datasize:%d\n "
"packetsize:%d\n numpackes:%d\n npixelsx:%d\n databytes:%d\n "
"ntotpixels:%d\n",
dr, bytesPerPixel, tgEnable, datasize, packetsize,
@ -2181,7 +2181,7 @@ void *start_timer(void *arg) {
usleep(eiger_virtual_transmission_delay_right);
sendUDPPacket(1, packetData2, packetsize);
}
LOG(logINFO, ("Sent frame: %d\n", iframes));
LOG(logINFO, ("Sent frame: %d[%lld]\n", iframes, (long long unsigned int)(frameNr + iframes)));
clock_gettime(CLOCK_REALTIME, &end);
int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 +
(end.tv_nsec - begin.tv_nsec));

View File

@ -25,5 +25,5 @@ vcom_adc2 704
#configure adc chip index adc index value(max 0x7F)
confadc -1 -1 0x22
#vetoreference gain index value(max 0x3ff)
vetoref 1 0x0
#vetoreference gain index value(max 1023)
vetoref 1 0

View File

@ -50,6 +50,7 @@ int onChipdacValues[ONCHIP_NDAC][NCHIP] = {};
int injectedChannelsOffset = 0;
int injectedChannelsIncrement = 0;
int vetoReference[NCHIP][NCHAN];
int vetoGainIndices[NCHIP][NCHAN];
uint8_t adcConfiguration[NCHIP][NADC];
int burstMode = BURST_INTERNAL;
int64_t numTriggersReg = 1;
@ -373,25 +374,16 @@ void setupDetector() {
burstPeriodReg = 0;
filter = 0;
cdsGain = 0;
for (int i = 0; i < NUM_CLOCKS; ++i) {
clkPhase[i] = 0;
}
for (int i = 0; i < NDAC; ++i) {
dacValues[i] = 0;
}
memset(clkPhase, 0, sizeof(clkPhase));
memset(dacValues, 0, sizeof(dacValues));
for (int i = 0; i < ONCHIP_NDAC; ++i) {
for (int j = 0; j < NCHIP; ++j) {
onChipdacValues[i][j] = -1;
}
}
for (int i = 0; i < NCHIP; ++i) {
for (int j = 0; j < NCHAN; ++j) {
vetoReference[i][j] = 0;
}
for (int j = 0; j < NADC; ++j) {
adcConfiguration[i][j] = 0;
}
}
memset(vetoReference, 0, sizeof(vetoReference));
memset(vetoGainIndices, 0, sizeof(vetoGainIndices));
memset(adcConfiguration, 0, sizeof(adcConfiguration));
#ifdef VIRTUAL
sharedMemory_setStatus(IDLE);
#endif
@ -560,7 +552,7 @@ int readConfigFile() {
int value = 0;
// cannot scan values
if (sscanf(line, "%s %d 0x%x", command, &igain, &value) != 3) {
if (sscanf(line, "%s %d %d", command, &igain, &value) != 3) {
sprintf(initErrorMessage,
"Could not scan vetoref commands from on-board server "
"config file. Line:[%s].\n",
@ -1757,8 +1749,9 @@ int setInjectChannel(int offset, int increment) {
char buffer[17];
memset(buffer, 0, sizeof(buffer));
int startCh = 4; // 4 due to padding
for (int ich = startCh + offset; ich < startCh + NCHAN;
ich = ich + increment) {
// reversing the channels sent (offset 0 is 127, 50 is 77 etc..)
for (int ich = startCh + NCHAN - 1 - offset; ich >= startCh;
ich -= increment) {
int byteIndex = ich / 8;
int bitIndex = ich % 8;
buffer[byteIndex] |= (1 << (8 - 1 - bitIndex));
@ -1783,46 +1776,52 @@ void getInjectedChannels(int *offset, int *increment) {
}
int setVetoReference(int gainIndex, int value) {
LOG(logINFO, ("Setting veto reference [chip:-1, G%d, value:0x%x]\n",
LOG(logINFO, ("Setting veto reference [chip:-1, G%d, value:%d]\n",
gainIndex, value));
int vals[NCHAN];
memset(vals, 0, sizeof(vals));
int values[NCHAN];
int gainIndices[NCHAN];
for (int ich = 0; ich < NCHAN; ++ich) {
vals[ich] = value;
values[ich] = value;
gainIndices[ich] = gainIndex;
}
return setVetoPhoton(-1, gainIndex, vals);
return configureASICVetoReference(-1, gainIndices, values);
}
int setVetoPhoton(int chipIndex, int gainIndex, int *values) {
LOG(logINFO,
("Setting veto photon [chip:%d, G%d]\n", chipIndex, gainIndex));
int setVetoPhoton(int chipIndex, int *gainIndices, int *values) {
return configureASICVetoReference(chipIndex, gainIndices, values);
}
// add gain bits
int gainValue = 0;
switch (gainIndex) {
case 0:
gainValue = ASIC_G0_VAL;
break;
case 1:
gainValue = ASIC_G1_VAL;
break;
case 2:
gainValue = ASIC_G2_VAL;
break;
default:
LOG(logERROR, ("Unknown gain index %d\n", gainIndex));
return FAIL;
}
LOG(logDEBUG2, ("Adding gain bits\n"));
int configureASICVetoReference(int chipIndex, int *gainIndices, int *values) {
LOG(logINFO, ("Setting veto photon/file/reference [chip:%d]\n", chipIndex));
// reversing the values sent to the chip
int revValues[NCHAN] = {};
for (int i = 0; i < NCHAN; ++i) {
values[i] |= gainValue;
LOG(logDEBUG2, ("Value %d: 0x%x\n", i, values[i]));
revValues[i] = values[NCHAN - 1 - i];
}
return configureASICVetoReference(chipIndex, values);
}
// correct gain bits and integrate into revValues
for (int i = 0; i < NCHAN; ++i) {
int gainValue = 0;
switch (gainIndices[i]) {
case 0:
gainValue = ASIC_G0_VAL;
break;
case 1:
gainValue = ASIC_G1_VAL;
break;
case 2:
gainValue = ASIC_G2_VAL;
break;
default:
LOG(logERROR,
("Unknown gain index %d for channel %d\n", gainIndices[i], i));
return FAIL;
}
revValues[NCHAN - 1 - i] |= gainValue; // reversed list, so NCHAN - 1 - i
LOG(logDEBUG2, ("Values[%d]: 0x%x\n", i, revValues[i]));
}
int configureASICVetoReference(int chipIndex, int *values) {
const int lenDataBitsPerchannel = ASIC_GAIN_MAX_BITS + ADU_MAX_BITS; // 14
const int lenBits = lenDataBitsPerchannel * NCHAN; // 1792
const int padding = 4; // due to address (4) to make it byte aligned
@ -1837,7 +1836,7 @@ int configureASICVetoReference(int chipIndex, int *values) {
// loop through all bits in a value
for (int iBit = 0; iBit < lenDataBitsPerchannel; ++iBit) {
commandBytes[offset++] =
((values[ich] >> (lenDataBitsPerchannel - 1 - iBit)) & 0x1);
((revValues[ich] >> (lenDataBitsPerchannel - 1 - iBit)) & 0x1);
}
}
@ -1861,11 +1860,12 @@ int configureASICVetoReference(int chipIndex, int *values) {
return FAIL;
}
// all chips
// all chips (saving unreversed values)
if (chipIndex == -1) {
for (int ichan = 0; ichan < NCHAN; ++ichan) {
for (int ichip = 0; ichip < NCHIP; ++ichip) {
vetoReference[ichip][ichan] = values[ichan];
vetoGainIndices[ichip][ichan] = gainIndices[ichan];
}
}
}
@ -1873,17 +1873,19 @@ int configureASICVetoReference(int chipIndex, int *values) {
// specific chip
else {
for (int ichan = 0; ichan < NCHAN; ++ichan) {
vetoReference[chipIndex][chipIndex] = values[ichan];
;
vetoReference[chipIndex][ichan] = values[ichan];
vetoGainIndices[chipIndex][ichan] = gainIndices[ichan];
}
}
return OK;
}
int getVetoPhoton(int chipIndex, int *retvals) {
int getVetoPhoton(int chipIndex, int *retvals, int *gainRetvals) {
if (chipIndex == -1) {
// if chipindex is -1, check that all values and gain indices are same
for (int i = 0; i < NCHAN; ++i) {
int val = vetoReference[0][i];
int gval = vetoGainIndices[0][i];
for (int j = 1; j < NCHIP; ++j) {
if (vetoReference[j][i] != val) {
LOG(logERROR,
@ -1893,6 +1895,14 @@ int getVetoPhoton(int chipIndex, int *retvals) {
chipIndex, j, i, vetoReference[j][i], i, val));
return FAIL;
}
if (vetoGainIndices[j][i] != gval) {
LOG(logERROR,
("Get vet photon fail for chipIndex:%d. Different "
"gain indices between [nchip:%d, nchan:%d, gain "
"index:%d] and [nchip:0, nchan:%d, gain index:%d]\n",
chipIndex, j, i, vetoGainIndices[j][i], i, gval));
return FAIL;
}
}
}
chipIndex = 0;
@ -1900,35 +1910,12 @@ int getVetoPhoton(int chipIndex, int *retvals) {
memcpy((char *)retvals,
((char *)vetoReference) + NCHAN * chipIndex * sizeof(int),
sizeof(int) * NCHAN);
memcpy((char *)gainRetvals,
((char *)vetoGainIndices) + NCHAN * chipIndex * sizeof(int),
sizeof(int) * NCHAN);
return OK;
}
int setVetoFile(int chipIndex, int *gainIndices, int *values) {
LOG(logINFO, ("Setting veto file [chip:%d]\n", chipIndex));
// correct gain bits and integrate into values
for (int i = 0; i < NCHAN; ++i) {
switch (gainIndices[i]) {
case 0:
gainIndices[i] = ASIC_G0_VAL;
break;
case 1:
gainIndices[i] = ASIC_G1_VAL;
break;
case 2:
gainIndices[i] = ASIC_G2_VAL;
break;
default:
LOG(logERROR,
("Unknown gain index %d for channel %d\n", gainIndices[i], i));
return FAIL;
}
values[i] |= gainIndices[i];
LOG(logDEBUG2, ("Values[%d]: 0x%x\n", i, values[i]));
}
return configureASICVetoReference(chipIndex, values);
}
int setADCConfiguration(int chipIndex, int adcIndex, int value) {
LOG(logINFO, ("Configuring ADC [chipIndex:%d, adcIndex:%d, value:0x%x]\n",
chipIndex, adcIndex, value));
@ -1956,10 +1943,10 @@ int setADCConfiguration(int chipIndex, int adcIndex, int value) {
chipmin = chipIndex;
chipmax = chipIndex + 1;
}
// specific adc
// specific adc (reversing adc when sending to chip)
if (adcIndex != -1) {
adcmin = adcIndex;
adcmax = adcIndex + 1;
adcmin = NADC - 1 - adcIndex;
adcmax = NADC - adcIndex;
}
// update values
for (int i = chipmin; i < chipmax; ++i) {
@ -2037,10 +2024,10 @@ int getADCConfiguration(int chipIndex, int adcIndex) {
chipmin = chipIndex;
chipmax = chipIndex + 1;
}
// specific adc
// specific adc (reversing adc when sending to chip)
if (adcIndex != -1) {
adcmin = adcIndex;
adcmax = adcIndex + 1;
adcmin = NADC - 1 - adcIndex;
adcmax = NADC - adcIndex;
}
int val = adcConfiguration[chipmin][adcmin];
@ -2166,16 +2153,21 @@ int setBurstMode(enum burstMode burst) {
}
int configureASICGlobalSettings() {
int modeValue =
burstMode ? ASIC_GLOBAL_BURST_VALUE : ASIC_GLOBAL_CONT_VALUE;
int value = ((modeValue << ASIC_GLOBAL_MODE_OFST) & ASIC_GLOBAL_MODE_MSK) |
((filter << ASIC_FILTER_OFST) & ASIC_FILTER_MSK) |
int value = ((filter << ASIC_FILTER_OFST) & ASIC_FILTER_MSK) |
((cdsGain << ASIC_CDS_GAIN_OFST) & ASIC_CDS_GAIN_MSK);
LOG(logINFO,
("\tSending Global Chip settings:0x%x (mode:%d(%s), filter:%d, "
"cdsgain:%d)\n",
value, modeValue, (burstMode == BURST_OFF ? "Continuous" : "Burst"),
filter, cdsGain));
switch (burstMode) {
case BURST_OFF:
value |= (ASIC_CONT_MODE_MSK | ASIC_EXT_TIMING_MSK);
break;
case BURST_INTERNAL:
break;
case BURST_EXTERNAL:
value |= ASIC_EXT_TIMING_MSK;
break;
}
LOG(logINFO, ("\tSending Global Chip settings:0x%x (filter:%d, "
"cdsgain:%d)\n",
value, filter, cdsGain));
const int padding = 6; // due to address (4) to make it byte aligned
const int lenTotalBits = padding + ASIC_GLOBAL_SETT_MAX_BITS +

View File

@ -136,10 +136,13 @@ enum PLLINDEX { READOUT_PLL, SYSTEM_PLL };
#define ASIC_ADC_MAX_BITS (7)
#define ASIC_ADC_MAX_VAL (0x7F)
#define ASIC_GLOBAL_SETT_MAX_BITS (6)
#define ASIC_GLOBAL_BURST_VALUE (0x0)
#define ASIC_GLOBAL_CONT_VALUE (0x6)
#define ASIC_GLOBAL_MODE_OFST (0)
#define ASIC_GLOBAL_MODE_MSK (0x7 << ASIC_GLOBAL_MODE_OFST)
#define ASIC_EXT_MEMCTRL_OFST (0)
#define ASIC_EXT_MEMCTRL_MSK (0x1 << ASIC_EXT_MEMCTRL_OFST)
#define ASIC_EXT_TIMING_OFST (1)
#define ASIC_EXT_TIMING_MSK (0x1 << ASIC_EXT_TIMING_OFST)
#define ASIC_CONT_MODE_OFST (2)
#define ASIC_CONT_MODE_MSK (0x1 << ASIC_CONT_MODE_OFST)
#define ASIC_FILTER_OFST (3)
#define ASIC_FILTER_MSK (0x3 << ASIC_FILTER_OFST)
#define ASIC_FILTER_MAX_VALUE (3)

View File

@ -1,9 +1,9 @@
#include "slsDetectorFunctionList.h"
#include "RegisterDefs.h"
#include "clogger.h"
#include "common.h"
#include "sharedMemory.h"
#include "versionAPI.h"
#include "common.h"
#include "LTC2620.h" // dacs
#ifdef VIRTUAL

View File

@ -279,6 +279,7 @@ u_int16_t getHardwareSerialNumber() {
HARDWARE_SERIAL_NUM_OFST);
}
// is board 1.0?, with value 2 (resistor network)
int isHardwareVersion2() {
return (((bus_r(MOD_SERIAL_NUM_REG) & HARDWARE_VERSION_NUM_MSK) ==
HARDWARE_VERSION_2_VAL)

View File

@ -3,8 +3,8 @@
#include "sls_detector_defs.h"
#define MIN_REQRD_VRSN_T_RD_API 0x171220
#define REQRD_FRMWRE_VRSN_BOARD2 0x190716 // old
#define REQRD_FRMWRE_VRSN 0x200305 // new
#define REQRD_FRMWRE_VRSN_BOARD2 0x200724 // 1.0 pcb
#define REQRD_FRMWRE_VRSN 0x200721 // 2.0 pcb
#define CTRL_SRVR_INIT_TIME_US (300 * 1000)
@ -66,7 +66,6 @@ enum CLKINDEX { RUN_CLK, ADC_CLK, DBIT_CLK, NUM_CLOCKS };
#define NCHAN (256 * 256)
#define NCHIP (8)
#define NDAC (8)
#define NDAC_OLDBOARD (16)
#define DYNAMIC_RANGE (16)
#define NUM_BYTES_PER_PIXEL (DYNAMIC_RANGE / 8)
#define DATA_BYTES (NCHIP * NCHAN * NUM_BYTES_PER_PIXEL)
@ -103,42 +102,45 @@ enum CLKINDEX { RUN_CLK, ADC_CLK, DBIT_CLK, NUM_CLOCKS };
#define MAX_STORAGE_CELL_DLY_NS_VAL (ASIC_CTRL_EXPSRE_TMR_MAX_VAL)
#define ACQ_TIME_MIN_CLOCK (2)
#define MAX_PHASE_SHIFTS (160)
#define MAX_PHASE_SHIFTS (240)
#define BIT16_MASK (0xFFFF)
#define ADC_OFST_FULL_SPEED_VAL (0xf)
#define ADC_OFST_HALF_SPEED_VAL (0xb)
#define ADC_OFST_QUARTER_SPEED_VAL (0x7)
#define ADC_OFST_HALF_SPEED_BOARD2_VAL (0x13)
#define ADC_OFST_QUARTER_SPEED_BOARD2_VAL (0x0b)
// pipeline
#define ADC_OFST_FULL_SPEED_VAL (0x10) // 2.0 pcb
#define ADC_OFST_HALF_SPEED_VAL (0x08) // 2.0 pcb
#define ADC_OFST_QUARTER_SPEED_VAL (0x04) // 2.0 pcb
#define ADC_OFST_HALF_SPEED_BOARD2_VAL (0x13) // 1.0 pcb (2 resistor network)
#define ADC_OFST_QUARTER_SPEED_BOARD2_VAL (0x0b) // 1.0 pcb (2 resistor network)
#define ADC_PORT_INVERT_VAL (0x5A5A5A5A)
#define ADC_PORT_INVERT_BOARD2_VAL (0x453b2a9c)
// 2.0 pcb
#define SAMPLE_ADC_FULL_SPEED \
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_0_VAL + \
SAMPLE_DGTL_SAMPLE_2_VAL + SAMPLE_DECMT_FACTOR_FULL_VAL) // 0x200
SAMPLE_DGTL_SAMPLE_1_VAL + SAMPLE_DECMT_FACTOR_FULL_VAL) // 0x100
#define SAMPLE_ADC_HALF_SPEED \
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_1_VAL + \
SAMPLE_DGTL_SAMPLE_3_VAL + SAMPLE_DECMT_FACTOR_HALF_VAL) // 0x1310
#define SAMPLE_ADC_QUARTER_SPEED \
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_3_VAL + \
SAMPLE_DGTL_SAMPLE_6_VAL + SAMPLE_DECMT_FACTOR_QUARTER_VAL) // 0x2630
// 1.0 pcb (2 resistor network)
#define SAMPLE_ADC_HALF_SPEED_BOARD2 \
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_0_VAL + \
SAMPLE_DGTL_SAMPLE_6_VAL + SAMPLE_DECMT_FACTOR_HALF_VAL) // 0x1600
SAMPLE_DGTL_SAMPLE_3_VAL + SAMPLE_DECMT_FACTOR_HALF_VAL) // 0x1300
#define SAMPLE_ADC_QUARTER_SPEED_BOARD2 \
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_1_VAL + \
SAMPLE_DGTL_SAMPLE_11_VAL + SAMPLE_DECMT_FACTOR_QUARTER_VAL) // 0x2b10
SAMPLE_DGTL_SAMPLE_6_VAL + SAMPLE_DECMT_FACTOR_QUARTER_VAL) // 0x2610
#define ADC_PHASE_FULL_SPEED (28)
#define ADC_PHASE_HALF_SPEED (35)
#define ADC_PHASE_QUARTER_SPEED (35)
#define ADC_PHASE_HALF_SPEED_BOARD2 (0x1E) // 30
#define ADC_PHASE_QUARTER_SPEED_BOARD2 (0x1E) // 30
#define ADC_PHASE_FULL_SPEED (150) // 2.0 pcb
#define ADC_PHASE_HALF_SPEED (200) // 2.0 pcb
#define ADC_PHASE_QUARTER_SPEED (200) // 2.0 pcb
#define ADC_PHASE_HALF_SPEED_BOARD2 (75) // 1.0 pcb (2 resistor network)
#define ADC_PHASE_QUARTER_SPEED_BOARD2 (75) // 1.0 pcb (2 resistor network)
#define DBIT_PHASE_FULL_SPEED (37)
#define DBIT_PHASE_HALF_SPEED (37)
#define DBIT_PHASE_QUARTER_SPEED (37)
#define DBIT_PHASE_HALF_SPEED_BOARD2 (37)
#define DBIT_PHASE_QUARTER_SPEED_BOARD2 (37)
#define DBIT_PHASE_FULL_SPEED (85) // 2.0 pcb
#define DBIT_PHASE_HALF_SPEED (150) // 2.0 pcb
#define DBIT_PHASE_QUARTER_SPEED (150) // 2.0 pcb
#define DBIT_PHASE_HALF_SPEED_BOARD2 (150) // 1.0 pcb (2 resistor network)
#define DBIT_PHASE_QUARTER_SPEED_BOARD2 (150) // 1.0 pcb (2 resistor network)

View File

@ -152,6 +152,17 @@
#define PKT_CONFIG_1G_INTERFACE_OFST (16)
#define PKT_CONFIG_1G_INTERFACE_MSK (0x00000001 << PKT_CONFIG_1G_INTERFACE_OFST)
#define PKT_FRAG_REG (0x01 * REG_OFFSET + BASE_PKT)
#define PKT_FRAG_1G_N_DSR_PER_PKT_OFST (0)
#define PKT_FRAG_1G_N_DSR_PER_PKT_MSK (0x0000003F << PKT_FRAG_1G_N_DSR_PER_PKT_OFST)
#define PKT_FRAG_10G_N_DSR_PER_PKT_OFST (8)
#define PKT_FRAG_10G_N_DSR_PER_PKT_MSK (0x0000003F << PKT_FRAG_10G_N_DSR_PER_PKT_OFST)
#define PKT_FRAG_1G_NUM_PACKETS_OFST (16)
#define PKT_FRAG_1G_NUM_PACKETS_MSK (0x0000003F << PKT_FRAG_1G_NUM_PACKETS_OFST)
#define PKT_FRAG_10G_NUM_PACKETS_OFST (24)
#define PKT_FRAG_10G_NUM_PACKETS_MSK (0x0000003F << PKT_FRAG_10G_NUM_PACKETS_OFST)
/* Module Coordinates Register */
#define COORD_0_REG (0x02 * REG_OFFSET + BASE_PKT)
#define COORD_ROW_OFST (0)

View File

@ -552,6 +552,7 @@ int setDynamicRange(int dr) {
// set it
bus_w(CONFIG_REG, bus_r(CONFIG_REG) & ~CONFIG_DYNAMIC_RANGE_MSK);
bus_w(CONFIG_REG, bus_r(CONFIG_REG) | regval);
updatePacketizing();
}
uint32_t regval = bus_r(CONFIG_REG) & CONFIG_DYNAMIC_RANGE_MSK;
@ -1032,6 +1033,7 @@ void setCounterMask(uint32_t arg) {
CONFIG_COUNTERS_ENA_MSK));
LOG(logDEBUG, ("Config Reg: 0x%x\n", bus_r(addr)));
updatePacketizing();
updateGatePeriod();
}
@ -1040,6 +1042,55 @@ uint32_t getCounterMask() {
CONFIG_COUNTERS_ENA_OFST);
}
void updatePacketizing() {
const int ncounters = __builtin_popcount(getCounterMask());
const int tgEnable = enableTenGigabitEthernet(-1);
int packetsPerFrame = 0;
// 10g
if (tgEnable) {
const int dr = setDynamicRange(-1);
packetsPerFrame = 1;
if (dr == 32 && ncounters > 1) {
packetsPerFrame = 2;
}
}
// 1g
else {
int dataSize = 1280;
if (ncounters == 3) {
dataSize = 768;
}
packetsPerFrame = calculateDataBytes() / dataSize;
}
const int deserializersPerPacket = MAX_NUM_DESERIALIZERS / packetsPerFrame;
// bus_w()
LOG(logINFO,
("[#Packets/Frame: %d, #Deserializers/Packet: %d] for %s\n",
packetsPerFrame, deserializersPerPacket, (tgEnable ? "10g" : "1g")));
const uint32_t addr = PKT_FRAG_REG;
if (tgEnable) {
bus_w(addr, bus_r(addr) & ~PKT_FRAG_10G_NUM_PACKETS_MSK);
bus_w(addr, bus_r(addr) |
((packetsPerFrame << PKT_FRAG_10G_NUM_PACKETS_OFST) &
PKT_FRAG_10G_NUM_PACKETS_MSK));
bus_w(addr, bus_r(addr) & ~PKT_FRAG_10G_N_DSR_PER_PKT_MSK);
bus_w(addr, bus_r(addr) | ((deserializersPerPacket
<< PKT_FRAG_10G_N_DSR_PER_PKT_OFST) &
PKT_FRAG_10G_N_DSR_PER_PKT_MSK));
} else {
bus_w(addr, bus_r(addr) & ~PKT_FRAG_1G_NUM_PACKETS_MSK);
bus_w(addr,
bus_r(addr) | ((packetsPerFrame << PKT_FRAG_1G_NUM_PACKETS_OFST) &
PKT_FRAG_1G_NUM_PACKETS_MSK));
bus_w(addr, bus_r(addr) & ~PKT_FRAG_1G_N_DSR_PER_PKT_MSK);
bus_w(addr, bus_r(addr) | ((deserializersPerPacket
<< PKT_FRAG_1G_N_DSR_PER_PKT_OFST) &
PKT_FRAG_1G_N_DSR_PER_PKT_MSK));
}
}
int setDelayAfterTrigger(int64_t val) {
if (val < 0) {
LOG(logERROR,
@ -1509,6 +1560,7 @@ int enableTenGigabitEthernet(int val) {
else {
bus_w(addr, bus_r(addr) & (~PKT_CONFIG_1G_INTERFACE_MSK));
}
updatePacketizing();
}
int oneG = ((bus_r(addr) & PKT_CONFIG_1G_INTERFACE_MSK) >>
PKT_CONFIG_1G_INTERFACE_OFST);
@ -2055,21 +2107,42 @@ void *start_timer(void *arg) {
return NULL;
}
int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() * getNumTriggers());
int64_t expUs = getGatePeriod() / 1000;
const int64_t periodNs = getPeriod();
const int numFrames = (getNumFrames() * getNumTriggers());
const int64_t expUs = getGatePeriod() / 1000;
int imagesize = calculateDataBytes();
int dataSize = imagesize / PACKETS_PER_FRAME;
int packetSize = dataSize + sizeof(sls_detector_header);
const int imageSize = calculateDataBytes();
const int tgEnable = enableTenGigabitEthernet(-1);
const int dr = setDynamicRange(-1);
int ncounters = __builtin_popcount(getCounterMask());
int dataSize = 0;
int packetsPerFrame = 0;
// 10g
if (tgEnable) {
packetsPerFrame = 1;
if (dr == 32 && ncounters > 1) {
packetsPerFrame = 2;
}
}
// 1g
else {
dataSize = 1280;
if (ncounters == 3) {
dataSize = 768;
}
packetsPerFrame = imageSize / dataSize;
}
const int packetSize = dataSize + sizeof(sls_detector_header);
LOG(logDEBUG1,
("imageSize:%d tg:%d packets/Frame:%d datasize:%d packetSize:%d\n",
imageSize, tgEnable, packetsPerFrame, dataSize, packetSize));
// Generate data
char imageData[imagesize];
memset(imageData, 0, imagesize);
char imageData[imageSize];
memset(imageData, 0, imageSize);
{
int dr = setDynamicRange(-1);
int numCounters = __builtin_popcount(getCounterMask());
int nchannels = NCHAN_1_COUNTER * NCHIP * numCounters;
const int nchannels = NCHAN_1_COUNTER * NCHIP * ncounters;
switch (dr) {
/*case 1: // TODO: Not implemented in firmware yet
@ -2111,7 +2184,7 @@ void *start_timer(void *arg) {
int srcOffset = 0;
// loop packet
for (int i = 0; i != PACKETS_PER_FRAME; ++i) {
for (int i = 0; i != packetsPerFrame; ++i) {
char packetData[packetSize];
memset(packetData, 0, packetSize);

View File

@ -49,6 +49,7 @@
#define FIXED_PLL_FREQUENCY (020000000) // 20MHz
#define READOUT_PLL_VCO_FREQ_HZ (1250000000) // 1.25GHz
#define SYSTEM_PLL_VCO_FREQ_HZ (1000000000) // 1GHz
#define MAX_NUM_DESERIALIZERS (40)
/** Other Definitions */
#define BIT16_MASK (0xFFFF)
@ -133,7 +134,8 @@ typedef struct udp_header_struct {
uint16_t udp_destport;
} udp_header;
#define UDP_IP_HEADER_LENGTH_BYTES (28)
#define PACKETS_PER_FRAME (2)
#define PACKETS_PER_FRAME_10G (2)
#define PACKETS_PER_FRAME_1G (20)
/** Signal Definitions */
#define SIGNAL_TBLoad_1 (0)

View File

@ -2,7 +2,6 @@
#include <stdio.h>
/**
* Convert a value from a range to a different range (eg voltage to dac or vice
* versa)
@ -17,6 +16,4 @@
int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin,
int outputMax, int inputValue, int *outputValue);
int getAbsPath(char* buf, size_t bufSize, char* fname);
int getAbsPath(char *buf, size_t bufSize, char *fname);

View File

@ -250,6 +250,7 @@ int getNumDigitalSamples();
#ifdef MYTHEN3D
void setCounterMask(uint32_t arg);
uint32_t getCounterMask();
void updatePacketizing();
#endif
#if defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(CHIPTESTBOARDD) || \
@ -504,10 +505,9 @@ int getClockDivider(enum CLKINDEX ind);
int setInjectChannel(int offset, int increment);
void getInjectedChannels(int *offset, int *increment);
int setVetoReference(int gainIndex, int value);
int setVetoPhoton(int chipIndex, int gainIndex, int *values);
int configureASICVetoReference(int chipIndex, int *values);
int getVetoPhoton(int chipIndex, int *retvals);
int setVetoFile(int chipIndex, int *gainIndices, int *values);
int setVetoPhoton(int chipIndex, int *gainIndices, int *values);
int configureASICVetoReference(int chipIndex, int *gainIndices, int *values);
int getVetoPhoton(int chipIndex, int *retvals, int *gainRetvals);
int setADCConfiguration(int chipIndex, int adcIndex, int value);
int getADCConfiguration(int chipIndex, int adcIndex);
int setBurstModeinFPGA(enum burstMode value);

View File

@ -151,7 +151,7 @@ int get_read_n_lines(int);
void calculate_and_set_position();
int set_detector_position(int);
int check_detector_idle();
int is_configurable();
int is_udp_configured();
void configure_mac();
int set_source_udp_ip(int);
int get_source_udp_ip(int);
@ -233,8 +233,9 @@ int get_cds_gain(int);
int set_cds_gain(int);
int get_filter(int);
int set_filter(int);
int set_veto_file(int);
int get_adc_config(int);
int set_adc_config(int);
int get_bad_channels(int);
int set_bad_channels(int);
int set_bad_channels(int);
int reconfigure_udp(int);
int validate_udp_configuration(int);

View File

@ -2,8 +2,8 @@
#include "clogger.h"
#include "sls_detector_defs.h"
#include <string.h>
#include <libgen.h> // dirname
#include <string.h>
#include <unistd.h> // readlink
int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin,
@ -42,8 +42,7 @@ int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin,
return OK;
}
int getAbsPath(char* buf, size_t bufSize, char* fname) {
int getAbsPath(char *buf, size_t bufSize, char *fname) {
// get path of current binary
char path[bufSize];
memset(path, 0, bufSize);
@ -58,6 +57,6 @@ int getAbsPath(char* buf, size_t bufSize, char* fname) {
char *dir = dirname(path);
memset(buf, 0, bufSize);
sprintf(buf, "%s/%s", dir, fname);
LOG(logDEBUG1, ("full path for %s: %s\n", fname, buf));
LOG(logDEBUG1, ("full path for %s: %s\n", fname, buf));
return OK;
}

View File

@ -1,9 +1,9 @@
#include "readDefaultPattern.h"
#include "ansi.h"
#include "clogger.h"
#include "common.h"
#include "slsDetectorServer_defs.h"
#include "sls_detector_defs.h"
#include "common.h"
#include <string.h>

View File

@ -350,11 +350,12 @@ void function_table() {
flist[F_SET_CDS_GAIN] = &set_cds_gain;
flist[F_GET_FILTER] = &get_filter;
flist[F_SET_FILTER] = &set_filter;
flist[F_SET_VETO_FILE] = &set_veto_file;
flist[F_GET_ADC_CONFIGURATION] = &get_adc_config;
flist[F_SET_ADC_CONFIGURATION] = &set_adc_config;
flist[F_GET_BAD_CHANNELS] = &get_bad_channels;
flist[F_SET_BAD_CHANNELS] = &set_bad_channels;
flist[F_RECONFIGURE_UDP] = &reconfigure_udp;
flist[F_VALIDATE_UDP_CONFIG] = &validate_udp_configuration;
// check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
@ -992,7 +993,7 @@ enum DACINDEX getDACIndex(enum dacIndex ind) {
default:
#ifdef CHIPTESTBOARDD
if (ind < NDAC_ONLY) {
//For CTB use the index directly, no conversion
// For CTB use the index directly, no conversion
serverDacIndex = (enum DACINDEX)ind;
break;
}
@ -4865,14 +4866,14 @@ int check_detector_idle() {
return ret;
}
int is_configurable() {
if (udpDetails.srcip == 0) {
strcpy(configureMessage, "udp source ip not configured\n");
int is_udp_configured() {
if (udpDetails.dstip == 0) {
strcpy(configureMessage, "udp destination ip not configured\n");
LOG(logWARNING, ("%s", configureMessage));
return FAIL;
}
if (udpDetails.dstip == 0) {
strcpy(configureMessage, "udp destination ip not configured\n");
if (udpDetails.srcip == 0) {
strcpy(configureMessage, "udp source ip not configured\n");
LOG(logWARNING, ("%s", configureMessage));
return FAIL;
}
@ -4914,7 +4915,7 @@ int is_configurable() {
}
void configure_mac() {
if (is_configurable() == OK) {
if (is_udp_configured() == OK) {
ret = configureMAC();
if (ret != OK) {
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
@ -6329,44 +6330,52 @@ int get_inject_channel(int file_des) {
int set_veto_photon(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int args[3] = {-1, -1, -1};
int args[2] = {-1, -1};
if (receiveData(file_des, args, sizeof(args), INT32) < 0)
return printSocketReadError();
int values[args[2]];
memset(values, 0, sizeof(values));
const int chipIndex = args[0];
const int numChannels = args[1];
int gainIndices[numChannels];
if (receiveData(file_des, gainIndices, sizeof(gainIndices), INT32) < 0)
return printSocketReadError();
int values[numChannels];
if (receiveData(file_des, values, sizeof(values), INT32) < 0)
return printSocketReadError();
LOG(logINFO, ("Setting Veto Photon: [chipIndex:%d, G%d, nch:%d]\n", args[0],
args[1], args[2]));
LOG(logINFO, ("Setting Veto Photon: [chipIndex:%d, nch:%d]\n", chipIndex,
numChannels));
#ifndef GOTTHARD2D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
int chipIndex = args[0];
int gainIndex = args[1];
int numChannels = args[2];
if (chipIndex < -1 || chipIndex >= NCHIP) {
ret = FAIL;
sprintf(mess, "Could not set veto photon. Invalid chip index %d\n",
chipIndex);
LOG(logERROR, (mess));
} else if (gainIndex < 0 || gainIndex > 2) {
ret = FAIL;
sprintf(mess, "Could not set veto photon. Invalid gain index %d\n",
gainIndex);
LOG(logERROR, (mess));
} else if (numChannels != NCHAN) {
if (numChannels != NCHAN) {
ret = FAIL;
sprintf(mess,
"Could not set veto photon. Invalid number of channels %d. "
"Expected %d\n",
numChannels, NCHAN);
LOG(logERROR, (mess));
} else if (chipIndex < -1 || chipIndex >= NCHIP) {
ret = FAIL;
sprintf(mess, "Could not set veto photon. Invalid chip index %d\n",
chipIndex);
LOG(logERROR, (mess));
} else {
for (int i = 0; i < NCHAN; ++i) {
if (gainIndices[i] < 0 || gainIndices[i] > 2) {
ret = FAIL;
sprintf(mess,
"Could not set veto photon. Invalid gain index %d "
"for channel %d.\n",
gainIndices[i], i);
LOG(logERROR, (mess));
break;
}
if (values[i] > ADU_MAX_VAL) {
ret = FAIL;
sprintf(mess,
@ -6378,7 +6387,7 @@ int set_veto_photon(int file_des) {
}
}
if (ret == OK) {
ret = setVetoPhoton(chipIndex, gainIndex, values);
ret = setVetoPhoton(chipIndex, gainIndices, values);
if (ret == FAIL) {
sprintf(mess,
"Could not set veto photon for chip index %d\n",
@ -6398,6 +6407,8 @@ int get_veto_photon(int file_des) {
int arg = -1;
int retvals[NCHAN];
memset(retvals, 0, sizeof(retvals));
int gainRetvals[NCHAN];
memset(gainRetvals, 0, sizeof(gainRetvals));
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
@ -6414,14 +6425,16 @@ int get_veto_photon(int file_des) {
chipIndex);
LOG(logERROR, (mess));
} else {
ret = getVetoPhoton(chipIndex, retvals);
ret = getVetoPhoton(chipIndex, retvals, gainRetvals);
if (ret == FAIL) {
strcpy(mess, "Could not get veto photon for chipIndex -1. Not the "
"same for all chips.\n");
strcpy(mess,
"Could not get veto photon for chipIndex -1. Not the "
"same for all chips. Select specific chip index instead.\n");
LOG(logERROR, (mess));
} else {
for (int i = 0; i < NCHAN; ++i) {
LOG(logDEBUG1, ("%d:0x%x\n", i, retvals[i]));
LOG(logDEBUG1,
("%d:[%d, %d]\n", i, retvals[i], gainRetvals[i]));
}
}
}
@ -6430,6 +6443,7 @@ int get_veto_photon(int file_des) {
if (ret != FAIL) {
int nch = NCHAN;
sendData(file_des, &nch, sizeof(nch), INT32);
sendData(file_des, gainRetvals, sizeof(gainRetvals), INT32);
sendData(file_des, retvals, sizeof(retvals), INT32);
}
return ret;
@ -6443,7 +6457,7 @@ int set_veto_reference(int file_des) {
if (receiveData(file_des, args, sizeof(args), INT32) < 0)
return printSocketReadError();
LOG(logINFO,
("Setting Veto Reference: [G%d, value:0x%x]\n", args[0], args[1]));
("Setting Veto Reference: [G%d, value:%d]\n", args[0], args[1]));
#ifndef GOTTHARD2D
functionNotImplemented();
@ -6461,7 +6475,7 @@ int set_veto_reference(int file_des) {
} else if (value > ADU_MAX_VAL) {
ret = FAIL;
sprintf(mess,
"Could not set veto reference. Invalid ADU value 0x%x, "
"Could not set veto reference. Invalid ADU value %d, "
"must be 12 bit.\n",
value);
LOG(logERROR, (mess));
@ -7014,7 +7028,8 @@ int get_receiver_parameters(int file_des) {
return printSocketReadError();
// 10 gbe
#if defined(EIGERD) || defined(CHIPTESTBOARDD) || defined(MOENCHD)
#if defined(EIGERD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) || \
defined(MYTHEN3D)
i32 = enableTenGigabitEthernet(GET_FLAG);
#else
i32 = 0;
@ -7378,7 +7393,7 @@ int set_veto(int file_des) {
setVeto(arg);
// if numinterfaces is 2 and veto is 1 now, then configuremac
if (arg > 0 && getNumberofUDPInterfaces() == 2 &&
is_configurable() == OK) {
is_udp_configured() == OK) {
ret = configureMAC();
if (ret != OK) {
sprintf(mess, "Configure Mac failed after enabling veto\n");
@ -7763,78 +7778,6 @@ int set_filter(int file_des) {
return Server_SendResult(file_des, INT32, NULL, 0);
}
int set_veto_file(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int args[2] = {-1, -1};
if (receiveData(file_des, args, sizeof(args), INT32) < 0)
return printSocketReadError();
int chipIndex = args[0];
int nch = args[1];
int gainIndices[nch];
memset(gainIndices, 0, sizeof(gainIndices));
int values[nch];
memset(values, 0, sizeof(values));
if (receiveData(file_des, gainIndices, sizeof(gainIndices), INT32) < 0)
return printSocketReadError();
if (receiveData(file_des, values, sizeof(values), INT32) < 0)
return printSocketReadError();
LOG(logINFO,
("Setting Veto file: [chipIndex:%d, nch:%d]\n", chipIndex, nch));
#ifndef GOTTHARD2D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
if (chipIndex < -1 || chipIndex >= NCHIP) {
ret = FAIL;
sprintf(mess, "Could not set veto file. Invalid chip index %d\n",
chipIndex);
LOG(logERROR, (mess));
} else if (nch != NCHAN) {
ret = FAIL;
sprintf(mess,
"Could not set veto file. Invalid number of channels %d. "
"Expected %d\n",
nch, NCHAN);
LOG(logERROR, (mess));
} else {
for (int i = 0; i < NCHAN; ++i) {
if (values[i] < 0 || values[i] > ADU_MAX_VAL) {
ret = FAIL;
sprintf(mess,
"Could not set veto file. Invalid ADU value 0x%x "
"for channel %d, must be 12 bit.\n",
values[i], i);
LOG(logERROR, (mess));
break;
}
if (gainIndices[i] < 0 || gainIndices[i] > 2) {
ret = FAIL;
sprintf(mess,
"Could not set veto file. Invalid gain index %d "
"for channel %d\n",
gainIndices[i], i);
LOG(logERROR, (mess));
break;
}
}
if (ret == OK) {
ret = setVetoFile(chipIndex, gainIndices, values);
if (ret == FAIL) {
sprintf(mess, "Could not set veto file for chip index %d\n",
chipIndex);
LOG(logERROR, (mess));
}
}
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_adc_config(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
@ -8035,3 +7978,37 @@ int set_bad_channels(int file_des) {
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int reconfigure_udp(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
if (Server_VerifyLock() == OK) {
LOG(logINFO, ("Reconfiguring UDP\n"));
if (check_detector_idle() == OK) {
configure_mac();
if (configured == FAIL) {
ret = FAIL;
strcpy(mess, "Invalid UDP Configuration because ");
strcat(mess, configureMessage);
LOG(logERROR, (mess));
}
}
}
return Server_SendResult(file_des, INT32, NULL, 0);
}
int validate_udp_configuration(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
LOG(logINFO, ("Validating UDP Configuration\n"));
if (configured == FAIL) {
ret = FAIL;
strcpy(mess, "Invalid UDP Configuration because ");
strcat(mess, configureMessage);
LOG(logERROR, (mess));
}
return Server_SendResult(file_des, INT32, NULL, 0);
}

View File

@ -509,6 +509,10 @@ class Detector {
*/
void setDestinationUDPPort2(int port, int module_id = -1);
void reconfigureUDPDestination(Positions pos = {});
void validateUDPConfiguration(Positions pos = {});
Result<std::string> printRxConfiguration(Positions pos = {}) const;
/** [Eiger][CTB][Moench][Mythen3] */
@ -980,9 +984,9 @@ class Detector {
void setInjectChannel(const int offsetChannel, const int incrementChannel,
Positions pos = {});
/** [Gotthard2] adu values for each channel */
Result<std::vector<int>> getVetoPhoton(const int chipIndex,
Positions pos = {});
/** [Gotthard2] gain indices and adu values for each channel */
void getVetoPhoton(const int chipIndex, const std::string &fname,
Positions pos = {});
/** [Gotthard2] energy in keV */
void setVetoPhoton(const int chipIndex, const int numPhotons,
@ -993,7 +997,7 @@ class Detector {
void setVetoReference(const int gainIndex, const int value,
Positions pos = {});
/** [Gotthard2] */
/** [Gotthard2] gain indices and adu values for each channel */
void setVetoFile(const int chipIndex, const std::string &fname,
Positions pos = {});
@ -1469,6 +1473,7 @@ class Detector {
private:
std::vector<int> getPortNumbers(int start_port);
void updateRxRateCorrections();
};
} // namespace sls

View File

@ -1,4 +1,5 @@
#include "CmdProxy.h"
#include "bit_utils.h"
#include "TimeHelper.h"
#include "ToString.h"
#include "container_utils.h"
@ -1559,9 +1560,7 @@ std::string CmdProxy::ROI(int action) {
if (args.size() != 2) {
WrongNumberOfParameters(2);
}
defs::ROI t;
t.xmin = StringTo<int>(args[0]);
t.xmax = StringTo<int>(args[1]);
defs::ROI t(StringTo<int>(args[0]), StringTo<int>(args[1]));
det->setROI(t, det_id);
os << '[' << t.xmin << ", " << t.xmax << "]\n";
} else {
@ -1625,17 +1624,19 @@ std::string CmdProxy::VetoPhoton(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[n_chip] [#photons] [energy in keV] [reference "
os << "[ichip] [#photons] [energy in keV] [reference "
"file]\n\t[Gotthard2] Set veto reference for 128 channels for "
"chip n_chip according to referenc file and #photons and energy "
"in keV."
"chip ichip according to reference file and #photons and energy "
"in keV.\n"
<< "[ichip] [output file]\n\t Get gain indices and veto reference "
"for 128 channels for chip ichip, saved to file."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
if (args.size() != 2) {
WrongNumberOfParameters(2);
}
auto t = det->getVetoPhoton(StringTo<int>(args[0]), {det_id});
os << args[0] << ' ' << OutStringHex(t) << '\n';
det->getVetoPhoton(StringTo<int>(args[0]), args[1], {det_id});
os << "saved to file " << args[1] << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() != 4) {
WrongNumberOfParameters(4);
@ -1653,7 +1654,7 @@ std::string CmdProxy::VetoReference(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[gain index] [12 bit value in hex] \n\t[Gotthard2] Set veto "
os << "[gain index] [12 bit value] \n\t[Gotthard2] Set veto "
"reference for all 128 channels for all chips."
<< '\n';
} else if (action == defs::GET_ACTION) {
@ -1677,7 +1678,7 @@ std::string CmdProxy::VetoFile(int action) {
if (action == defs::HELP_ACTION) {
os << "[chip index 0-10, -1 for all] [file name] \n\t[Gotthard2] Set "
"veto reference for each 128 channels for specific chip. The "
"file should have 128 rows of gain index and 12 bit value in hex"
"file should have 128 rows of gain index and 12 bit value in dec"
<< '\n';
} else if (action == defs::GET_ACTION) {
throw sls::RuntimeError(
@ -1810,14 +1811,7 @@ std::string CmdProxy::Counters(int action) {
WrongNumberOfParameters(0);
}
auto mask = det->getCounterMask({det_id}).squash(-1);
// scan counter enable mask to get vector
std::vector<int> result;
for (size_t i = 0; i < 32; ++i) {
if (mask & (1 << i)) {
result.push_back(static_cast<int>(i));
}
}
os << sls::ToString(result) << '\n';
os << sls::ToString(getSetBits(mask)) << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.empty()) {
WrongNumberOfParameters(1);

View File

@ -528,6 +528,7 @@ class CmdProxy {
{"cycles", "triggers"},
{"cyclesl", "triggersl"},
{"clkdivider", "speed"},
{"vhighvoltage", "highvoltage"},
{"digitest", "imagetest"},
/** temperature */
@ -654,7 +655,7 @@ class CmdProxy {
{"clkphase", &CmdProxy::ClockPhase},
{"maxclkphaseshift", &CmdProxy::MaxClockPhaseShift},
{"clkdiv", &CmdProxy::ClockDivider},
{"vhighvoltage", &CmdProxy::vhighvoltage},
{"highvoltage", &CmdProxy::highvoltage},
{"powerchip", &CmdProxy::powerchip},
{"imagetest", &CmdProxy::imagetest},
{"extsig", &CmdProxy::ExternalSignal},
@ -775,6 +776,8 @@ class CmdProxy {
{"udp_dstmac2", &CmdProxy::udp_dstmac2},
{"udp_dstport", &CmdProxy::udp_dstport},
{"udp_dstport2", &CmdProxy::udp_dstport2},
{"udp_reconfigure", &CmdProxy::udp_reconfigure},
{"udp_validate", &CmdProxy::udp_validate},
{"rx_printconfig", &CmdProxy::rx_printconfig},
{"tengiga", &CmdProxy::tengiga},
{"flowcontrol10g", &CmdProxy::flowcontrol10g},
@ -1185,7 +1188,7 @@ class CmdProxy {
"\n\t[CTB][Jungfrau] Absolute maximum Phase shift of of the "
"clock to latch digital bits.");
INTEGER_COMMAND(vhighvoltage, getHighVoltage, setHighVoltage, StringTo<int>,
INTEGER_COMMAND(highvoltage, getHighVoltage, setHighVoltage, StringTo<int>,
"[n_value]\n\tHigh voltage to the sensor in Voltage."
"\n\t[Gotthard] [0|90|110|120|150|180|200]"
"\n\t[Eiger][Mythen3][Gotthard2] 0-200"
@ -1644,6 +1647,18 @@ class CmdProxy {
"sent to. \n[Eiger] Port number of the reciever (desintation) udp "
"interface where the right half of the detector data is sent to.");
EXECUTE_SET_COMMAND(
udp_reconfigure, reconfigureUDPDestination,
"\n\tReconfigures Detector with UDP destination. More for debugging as "
"the configuration is done automatically when the detector has "
"sufficient UDP details.");
EXECUTE_SET_COMMAND(
udp_validate, validateUDPConfiguration,
"\n\tValidates that UDP configuration in the detector is "
"valid. If not configured, it will throw with error message "
"requesting missing udp information.");
GET_COMMAND(rx_printconfig, printRxConfiguration,
"\n\tPrints the receiver configuration.");

View File

@ -9,8 +9,8 @@
#include "sls_detector_defs.h"
#include "versionAPI.h"
#include <fstream>
#include <chrono>
#include <fstream>
#include <thread>
namespace sls {
@ -281,6 +281,7 @@ Result<int> Detector::getDynamicRange(Positions pos) const {
void Detector::setDynamicRange(int value) {
pimpl->Parallel(&Module::setDynamicRange, {}, value);
updateRxRateCorrections();
}
Result<defs::timingMode> Detector::getTimingMode(Positions pos) const {
@ -715,6 +716,14 @@ void Detector::setDestinationUDPPort2(int port, int module_id) {
}
}
void Detector::reconfigureUDPDestination(Positions pos) {
pimpl->Parallel(&Module::reconfigureUDPDestination, pos);
}
void Detector::validateUDPConfiguration(Positions pos) {
pimpl->Parallel(&Module::validateUDPConfiguration, pos);
}
Result<std::string> Detector::printRxConfiguration(Positions pos) const {
return pimpl->Parallel(&Module::printReceiverConfiguration, pos);
}
@ -771,6 +780,7 @@ Result<std::string> Detector::getRxHostname(Positions pos) const {
void Detector::setRxHostname(const std::string &receiver, Positions pos) {
pimpl->Parallel(&Module::setReceiverHostname, pos, receiver);
updateRxRateCorrections();
}
void Detector::setRxHostname(const std::vector<std::string> &name) {
@ -788,6 +798,7 @@ void Detector::setRxHostname(const std::vector<std::string> &name) {
pimpl->Parallel(&Module::setReceiverHostname, {idet}, name[idet]);
}
}
updateRxRateCorrections();
}
Result<int> Detector::getRxPort(Positions pos) const {
@ -1038,6 +1049,7 @@ Result<ns> Detector::getSubExptime(Positions pos) const {
void Detector::setSubExptime(ns t, Positions pos) {
pimpl->Parallel(&Module::setSubExptime, pos, t.count());
updateRxRateCorrections();
}
Result<ns> Detector::getSubDeadTime(Positions pos) const {
@ -1105,10 +1117,25 @@ Result<ns> Detector::getRateCorrection(Positions pos) const {
void Detector::setDefaultRateCorrection(Positions pos) {
pimpl->Parallel(&Module::setDefaultRateCorrection, pos);
updateRxRateCorrections();
}
void Detector::setRateCorrection(ns dead_time, Positions pos) {
pimpl->Parallel(&Module::setRateCorrection, pos, dead_time.count());
updateRxRateCorrections();
}
void Detector::updateRxRateCorrections() {
// get tau from all modules and send to Rx index 0
if (getDetectorType().squash() == defs::EIGER) {
if (getUseReceiverFlag().squash(false)) {
std::vector<int64_t> dead_times;
for (auto item : getRateCorrection())
dead_times.push_back(item.count());
pimpl->Parallel(&Module::sendReceiverRateCorrections, {0},
dead_times);
}
}
}
Result<int> Detector::getPartialReadout(Positions pos) const {
@ -1290,9 +1317,9 @@ void Detector::setInjectChannel(const int offsetChannel,
incrementChannel);
}
Result<std::vector<int>> Detector::getVetoPhoton(const int chipIndex,
Positions pos) {
return pimpl->Parallel(&Module::getVetoPhoton, pos, chipIndex);
void Detector::getVetoPhoton(const int chipIndex, const std::string &fname,
Positions pos) {
pimpl->Parallel(&Module::getVetoPhoton, pos, chipIndex, fname);
}
void Detector::setVetoPhoton(const int chipIndex, const int numPhotons,
@ -1405,6 +1432,7 @@ Result<ns> Detector::getExptime(int gateIndex, Positions pos) const {
void Detector::setExptime(int gateIndex, ns t, Positions pos) {
pimpl->Parallel(&Module::setExptime, pos, gateIndex, t.count());
updateRxRateCorrections();
}
Result<std::array<ns, 3>> Detector::getExptimeForAllGates(Positions pos) const {

View File

@ -434,7 +434,8 @@ void DetectorImpl::readFrameFromReceiver() {
numInterfaces = Parallel(&Module::getNumberofUDPInterfacesFromShm, {})
.squash(); // cannot pick up from zmq
}
bool runningList[zmqSocket.size()], connectList[zmqSocket.size()];
std::vector<bool> runningList(zmqSocket.size());
std::vector<bool> connectList(zmqSocket.size());
int numRunning = 0;
for (size_t i = 0; i < zmqSocket.size(); ++i) {
if (zmqSocket[i]->Connect() == 0) {

File diff suppressed because it is too large Load Diff

View File

@ -78,7 +78,7 @@ class Module : public virtual slsDetectorDefs {
Safe to call only if detector shm also deleted or its numberOfDetectors is
updated */
void freeSharedMemory();
bool isFixedPatternSharedMemoryCompatible();
bool isFixedPatternSharedMemoryCompatible() const;
std::string getHostname() const;
/** initialChecks is enable or disable initial compatibility checks and
@ -86,9 +86,9 @@ class Module : public virtual slsDetectorDefs {
users! */
void setHostname(const std::string &hostname, const bool initialChecks);
int64_t getFirmwareVersion();
int64_t getDetectorServerVersion();
int64_t getSerialNumber();
int64_t getFirmwareVersion() const;
int64_t getDetectorServerVersion() const;
int64_t getSerialNumber() const;
int64_t getReceiverSoftwareVersion() const;
static detectorType getTypeFromDetector(const std::string &hostname,
int cport = DEFAULT_PORTNO);
@ -98,10 +98,10 @@ class Module : public virtual slsDetectorDefs {
void updateNumberOfChannels();
slsDetectorDefs::xy getNumberOfChannels() const;
void updateNumberOfDetector(slsDetectorDefs::xy det);
detectorSettings getSettings();
detectorSettings getSettings() const;
void setSettings(detectorSettings isettings);
void loadSettingsFile(const std::string &fname);
int getAllTrimbits();
int getAllTrimbits() const;
void setAllTrimbits(int val);
/**************************************************
@ -109,45 +109,45 @@ class Module : public virtual slsDetectorDefs {
* Acquisition Parameters *
* *
* ************************************************/
int64_t getNumberOfFrames();
int64_t getNumberOfFrames() const;
void setNumberOfFrames(int64_t value);
int64_t getNumberOfTriggers();
int64_t getNumberOfTriggers() const;
void setNumberOfTriggers(int64_t value);
/** [Mythen3] gatIndex: 0-2, [Others]: -1 always */
int64_t getExptime(int gateIndex);
int64_t getExptime(int gateIndex) const;
/** [Mythen3] gatIndex: -1 for all, 0-2, [Others]: -1 always */
void setExptime(int gateIndex, int64_t value);
int64_t getPeriod();
int64_t getPeriod() const;
void setPeriod(int64_t value);
int64_t getDelayAfterTrigger();
int64_t getDelayAfterTrigger() const;
void setDelayAfterTrigger(int64_t value);
int64_t getNumberOfFramesLeft() const;
int64_t getNumberOfTriggersLeft() const;
int64_t getDelayAfterTriggerLeft() const;
int64_t getPeriodLeft() const;
int getDynamicRange();
void setDynamicRange(int n);
timingMode getTimingMode();
int getDynamicRange() const;
void setDynamicRange(int dr);
timingMode getTimingMode() const;
void setTimingMode(timingMode value);
int getClockDivider(int clkIndex);
int getClockDivider(int clkIndex) const;
void setClockDivider(int clkIndex, int value);
int getClockPhase(int clkIndex, bool inDegrees);
int getClockPhase(int clkIndex, bool inDegrees) const;
void setClockPhase(int clkIndex, int value, bool inDegrees);
int getMaxClockPhaseShift(int clkIndex);
int getClockFrequency(int clkIndex);
int getMaxClockPhaseShift(int clkIndex) const;
int getClockFrequency(int clkIndex) const;
void setClockFrequency(int clkIndex, int value);
int getDAC(dacIndex index, bool mV);
int getDAC(dacIndex index, bool mV) const;
void setDAC(int val, dacIndex index, bool mV);
bool getPowerChip();
bool getPowerChip() const;
void setPowerChip(bool on);
int getImageTestMode();
int getImageTestMode() const;
void setImageTestMode(const int value);
/* temperature in millidegrees */
int getADC(dacIndex index);
int getOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex);
int getADC(dacIndex index) const;
int getOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex) const;
void setOnChipDAC(slsDetectorDefs::dacIndex index, int chipIndex,
int value);
externalSignalFlag getExternalSignalFlags(int signalIndex);
externalSignalFlag getExternalSignalFlags(int signalIndex) const;
void setExternalSignalFlags(int signalIndex, externalSignalFlag type);
/**************************************************
@ -165,53 +165,55 @@ class Module : public virtual slsDetectorDefs {
int getReceiverProgress() const;
int64_t getFramesCaughtByReceiver() const;
std::vector<uint64_t> getNumMissingPackets() const;
uint64_t getStartingFrameNumber();
uint64_t getStartingFrameNumber() const;
void setStartingFrameNumber(uint64_t value);
void sendSoftwareTrigger();
defs::scanParameters getScan();
defs::scanParameters getScan() const;
void setScan(const defs::scanParameters t);
std::string getScanErrorMessage();
std::string getScanErrorMessage() const;
/**************************************************
* *
* Network Configuration (Detector<->Receiver) *
* *
* ************************************************/
int getNumberofUDPInterfacesFromShm();
int getNumberofUDPInterfaces();
int getNumberofUDPInterfacesFromShm() const;
int getNumberofUDPInterfaces() const;
void setNumberofUDPInterfaces(int n);
int getSelectedUDPInterface();
int getSelectedUDPInterface() const;
void selectUDPInterface(int n);
sls::IpAddr getSourceUDPIP();
sls::IpAddr getSourceUDPIP() const;
void setSourceUDPIP(const sls::IpAddr ip);
sls::IpAddr getSourceUDPIP2();
sls::IpAddr getSourceUDPIP2() const;
void setSourceUDPIP2(const sls::IpAddr ip);
sls::MacAddr getSourceUDPMAC();
sls::MacAddr getSourceUDPMAC() const;
void setSourceUDPMAC(const sls::MacAddr mac);
sls::MacAddr getSourceUDPMAC2();
sls::MacAddr getSourceUDPMAC2() const;
void setSourceUDPMAC2(const sls::MacAddr mac);
sls::IpAddr getDestinationUDPIP();
sls::IpAddr getDestinationUDPIP() const;
void setDestinationUDPIP(const sls::IpAddr ip);
sls::IpAddr getDestinationUDPIP2();
sls::IpAddr getDestinationUDPIP2() const;
void setDestinationUDPIP2(const sls::IpAddr ip);
sls::MacAddr getDestinationUDPMAC();
sls::MacAddr getDestinationUDPMAC() const;
void setDestinationUDPMAC(const sls::MacAddr mac);
sls::MacAddr getDestinationUDPMAC2();
sls::MacAddr getDestinationUDPMAC2() const;
void setDestinationUDPMAC2(const sls::MacAddr mac);
int getDestinationUDPPort();
int getDestinationUDPPort() const;
void setDestinationUDPPort(int udpport);
int getDestinationUDPPort2();
int getDestinationUDPPort2() const;
void setDestinationUDPPort2(int udpport);
void reconfigureUDPDestination();
void validateUDPConfiguration();
std::string printReceiverConfiguration();
bool getTenGiga();
bool getTenGiga() const;
void setTenGiga(bool value);
bool getTenGigaFlowControl();
bool getTenGigaFlowControl() const;
void setTenGigaFlowControl(bool enable);
int getTransmissionDelayFrame();
int getTransmissionDelayFrame() const;
void setTransmissionDelayFrame(int value);
int getTransmissionDelayLeft();
int getTransmissionDelayLeft() const;
void setTransmissionDelayLeft(int value);
int getTransmissionDelayRight();
int getTransmissionDelayRight() const;
void setTransmissionDelayRight(int value);
/**************************************************
@ -224,18 +226,18 @@ class Module : public virtual slsDetectorDefs {
void setReceiverHostname(const std::string &receiver);
int getReceiverPort() const;
int setReceiverPort(int port_number);
int getReceiverFifoDepth();
int getReceiverFifoDepth() const;
void setReceiverFifoDepth(int n_frames);
bool getReceiverSilentMode();
bool getReceiverSilentMode() const;
void setReceiverSilentMode(bool enable);
frameDiscardPolicy getReceiverFramesDiscardPolicy();
frameDiscardPolicy getReceiverFramesDiscardPolicy() const;
void setReceiverFramesDiscardPolicy(frameDiscardPolicy f);
bool getPartialFramesPadding();
bool getPartialFramesPadding() const;
void setPartialFramesPadding(bool padding);
int64_t getReceiverUDPSocketBufferSize() const;
int64_t getReceiverRealUDPSocketBufferSize() const;
void setReceiverUDPSocketBufferSize(int64_t udpsockbufsize);
bool getReceiverLock();
bool getReceiverLock() const;
void setReceiverLock(bool lock);
sls::IpAddr getReceiverLastClientIP() const;
std::array<pid_t, NUM_RX_THREAD_IDS> getReceiverThreadIds() const;
@ -245,22 +247,22 @@ class Module : public virtual slsDetectorDefs {
* File *
* *
* ************************************************/
fileFormat getFileFormat();
fileFormat getFileFormat() const;
void setFileFormat(fileFormat f);
std::string getFilePath();
std::string getFilePath() const;
void setFilePath(const std::string &path);
std::string getFileName();
std::string getFileName() const;
void setFileName(const std::string &fname);
int64_t getFileIndex();
int64_t getFileIndex() const;
void setFileIndex(int64_t file_index);
void incrementFileIndex();
bool getFileWrite();
bool getFileWrite() const;
void setFileWrite(bool value);
bool getMasterFileWrite();
bool getMasterFileWrite() const;
void setMasterFileWrite(bool value);
bool getFileOverWrite();
bool getFileOverWrite() const;
void setFileOverWrite(bool value);
int getFramesPerFile();
int getFramesPerFile() const;
/** 0 will set frames per file to unlimited */
void setFramesPerFile(int n_frames);
@ -269,22 +271,22 @@ class Module : public virtual slsDetectorDefs {
* ZMQ Streaming Parameters (Receiver<->Client)*
* *
* ************************************************/
bool getReceiverStreaming();
bool getReceiverStreaming() const;
void setReceiverStreaming(bool enable);
int getReceiverStreamingFrequency();
int getReceiverStreamingFrequency() const;
/** Option: nth frame streamed out, if 0, streamed out at a timer of 200 */
void setReceiverStreamingFrequency(int freq);
int getReceiverStreamingTimer();
int getReceiverStreamingTimer() const;
void setReceiverStreamingTimer(int time_in_ms = 200);
int getReceiverStreamingStartingFrame();
int getReceiverStreamingStartingFrame() const;
void setReceiverStreamingStartingFrame(int fnum);
int getReceiverStreamingPort();
int getReceiverStreamingPort() const;
void setReceiverStreamingPort(int port);
sls::IpAddr getReceiverStreamingIP();
sls::IpAddr getReceiverStreamingIP() const;
void setReceiverStreamingIP(const sls::IpAddr ip);
int getClientStreamingPort();
int getClientStreamingPort() const;
void setClientStreamingPort(int port);
sls::IpAddr getClientStreamingIP();
sls::IpAddr getClientStreamingIP() const;
void setClientStreamingIP(const sls::IpAddr ip);
/**************************************************
@ -292,42 +294,43 @@ class Module : public virtual slsDetectorDefs {
* Eiger Specific *
* *
* ************************************************/
int64_t getSubExptime();
int64_t getSubExptime() const;
void setSubExptime(int64_t value);
int64_t getSubDeadTime();
int64_t getSubDeadTime() const;
void setSubDeadTime(int64_t value);
int getThresholdEnergy();
int getThresholdEnergy() const;
void setThresholdEnergy(int e_eV, detectorSettings isettings,
bool trimbits);
std::string getSettingsDir();
std::string getSettingsDir() const;
std::string setSettingsDir(const std::string &dir);
bool getParallelMode();
bool getParallelMode() const;
void setParallelMode(const bool enable);
bool getOverFlowMode();
bool getOverFlowMode() const;
void setOverFlowMode(const bool enable);
bool getFlippedDataX();
bool getFlippedDataX() const;
void setFlippedDataX(bool value);
std::vector<int> getTrimEn();
std::vector<int> getTrimEn() const;
int setTrimEn(const std::vector<int> &energies = {});
int64_t getRateCorrection();
int64_t getRateCorrection() const;
void setDefaultRateCorrection();
void setRateCorrection(int64_t t = 0);
int getReadNLines();
void sendReceiverRateCorrections(const std::vector<int64_t> &t);
int getReadNLines() const;
void setReadNLines(const int value);
bool getInterruptSubframe();
bool getInterruptSubframe() const;
void setInterruptSubframe(const bool enable);
int64_t getMeasuredPeriod() const;
int64_t getMeasuredSubFramePeriod() const;
bool getActivate();
bool getActivate() const;
void setActivate(const bool enable);
bool getDeactivatedRxrPaddingMode();
bool getDeactivatedRxrPaddingMode() const;
void setDeactivatedRxrPaddingMode(bool padding);
bool getCounterBit();
bool getCounterBit() const;
void setCounterBit(bool cb);
void pulsePixel(int n = 0, int x = 0, int y = 0);
void pulsePixelNMove(int n = 0, int x = 0, int y = 0);
void pulseChip(int n_pulses = 0);
bool getQuad();
bool getQuad() const;
void setQuad(const bool enable);
/**************************************************
@ -335,19 +338,19 @@ class Module : public virtual slsDetectorDefs {
* Jungfrau Specific *
* *
* ************************************************/
int getThresholdTemperature();
int getThresholdTemperature() const;
void setThresholdTemperature(int val);
bool getTemperatureControl();
bool getTemperatureControl() const;
void setTemperatureControl(bool val);
int getTemperatureEvent();
int getTemperatureEvent() const;
void resetTemperatureEvent();
bool getAutoComparatorDisableMode();
bool getAutoComparatorDisableMode() const;
void setAutoComparatorDisableMode(bool val);
int getNumberOfAdditionalStorageCells();
int getNumberOfAdditionalStorageCells() const;
void setNumberOfAdditionalStorageCells(int value);
int getStorageCellStart();
int getStorageCellStart() const;
void setStorageCellStart(int pos);
int64_t getStorageCellDelay();
int64_t getStorageCellDelay() const;
void setStorageCellDelay(int64_t value);
/**************************************************
@ -355,7 +358,7 @@ class Module : public virtual slsDetectorDefs {
* Gotthard Specific *
* *
* ************************************************/
slsDetectorDefs::ROI getROI();
slsDetectorDefs::ROI getROI() const;
void setROI(slsDetectorDefs::ROI arg);
void clearROI();
int64_t getExptimeLeft() const;
@ -365,33 +368,36 @@ class Module : public virtual slsDetectorDefs {
* Gotthard2 Specific *
* *
* ************************************************/
int64_t getNumberOfBursts();
int64_t getNumberOfBursts() const;
void setNumberOfBursts(int64_t value);
int64_t getBurstPeriod();
int64_t getBurstPeriod() const;
void setBurstPeriod(int64_t value);
std::array<int, 2> getInjectChannel();
std::array<int, 2> getInjectChannel() const;
void setInjectChannel(const int offsetChannel, const int incrementChannel);
std::vector<int> getVetoPhoton(const int chipIndex);
void sendVetoPhoton(const int chipIndex,
const std::vector<int> &gainIndices,
const std::vector<int> &values);
void getVetoPhoton(const int chipIndex, const std::string &fname) const;
void setVetoPhoton(const int chipIndex, const int numPhotons,
const int energy, const std::string &fname);
void setVetoReference(const int gainIndex, const int value);
void setVetoFile(const int chipIndex, const std::string &fname);
burstMode getBurstMode();
burstMode getBurstMode() const;
void setBurstMode(burstMode value);
bool getCDSGain();
bool getCDSGain() const;
void setCDSGain(bool value);
int getFilter();
int getFilter() const;
void setFilter(int value);
bool getCurrentSource();
bool getCurrentSource() const;
void setCurrentSource(bool value);
slsDetectorDefs::timingSourceType getTimingSource();
slsDetectorDefs::timingSourceType getTimingSource() const;
void setTimingSource(slsDetectorDefs::timingSourceType value);
bool getVeto();
bool getVeto() const;
void setVeto(bool enable);
int getADCConfiguration(const int chipIndex, const int adcIndex);
int getADCConfiguration(const int chipIndex, const int adcIndex) const;
void setADCConfiguration(const int chipIndex, const int adcIndex,
int value);
void getBadChannels(const std::string &fname);
void getBadChannels(const std::string &fname) const;
void setBadChannels(const std::string &fname);
/**************************************************
@ -399,27 +405,27 @@ class Module : public virtual slsDetectorDefs {
* Mythen3 Specific *
* *
* ************************************************/
uint32_t getCounterMask();
uint32_t getCounterMask() const;
void setCounterMask(uint32_t countermask);
int getNumberOfGates();
int getNumberOfGates() const;
void setNumberOfGates(int value);
std::array<time::ns, 3> getExptimeForAllGates();
int64_t getGateDelay(int gateIndex);
std::array<time::ns, 3> getExptimeForAllGates() const;
int64_t getGateDelay(int gateIndex) const;
void setGateDelay(int gateIndex, int64_t value);
std::array<time::ns, 3> getGateDelayForAllGates();
std::array<time::ns, 3> getGateDelayForAllGates() const;
/**************************************************
* *
* CTB / Moench Specific *
* *
* ************************************************/
int getNumberOfAnalogSamples();
int getNumberOfAnalogSamples() const;
void setNumberOfAnalogSamples(int value);
int getPipeline(int clkIndex);
int getPipeline(int clkIndex) const;
void setPipeline(int clkIndex, int value);
uint32_t getADCEnableMask();
uint32_t getADCEnableMask() const;
void setADCEnableMask(uint32_t mask);
uint32_t getTenGigaADCEnableMask();
uint32_t getTenGigaADCEnableMask() const;
void setTenGigaADCEnableMask(uint32_t mask);
/**************************************************
@ -427,20 +433,20 @@ class Module : public virtual slsDetectorDefs {
* CTB Specific *
* *
* ************************************************/
int getNumberOfDigitalSamples();
int getNumberOfDigitalSamples() const;
void setNumberOfDigitalSamples(int value);
readoutMode getReadoutMode();
readoutMode getReadoutMode() const;
void setReadoutMode(const readoutMode mode);
int getExternalSamplingSource();
int setExternalSamplingSource(int value);
bool getExternalSampling();
bool getExternalSampling() const;
void setExternalSampling(bool value);
std::vector<int> getReceiverDbitList() const;
void setReceiverDbitList(const std::vector<int> &list);
int getReceiverDbitOffset();
int getReceiverDbitOffset() const;
void setReceiverDbitOffset(int value);
void setDigitalIODelay(uint64_t pinMask, int delay);
bool getLEDEnable();
bool getLEDEnable() const;
void setLEDEnable(bool enable);
/**************************************************
@ -449,21 +455,21 @@ class Module : public virtual slsDetectorDefs {
* *
* ************************************************/
void setPattern(const std::string &fname);
uint64_t getPatternIOControl();
uint64_t getPatternIOControl() const;
void setPatternIOControl(uint64_t word);
uint64_t getPatternWord(int addr);
uint64_t getPatternWord(int addr) const;
void setPatternWord(int addr, uint64_t word);
std::array<int, 2> getPatternLoopAddresses(int level);
std::array<int, 2> getPatternLoopAddresses(int level) const;
void setPatternLoopAddresses(int level, int start, int stop);
int getPatternLoopCycles(int level);
int getPatternLoopCycles(int level) const;
void setPatternLoopCycles(int level, int n);
int getPatternWaitAddr(int level);
int getPatternWaitAddr(int level) const;
void setPatternWaitAddr(int level, int addr);
uint64_t getPatternWaitTime(int level);
uint64_t getPatternWaitTime(int level) const;
void setPatternWaitTime(int level, uint64_t t);
uint64_t getPatternMask();
uint64_t getPatternMask() const;
void setPatternMask(uint64_t mask);
uint64_t getPatternBitMask();
uint64_t getPatternBitMask() const;
void setPatternBitMask(uint64_t mask);
void startPattern();
@ -472,10 +478,10 @@ class Module : public virtual slsDetectorDefs {
* Moench *
* *
* ************************************************/
std::map<std::string, std::string> getAdditionalJsonHeader();
std::map<std::string, std::string> getAdditionalJsonHeader() const;
void setAdditionalJsonHeader(
const std::map<std::string, std::string> &jsonHeader);
std::string getAdditionalJsonParameter(const std::string &key);
std::string getAdditionalJsonParameter(const std::string &key) const;
void setAdditionalJsonParameter(const std::string &key,
const std::string &value);
@ -489,14 +495,14 @@ class Module : public virtual slsDetectorDefs {
void copyDetectorServer(const std::string &fname,
const std::string &hostname);
void rebootController();
uint32_t readRegister(uint32_t addr);
uint32_t readRegister(uint32_t addr) const;
uint32_t writeRegister(uint32_t addr, uint32_t val);
uint32_t setBit(uint32_t addr, int n);
uint32_t clearBit(uint32_t addr, int n);
void executeFirmwareTest();
void executeBusTest();
void writeAdcRegister(uint32_t addr, uint32_t val);
uint32_t getADCInvert();
uint32_t getADCInvert() const;
void setADCInvert(uint32_t value);
/**************************************************
@ -505,12 +511,12 @@ class Module : public virtual slsDetectorDefs {
* *
* ************************************************/
int getControlPort() const;
int setControlPort(int port_number);
void setControlPort(int port_number);
int getStopPort() const;
int setStopPort(int port_number);
bool getLockDetector();
void setStopPort(int port_number);
bool getLockDetector() const;
void setLockDetector(bool lock);
sls::IpAddr getLastClientIP();
sls::IpAddr getLastClientIP() const;
std::string execCommand(const std::string &cmd);
int64_t getNumberOfFramesFromStart() const;
int64_t getActualTime() const;
@ -518,6 +524,9 @@ class Module : public virtual slsDetectorDefs {
uint64_t getReceiverCurrentFrameIndex() const;
private:
void checkArgs(const void *args, size_t args_size, void *retval,
size_t retval_size) const;
/**
* Send function parameters to detector (control server)
* @param fnum function enum
@ -529,19 +538,39 @@ class Module : public virtual slsDetectorDefs {
void sendToDetector(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
void sendToDetector(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const;
template <typename Arg, typename Ret>
void sendToDetector(int fnum, const Arg &args, Ret &retval);
template <typename Arg, typename Ret>
void sendToDetector(int fnum, const Arg &args, Ret &retval) const;
template <typename Arg>
void sendToDetector(int fnum, const Arg &args, std::nullptr_t);
template <typename Arg>
void sendToDetector(int fnum, const Arg &args, std::nullptr_t) const;
template <typename Ret>
void sendToDetector(int fnum, std::nullptr_t, Ret &retval);
template <typename Ret>
void sendToDetector(int fnum, std::nullptr_t, Ret &retval) const;
void sendToDetector(int fnum);
void sendToDetector(int fnum) const;
template <typename Ret> Ret sendToDetector(int fnum);
template <typename Ret> Ret sendToDetector(int fnum) const;
template <typename Ret, typename Arg>
Ret sendToDetector(int fnum, const Arg &args);
template <typename Ret, typename Arg>
Ret sendToDetector(int fnum, const Arg &args) const;
/** Send function parameters to detector (stop server) */
void sendToDetectorStop(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
@ -578,6 +607,9 @@ class Module : public virtual slsDetectorDefs {
template <typename Ret, typename Arg>
Ret sendToDetectorStop(int fnum, const Arg &args);
template <typename Ret, typename Arg>
Ret sendToDetectorStop(int fnum, const Arg &args) const;
/** Send function parameters to receiver */
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);

View File

@ -316,7 +316,9 @@ TEST_CASE("vetophoton", "[.cmd][.new]") {
if (det_type == defs::GOTTHARD2) {
REQUIRE_THROWS(proxy.Call("vetophoton", {}, -1, GET));
REQUIRE_NOTHROW(proxy.Call("vetophoton", {"-1"}, -1, GET));
REQUIRE_THROWS(proxy.Call("vetophoton", {"-1"}, -1, GET));
REQUIRE_NOTHROW(
proxy.Call("vetophoton", {"-1", "/tmp/bla.txt"}, -1, GET));
REQUIRE_THROWS(proxy.Call("vetophoton", {"12", "1", "39950"}, -1,
PUT)); // invalid chip index
REQUIRE_THROWS(proxy.Call("vetophoton", {"-1", "0"}, -1,
@ -324,7 +326,8 @@ TEST_CASE("vetophoton", "[.cmd][.new]") {
REQUIRE_THROWS(proxy.Call("vetophoton", {"-1", "1", "39950"}, -1,
PUT)); // invald file
} else {
REQUIRE_THROWS(proxy.Call("vetophoton", {"-1"}, -1, GET));
REQUIRE_THROWS(
proxy.Call("vetophoton", {"-1", "/tmp/bla.txt"}, -1, GET));
}
}

View File

@ -36,6 +36,7 @@ TEST_CASE("rx_version", "[.cmd][.rx][.new]") {
TEST_CASE("rx_start", "[.cmd][.rx][.new]") {
Detector det;
CmdProxy proxy(&det);
det.setFileWrite(false); //avoid writing or error on file creation
// PUT only command
REQUIRE_THROWS(proxy.Call("rx_start", {}, -1, GET));
{
@ -69,6 +70,7 @@ TEST_CASE("rx_stop", "[.cmd][.rx][.new]") {
TEST_CASE("rx_status", "[.cmd][.rx][.new]") {
Detector det;
det.setFileWrite(false); //avoid writing or error on file creation
CmdProxy proxy(&det);
det.startReceiver();
{
@ -89,6 +91,7 @@ TEST_CASE("rx_framescaught", "[.cmd][.rx][.new]") {
CmdProxy proxy(&det);
// This ensures 0 caught frames
det.setFileWrite(false); //avoid writing or error on file creation
det.startReceiver();
det.stopReceiver();
{
@ -110,6 +113,7 @@ TEST_CASE("rx_framescaught", "[.cmd][.rx][.new]") {
TEST_CASE("rx_missingpackets", "[.cmd][.rx][.new]") {
Detector det;
det.setFileWrite(false); //avoid writing or error on file creation
CmdProxy proxy(&det);
{
// some missing packets

View File

@ -793,97 +793,97 @@ TEST_CASE("maxclkphaseshift", "[.cmd][.new]") {
}
}
TEST_CASE("vhighvoltage", "[.cmd][.new]") {
TEST_CASE("highvoltage", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
auto prev_val = det.getHighVoltage();
// selected values
if (det_type == defs::GOTTHARD) {
REQUIRE_THROWS(proxy.Call("vhighvoltage", {"50"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("highvoltage", {"50"}, -1, PUT));
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"90"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 90\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 90\n");
proxy.Call("highvoltage", {"90"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 90\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 90\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 0\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 0\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 0\n");
}
}
// range 0, 60 - 200
else if (det_type == defs::JUNGFRAU || det_type == defs::CHIPTESTBOARD ||
det_type == defs::MOENCH) {
REQUIRE_THROWS(proxy.Call("vhighvoltage", {"50"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("highvoltage", {"50"}, -1, PUT));
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"90"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 90\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 90\n");
proxy.Call("highvoltage", {"90"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 90\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 90\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 0\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 0\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 0\n");
}
}
// full range 0 - 200 (get needs to wait)
else if (det_type == defs::EIGER) {
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"50"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 50\n");
proxy.Call("highvoltage", {"50"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 50\n");
std::this_thread::sleep_for(std::chrono::seconds(2));
proxy.Call("vhighvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 50\n");
proxy.Call("highvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 50\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"120"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 120\n");
proxy.Call("highvoltage", {"120"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 120\n");
std::this_thread::sleep_for(std::chrono::seconds(2));
proxy.Call("vhighvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 120\n");
proxy.Call("highvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 120\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"0"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {"0"}, 0, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 0\n");
std::this_thread::sleep_for(std::chrono::seconds(2));
proxy.Call("vhighvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {}, 0, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 0\n");
}
}
// full range 0 - 200
else {
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"50"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 50\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 50\n");
proxy.Call("highvoltage", {"50"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 50\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 50\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"120"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 120\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 120\n");
proxy.Call("highvoltage", {"120"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 120\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 120\n");
}
{
std::ostringstream oss1, oss2;
proxy.Call("vhighvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "vhighvoltage 0\n");
proxy.Call("vhighvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "vhighvoltage 0\n");
proxy.Call("highvoltage", {"0"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "highvoltage 0\n");
proxy.Call("highvoltage", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "highvoltage 0\n");
}
}
for (int i = 0; i != det.size(); ++i) {
@ -1267,70 +1267,73 @@ TEST_CASE("scan", "[.cmd][.new]") {
std::ostringstream oss;
proxy.Call("scan", {sls::ToString(ind), "500", "1500", "500"}, -1, PUT,
oss);
REQUIRE(oss.str() ==
"scan [" + sls::ToString(ind) + ", 500, 1500, 500]\n");
CHECK(oss.str() ==
"scan [" + sls::ToString(ind) + ", 500, 1500, 500]\n");
}
{
std::ostringstream oss;
proxy.Call("scan", {}, -1, GET, oss);
REQUIRE(oss.str() == "scan [[enabled\ndac " + sls::ToString(ind) +
"\nstart 500\nstop 1500\nstep "
"500\nsettleTime 1ms\n]]\n");
CHECK(oss.str() == "scan [enabled\ndac " + sls::ToString(ind) +
"\nstart 500\nstop 1500\nstep "
"500\nsettleTime 1ms\n]\n");
}
{
std::ostringstream oss;
proxy.Call("scan", {sls::ToString(ind), "500", "1500", "500", "2s"}, -1,
PUT, oss);
REQUIRE(oss.str() ==
"scan [" + sls::ToString(ind) + ", 500, 1500, 500, 2s]\n");
CHECK(oss.str() ==
"scan [" + sls::ToString(ind) + ", 500, 1500, 500, 2s]\n");
}
{
std::ostringstream oss;
proxy.Call("scan", {}, -1, GET, oss);
REQUIRE(oss.str() == "scan [[enabled\ndac " + sls::ToString(ind) +
"\nstart 500\nstop 1500\nstep "
"500\nsettleTime 2s\n]]\n");
CHECK(oss.str() == "scan [enabled\ndac " + sls::ToString(ind) +
"\nstart 500\nstop 1500\nstep "
"500\nsettleTime 2s\n]\n");
}
{
std::ostringstream oss;
proxy.Call("scan", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "scan [0]\n");
CHECK(oss.str() == "scan [0]\n");
}
{
std::ostringstream oss;
proxy.Call("scan", {}, -1, GET, oss);
REQUIRE(oss.str() == "scan [[disabled]]\n");
CHECK(oss.str() == "scan [disabled]\n");
}
{
std::ostringstream oss;
proxy.Call("scan", {sls::ToString(ind), "1500", "500", "-500"}, -1, PUT,
oss);
REQUIRE(oss.str() ==
"scan [" + sls::ToString(ind) + ", 1500, 500, -500]\n");
CHECK(oss.str() ==
"scan [" + sls::ToString(ind) + ", 1500, 500, -500]\n");
}
REQUIRE_THROWS(proxy.Call(
CHECK_THROWS(proxy.Call(
"scan", {sls::ToString(notImplementedInd), "500", "1500", "500"}, -1,
PUT));
REQUIRE_THROWS(proxy.Call(
"scan", {sls::ToString(ind), "500", "1500", "-500"}, -1, PUT));
REQUIRE_THROWS(proxy.Call(
"scan", {sls::ToString(ind), "1500", "500", "500"}, -1, PUT));
CHECK_THROWS(proxy.Call("scan", {sls::ToString(ind), "500", "1500", "-500"},
-1, PUT));
CHECK_THROWS(proxy.Call("scan", {sls::ToString(ind), "1500", "500", "500"},
-1, PUT));
if (det_type == defs::MYTHEN3 || defs::EIGER) {
{
std::ostringstream oss;
proxy.Call("scan", {"trimbit_scan", "0", "63", "16", "2s"}, -1, PUT,
oss);
REQUIRE(oss.str() == "scan [trimbit_scan, 0, 63, 16, 2s]\n");
CHECK(oss.str() == "scan [trimbit_scan, 0, 63, 16, 2s]\n");
}
{
std::ostringstream oss;
proxy.Call("scan", {}, -1, GET, oss);
REQUIRE(oss.str() ==
"scan [[enabled\ndac trimbit_scan\nstart 0\nstop 48\nstep "
"16\nsettleTime 2s\n]]\n");
CHECK(oss.str() ==
"scan [enabled\ndac trimbit_scan\nstart 0\nstop 48\nstep "
"16\nsettleTime 2s\n]\n");
}
}
// Switch off scan for future tests
det.setScan(defs::scanParameters());
// acquire for each?
// when taking acquisition
@ -1559,6 +1562,20 @@ TEST_CASE("udp_dstport2", "[.cmd][.new]") {
}
}
TEST_CASE("udp_reconfigure", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
REQUIRE_THROWS(proxy.Call("udp_reconfigure", {}, -1, GET));
REQUIRE_NOTHROW(proxy.Call("udp_reconfigure", {}, -1, PUT));
}
TEST_CASE("udp_validate", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
REQUIRE_THROWS(proxy.Call("udp_validate", {}, -1, GET));
REQUIRE_NOTHROW(proxy.Call("udp_validate", {}, -1, PUT));
}
TEST_CASE("tengiga", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
@ -1825,7 +1842,7 @@ TEST_CASE("adcreg", "[.cmd]") {
if (det_type == defs::JUNGFRAU || det_type == defs::CHIPTESTBOARD ||
det_type == defs::MOENCH || det_type == defs::GOTTHARD) {
std::ostringstream oss;
proxy.Call("adcreg", {"0x08", "0x3"}, -1, PUT, oss);
proxy.Call("adcreg", {"0x8", "0x3"}, -1, PUT, oss);
REQUIRE(oss.str() == "adcreg [0x8, 0x3]\n");
// This is a put only command
REQUIRE_THROWS(proxy.Call("adcreg", {}, -1, GET));

View File

@ -9,50 +9,50 @@ TEST_CASE("Construction with a defined detector type") {
m.freeSharedMemory(); // clean up
}
TEST_CASE("Read back detector type from shm"){
TEST_CASE("Read back detector type from shm") {
// Create specific detector in order to create shm
sls::Module m(dt::JUNGFRAU);
// New detector that reads type from shm
sls::Module m2;
REQUIRE(m2.getDetectorType()== dt::JUNGFRAU);
REQUIRE(m2.getDetectorType() == dt::JUNGFRAU);
// Now both objects point to the same shm so we can only
// Now both objects point to the same shm so we can only
// free one!
m2.freeSharedMemory();
}
TEST_CASE("Is shm fixed pattern shm compatible"){
TEST_CASE("Is shm fixed pattern shm compatible") {
sls::Module m(dt::JUNGFRAU);
// Should be true since we just created the shm
REQUIRE(m.isFixedPatternSharedMemoryCompatible() == true);
// Set shm version to 0
sls::SharedMemory<sls::sharedSlsDetector> shm(0,0);
REQUIRE(shm.IsExisting()== true);
// Set shm version to 0
sls::SharedMemory<sls::sharedSlsDetector> shm(0, 0);
REQUIRE(shm.IsExisting() == true);
shm.OpenSharedMemory();
shm()->shmversion = 0;
// Should fail since version is set to 0
REQUIRE(m.isFixedPatternSharedMemoryCompatible() == false);
m.freeSharedMemory();
}
TEST_CASE("Get default control port"){
TEST_CASE("Get default control port") {
sls::Module m(dt::MYTHEN3);
REQUIRE(m.getControlPort() == 1952);
m.freeSharedMemory();
}
TEST_CASE("Get default stop port"){
TEST_CASE("Get default stop port") {
sls::Module m(dt::GOTTHARD2);
REQUIRE(m.getStopPort() == 1953);
m.freeSharedMemory();
}
TEST_CASE("Get default receiver TCP port"){
TEST_CASE("Get default receiver TCP port") {
sls::Module m(dt::MYTHEN3);
REQUIRE(m.getReceiverPort() == 1954);
m.freeSharedMemory();

View File

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

View File

@ -42,7 +42,7 @@ class BinaryFile : private virtual slsDetectorDefs, public File {
void PrintMembers(TLogLevel level = logDEBUG1) override;
void CreateFile() override;
void CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes) override;
MasterAttributes *attr) override;
void CloseCurrentFile() override;
void CloseAllFiles() override;
void WriteToFile(char *buffer, int buffersize, uint64_t currentFrameNumber,
@ -51,9 +51,8 @@ class BinaryFile : private virtual slsDetectorDefs, public File {
private:
int WriteData(char *buf, int bsize);
FILE *filefd;
FILE *filefd = nullptr;
static FILE *masterfd;
uint32_t numFramesInFile;
uint64_t numActualPacketsInFile;
const size_t maxMasterFileSize;
};
uint32_t numFramesInFile = 0;
uint64_t numActualPacketsInFile = 0;
};

View File

@ -8,6 +8,7 @@
#include "versionAPI.h"
#include <array>
#include <chrono>
#include <cstdlib>
#include <fstream>
#include <iostream>
@ -19,6 +20,7 @@
#include <unistd.h>
#include <vector>
using ns = std::chrono::nanoseconds;
using sls::RuntimeError;
using sls::SocketError;
using Interface = sls::ServerInterface;
@ -37,7 +39,6 @@ ClientInterface::ClientInterface(int portNumber)
server(portNumber) {
functionTable();
parentThreadId = syscall(SYS_gettid);
// start up tcp thread
tcpThread =
sls::make_unique<std::thread>(&ClientInterface::startTCPServer, this);
}
@ -76,7 +77,7 @@ void ClientInterface::startTCPServer() {
LOG(logINFOBLUE) << "Created [ TCP server Tid: " << tcpThreadId << "]";
LOG(logINFO) << "SLS Receiver starting TCP Server on port " << portNumber
<< '\n';
// server = sls::make_unique<sls::ServerSocket>(portNumber);
while (!killTcpThread) {
LOG(logDEBUG1) << "Start accept loop";
try {
@ -108,7 +109,6 @@ void ClientInterface::startTCPServer() {
// clang-format off
int ClientInterface::functionTable(){
flist[F_EXEC_RECEIVER_COMMAND] = &ClientInterface::exec_command;
flist[F_LOCK_RECEIVER] = &ClientInterface::lock_receiver;
flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip;
flist[F_SET_RECEIVER_PORT] = &ClientInterface::set_port;
@ -191,7 +191,7 @@ int ClientInterface::functionTable(){
flist[F_SET_RECEIVER_UDP_PORT2] = &ClientInterface::set_udp_port2;
flist[F_SET_RECEIVER_NUM_INTERFACES] = &ClientInterface::set_num_interfaces;
flist[F_RECEIVER_SET_ADC_MASK_10G] = &ClientInterface::set_adc_mask_10g;
flist[F_RECEIVER_SET_NUM_COUNTERS] = &ClientInterface::set_num_counters;
flist[F_RECEIVER_SET_COUNTER_MASK] = &ClientInterface::set_counter_mask;
flist[F_INCREMENT_FILE_INDEX] = &ClientInterface::increment_file_index;
flist[F_SET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::set_additional_json_parameter;
flist[F_GET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::get_additional_json_parameter;
@ -201,6 +201,7 @@ int ClientInterface::functionTable(){
flist[F_GET_RECEIVER_THREAD_IDS] = &ClientInterface::get_thread_ids;
flist[F_GET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::get_streaming_start_fnum;
flist[F_SET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::set_streaming_start_fnum;
flist[F_SET_RECEIVER_RATE_CORRECT] = &ClientInterface::set_rate_correct;
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@ -270,28 +271,6 @@ void ClientInterface::verifyIdle(Interface &socket) {
}
}
int ClientInterface::exec_command(Interface &socket) {
char cmd[MAX_STR_LENGTH]{};
char retval[MAX_STR_LENGTH]{};
socket.Receive(cmd);
LOG(logINFO) << "Executing command (" << cmd << ")";
const size_t tempsize = 256;
std::array<char, tempsize> temp{};
std::string sresult;
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw RuntimeError("Executing Command failed\n");
} else {
while (!feof(pipe.get())) {
if (fgets(temp.data(), tempsize, pipe.get()) != nullptr)
sresult += temp.data();
}
strncpy(retval, sresult.c_str(), MAX_STR_LENGTH);
LOG(logINFO) << "Result of cmd (" << cmd << "):\n" << retval;
}
return socket.sendResult(retval);
}
int ClientInterface::lock_receiver(Interface &socket) {
auto lock = socket.Receive<int>();
LOG(logDEBUG1) << "Locking Server to " << lock;
@ -404,12 +383,13 @@ int ClientInterface::setup_receiver(Interface &socket) {
}
}
if (myDetectorType != MYTHEN3) {
impl()->setAcquisitionTime(arg.expTimeNs);
impl()->setAcquisitionTime(std::chrono::nanoseconds(arg.expTimeNs));
}
impl()->setAcquisitionPeriod(arg.periodNs);
impl()->setAcquisitionPeriod(std::chrono::nanoseconds(arg.periodNs));
if (myDetectorType == EIGER) {
impl()->setSubExpTime(arg.subExpTimeNs);
impl()->setSubPeriod(arg.subExpTimeNs + arg.subDeadTimeNs);
impl()->setSubExpTime(std::chrono::nanoseconds(arg.subExpTimeNs));
impl()->setSubPeriod(std::chrono::nanoseconds(arg.subExpTimeNs) +
std::chrono::nanoseconds(arg.subDeadTimeNs));
impl()->setActivate(static_cast<bool>(arg.activate));
try {
impl()->setQuad(arg.quad == 0 ? false : true);
@ -467,14 +447,13 @@ int ClientInterface::setup_receiver(Interface &socket) {
}
}
if (myDetectorType == MYTHEN3) {
int ncounters = __builtin_popcount(arg.countermask);
impl()->setNumberofCounters(ncounters);
impl()->setAcquisitionTime1(arg.expTime1Ns);
impl()->setAcquisitionTime2(arg.expTime2Ns);
impl()->setAcquisitionTime3(arg.expTime3Ns);
impl()->setGateDelay1(arg.gateDelay1Ns);
impl()->setGateDelay2(arg.gateDelay2Ns);
impl()->setGateDelay3(arg.gateDelay3Ns);
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 (myDetectorType == GOTTHARD2) {
@ -525,9 +504,7 @@ void ClientInterface::setDetectorType(detectorType arg) {
}
int ClientInterface::set_roi(Interface &socket) {
static_assert(sizeof(ROI) == 2 * sizeof(int), "ROI not packed");
ROI arg;
socket.Receive(arg);
auto arg = socket.Receive<ROI>();
LOG(logDEBUG1) << "Set ROI: [" << arg.xmin << ", " << arg.xmax << "]";
if (myDetectorType != GOTTHARD)
@ -550,8 +527,6 @@ int ClientInterface::set_num_frames(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting num frames to " << value;
impl()->setNumberOfFrames(value);
int64_t retval = impl()->getNumberOfFrames();
validate(value, retval, "set number of frames", DEC);
return socket.Send(OK);
}
@ -562,10 +537,7 @@ int ClientInterface::set_num_triggers(Interface &socket) {
std::to_string(value));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting num triggers to " << value;
impl()->setNumberOfTriggers(value);
int64_t retval = impl()->getNumberOfTriggers();
validate(value, retval, "set number of triggers", DEC);
return socket.Send(OK);
}
@ -575,10 +547,7 @@ int ClientInterface::set_num_bursts(Interface &socket) {
throw RuntimeError("Invalid number of bursts " + std::to_string(value));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting num bursts to " << value;
impl()->setNumberOfBursts(value);
int64_t retval = impl()->getNumberOfBursts();
validate(value, retval, "set number of bursts", DEC);
return socket.Send(OK);
}
@ -591,8 +560,6 @@ int ClientInterface::set_num_add_storage_cells(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting num additional storage cells to " << value;
impl()->setNumberOfAdditionalStorageCells(value);
int retval = impl()->getNumberOfAdditionalStorageCells();
validate(value, retval, "set number of additional storage cells", DEC);
return socket.Send(OK);
}
@ -604,8 +571,6 @@ int ClientInterface::set_timing_mode(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting timing mode to " << value;
impl()->setTimingMode(static_cast<timingMode>(value));
int retval = impl()->getTimingMode();
validate(value, retval, "set timing mode", DEC);
return socket.Send(OK);
}
@ -617,8 +582,6 @@ int ClientInterface::set_burst_mode(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting burst mode to " << value;
impl()->setBurstMode(static_cast<burstMode>(value));
int retval = impl()->getBurstMode();
validate(value, retval, "set burst mode", DEC);
return socket.Send(OK);
}
@ -658,9 +621,9 @@ int ClientInterface::set_exptime(Interface &socket) {
int64_t args[2]{-1, -1};
socket.Receive(args);
int gateIndex = static_cast<int>(args[0]);
int64_t value = args[1];
LOG(logDEBUG1) << "Setting exptime to " << value
<< "ns (gateIndex: " << gateIndex << ")";
ns value = std::chrono::nanoseconds(args[1]);
LOG(logDEBUG1) << "Setting exptime to " << sls::ToString(value)
<< " (gateIndex: " << gateIndex << ")";
switch (gateIndex) {
case -1:
if (myDetectorType == MYTHEN3) {
@ -697,27 +660,27 @@ int ClientInterface::set_exptime(Interface &socket) {
}
int ClientInterface::set_period(Interface &socket) {
auto value = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Setting period to " << value << "ns";
auto value = std::chrono::nanoseconds(socket.Receive<int64_t>());
LOG(logDEBUG1) << "Setting period to " << sls::ToString(value);
impl()->setAcquisitionPeriod(value);
return socket.Send(OK);
}
int ClientInterface::set_subexptime(Interface &socket) {
auto value = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Setting period to " << value << "ns";
uint64_t subdeadtime = impl()->getSubPeriod() - impl()->getSubExpTime();
auto value = std::chrono::nanoseconds(socket.Receive<int64_t>());
LOG(logDEBUG1) << "Setting period to " << sls::ToString(value);
ns subdeadtime = impl()->getSubPeriod() - impl()->getSubExpTime();
impl()->setSubExpTime(value);
impl()->setSubPeriod(impl()->getSubExpTime() + subdeadtime);
return socket.Send(OK);
}
int ClientInterface::set_subdeadtime(Interface &socket) {
auto value = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Setting sub deadtime to " << value << "ns";
auto value = std::chrono::nanoseconds(socket.Receive<int64_t>());
LOG(logDEBUG1) << "Setting sub deadtime to " << sls::ToString(value);
impl()->setSubPeriod(value + impl()->getSubExpTime());
LOG(logDEBUG1) << "Setting sub period to " << impl()->getSubPeriod()
<< "ns";
LOG(logDEBUG1) << "Setting sub period to "
<< sls::ToString(impl()->getSubPeriod());
return socket.Send(OK);
}
@ -775,11 +738,7 @@ int ClientInterface::set_streaming_frequency(Interface &socket) {
std::to_string(index));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting streaming frequency: " << index;
impl()->setStreamingFrequency(index);
int retval = impl()->getStreamingFrequency();
validate(index, retval, "set streaming frequency", DEC);
return socket.Send(OK);
}
@ -819,58 +778,41 @@ int ClientInterface::stop_receiver(Interface &socket) {
}
int ClientInterface::set_file_dir(Interface &socket) {
char fPath[MAX_STR_LENGTH]{};
char retval[MAX_STR_LENGTH]{};
socket.Receive(fPath);
std::string fpath = socket.Receive(MAX_STR_LENGTH);
if (strlen(fPath) == 0) {
if (fpath.empty()) {
throw RuntimeError("Cannot set empty file path");
}
if (fPath[0] != '/')
if (fpath[0] != '/')
throw RuntimeError("Receiver path needs to be absolute path");
LOG(logDEBUG1) << "Setting file path: " << fPath;
impl()->setFilePath(fPath);
std::string s = impl()->getFilePath();
sls::strcpy_safe(retval, s.c_str());
if ((s.empty()) || (strlen(fPath) && strcasecmp(fPath, retval)))
throw RuntimeError("Receiver file path does not exist");
else
LOG(logDEBUG1) << "file path:" << retval;
LOG(logDEBUG1) << "Setting file path: " << fpath;
impl()->setFilePath(fpath);
return socket.Send(OK);
}
int ClientInterface::get_file_dir(Interface &socket) {
char retval[MAX_STR_LENGTH]{};
std::string s = impl()->getFilePath();
sls::strcpy_safe(retval, s.c_str());
LOG(logDEBUG1) << "file path:" << retval;
return socket.sendResult(retval);
auto fpath = impl()->getFilePath();
LOG(logDEBUG1) << "file path:" << fpath;
fpath.resize(MAX_STR_LENGTH);
return socket.sendResult(fpath);
}
int ClientInterface::set_file_name(Interface &socket) {
char fName[MAX_STR_LENGTH]{};
char retval[MAX_STR_LENGTH]{};
socket.Receive(fName);
if (strlen(fName) == 0) {
std::string fname = socket.Receive(MAX_STR_LENGTH);
if (fname.empty()) {
throw RuntimeError("Cannot set empty file name");
}
LOG(logDEBUG1) << "Setting file name: " << fName;
impl()->setFileName(fName);
std::string s = impl()->getFileName();
sls::strcpy_safe(retval, s.c_str());
LOG(logDEBUG1) << "file name:" << retval;
LOG(logDEBUG1) << "Setting file name: " << fname;
impl()->setFileName(fname);
return socket.Send(OK);
}
int ClientInterface::get_file_name(Interface &socket) {
char retval[MAX_STR_LENGTH]{};
std::string s = impl()->getFileName();
sls::strcpy_safe(retval, s.c_str());
LOG(logDEBUG1) << "file name:" << retval;
return socket.sendResult(retval);
auto fname = impl()->getFileName();
LOG(logDEBUG1) << "file name:" << fname;
fname.resize(MAX_STR_LENGTH);
return socket.sendResult(fname);
}
int ClientInterface::set_file_index(Interface &socket) {
@ -879,12 +821,7 @@ int ClientInterface::set_file_index(Interface &socket) {
throw RuntimeError("Invalid file index: " + std::to_string(index));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting file index: " << index;
impl()->setFileIndex(index);
int64_t retval = impl()->getFileIndex();
validate(index, retval, "set file index", DEC);
LOG(logDEBUG1) << "file index:" << retval;
return socket.Send(OK);
}
@ -901,14 +838,12 @@ int ClientInterface::get_frame_index(Interface &socket) {
}
int ClientInterface::get_missing_packets(Interface &socket) {
std::vector<uint64_t> m = impl()->getNumMissingPackets();
LOG(logDEBUG1) << "missing packets:" << sls::ToString(m);
int retvalsize = m.size();
uint64_t retval[retvalsize];
std::copy(std::begin(m), std::end(m), retval);
auto missing_packets = impl()->getNumMissingPackets();
LOG(logDEBUG1) << "missing packets:" << sls::ToString(missing_packets);
auto size = static_cast<int>(missing_packets.size());
socket.Send(OK);
socket.Send(&retvalsize, sizeof(retvalsize));
socket.Send(retval, sizeof(retval));
socket.Send(size);
socket.Send(missing_packets);
return OK;
}
@ -927,10 +862,6 @@ int ClientInterface::set_file_write(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting File write enable:" << enable;
impl()->setFileWriteEnable(enable);
int retval = impl()->getFileWriteEnable();
validate(enable, retval, "set file write enable", DEC);
LOG(logDEBUG1) << "file write enable:" << retval;
return socket.Send(OK);
}
@ -947,12 +878,7 @@ int ClientInterface::set_master_file_write(Interface &socket) {
std::to_string(enable));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting Master File write enable:" << enable;
impl()->setMasterFileWriteEnable(enable);
int retval = impl()->getMasterFileWriteEnable();
validate(enable, retval, "set master file write enable", DEC);
LOG(logDEBUG1) << "master file write enable:" << retval;
return socket.Send(OK);
}
@ -969,12 +895,7 @@ int ClientInterface::set_overwrite(Interface &socket) {
std::to_string(index));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting File overwrite enable:" << index;
impl()->setOverwriteEnable(index);
int retval = impl()->getOverwriteEnable();
validate(index, retval, "set file overwrite enable", DEC);
LOG(logDEBUG1) << "file overwrite enable:" << retval;
return socket.Send(OK);
}
@ -1053,10 +974,6 @@ int ClientInterface::set_streaming(Interface &socket) {
throw RuntimeError("Could not set data stream enable to " +
std::to_string(index));
}
auto retval = static_cast<int>(impl()->getDataStreamEnable());
validate(index, retval, "set data stream enable", DEC);
LOG(logDEBUG1) << "data streaming enable:" << retval;
return socket.Send(OK);
}
@ -1123,12 +1040,7 @@ int ClientInterface::set_streaming_port(Interface &socket) {
throw RuntimeError("Invalid zmq port " + std::to_string(port));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting streaming port:" << port;
impl()->setStreamingPort(port);
int retval = impl()->getStreamingPort();
validate(port, retval, "set streaming port", DEC);
LOG(logDEBUG1) << "streaming port:" << retval;
return socket.Send(OK);
}
@ -1139,23 +1051,11 @@ int ClientInterface::get_streaming_port(Interface &socket) {
}
int ClientInterface::set_streaming_source_ip(Interface &socket) {
sls::IpAddr arg;
socket.Receive(arg);
if (arg == 0) {
throw RuntimeError("Invalid zmq ip " + arg.str());
}
auto ip = socket.Receive<sls::IpAddr>();
if (ip == 0)
throw RuntimeError("Invalid zmq ip " + ip.str());
verifyIdle(socket);
LOG(logDEBUG1) << "Setting streaming source ip:" << arg;
impl()->setStreamingSourceIP(arg);
sls::IpAddr retval = impl()->getStreamingSourceIP();
LOG(logDEBUG1) << "streaming IP:" << retval;
if (retval != arg && arg != 0) {
std::ostringstream os;
os << "Could not set streaming ip. Set " << arg << ", but read "
<< retval << '\n';
throw RuntimeError(os.str());
}
impl()->setStreamingSourceIP(ip);
return socket.Send(OK);
}
@ -1173,10 +1073,6 @@ int ClientInterface::set_silent_mode(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting silent mode:" << value;
impl()->setSilentMode(value);
auto retval = static_cast<int>(impl()->getSilentMode());
validate(value, retval, "set silent mode", DEC);
LOG(logDEBUG1) << "silent mode:" << retval;
return socket.Send(OK);
}
@ -1200,13 +1096,15 @@ int ClientInterface::restream_stop(Interface &socket) {
int ClientInterface::set_additional_json_header(Interface &socket) {
std::map<std::string, std::string> json;
int size = socket.Receive<int>();
auto size = socket.Receive<int>();
if (size > 0) {
char args[size * 2][SHORT_STR_LENGTH];
memset(args, 0, sizeof(args));
socket.Receive(args, sizeof(args));
for (int i = 0; i < size; ++i) {
json[args[2 * i]] = args[2 * i + 1];
std::string buff(size, '\0');
socket.Receive(&buff[0], buff.size());
std::istringstream iss(buff);
std::string key, value;
while (iss >> key) {
iss >> value;
json[key] = value;
}
}
verifyIdle(socket);
@ -1218,19 +1116,15 @@ int ClientInterface::set_additional_json_header(Interface &socket) {
int ClientInterface::get_additional_json_header(Interface &socket) {
std::map<std::string, std::string> json = impl()->getAdditionalJsonHeader();
LOG(logDEBUG1) << "additional json header:" << sls::ToString(json);
int size = json.size();
socket.sendResult(size);
if (size > 0) {
char retvals[size * 2][SHORT_STR_LENGTH];
memset(retvals, 0, sizeof(retvals));
int iarg = 0;
for (auto &it : json) {
sls::strcpy_safe(retvals[iarg], it.first.c_str());
sls::strcpy_safe(retvals[iarg + 1], it.second.c_str());
iarg += 2;
}
socket.Send(retvals, sizeof(retvals));
std::ostringstream oss;
for (auto &it : json) {
oss << it.first << ' ' << it.second << ' ';
}
auto buff = oss.str();
auto size = static_cast<int>(buff.size());
socket.sendResult(size);
if (size > 0)
socket.Send(buff);
return OK;
}
@ -1264,10 +1158,6 @@ int ClientInterface::set_frames_per_file(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting frames per file: " << index;
impl()->setFramesPerFile(index);
auto retval = static_cast<int>(impl()->getFramesPerFile());
validate(index, retval, "set frames per file", DEC);
LOG(logDEBUG1) << "frames per file:" << retval;
return socket.Send(OK);
}
@ -1312,9 +1202,6 @@ int ClientInterface::set_discard_policy(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting frames discard policy: " << index;
impl()->setFrameDiscardPolicy(static_cast<frameDiscardPolicy>(index));
int retval = impl()->getFrameDiscardPolicy();
validate(index, retval, "set discard policy", DEC);
LOG(logDEBUG1) << "frame discard policy:" << retval;
return socket.Send(OK);
}
@ -1332,10 +1219,6 @@ int ClientInterface::set_padding_enable(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting frames padding enable: " << index;
impl()->setFramePaddingEnable(static_cast<bool>(index));
auto retval = static_cast<int>(impl()->getFramePaddingEnable());
validate(index, retval, "set frame padding enable", DEC);
LOG(logDEBUG1) << "Frame Padding Enable:" << retval;
return socket.Send(OK);
}
@ -1357,10 +1240,6 @@ int ClientInterface::set_deactivated_padding_enable(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting deactivated padding enable: " << enable;
impl()->setDeactivatedPadding(enable > 0);
auto retval = static_cast<int>(impl()->getDeactivatedPadding());
validate(enable, retval, "set deactivated padding enable", DEC);
LOG(logDEBUG1) << "Deactivated Padding Enable: " << retval;
return socket.Send(OK);
}
@ -1425,7 +1304,7 @@ int ClientInterface::set_dbit_list(Interface &socket) {
for (auto &it : args) {
LOG(logDEBUG1) << it << " ";
}
LOG(logDEBUG1) << "\n";
LOG(logDEBUG1) << '\n';
verifyIdle(socket);
impl()->setDbitList(args);
return socket.Send(OK);
@ -1450,10 +1329,6 @@ int ClientInterface::set_dbit_offset(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting Dbit offset: " << arg;
impl()->setDbitOffset(arg);
int retval = impl()->getDbitOffset();
validate(arg, retval, "set dbit offset", DEC);
LOG(logDEBUG1) << "Dbit offset retval: " << retval;
return socket.Send(OK);
}
@ -1628,11 +1503,11 @@ int ClientInterface::set_adc_mask_10g(Interface &socket) {
return socket.sendResult(retval);
}
int ClientInterface::set_num_counters(Interface &socket) {
auto arg = socket.Receive<int>();
int ClientInterface::set_counter_mask(Interface &socket) {
auto arg = socket.Receive<uint32_t>();
verifyIdle(socket);
LOG(logDEBUG1) << "Setting counters: " << arg;
impl()->setNumberofCounters(arg);
impl()->setCounterMask(arg);
return socket.Send(OK);
}
@ -1656,12 +1531,10 @@ int ClientInterface::set_additional_json_parameter(Interface &socket) {
}
int ClientInterface::get_additional_json_parameter(Interface &socket) {
char arg[SHORT_STR_LENGTH]{};
socket.Receive(arg);
char retval[SHORT_STR_LENGTH]{};
sls::strcpy_safe(retval, impl()->getAdditionalJsonParameter(arg).c_str());
LOG(logDEBUG1) << "additional json parameter (" << arg << "):" << retval;
return socket.sendResult(retval);
std::string key = socket.Receive(SHORT_STR_LENGTH);
std::string value = impl()->getAdditionalJsonParameter(key);
value.resize(SHORT_STR_LENGTH);
return socket.sendResult(value);
}
int ClientInterface::get_progress(Interface &socket) {
@ -1684,9 +1557,9 @@ int ClientInterface::set_gate_delay(Interface &socket) {
int64_t args[2]{-1, -1};
socket.Receive(args);
int gateIndex = static_cast<int>(args[0]);
int64_t value = args[1];
LOG(logDEBUG1) << "Setting gate delay to " << value
<< "ns (gateIndex: " << gateIndex << ")";
auto value = std::chrono::nanoseconds(args[1]);
LOG(logDEBUG1) << "Setting gate delay to " << sls::ToString(value)
<< " (gateIndex: " << gateIndex << ")";
if (myDetectorType != MYTHEN3) {
functionNotImplemented();
}
@ -1733,8 +1606,20 @@ int ClientInterface::set_streaming_start_fnum(Interface &socket) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting streaming start fnum: " << index;
impl()->setStreamingStartingFrameNumber(index);
int retval = impl()->getStreamingStartingFrameNumber();
validate(index, retval, "set streaming start fnum", DEC);
return socket.Send(OK);
}
int ClientInterface::set_rate_correct(Interface &socket) {
auto index = socket.Receive<int>();
if (index <= 0) {
throw RuntimeError("Invalid number of rate correction values: " +
std::to_string(index));
}
LOG(logDEBUG) << "Number of detectors for rate correction: " << index;
std::vector<int64_t> t(index);
socket.Receive(t);
verifyIdle(socket);
LOG(logINFOBLUE) << "Setting rate corrections[" << index << ']';
impl()->setRateCorrections(t);
return socket.Send(OK);
}

View File

@ -60,7 +60,6 @@ class ClientInterface : private virtual slsDetectorDefs {
void verifyLock();
void verifyIdle(sls::ServerInterface &socket);
int exec_command(sls::ServerInterface &socket);
int lock_receiver(sls::ServerInterface &socket);
int get_last_client_ip(sls::ServerInterface &socket);
int set_port(sls::ServerInterface &socket);
@ -147,7 +146,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_udp_port2(sls::ServerInterface &socket);
int set_num_interfaces(sls::ServerInterface &socket);
int set_adc_mask_10g(sls::ServerInterface &socket);
int set_num_counters(sls::ServerInterface &socket);
int set_counter_mask(sls::ServerInterface &socket);
int increment_file_index(sls::ServerInterface &socket);
int set_additional_json_parameter(sls::ServerInterface &socket);
int get_additional_json_parameter(sls::ServerInterface &socket);
@ -157,6 +156,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_thread_ids(sls::ServerInterface &socket);
int get_streaming_start_fnum(sls::ServerInterface &socket);
int set_streaming_start_fnum(sls::ServerInterface &socket);
int set_rate_correct(sls::ServerInterface &socket);
Implementation *impl() {
if (receiver != nullptr) {

View File

@ -9,6 +9,7 @@
#include "BinaryFile.h"
#include "Fifo.h"
#include "GeneralData.h"
#include "MasterAttributes.h"
#ifdef HDF5C
#include "HDF5File.h"
#endif
@ -143,7 +144,7 @@ void DataProcessor::SetupFileWriter(bool fwe, int *nd, uint32_t *maxf,
}
// only the first file
void DataProcessor::CreateNewFile(masterAttributes &attr) {
void DataProcessor::CreateNewFile(MasterAttributes *attr) {
if (file == nullptr) {
throw sls::RuntimeError("file object not contstructed");
}
@ -411,6 +412,7 @@ void DataProcessor::PadMissingPackets(char *buf) {
/** ctb specific */
void DataProcessor::RearrangeDbitData(char *buf) {
// TODO! (Erik) Refactor and add tests
int totalSize = (int)(*((uint32_t *)buf));
int ctbDigitalDataBytes =
totalSize - (*ctbAnalogDataBytes) - (*ctbDbitOffset);
@ -429,9 +431,8 @@ void DataProcessor::RearrangeDbitData(char *buf) {
// ceil as numResult8Bits could be decimal
const int numResult8Bits =
ceil((double)(numSamples * (*ctbDbitList).size()) / 8.00);
uint8_t result[numResult8Bits];
memset(result, 0, numResult8Bits * sizeof(uint8_t));
uint8_t *dest = result;
std::vector<uint8_t> result(numResult8Bits);
uint8_t *dest = &result[0];
auto *source = (uint64_t *)(buf + digOffset + (*ctbDbitOffset));
@ -459,6 +460,6 @@ void DataProcessor::RearrangeDbitData(char *buf) {
}
// copy back to buf and update size
memcpy(buf + digOffset, result, numResult8Bits * sizeof(uint8_t));
memcpy(buf + digOffset, result.data(), numResult8Bits * sizeof(uint8_t));
(*((uint32_t *)buf)) = numResult8Bits * sizeof(uint8_t);
}

View File

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

View File

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

View File

@ -157,8 +157,9 @@ class GeneralData {
* set number of counters (mythen3)
* @param n number of counters
* @param dr dynamic range
* @param tgEnable ten giga enable
*/
virtual void SetNumberofCounters(const int n, const int dr) {
virtual void SetNumberofCounters(const int n, const int dr, bool tgEnable) {
LOG(logERROR) << "SetNumberofCounters is a generic function that "
"should be overloaded by a derived class";
}
@ -440,17 +441,33 @@ class Mythen3Data : public GeneralData {
* set number of counters (mythen3)
* @param n number of counters
* @param dr dynamic range
* @param tgEnable ten giga enable
*/
virtual void SetNumberofCounters(const int n, const int dr) {
if (n < 1 || n > 3) {
throw sls::RuntimeError("Invalid number of counters " +
std::to_string(n));
}
virtual void SetNumberofCounters(const int n, const int dr, bool tgEnable) {
ncounters = n;
nPixelsX = NCHAN * ncounters;
LOG(logINFO) << "nPixelsX: " << nPixelsX;
imageSize = nPixelsX * nPixelsY * ((double)dr / 8.00);
dataSize = imageSize / packetsPerFrame;
// 10g
if (tgEnable) {
if (dr == 32 && n > 1) {
packetsPerFrame = 2;
} else {
packetsPerFrame = 1;
}
dataSize = imageSize / packetsPerFrame;
}
// 1g
else {
if (n == 3) {
dataSize = 768;
} else {
dataSize = 1280;
}
packetsPerFrame = imageSize / dataSize;
}
LOG(logINFO) << "Packets Per Frame: " << packetsPerFrame;
packetSize = headerSizeinPacket + dataSize;
LOG(logINFO) << "PacketSize: " << packetSize;
}
@ -462,6 +479,8 @@ class Mythen3Data : public GeneralData {
*/
void SetDynamicRange(int dr, bool tgEnable) {
imageSize = nPixelsX * nPixelsY * ((double)dr / 8.00);
packetsPerFrame = tgEnable ? 2 : 20;
dataSize = imageSize / packetsPerFrame;
packetSize = headerSizeinPacket + dataSize;
LOG(logINFO) << "PacketSize: " << packetSize;

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -11,14 +11,16 @@ class Fifo;
class slsDetectorDefs;
#include <atomic>
#include <chrono>
#include <exception>
#include <map>
#include <memory>
#include <vector>
using ns = std::chrono::nanoseconds;
class Implementation : private virtual slsDetectorDefs {
public:
Implementation(const detectorType d);
explicit Implementation(const detectorType d);
virtual ~Implementation();
/**************************************************
@ -156,38 +158,39 @@ class Implementation : private virtual slsDetectorDefs {
burstMode getBurstMode() const;
/** [Gottthard2] */
void setBurstMode(const burstMode i);
uint64_t getAcquisitionTime() const;
void setAcquisitionTime(const uint64_t i);
ns getAcquisitionTime() const;
void setAcquisitionTime(const ns i);
/** [Mythen3] */
void updateAcquisitionTime();
/** [Mythen3] */
void setAcquisitionTime1(const uint64_t i);
void setAcquisitionTime1(const ns i);
/** [Mythen3] */
void setAcquisitionTime2(const uint64_t i);
void setAcquisitionTime2(const ns i);
/** [Mythen3] */
void setAcquisitionTime3(const uint64_t i);
void setAcquisitionTime3(const ns i);
/** [Mythen3] */
void setGateDelay1(const uint64_t i);
void setGateDelay1(const ns i);
/** [Mythen3] */
void setGateDelay2(const uint64_t i);
void setGateDelay2(const ns i);
/** [Mythen3] */
void setGateDelay3(const uint64_t i);
uint64_t getAcquisitionPeriod() const;
void setAcquisitionPeriod(const uint64_t i);
uint64_t getSubExpTime() const;
void setGateDelay3(const ns i);
ns getAcquisitionPeriod() const;
void setAcquisitionPeriod(const ns i);
ns getSubExpTime() const;
/* [Eiger] */
void setSubExpTime(const uint64_t i);
uint64_t getSubPeriod() const;
void setSubExpTime(const ns i);
ns getSubPeriod() const;
/* [Eiger] */
void setSubPeriod(const uint64_t i);
void setSubPeriod(const ns i);
uint32_t getNumberofAnalogSamples() const;
/**[Ctb][Moench] */
void setNumberofAnalogSamples(const uint32_t i);
uint32_t getNumberofDigitalSamples() const;
/**[Ctb] */
void setNumberofDigitalSamples(const uint32_t i);
int getNumberofCounters() const;
void setNumberofCounters(const int i);
uint32_t getCounterMask() const;
/** [Mythen3] */
void setCounterMask(const uint32_t i);
uint32_t getDynamicRange() const;
void setDynamicRange(const uint32_t i);
ROI getROI() const;
@ -207,10 +210,12 @@ class Implementation : private virtual slsDetectorDefs {
bool setActivate(const bool enable);
bool getDeactivatedPadding() const;
/* [Eiger] */
bool setDeactivatedPadding(const bool enable);
void setDeactivatedPadding(const bool enable);
int getReadNLines() const;
/* [Eiger] */
void setReadNLines(const int value);
/* [Eiger] */
void setRateCorrections(const std::vector<int64_t> &t);
readoutMode getReadoutMode() const;
/* [Ctb] */
void setReadoutMode(const readoutMode f);
@ -222,7 +227,7 @@ class Implementation : private virtual slsDetectorDefs {
void setTenGigaADCEnableMask(const uint32_t mask);
std::vector<int> getDbitList() const;
/* [Ctb] */
void setDbitList(const std::vector<int> v);
void setDbitList(const std::vector<int> &v);
int getDbitOffset() const;
/* [Ctb] */
void setDbitOffset(const int s);
@ -246,8 +251,6 @@ class Implementation : private virtual slsDetectorDefs {
void *arg);
private:
void DeleteMembers();
void InitializeMembers();
void SetLocalNetworkParameters();
void SetThreadPriorities();
void SetupFifoStructure();
@ -264,88 +267,89 @@ class Implementation : private virtual slsDetectorDefs {
* ************************************************/
// config parameters
int numThreads;
detectorType myDetectorType;
int numDet[MAX_DIMENSIONS];
int modulePos;
int numThreads{1};
detectorType myDetectorType{GENERIC};
int numDet[MAX_DIMENSIONS] = {0, 0};
int modulePos{0};
std::string detHostname;
bool silentMode;
uint32_t fifoDepth;
frameDiscardPolicy frameDiscardMode;
bool framePadding;
bool silentMode{false};
uint32_t fifoDepth{0};
frameDiscardPolicy frameDiscardMode{NO_DISCARD};
bool framePadding{true};
pid_t parentThreadId;
pid_t tcpThreadId;
// file parameters
fileFormat fileFormatType;
std::string filePath;
std::string fileName;
uint64_t fileIndex;
bool fileWriteEnable;
bool masterFileWriteEnable;
bool overwriteEnable;
uint32_t framesPerFile;
fileFormat fileFormatType{BINARY};
std::string filePath{"/"};
std::string fileName{"run"};
uint64_t fileIndex{0};
bool fileWriteEnable{true};
bool masterFileWriteEnable{true};
bool overwriteEnable{true};
uint32_t framesPerFile{0};
// acquisition
std::atomic<runStatus> status;
bool stoppedFlag;
std::atomic<runStatus> status{IDLE};
bool stoppedFlag{false};
// network configuration (UDP)
int numUDPInterfaces;
std::vector<std::string> eth;
std::vector<uint32_t> udpPortNum;
int64_t udpSocketBufferSize;
int64_t actualUDPSocketBufferSize;
int numUDPInterfaces{1};
std::array<std::string,MAX_NUMBER_OF_LISTENING_THREADS>eth;
std::array<uint32_t,MAX_NUMBER_OF_LISTENING_THREADS> udpPortNum{{DEFAULT_UDP_PORTNO, DEFAULT_UDP_PORTNO+1}};
int64_t udpSocketBufferSize{0};
int64_t actualUDPSocketBufferSize{0};
// zmq parameters
bool dataStreamEnable;
uint32_t streamingFrequency;
uint32_t streamingTimerInMs;
uint32_t streamingStartFnum;
uint32_t streamingPort;
sls::IpAddr streamingSrcIP;
bool dataStreamEnable{false};
uint32_t streamingFrequency{1};
uint32_t streamingTimerInMs{DEFAULT_STREAMING_TIMER_IN_MS};
uint32_t streamingStartFnum{0};
uint32_t streamingPort{0};
sls::IpAddr streamingSrcIP = sls::IpAddr{};
std::map<std::string, std::string> additionalJsonHeader;
// detector parameters
uint64_t numberOfTotalFrames;
uint64_t numberOfFrames;
uint64_t numberOfTriggers;
uint64_t numberOfBursts;
int numberOfAdditionalStorageCells;
int numberOfGates;
timingMode timingMode;
burstMode burstMode;
uint64_t acquisitionPeriod;
uint64_t acquisitionTime;
uint64_t acquisitionTime1;
uint64_t acquisitionTime2;
uint64_t acquisitionTime3;
uint64_t gateDelay1;
uint64_t gateDelay2;
uint64_t gateDelay3;
uint64_t subExpTime;
uint64_t subPeriod;
uint64_t numberOfAnalogSamples;
uint64_t numberOfDigitalSamples;
int numberOfCounters;
uint32_t dynamicRange;
ROI roi;
bool tengigaEnable;
int flippedDataX;
bool quadEnable;
bool activated;
bool deactivatedPaddingEnable;
int numLinesReadout;
readoutMode readoutType;
uint32_t adcEnableMaskOneGiga;
uint32_t adcEnableMaskTenGiga;
uint64_t numberOfTotalFrames{0};
uint64_t numberOfFrames{1};
uint64_t numberOfTriggers{1};
uint64_t numberOfBursts{1};
int numberOfAdditionalStorageCells{0};
int numberOfGates{0};
timingMode timingMode{AUTO_TIMING};
burstMode burstMode{BURST_INTERNAL};
ns acquisitionPeriod = std::chrono::nanoseconds(SAMPLE_TIME_IN_NS);
ns acquisitionTime = std::chrono::nanoseconds(0);
ns acquisitionTime1 = std::chrono::nanoseconds(0);
ns acquisitionTime2 = std::chrono::nanoseconds(0);
ns acquisitionTime3 = std::chrono::nanoseconds(0);
ns gateDelay1 = std::chrono::nanoseconds(0);
ns gateDelay2 = std::chrono::nanoseconds(0);
ns gateDelay3 = std::chrono::nanoseconds(0);
ns subExpTime = std::chrono::nanoseconds(0);
ns subPeriod = std::chrono::nanoseconds(0);
uint32_t numberOfAnalogSamples{0};
uint32_t numberOfDigitalSamples{0};
uint32_t counterMask{0};
uint32_t dynamicRange{16};
ROI roi{};
bool tengigaEnable{false};
int flippedDataX{0};
bool quadEnable{false};
bool activated{true};
bool deactivatedPaddingEnable{true};
int numLinesReadout{MAX_EIGER_ROWS_PER_READOUT};
std::vector<int64_t> rateCorrections;
readoutMode readoutType{ANALOG_ONLY};
uint32_t adcEnableMaskOneGiga{BIT32_MASK};
uint32_t adcEnableMaskTenGiga{BIT32_MASK};
std::vector<int> ctbDbitList;
int ctbDbitOffset;
int ctbAnalogDataBytes;
int ctbDbitOffset{0};
int ctbAnalogDataBytes{0};
// callbacks
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t,
uint32_t, void *);
uint32_t, void *){nullptr};
void *pStartAcquisition;
void (*acquisitionFinishedCallBack)(uint64_t, void *);
void *pAcquisitionFinished;

View File

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

View File

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

View File

@ -40,6 +40,7 @@ if(SLS_DEVEL_HEADERS)
include/UdpRxSocket.h
include/versionAPI.h
include/ZmqSocket.h
include/bit_utils.h
)
endif()

View File

@ -15,6 +15,7 @@ class ClientSocket : public DataSocket {
int sendCommandThenRead(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
std::string readErrorMessage();
private:
void readReply(int &ret, void *retval, size_t retval_size);
struct sockaddr_in serverAddr {};

View File

@ -1,10 +1,13 @@
#pragma once
#include "TypeTraits.h"
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <netdb.h>
#include <numeric>
#include <string>
#include <vector>
namespace sls {
/* Base class for TCP socket, this is used to send data between detector, client
@ -24,9 +27,27 @@ class DataSocket {
int getSocketId() const { return sockfd_; }
int Send(const void *buffer, size_t size);
template <typename T> int Send(T &&data) {
// Send everything that is not a vector or string by using address and
// sizeof
// TODO! We probably should restrict this even more to avoid bugs when
// we send object instead of data
template <typename T>
typename std::enable_if<
!is_vector<typename std::remove_reference<T>::type>::value &&
!std::is_same<typename std::remove_reference<T>::type,
std::string>::value,
int>::type
Send(T &&data) {
return Send(&data, sizeof(data));
}
template <typename T> int Send(const std::vector<T> &vec) {
return Send(vec.data(), sizeof(T) * vec.size());
}
int Send(const std::string &s);
// Variadic template to send all arguments
template <class... Args> int SendAll(Args &&... args) {
auto l = std::initializer_list<int>{Send(args)...};
@ -34,16 +55,23 @@ class DataSocket {
return sum;
}
int Receive(void *buffer, size_t size);
template <typename T> int Receive(T &arg) {
return Receive(&arg, sizeof(arg));
}
template <typename T> int Receive(std::vector<T> &buff) {
return Receive(buff.data(), sizeof(T) * buff.size());
}
template <typename T> T Receive() {
T arg;
Receive(&arg, sizeof(arg));
return arg;
}
std::string Receive(size_t length);
int read(void *buffer, size_t size);
int write(void *buffer, size_t size);
int setTimeOut(int t_seconds);

View File

@ -16,5 +16,7 @@ abs(std::chrono::duration<Rep, Period> d) {
return d >= d.zero() ? d : -d;
}
static_assert(sizeof(ns) == 8, "ns needs to be 64bit");
} // namespace time
} // namespace sls

View File

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

View File

@ -1,5 +1,6 @@
#pragma once
#include <type_traits>
#include <vector>
namespace sls {
@ -62,14 +63,17 @@ template <typename T>
struct is_container<
T, typename std::conditional<
false,
is_container_helper<typename T::value_type, typename T::size_type,
typename T::iterator, typename T::const_iterator,
decltype(std::declval<T>().size()),
decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end()),
decltype(std::declval<T>().cbegin()),
decltype(std::declval<T>().cend()),
decltype(std::declval<T>().empty())>,
is_container_helper<
typename std::remove_reference<T>::type::value_type,
typename std::remove_reference<T>::type::size_type,
typename std::remove_reference<T>::type::iterator,
typename std::remove_reference<T>::type::const_iterator,
decltype(std::declval<T>().size()),
decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end()),
decltype(std::declval<T>().cbegin()),
decltype(std::declval<T>().cend()),
decltype(std::declval<T>().empty())>,
void>::type> : public std::true_type {};
/**
@ -92,4 +96,9 @@ struct is_light_container<
decltype(std::declval<T>().end())>,
void>::type> : public std::true_type {};
template <typename T> struct is_vector : public std::false_type {};
template <typename T>
struct is_vector<std::vector<T>> : public std::true_type {};
} // namespace sls

View File

@ -0,0 +1,19 @@
#pragma once
#include <vector>
#include <bitset>
namespace sls {
template <typename T> std::vector<int> getSetBits(T val) {
constexpr size_t bitsPerByte = 8;
constexpr size_t numBits = sizeof(T)*bitsPerByte;
std::bitset<numBits> bs(val);
std::vector<int> set_bits;
set_bits.reserve(bs.count());
for (size_t i = 0; i < bs.size(); ++i) {
if (bs[i]) {
set_bits.push_back(static_cast<int>(i));
}
}
return set_bits;
}
} // namespace sls

View File

@ -135,6 +135,8 @@ class slsDetectorDefs {
} sls_detector_header;
#ifdef __cplusplus
//For sending and receiving data
static_assert(sizeof(detectorType) == sizeof(int), "enum and int differ in size");
#define MAX_NUM_PACKETS 512
using sls_bitset = std::bitset<MAX_NUM_PACKETS>;
using bitset_storage = uint8_t[MAX_NUM_PACKETS / 8];
@ -160,6 +162,8 @@ class slsDetectorDefs {
struct ROI {
int xmin{-1};
int xmax{-1};
ROI() = default;
ROI(int xmin, int xmax) : xmin(xmin), xmax(xmax){};
} __attribute__((packed));
#else
typedef struct {

View File

@ -207,11 +207,12 @@ enum detFuncs {
F_SET_CDS_GAIN,
F_GET_FILTER,
F_SET_FILTER,
F_SET_VETO_FILE,
F_GET_ADC_CONFIGURATION,
F_SET_ADC_CONFIGURATION,
F_GET_BAD_CHANNELS,
F_SET_BAD_CHANNELS,
F_RECONFIGURE_UDP,
F_VALIDATE_UDP_CONFIG,
NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
@ -299,7 +300,7 @@ enum detFuncs {
F_SET_RECEIVER_UDP_PORT2,
F_SET_RECEIVER_NUM_INTERFACES,
F_RECEIVER_SET_ADC_MASK_10G,
F_RECEIVER_SET_NUM_COUNTERS,
F_RECEIVER_SET_COUNTER_MASK,
F_INCREMENT_FILE_INDEX,
F_SET_ADDITIONAL_JSON_PARAMETER,
F_GET_ADDITIONAL_JSON_PARAMETER,
@ -310,6 +311,7 @@ enum detFuncs {
F_GET_RECEIVER_THREAD_IDS,
F_GET_RECEIVER_STREAMING_START_FNUM,
F_SET_RECEIVER_STREAMING_START_FNUM,
F_SET_RECEIVER_RATE_CORRECT,
NUM_REC_FUNCTIONS
};
@ -519,11 +521,12 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_CDS_GAIN: return "F_SET_CDS_GAIN";
case F_GET_FILTER: return "F_GET_FILTER";
case F_SET_FILTER: return "F_SET_FILTER";
case F_SET_VETO_FILE: return "F_SET_VETO_FILE";
case F_SET_ADC_CONFIGURATION: return "F_SET_ADC_CONFIGURATION";
case F_GET_ADC_CONFIGURATION: return "F_GET_ADC_CONFIGURATION";
case F_GET_BAD_CHANNELS: return "F_GET_BAD_CHANNELS";
case F_SET_BAD_CHANNELS: return "F_SET_BAD_CHANNELS";
case F_RECONFIGURE_UDP: return "F_RECONFIGURE_UDP";
case F_VALIDATE_UDP_CONFIG: return "F_VALIDATE_UDP_CONFIG";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
@ -610,7 +613,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_RECEIVER_UDP_PORT2: return "F_SET_RECEIVER_UDP_PORT2";
case F_SET_RECEIVER_NUM_INTERFACES: return "F_SET_RECEIVER_NUM_INTERFACES";
case F_RECEIVER_SET_ADC_MASK_10G: return "F_RECEIVER_SET_ADC_MASK_10G";
case F_RECEIVER_SET_NUM_COUNTERS: return "F_RECEIVER_SET_NUM_COUNTERS";
case F_RECEIVER_SET_COUNTER_MASK: return "F_RECEIVER_SET_COUNTER_MASK";
case F_INCREMENT_FILE_INDEX: return "F_INCREMENT_FILE_INDEX";
case F_SET_ADDITIONAL_JSON_PARAMETER: return "F_SET_ADDITIONAL_JSON_PARAMETER";
case F_GET_ADDITIONAL_JSON_PARAMETER: return "F_GET_ADDITIONAL_JSON_PARAMETER";
@ -619,9 +622,9 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_RECEIVER_NUM_GATES: return "F_SET_RECEIVER_NUM_GATES";
case F_SET_RECEIVER_GATE_DELAY: return "F_SET_RECEIVER_GATE_DELAY";
case F_GET_RECEIVER_THREAD_IDS: return "F_GET_RECEIVER_THREAD_IDS";
case F_GET_RECEIVER_STREAMING_START_FNUM: return "F_GET_RECEIVER_STREAMING_START_FNUM";
case F_SET_RECEIVER_STREAMING_START_FNUM: return "F_SET_RECEIVER_STREAMING_START_FNUM";
case F_SET_RECEIVER_RATE_CORRECT: return "F_SET_RECEIVER_RATE_CORRECT";
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function";

View File

@ -1,12 +1,12 @@
/** API versions */
#define GITBRANCH "developer"
#define APILIB 0x200409
#define APIRECEIVER 0x200409
#define APIGUI 0x200409
#define APICTB 0x200723
#define APIGOTTHARD 0x200723
#define APIGOTTHARD2 0x200723
#define APIJUNGFRAU 0x200723
#define APIMYTHEN3 0x200723
#define APIMOENCH 0x200722
#define APIEIGER 0x200723
#define GITBRANCH "developer"
#define APILIB 0x200810
#define APIRECEIVER 0x200810
#define APIGUI 0x200804
#define APICTB 0x200810
#define APIGOTTHARD 0x200810
#define APIGOTTHARD2 0x200810
#define APIJUNGFRAU 0x200810
#define APIMYTHEN3 0x200810
#define APIMOENCH 0x200810
#define APIEIGER 0x200810

View File

@ -101,4 +101,10 @@ void ClientSocket::readReply(int &ret, void *retval, size_t retval_size) {
}
}
std::string ClientSocket::readErrorMessage(){
std::string error_msg(MAX_STR_LENGTH, '\0');
Receive(&error_msg[0], error_msg.size());
return error_msg;
}
}; // namespace sls

View File

@ -63,6 +63,14 @@ int DataSocket::Receive(void *buffer, size_t size) {
}
}
std::string DataSocket::Receive(size_t length) {
std::string buff(length, '\0');
Receive(&buff[0], buff.size());
auto pos = buff.find('\0');
if (pos != std::string::npos)
buff.erase(pos);
return buff;
}
int DataSocket::Send(const void *buffer, size_t size) {
int bytes_sent = 0;
int data_size = static_cast<int>(size); // signed size
@ -81,6 +89,8 @@ int DataSocket::Send(const void *buffer, size_t size) {
return bytes_sent;
}
int DataSocket::Send(const std::string &s) { return Send(&s[0], s.size()); }
int DataSocket::write(void *buffer, size_t size) {
return ::write(getSocketId(), buffer, size);
}

View File

@ -3,6 +3,16 @@
namespace sls {
std::string ToString(const slsDetectorDefs::xy &coord) {
std::ostringstream oss;
oss << '[' << coord.x << ", " << coord.y << ']';
return oss.str();
}
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord) {
return os << ToString(coord);
}
std::string ToString(const slsDetectorDefs::ROI &roi) {
std::ostringstream oss;
oss << '[' << roi.xmin << ", " << roi.xmax << ']';
@ -32,10 +42,14 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) {
<< "bursts:" << r.bursts << std::endl
<< "analogSamples:" << r.analogSamples << std::endl
<< "digitalSamples:" << r.digitalSamples << std::endl
<< "expTimeNs:" << r.expTimeNs << std::endl
<< "periodNs:" << r.periodNs << std::endl
<< "subExpTimeNs:" << r.subExpTimeNs << std::endl
<< "subDeadTimeNs:" << r.subDeadTimeNs << std::endl
<< "expTime:" << ToString(std::chrono::nanoseconds(r.expTimeNs))
<< std::endl
<< "period:" << ToString(std::chrono::nanoseconds(r.periodNs))
<< std::endl
<< "subExpTime:" << ToString(std::chrono::nanoseconds(r.subExpTimeNs))
<< std::endl
<< "subDeadTime:" << ToString(std::chrono::nanoseconds(r.subDeadTimeNs))
<< std::endl
<< "activate:" << r.activate << std::endl
<< "quad:" << r.quad << std::endl
<< "dynamicRange:" << r.dynamicRange << std::endl
@ -48,12 +62,18 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) {
<< "roi.xmax:" << r.roi.xmax << std::endl
<< "countermask:" << r.countermask << std::endl
<< "burstType:" << r.burstType << std::endl
<< "exptime1:" << r.expTime1Ns << std::endl
<< "exptime2:" << r.expTime2Ns << std::endl
<< "exptime3:" << r.expTime3Ns << std::endl
<< "gateDelay1:" << r.gateDelay1Ns << std::endl
<< "gateDelay2:" << r.gateDelay2Ns << std::endl
<< "gateDelay3:" << r.gateDelay3Ns << std::endl
<< "exptime1:" << ToString(std::chrono::nanoseconds(r.expTime1Ns))
<< std::endl
<< "exptime2:" << ToString(std::chrono::nanoseconds(r.expTime2Ns))
<< std::endl
<< "exptime3:" << ToString(std::chrono::nanoseconds(r.expTime3Ns))
<< std::endl
<< "gateDelay1:" << ToString(std::chrono::nanoseconds(r.gateDelay1Ns))
<< std::endl
<< "gateDelay2:" << ToString(std::chrono::nanoseconds(r.gateDelay2Ns))
<< std::endl
<< "gateDelay3:" << ToString(std::chrono::nanoseconds(r.gateDelay3Ns))
<< std::endl
<< "gates:" << r.gates << std::endl
<< ']';
return oss.str();
@ -492,7 +512,7 @@ std::string ToString(const defs::dacIndex s) {
case defs::TRIMBIT_SCAN:
return std::string("trimbit_scan");
case defs::HIGH_VOLTAGE:
return std::string("vhighvoltage");
return std::string("highvoltage");
case defs::IO_DELAY:
return std::string("iodelay");
default:
@ -850,7 +870,7 @@ template <> defs::dacIndex StringTo(const std::string &s) {
return defs::IBIAS_SFP;
if (s == "trimbit_scan")
return defs::TRIMBIT_SCAN;
if (s == "vhighvoltage")
if (s == "highvoltage")
return defs::HIGH_VOLTAGE;
if (s == "iodelay")
return defs::IO_DELAY;

View File

@ -1,22 +1,21 @@
#include "ZmqSocket.h"
#include "logger.h"
#include "network_utils.h" //ip
#include <chrono>
#include <errno.h>
#include <iostream>
#include <sstream>
#include <string.h>
#include <chrono>
#include <thread>
#include <vector>
#include <sstream>
#include <zmq.h>
#include "network_utils.h" //ip
using namespace rapidjson;
ZmqSocket::ZmqSocket(const char *const hostname_or_ip,
const uint32_t portnumber)
: portno(portnumber), sockfd(false)
{
: portno(portnumber), sockfd(false) {
// Extra check that throws if conversion fails, could be removed
auto ipstr = sls::HostnameToIp(hostname_or_ip).str();
auto ipstr = sls::HostnameToIp(hostname_or_ip).str();
std::ostringstream oss;
oss << "tcp://" << ipstr << ":" << portno;
sockfd.serverAddress = oss.str();
@ -52,8 +51,7 @@ ZmqSocket::ZmqSocket(const char *const hostname_or_ip,
}
ZmqSocket::ZmqSocket(const uint32_t portnumber, const char *ethip)
:portno(portnumber), sockfd(true)
{
: portno(portnumber), sockfd(true) {
// create context
sockfd.contextDescriptor = zmq_ctx_new();
if (sockfd.contextDescriptor == nullptr)
@ -124,11 +122,11 @@ int ZmqSocket::SendHeader(int index, zmqHeader header) {
"\"flippedDataX\":%u, "
"\"quad\":%u"
; //"}\n";
memset(header_buffer.get(),'\0',MAX_STR_LENGTH); //TODO! Do we need this
sprintf(header_buffer.get(), jsonHeaderFormat, header.jsonversion, header.dynamicRange,
header.fileIndex, header.ndetx, header.ndety, header.npixelsx,
header.npixelsy, header.imageSize, header.acqIndex,
; //"}\n";
memset(header_buffer.get(), '\0', MAX_STR_LENGTH); // TODO! Do we need this
sprintf(header_buffer.get(), jsonHeaderFormat, header.jsonversion,
header.dynamicRange, header.fileIndex, header.ndetx, header.ndety,
header.npixelsx, header.npixelsy, header.imageSize, header.acqIndex,
header.frameIndex, header.progress, header.fname.c_str(),
header.data ? 1 : 0, header.completeImage ? 1 : 0,
@ -186,14 +184,15 @@ int ZmqSocket::SendData(char *buf, int length) {
int ZmqSocket::ReceiveHeader(const int index, zmqHeader &zHeader,
uint32_t version) {
const int bytes_received =
zmq_recv(sockfd.socketDescriptor, header_buffer.get(), MAX_STR_LENGTH, 0);
const int bytes_received = zmq_recv(sockfd.socketDescriptor,
header_buffer.get(), MAX_STR_LENGTH, 0);
if (bytes_received > 0) {
#ifdef ZMQ_DETAIL
cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno,
bytes_received, buffer.data());
#endif
if (ParseHeader(index, bytes_received, header_buffer.get(), zHeader, version)) {
if (ParseHeader(index, bytes_received, header_buffer.get(), zHeader,
version)) {
#ifdef ZMQ_DETAIL
cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index,
portno, bytes_received, buffer.data());

View File

@ -1,4 +1,5 @@
target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-bit_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-container_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-network_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-string_utils.cpp

View File

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

View File

@ -0,0 +1,39 @@
#include "catch.hpp"
#include <vector>
#include "bit_utils.h"
TEST_CASE("Get set bits from 0"){
auto vec = sls::getSetBits(0);
REQUIRE(vec.empty());
}
TEST_CASE("Get set bits from 1"){
auto vec = sls::getSetBits(1);
REQUIRE(vec.size() == 1);
REQUIRE(vec[0] == 0);
}
TEST_CASE("Get set bits from 2"){
auto vec = sls::getSetBits(2ul);
REQUIRE(vec.size() == 1);
REQUIRE(vec[0] == 1);
}
TEST_CASE("Get set bits from 3"){
auto vec = sls::getSetBits(3u);
REQUIRE(vec.size() == 2);
REQUIRE(vec[0] == 0);
REQUIRE(vec[1] == 1);
}
TEST_CASE("All bits set"){
uint8_t val = -1;
auto vec = sls::getSetBits(val);
REQUIRE(vec == std::vector<int>{0,1,2,3,4,5,6,7});
}
TEST_CASE("Get set bits from 523"){
//0b1000001011 == 523
auto vec = sls::getSetBits(523);
REQUIRE(vec == std::vector<int>{0,1,3,9});
}

View File

@ -51,7 +51,7 @@ TEST_CASE("assign module", "[support]") {
CHECK(m3.nchan == 256 * 256 * 4);
}
TEST_CASE("default construct scanParameters"){
TEST_CASE("default construct scanParameters") {
slsDetectorDefs::scanParameters p;
CHECK(p.dacSettleTime_ns == 0);
CHECK(p.dacInd == slsDetectorDefs::DAC_0);
@ -59,10 +59,9 @@ TEST_CASE("default construct scanParameters"){
CHECK(p.startOffset == 0);
CHECK(p.stopOffset == 0);
CHECK(p.stepSize == 0);
}
TEST_CASE("compare two scanParameters"){
TEST_CASE("compare two scanParameters") {
slsDetectorDefs::scanParameters p0;
slsDetectorDefs::scanParameters p1;
@ -70,5 +69,4 @@ TEST_CASE("compare two scanParameters"){
p0.enable = 1;
CHECK_FALSE(p0 == p1);
}

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