Compare commits

...

45 Commits
4.0.2 ... 4.1.1

Author SHA1 Message Date
0a1c4992e2 Merge branch 'main-rc' into b4.1.1 2020-11-30 17:12:26 +01:00
59b56c764f Merge branch 'main-rc' into b4.1.0 2020-11-30 17:09:23 +01:00
a5f0f6eb34 Merge branch 'main' into test 2020-11-20 14:28:29 +01:00
62c86f56b1 Merge branch 'main' into test 2020-11-20 14:27:25 +01:00
9649982932 sw trigger with acquire and parameter file understands submodules 2020-01-15 11:22:40 +01:00
eca2836703 Merge branch '4.1.1' of github.com:slsdetectorgroup/slsDetectorPackage into 4.1.1 2020-01-14 16:25:57 +01:00
d14c9600bb conda version 2020-01-14 16:24:10 +01:00
42971c94b7 updated versioning 2020-01-14 16:16:45 +01:00
b0fd4f4c44 updated release doc 2020-01-14 16:11:24 +01:00
06473cfcb2 bug fix: software trigger using control connect 2020-01-14 13:59:08 +01:00
6f2aad3836 updated temporary versioning 2020-01-06 19:01:44 +01:00
38aad40fef read/write of config/parameter file rewritten so that parameter file can take in slsdetector level commands 2020-01-06 18:16:41 +01:00
51c5520472 unregistering call back, detangling receiver streaming from callback 2020-01-06 11:51:19 +01:00
75838f77b3 unregistering call back, detangling receiver streaming from callback 2020-01-06 11:50:08 +01:00
54bedeaa0a software trigger via stop server instead of control server for sls_detector_acquire 2020-01-06 11:31:05 +01:00
b33b2edbd0 bug fix: locks in acquire 2020-01-06 11:29:11 +01:00
f7cb2b5dcd conda pkg 2019-10-08 12:48:51 +02:00
9ea3cbc8f1 Update RELEASE.txt 2019-10-04 10:56:14 +02:00
53bb677f8c eiger doc updated 2019-10-04 10:41:13 +02:00
663999a539 updated versions 2019-10-04 10:35:42 +02:00
98b45b32fd added jungfrau virtual binaries 2019-10-04 10:29:57 +02:00
74c08cd742 updated binaries in sererbin 2019-10-04 09:42:07 +02:00
696073b505 fixed eiger virtual software versions 2019-10-04 09:41:21 +02:00
e4645a8273 Update RELEASE.txt 2019-10-02 09:37:26 +02:00
c0cd25460d Update RELEASE.txt 2019-10-02 09:35:59 +02:00
e7e30693f0 transmission delays 2019-08-21 20:29:07 +02:00
dd96aac3cd build for conda 2019-08-20 12:24:39 +02:00
5697393a70 Merge branch '4.1.0-rc' of github.com:slsdetectorgroup/slsDetectorPackage into 4.1.0-rc 2019-08-16 15:33:04 +02:00
052dd8058f updated eiger binary 2019-08-16 15:32:49 +02:00
4d99ce8c52 receiver master file includes quad, gap pixels enable, version updated for binary and hdf5 2019-08-14 20:33:40 +02:00
633c646239 eiger bug fix: 4 bit mode gap pixels, also added quad to shm 2019-08-14 15:31:18 +02:00
2a88bc6a1e Merge branch '4.1.0-rc' of github.com:slsdetectorgroup/slsDetectorPackage into 4.1.0-rc 2019-08-14 10:43:15 +02:00
d8af2e594a eiger bug fix: quad mode, without gap pixels, data messed up 2019-08-14 10:42:54 +02:00
8da7c3e805 eiger manual 2019-08-13 16:57:22 +02:00
ddfbea76be eiger server bug fix: interrupt subframe wrong bit mapped, virtual compilation 2019-08-06 17:22:54 +02:00
c5f2275703 eiger serveR: minor fix for beb check quad fail 2019-07-31 15:20:25 +02:00
8c491f18fd quad enabled with gap pixels without the extra vertical pixel line 2019-07-31 13:00:12 +02:00
e07e2f2da0 eiger server bug fix: split quad and interruptframe into set and get to catch fails in set and when quad and interrupt subframe used together(different register values for tl and tr) 2019-07-31 10:58:49 +02:00
d981e1b8e5 eiger server: interrupt subframe, quad change flipping, registers set left and right separately 2019-07-29 15:19:46 +02:00
58e6338f9c eiger server for v24 2019-07-29 09:36:45 +02:00
27f3af5365 updated release text 2019-07-29 09:32:17 +02:00
350b4f0368 bug fix on quad: if no data streaming enabled in the beginning 2019-07-22 17:09:34 +02:00
445f3c66fd bug fix for previous commit to work for bottom module 2019-07-10 17:56:32 +02:00
1189b991e5 quad implemented 2019-07-10 17:39:43 +02:00
3e2b471ee1 client bug fix: framesl, cyclesl printed in float, fixed 2019-07-10 11:13:35 +02:00
72 changed files with 2104 additions and 1220 deletions

View File

@ -41,4 +41,4 @@ deploy:
provider: script
script: find $HOME/miniconda/conda-bld/${TRAVIS_OS_NAME}-64 -name "*.tar.bz2" -exec anaconda -t $CONDA_TOKEN upload --force {} \;
on:
branch: 4.0.2
branch: 4.1.1

View File

@ -1,8 +1,8 @@
SLS Detector Package 4.0.2 released on 13.06.2019 (Bug Fix Release)
SLS Detector Package 4.1.1 released on 15.01.2020 (Bug Fix Release)
===================================================================
This document describes the differences between 4.0.2 and 4.0.1 releases.
This document describes the differences between 4.1.0 and 4.1.1 releases.
CONTENTS
--------
@ -17,72 +17,46 @@ This document describes the differences between 4.0.2 and 4.0.1 releases.
1. Topics Concerning
====================
- Jungfrau receiver as root user
- Receiver HDF5 printErrorStack
- Jungfrau server detector position error when switching between different detector sizes
- Gotthard server get settings does not set default dacs anymore
- Jungfrau powerchip multi detector command delay
- Client API data call back / Gui (Eiger in 4 bit mode)
- Users class added burst_trigger in getTimingMode from string
- Gui switching to tabplot during acquisition error messages
- detangled receiver streaming from data call back in client
and allow for unregister data call back in client
- (eiger) software trigger made to work along with blocking acquire
- bug fix for locks in blocking acquire
- parameter file allows for modular commands
Compared to 4.1.0,
no firmware or on-board detector server update required for this release.
2. Resolved Issues
==================
Receiver
--------
1. Jungfrau Receiver as root user fails to set UDP socket size to default value
of (2000 * 1024 * 1024). It does not receive any packets afterwards.
Temporary solution was to set it to a lower number using
sls_detector_put rx_udpsocksize 1048576000
This has been fixed now to allow a greater size (including the default size).
2. Fixed bug where printError was still being called once instead of printErrorStack.
Detector Server
---------------
1. (Jungfrau)
Switching between different detector size configurations with same detector modules,
the detector gave an error "Could not set detector position". This is fixed now.
2. (Gotthard)
Get settings was setting the default dacs previously. It has been fixed now.
Client
------
1. (Jungfrau)
Using multi detector command for powerchip will have a delay of 1 second between
modules when there are more than 3 modules for extra protection.
1. Registering data call back (registerDataCallback) used to enable data streaming
via zmq in both receiver and client. Sending NULL unregistered call back,
but did not disable streaming.
Now, registering/unregistering this call back will only enable data streaming
in client. Data streaming in receiver will have to be explicitly enabled.
2. Client Callback / Gui (Eiger)
Client data call back provided the complete image data, but the number of pixels
in x and y was provided incorrectly at a modular level. This has been fixed to give
the proper value. This also fixes the Gui crashing for Eiger 4 bit mode when
acquiring for multiple images.
2. (Eiger)
Software trigger triggered via the stop server and hence, can be triggered
also during blocking acquire.
3. (API)
Added "burst_trigger" in getTimingMode (from string to int) in Users class.
Gui
---
1. Switching to Tab Plot during acquisition produced error messages. This has been
fixed.
3. If stop acquisition command was given immediately after starting a blocking acquire,
it might have hanged the process. This bug is fixed now.
4. Parameter file now allows modular commands (using ':'). They are not ignored anymore.
3. Known Issues
===============
:)
4. Firmware Requirements
========================
Gotthard
========
Minimum compatible version : 11.01.2013
@ -90,8 +64,8 @@ This document describes the differences between 4.0.2 and 4.0.1 releases.
09.02.2018 (25 um Slave)
Eiger
=====
Minimum compatible version : 23
Latest compatible version : 23
Minimum compatible version : 24
Latest compatible version : 24
Jungfrau
========
@ -106,12 +80,13 @@ This document describes the differences between 4.0.2 and 4.0.1 releases.
Jungfrau Can be upgraded remotely using sls_detector_put programfpga <pof>
Instructions available at
https://www.psi.ch/detectors/installation-instructions
under Detector Upgrade -> [Detector Type] -> Firmware.
https://slsdetectorgroup.github.io/slsDetectorPackage/docs/html/slsDetectorInstall/GOTTHARD_Firmware.html
https://slsdetectorgroup.github.io/slsDetectorPackage/docs/html/slsDetectorInstall/EIGER_Firmware.html
https://slsdetectorgroup.github.io/slsDetectorPackage/docs/html/slsDetectorInstall/JUNGFRAU_Firmware.html
Please refer to the link below for more details on the firmware versions.
https://www.psi.ch/detectors/firmware.
https://www.psi.ch/en/detectors/firmware
@ -138,26 +113,37 @@ This document describes the differences between 4.0.2 and 4.0.1 releases.
-------------
Manual (HTML & PDF):
https://www.psi.ch/detectors/documentation
https://www.psi.ch/en/detectors/documentation
slsDetectorPackage/manual/docs/
Command Line Documentation:
https://slsdetectorgroup.github.io/slsDetectorPackage/docs/html/slsDetectorClientDocs/index.html
https://slsdetectorgroup.github.io/slsDetectorPackage/docs/pdf/slsDetectorClientDocs.pdf
manual/docs/html/slsDetectorClientDocs/index.html
manual/docs/pdf/slsDetectorClientDocs.pdf
C++ API Documentation:
https://slsdetectorgroup.github.io/slsDetectorPackage/docs/html/slsDetectorUsersDocs/index.html
https://slsdetectorgroup.github.io/slsDetectorPackage/docs/pdf/slsDetectorUsersDocs.pdf
manual/docs/html/slsDetectorUsersDocs/index.html
manual/docs/pdf/slsDetectorUsersDocs.pdf
C++ API Example:
https://slsdetectorgroup.github.io/slsDetectorPackage/exampleCode/slsDetectorUsersExample/index.html
manual/manual-api/mainClient.cpp
manual/manual-api/mainReceiver.cpp
Python API Documentation:
https://slsdetectorgroup.github.io/sls_detector/
TroubleShotting:
https://www.psi.ch/en/detectors/troubleshooting
Further Documentation:
https://www.psi.ch/detectors/users-support
https://www.psi.ch/en/detectors/users-support
Support

5
cmk.sh
View File

@ -60,6 +60,7 @@ while getopts ":bchd:j:trge" opt ; do
b)
echo "Building of CMake files Required"
REBUILD=1
CLEAN=1
;;
c)
echo "Clean Required"
@ -69,6 +70,7 @@ while getopts ":bchd:j:trge" opt ; do
echo "Building of CMake files with HDF5 option Required"
HDF5=1
REBUILD=1
CLEAN=1
;;
d)
echo "New HDF5 directory: $OPTARG"
@ -82,16 +84,19 @@ while getopts ":bchd:j:trge" opt ; do
echo "Compiling Options: Text Client"
TEXTCLIENT=1
REBUILD=1
CLEAN=1
;;
r)
echo "Compiling Options: Receiver"
RECEIVER=1
REBUILD=1
CLEAN=1
;;
g)
echo "Compiling Options: GUI"
GUI=1
REBUILD=1
CLEAN=1
;;
e)
echo "Compiling Options: Debug"

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

View File

@ -6,6 +6,7 @@
\usepackage{verbatim}
\usepackage{xspace}
\usepackage{hyperref}
\usepackage{xcolor}
\newcommand{\E}{EIGER\xspace}
\newcommand{\p}{sls\_detector\_put}
\newcommand{\g}{sls\_detector\_get}
@ -24,7 +25,7 @@ Figure ~\ref{boards} show the readout board basic components on an Eiger half mo
\begin{center}
\includegraphics[width=1\textwidth]{Boards}
\end{center}
\caption{Picture with most relevant components of the EIGER readout system. The readout system starts with the Front End Boards (FEB) which performs data descrambling (also converts the packets from 12 $\to$ 16 bits) and rate correction. The BackEndBoard (BEB) has 2x2GB DDR2 memories and can perform data buffering (storing images on board) and data summation (16 bit $\to$ 32 bits). The controls to the detector are passed through the 1Gb, while in most installations, the data are sent out through the 10GB ethernet connection.}
\caption{Picture with most relevant components of the EIGER readout system. The readout system starts with the Front End Boards (FEB) which performs data descrambling (also converts the packets from 12 $\to$ 16 bits) and rate correction. The BackEndBoard (BEB) has 2x2GB DDR2 memories and can perform data buffering (storing images on board) and data summation (16 bit $\to$ 32 bits). The controls to the detector are passed through the 1Gb, while in most installations, the data are sent out through the 10~GB ethernet connection.}
\label{boards}
\end{figure}
@ -156,6 +157,14 @@ outdir /sls/X12SA/data/x12saop/Data10/Eiger0.5M
threaded 1
\end{verbatim}
The geometry on af an EIGER module, showing the quadrants corresponding to the udp ports and the 2 receivers is shown in figure~\ref{fig:eigerports}.
\begin{figure}[t]
\begin{center}
\includegraphics[width=0.9\textwidth]{Eiger-Chips}
\end{center}
\caption{Geometry of UDP ports and receivers in a singel module.}
\label{fig:eigerports}
\end{figure}
In the case you are developing your own receiver, then you need to remove the 1Gb receiver hostname {\tt{rx\_hostname}} and substitute it with the mac address of the device:
\begin{verbatim}
@ -163,11 +172,11 @@ configuremac 0
rx_udpmac xx:xx:...
\end{verbatim}
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.
Other important settings that are configured in the {\tt{setup.det}} file are:
@ -219,6 +228,7 @@ We have added a special command, {\tt{thresholdnotb}}, which allows to scan the
\begin{verbatim}
sls_detector_put 0-thresholdnotb energy_in_eV
\end{verbatim}
See section~\ref{sec:fastthresholdscan}.
\section{Standard acquisition}
@ -317,31 +327,49 @@ The size of the gap pixels between modules to insert is
GapPixelsBetweenModules_y = 36
\end{verbatim}
where the {\tt{GapPixelsBetweenModules\_x}} are the one on the short side of the module, while {\tt{GapPixelsBetweenModules\_y}} are the ones on the long side of the module (where the wirebonds take physical space).
\section{QUAD special geometry}
Starting from release 4.1.0, we support a special geometry with 2x2 pixels. This is for a Quad, where a single half module reads out 4 chips but in a quad shape. For now this hardware is only available as a PEEM detector at SIM.
The {\tt{detsizechan 1024 512}} needs to remain set like this for a half module. However, thanks to the command:
\begin{verbatim}
./sls_detector_put quad 1
\end{verbatim}
a 512x512 geomtry will be read out if {\tt{gappixels 0}} and 514x514 will be readout if {\tt{gappixels 1}}. Note that as above, {\tt{gappixels 1}} is not supported for {\tt{dr 4}}.
If {\tt{gappixels 0}}, in the master.raw file you will read:
\begin{verbatim}
row : 512 pixels
col : 256 pixels
\end{verbatim}
else if {\tt{gappixels 1}}, in the master.raw file you will read:
\begin{verbatim}
row : 514 pixels
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.
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}.
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}
\begin{tabular}{|c|c|c|c|}
\begin{tabular}{|c|c|c|c|c|}
\hline
GbE & dynamic range & continuos maximum frame rate(Hz) & minimum period ($\mu$s)\\
\tiny{GbE} & \tiny{dynamic range} & \tiny{continuos maximum frame rate(Hz)} & \tiny{minimum period ($\mu$s)}& \tiny{calculated/measered time to send out data ($\mu$s)}\\
\hline
1 & 16 & \textbf{256} & 3901\\
1 & 16 & \textbf{256} & 3901 & \\
\hline
1 & 32 & \textbf{128} & 7820\\
1 & 32 & \textbf{128} & 7820 & \\
\hline
10 & 16 & \textbf{2560} & 391\\
10 & 4 & \textbf{10240} & 98 & 105/128\\
\hline
10 & 32 & \textbf{1280}& 782\\
\hline
10 & 8 & \textbf{5120} & 196\\
\hline
10 & 4 & \textbf{10240} & 98\\
10 & 8 & \textbf{5120} & 196 & 210/250\\
\hline
10 & 16 & \textbf{2560} & 391 & 420/490\\
\hline
10 & 32 & \textbf{1280} & 782 & 840/977\\
\hline
\end{tabular}
\caption{Frame rate limits for the CONTINUOS streaming out of images, i.e. the data rate out is just below 1Gb/s or 10Gb/s.}
\caption{Frame rate limits for the CONTINUOS streaming out of images, i.e. the data rate out is just below 1Gb/s or 10Gb/s. 1280~Hz for 32-bit, 10GbE is obtained from the 10GbE limitation. The maximum achievable frame rate is 977~Hz.}
\label{tcont}\end{table}
Note that in the {\tt{continuous}} flag mode, some buffering is still done on the memories, so a higher frame rate than the proper real continuous one can be achieved. Still, this extra buffering is possible till the memories are not saturated. The number of images that can be stored on the DDR2 on board memories are listed in table~\ref{timgs}.
\begin{table}
@ -411,18 +439,9 @@ where the 'minimum time between frames' and the minimum period will be discussed
\hline
4 & 0 & \tiny {parallel} & 3.4 & 22 & 44 & 44.01 & 30k/50k\\
\hline
4 & 1 & \tiny {parallel} & 6 & 10.5 & 92 & 92.02 & 30k/100k\\
\hline
4 & 2 & \tiny {parallel} & 11.2 & 5.4 & 197& 197.01 & infinite\\
\hline
\hline
8 & 0 & \tiny {parallel} & 3.4 & 11.1 & 89 & 89.01 & 15k/24k\\
\hline
8 & 1 & \tiny {parallel} & 6.1 & 5.7 & 181 & 181.01 & 15k/52k\\
\hline
8 & 2 & \tiny {parallel} & 11.2 & 2.9 & 342 & 342.01 & infinite\\
\hline
\hline
16 & 0 & \tiny {parallel} & 3.4 & 6.1 & (126+38)* =164 & 164.02 & 8k/12k\\
\hline
16 & 0 & \tiny {nonparallel} & 127 & 5.6 & (126+52)*= 179 & 179.01& 8k/23k\\
@ -431,14 +450,6 @@ where the 'minimum time between frames' and the minimum period will be discussed
\hline
16 & 1 & \tiny {nonparallel} & 255 & 3.3 & 303 & 303.01 & infinite\\
\hline
16 & 2 & \tiny {parallel} & 11.2 & 1.9 & 526 & 526.2 & infinite \\
\hline
16 & 2 & \tiny {nonparallel} & 505 & 1.8 & 555 & 555.01& infinite\\
\hline
%32 & 2 & parallel & 11 & 2& & &\\
%\hline
%32 & 2 & nonparallel & 504 & $<2$& & &\\
%\hline
\end{tabular}
\caption{Readout settings. The {\tiny{min exptime}} possible is 5$-$10~$\mu$s. This is due to the time to pass the pixel enable signal in the whole chip. The time between frames ($\Delta$t) has been measured with the oscilloscope and the maximum frames rate (max FR) has been tested with an external gating from a pulse generator at known frequency. The minimum period is obtained as 1/$\textrm{max frame rate}$.}
\label{tframes}
@ -449,7 +460,6 @@ 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.}
\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}
\textrm{new period} = \textrm{exptime} + \textrm{minimum time between frames} + (\textrm{10$-$20 }\mu \textrm{s})
@ -459,7 +469,56 @@ to let the signal settle or, if the frame rate is important, leave the {\tt{pe
\textrm{new exptime} = \textrm{old exptime} - (\textrm{10$-$20 }\mu \textrm{s})
\end{equation}
In general, choose first the desired dead time: this will tell you if you want to run in parallel or non parallel mode, although most likely it is parallel mode. Then, choose the maximum frame rate you want to aim, not exceeding what you aim for not to increase the noise. In 4 and 8 bit modes it makes no sense to run nonparallel as the exposure time is too small compared to the readout time.
In general, choose the maximum frame rate you want to aim, not exceeding what you aim for not to increase the noise. In 4 and 8 bit modes it makes no sense to run nonparallel as the exposure time is too small compared to the readout time.
Here below are the final tables for settting the detcetor correctly:
\begin{itemize}
\item CONTINUOUS redout (imagesnot stored on board memories, frames can be achieved. {\tt{flags parallel}}, {\tt{clkdivider 0}} are always set. In 32-bit no extra {\tt{subdeadtime}} is assumed. The difference between {\tt{exptime}} and {\tt{period}} has to be $\approx$5 $\mu$s:
\begin{center}
\begin{tabular}{ |c| c| }
\hline
max frame rate & settings\\
\hline
\textcolor{red}{189~Hz (977~Hz max)} & \textcolor{red}{32-bit} \\
& Nframes=infinite\\
\hline
\textcolor{red}{2.56 kHz} & \textcolor{red}{16-bit}\\
& Nframes=infinite\\
\hline
\textcolor{red}{5.1 kHz} & \textcolor{red}{8-bit}\\
& Nframes=infinite\\
\hline
\textcolor{red}{10.2 kHz} & \textcolor{red}{4-bit}\\
& Nframes=infinite\\
\hline
\end{tabular}
\end{center}
BE CAREFUL that if you have the transmission delays setup (see sec.~\ref{network}), this will slow down the sending of the data and you risk to fill up the memories of the boards on eiger (30000 images in 4 bit mode) and you will get corrupted data (parts of the memory on the boads will be overwritten).
\item BUFFERED readout (images stored on board memories, such that the maximum frame rate can be achieved for a limited amount of frames. {\tt{flags parallel}}, {\tt{clkdivider 0}} are always set. In 32-bit no extra {\tt{subdeadtime}} is assumed. The difference between {\tt{exptime}} and {\tt{period}} has to be $\approx$5 $\mu$s:
\begin{center}
\begin{tabular}{ |c| c| }
\hline
max frame rate & settings\\
\hline
\textcolor{red}{189~Hz (977~Hz)} & \textcolor{red}{32-bit} \\
& Nframes=infinite\\
\hline
\textcolor{red}{6.1 kHz} & \textcolor{red}{16-bit}\\
& Nframes=7600\\
\hline
\textcolor{red}{11.1 kHz} & \textcolor{red}{8-bit}\\
& Nframes=15000\\
\hline
\textcolor{red}{22 kHz} & \textcolor{red}{4-bit}\\
& Nframes=30000\\
\hline
\end{tabular}
\end{center}
\end{itemize}
\subsubsection{4 and 8 bit mode}
In {\tt{parallel}} mode, the minimum time between frames is due to the time required to latch the values of the counter with capacitors. These values are determined in firmware and they can be estimated as:
@ -497,16 +556,16 @@ The time between 12-bit subframes are listed in table~\ref{t32bitframe}.
\begin{tiny}
\begin{table}
\begin{flushleft}
\begin{tabular}{|c|c|c|c|c|c|}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline
\tiny{dr} & \tiny{clkdivider} & \tiny{flags} & \tiny{t difference between subframes($\mu$s)} & \tiny{max internal subframe rate (kHz)} & \tiny{maximum frame rate (Hz)}\\
\tiny{dr} & \tiny{clkdivider} & \tiny{flags} & \tiny{subexptime (s)} & \tiny{t difference between subframes($\mu$s)} & \tiny{max internal subframe rate (kHz)} & \tiny{maximum frame rate (Hz)}\\
\hline
32 & 2 & parallel & 12 & 2 & 170\\
32 & 2 & parallel & 0.00262144 & 12 & 380 & 189\\
\hline
32 & 2 & nonparallel & 504 & $<2$ & 160\\
32 & 2 & parallel & 0.000490 & 12 & 2 & 997\\
\hline
\end{tabular}
\caption{Timing for the 32bit case. The maximum frame rate has been computed assuming 2 subframes of default {\tt{subexptime}} of 2.62144 ms.}
\caption{Timing for the 32bit case. The maximum frame rate has been computed assuming 2 subframes of default {\tt{subexptime}} of 2.62144 ms, which is the default value. By setting up {\tt{subexptime}} to 490~$\mu$s one can achieve a maximum frame rate. Note that one has to leave 490$\mu$s extra between a frame and the following.}
\label{t32bitframe}
\end{flushleft}
\end{table}
@ -561,7 +620,11 @@ Here are the implemented options so far:
\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}}. 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. If the exposure time is unknow, it is recommended that you switch off the rate corrections. 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{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.
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.
However, from 4.1.0, in gating mode, an option to immediately terminate the subframe when the gate signal goes down it is implemented to stop the acquisition at the same time. This option is {\tt{./sls\_detector\_put interruptsubframe 1}} while the default option is {\tt{./sls\_detector\_put interruptsubframe 0}}.
\end{itemize}
@ -576,7 +639,7 @@ sls_detector_put 0-frames x
sls_detector_put 0-cycles y
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}.
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}.
\section{Autosumming and rate corrections} \label{advanced}
@ -616,6 +679,19 @@ sls_detector_put 0-ratecorr -1
Every time either the rate corrections are activated, $\tau$ is changed or the subframe length is changed, then a new correction table is evaluated. Note that computing the correction table is time consuming.
Here in figure~\ref{rateplots} you can find typical values of $\tau$ and typical values of the rates for which we have small non linerities (10\% non linearity) as a function of the beam energy.
\begin{figure}[t]
\begin{center}
\includegraphics[width=.7\textwidth]{tauvsE}
\includegraphics[width=.7\textwidth]{Ratecapabilityflux}
\end{center}
\caption{Typical values of the dead time for the detector and safe fluxes as a function of the beam energy}.
\label{rateplots}
\end{figure}
\section{Dependent parameters and limits}
Here is a list of dependent parameters:
\begin{enumerate}
@ -664,7 +740,7 @@ LEDs on the backpanel board at the back of each half module signal:
\subsection{Delays in sending for 1Gb/s, 10Gb/s, 10Gb flow control, receiver fifo}
\subsection{Delays in sending for 1Gb/s, 10Gb/s, 10Gb flow control, receiver fifo}\label{network}
Extremely advanced options allow to:
\begin{itemize}
@ -693,6 +769,7 @@ for X in $(seq 0 4); do ./sls_detector_put $X:txndelay_left $((X*100000)); done
./sls_detector_put txndelay_frame zzzz
\end{verbatim}
In the example before, it would be: {\tt{zzzz}}=4*100000+ 100000
To decide the size of the transmission delays, look at subsection~\ref{delays}.
\item Readjust the size of the fifo of the receiver between listening and writing (useful when writing is limited)
\begin{verbatim}
@ -711,35 +788,132 @@ To activate back a module, do:
\end{verbatim}
\end{itemize}
\subsection{Setting up 10Gb correctly: experience so far}\label{10g}
\section{Choose correct transmission delays}\label{delays}
Transmission delays should be chosen only to accomodate the writing speed of the disk. The 10Gb network should be optimised independently to allow no packet loss situation. This can be done by turning off the writing of the files and check only for missing frames.
Table~\ref{tcont} gives the times that are needed to transfer 1 images out of the 10~Gb Ethernet connection. This reflects the CONTINUOS frame rate achieavable. The disk speed can be monitored with {\tt{dstat}}. One you have worked out this, you can calculated the {\tt{txndelay\_frame}} delay as:
\begin{equation}
{\tt{txndelay\_frame}}=-t_sending+dr \cdot \frac{4*256*256*N\_half\_modules}{1024 \cdot 1000 \cdot disk\_speed [MB/s] \cdot 8}
\end{equation}
In 4-bit mode, for a disk seed of 320MB/s, the {\tt{txndelay\_frame}} is 300~$\mu$s (30000 to be set up to the detector). The sending time is 100~$\mu$s, such that an total ackievable writing speed of 1/400~$\mu$s (2.5~kHz) in achieved.
Note that:
\begin{enumerate}
\item The continuos frame rate goes down when transmission delays are introduced:
\begin{equation}
continuos\_frame\_rate= \frac{1}{\tt{txndelay\_frame}+t\_sending}
\end{equation}
\item If your transmission delays reduce the continuos frame rate, you will saturate the memory on board at some point and you will corrupt images. Conservatively, we say that the number of maximum images in buffered mode is the one listed in table~\ref{timgs}, call N\_images. However, one can approximately say that (and here we need to test more, so do not believe to these numbers yet),
\begin{equation}
N\_tot\_images= N\_images+\frac{ N\_images}{frame\_rate \cdot (t\_delay\_frame + t\_sending) }
\end{equation}
\end{enumerate}
\section{Setting up the PC settings for 10Gb}\label{10g}
For configuring well the 10Gb card not to loose packets,
\begin{itemize}
\item MTU must be set up to 9000 (jumbo frames) on all the involved sides: detector, switch, server NIC
\item you should set up static MAC address tables with separated VLANs
\end{itemize}
As root, also do:
As root, also first check your ethtool settings (-small letter arguments), then change the settings (-capital letter arguments):
\begin{verbatim}
ethtool -G xth1 rx 4096, ethtool -C xth1 rx-usecs 100
ethtool -g xth1
ethtool -c xth1
ethtool -a xth1
\end{verbatim}
where {\tt{xth1}} can be replaced with the correct 10Gb device. To minimise loosing packets, priorities are set better as root user, so have the receiver as root.
To change settings:
\begin{verbatim}
ethtool -G xth1 rx 4096 #or wheterver is the max number for your pc
ethtool -C xth1 rx-usecs 100
ethtool -A xth1 rx on
\end{verbatim}
where {\tt{xth1}} can be replaced with the correct 10Gb device.
NOTE THAT THIS SETTINGS WILL BE LOST IF YOU REBOOT THE COMPUTER.
Very important is to activate the flow control in 10Gb (in 1Gb it is on by default and not configurable)
\begin{verbatim}
./sls_detector_put flowcontrol_10g 1
\end{verbatim}
You ned to check that flow control is setup on the reeceiving interfaces. Check with:
\begin{verbatim}
ethtool -a eth1
\end{verbatim}
.RX should be ON. Set the transmission delays as explained in the manual if necessary. These transmission delays should help matching teh writing speed performance of your disk. You can check how fast you are writing using the {\tt{dstat}} command.
Now setup the computer server propery:
Check the size of:
\begin{verbatim}
sysctl -a | grep backlog
sysctl -a | grep rmem
\end{verbatim}
Set it correctly with:
\begin{verbatim}
sysctl net.core.netdev_max_backlog=250000
sysctl net.core.rmem_default=$((100*1024*1024))
sysctl net.core.rmem_max=$((100*1024*1024))
\end{verbatim}
Other way to setup the same, increase the socket receiving buffer size and the maximum length of the input queue:
\begin{verbatim}
echo $((100*1024*1024)) > /proc/sys/net/core/rmem_max
echo 250000 > /proc/sys/net/core/netdev_max_backlog
\end{verbatim}
to make the settings permanent, edit /etc/sysctl.conf:
\begin{verbatim}
# 100MiB
net.core.rmem_max = 104857600
net.core.rmem_default= 104857600
net.core.netdev_max_backlog = 250000
\end{verbatim}
and run \textbf{sysctl -p}.
To minimise loosing packets, priorities are set better as root user, so have the receiver as root.
To try to bypass being root, we trued something like this:
\begin{verbatim}
/etc/security/limits.conf username rtprio 99
\end{verbatim}
but somehow it did not fully worked so we kept the trick of being root.
Very important is to activate the flow control in 10Gb (in 1Gb it is on by default and not configurable)
Last, you can disable power saving in the CPU frequency (chose the appropriate command for your system):
\begin{verbatim}
./sls_detector_put flowcontrol_10g 1
cpupower frequency-info
cpupower frequency-set -g performance
\end{verbatim}
or
\begin{verbatim}
cpufreq-info
for i in `seq 0 7`; do cpufreq-set -c $i -g performance; done
\end{verbatim}
Set the transmission delays as explained in the manual.
It can help to increase the fifo size of the receiver to {\tt{rx\_fifodepth}} to 1000 images
\begin{verbatim}
./sls_detector_put rx_fifodepth 1000
\end{verbatim}
One needs to keep into account that in 16 bit mode for 1 image we expect each slsReceiver to allocate 0.5MB. So for 1000 images, we expect 500MB memory for each receiver. This can be monitored in Linux with "top" or "free -m".
One needs to keep into account that in 16 bit mode for 1 image we expect each slsReceiver to allocate 0.5MB. So for 1000 images, we expect 500MB memory for each receiver. This can be monitored in Linux with "top" or "free -m". To receive the max number of images possible on the detector, a minimum of 8~GB of memories are required.
For very high frame rate, very long measurements, we had to increase the {\tt{rx\_fifodepth}} to 10000 images but this only in 4, 8, 16 bit mode. In 32 bit mode it will assign 40~GB of memory, which is more than what normal PC would have. So make sure you do not require too much memory.
Last, it is very important that not too many files are created. There is high possibility to loose packets in the time to close and open files for the writer. IN 3.1.x, the default number of images written per file, in Eiger is 2000. This is defined by the line:
\begin{verbatim}
#define EIGER_MAX_FRAMES_PER_FILE 2000
\end{verbatim}
in {\tt{slsDetectorsPackage/slsReceiverSoftware/include/sls\_receiver\_defs.h}}. In 4.0.x, this is interactively defined using the command: {\tt{r\_framesperfile}}. By default it is 10000.
If you do not have a large disk, you can write to memory if your pc is not fast enough:
\begin{verbatim}
mount -t tmpfs none /ramdisk_folder
\end{verbatim}
or
\begin{verbatim}
mount -t tmpfs none /mnt/ramdisk -o size=10G
\end{verbatim}
check how many GB memory you can allocate, to avoid swapping otherwise
\section{Offline processing and monitoring}
@ -778,19 +952,22 @@ If you use the option of writing raw files, you will have a raw file for each UD
The master file is named: {\tt{filename\_master\_0.raw}} and for version ``4.0.0'' of the slsDetectorSoftware looks like:
\begin{verbatim}
Version : 2.0
Version : 4.0
Detector Type : 3
Dynamic Range : 32
Ten Giga : 1
Image Size : 524288 bytes
x : 512 pixels
y : 256 pixels
Max. Frames Per File : 10000
Total Frames : 1
Exptime (ns) : 1000000000
nPixelsX : 512 pixels
nPixelsY : 256 pixels
Max Frames Per File : 10000
Total Frames : 3
Exptime (ns) : 10000000
SubExptime (ns) : 2621440
SubPeriod(ns) : 2621440
Period (ns) : 1000000000
Timestamp : Mon Sep 3 09:07:05 2018
Period (ns) : 0
Gap Pixels Enable : 0
Quad Enable : 0
Timestamp : Wed Aug 21 16:30:20 2019
#Frame Header
@ -800,9 +977,9 @@ Packet Number : 4 bytes
Bunch ID : 8 bytes
Timestamp : 8 bytes
Module Id : 2 bytes
X Coordinate : 2 bytes
Y Coordinate : 2 bytes
Z Coordinate : 2 bytes
Row : 2 bytes
Column : 2 bytes
Reserved : 2 bytes
Debug : 4 bytes
Round Robin Number : 2 bytes
Detector Type : 1 byte
@ -815,13 +992,18 @@ Note that if one wants to reconstruct the real time the detector was acquiring
\subsection{Offline image reconstruction}
The offline image reconstruction{\tt{slsImageReconstruction}} is not part of the package anymore. The code is still available doing \\
{\tt{git clone git@git.psi.ch:sls\_detectors\_software/sls\_image\_reconstruction.git slsImageReconstruction}}.
Checkout the {\tt{developer}} branch if in a 3.1.X release or the {\tt{v4.0.0}} branch if in 4.0.X release of the {\tt{slsDetector}} code.
Checkout the {\tt{developer}} branch if in a 3.1.X release, the {\tt{v4.0.0}} branch if in 4.0.X release, or the {\tt{v4.1}} branch if in 4.1.X release of the {\tt{slsDetector}} code.
Three possible conversions are possible: into \textbf{cbf}, \textbf{hdf5} and \textbf{root} format. The detector writes 4 raw files per receiver. An offline image reconstruction executable has been written to collate the possible files together and produce output files. By default an interpolation between the values of the large pixels is performed. Gap pixels between modules are also inserted.
Note that the number of images per file in the 3.1.X release is hardcoded and needs to match whatever you are using in {\tt{slsDetectorsPackage/slsReceiverSoftware/include/sls\_receiver\_defs.h}}:
\begin{verbatim}
#define EIGER_MAX_FRAMES_PER_FILE 2000
\end{verbatim}
The default is 2000 in the 3.1.X release. The default has been changed to 10000 frm realease 4.0.X and now this is picked up automatically without doing anything.
\subsubsection{cbf}
The cbf executable executable uses the CBFlib-0.9.5 library (downloaded from the web as it download some architecture dependent packages at installation).Edit the Makefile to correclty point at it.\\
The cbf executable executable uses the CBFlib-0.9.5 library (downloaded from the web as it downloads architecture dependent packages at installation).Edit the Makefile to correclty point at it.\\
\underline{At cSAXS, the CBFlib-0.9.5 has been compiled -such that the required packages are}\\\underline{ downloaded in /sls/X12SA/data/x12saop/EigerPackage/CBFlib-0.9.5.}\\
To use it for a single module:
@ -832,7 +1014,7 @@ eg.
{\tt{cbfMaker /scratch/run\_63\_d1\_f000000000000\_3.raw}}\\
To use it any geometry:\\
{\tt{cbfMaker [filename] [pixels x, def=1024] [pixels y, def=512] [singlemodulelongside\_x, def=1] [fillgaps, def=Interpolate Big Pixels] [hdf5datasetname, def="Eiger"] [start det,def=0]}}\\
{\tt{cbfMaker [filename] [outdir, def=same as filename] [pixels x, def=1024] [pixels y, def=512] [singlemodulelongside\_x, def=1] [fillgaps, def=Interpolate Big Pixels] [hdf5datasetname, def="Eiger"] [start det,def=0]}}\\
eg.
{\tt cbfMaker /scratch/run\_63\_d0\_f000000000000\_3.raw 3072 512 1 2 ``Eiger'' 0}.\\
@ -876,7 +1058,7 @@ make cbfMaker; make cbfMakerOMNY;
\end{verbatim}
\subsubsection{hdf5}
In case of HDF5 output file, we rely on having the HDF5 1.10.1 library installed. Edit the Makefile to correclty point at it. Different compression methods are being tried so different external filters might be to be installed. This work is not finished yet.
In case of HDF5 output file, we rely on having the HDF5 1.10.1 library installed and {\tt{HDF5-External-Filter-Plugins}} installed. With HDF5 1.10.3, no need of the external plugings package is needed, but a small modification to the file is needed. Edit the Makefile to correclty point at it. Different compression methods are being tried so different external filters might be to be installed. This work is not finished yet.
To choose HDF5, with ZLIB implementation, open {\tt{slsImageReconstruction/src/main\_csaxs.cpp}} and make sure that
\begin{verbatim}
@ -888,7 +1070,7 @@ are not commented out. All other options need to be commented out. Copile the co
make hdf5Maker; make hdf5MakerOMNY;
\end{verbatim}
If you are at cSAXS. all images collected will be written in a single file. If you are not at CSAXS, most likely you want to have all the images written in a single raw file into an HDF5 file. The multiple HDF5 files are then linked in a master file, with many subdatasets (can be read by albula) or by a virtual file with a single dataset. If you want a mster o virtual file, uncomment this option:
If you are at cSAXS. all images collected will be written in a single file. If you are not at CSAXS, most likely you want to have all the images written in a single raw file into an HDF5 file. The multiple HDF5 files are then linked in a master file, with many subdatasets (can be read by albula) or by a virtual file with a single dataset. If you want a master o virtual file, uncomment this option:
\begin{verbatim}
#define MASTERVIRTUAL
\end{verbatim}
@ -910,7 +1092,7 @@ The data will be written as TH2D in root format. Edit the {\tt{Makefile}} to poi
\begin{verbatim}
make image
\end{verbatim}
There is no program other executable that alredy keeps into account the geometry for it.
There is no program other executable that already keeps into account the geometry for it.
To use it any geometry:\\
{\tt{image [filename] [pixels x, def=1024] [pixels y, def=512] [singlemodulelongside\_x, def=1] [fillgaps, def=Interpolate Big Pixels] [hdf5datasetname, def="Eiger"] [start det,def=0]}}\\
eg.
@ -978,9 +1160,9 @@ ssh root@$i sync; done
\section{Loading firmware bitfiles}
\textbf{As a new procedure, the first thing to do is to kill the server on the boards, copy the new one there without starting it.} Note taht failure to do this step before may cause the linux on the baords to crash and not being able to ping it (this if the registers between the old and new firmware change).
\textbf{As a new procedure, the first thing to do is to kill the server on the boards, copy the new one there without starting it.} Note that failure to do this step before may cause the linux on the boards to crash and not being able to ping it (this if the registers between the old and new firmware change).
This is teh procedure from a terminal;
This is the procedure from a terminal;
\begin{verbatim}
for i in beb111 beb070;
do ssh root@$i killall eigerDetectorServer;
@ -1058,12 +1240,40 @@ To load the special noise file look at {\tt{settingsdir/eiger/standard/eigernois
\begin{verbatim}
sls_detector_put trimbits ../settingsdir/eiger/standard/eigernoise
\end{verbatim}
To exit from this pattern noise, just set the theshold to something known.
To exit from this pattern noise, just set the threshold to something known.
\begin{verbatim}
\item sls_detector_put threshold 50000 standard
\end{verbatim}
where 5000 would be a value in eV and {/tt{standard}} is important in this case.
\section{(Fast) threshold scans during beam operation}\label{sec:fastthresholdscan}
Occasionally you might need to do threshold scans during your data taking (for example for Laue experiments or to get any spectral information). Setting the threshold in this case would be not optimal as you would change trimbits at every energy and this could give you a ``step'' behaviour. What you could do is to use the
\begin{verbatim}
\item sls_detector_put thresholdnotb 50000
\end{verbatim}
which set the threshold to an energy but does not change trimbits. We suggest that before using this function you load the {\tt{threshold}} at an energy in the middle of your scan range and then change {\tt{thresholdnotb}}.
We have also been requested if we could speed up the threshold scan. At the moment no specific function has been integrated in firmware, but one could use the software trigger option to perform what you need:
\begin{verbatim}
./sls_detector_put exptime 0.01
./sls_detector_put timing trigger
./sls_detector_put enablefwrite 0
./sls_detector_put resetframescaught 0
./sls_detector_put index 0
./sls_detector_put cycles 21
./sls_detector_put receiver start
./sls_detector_put status start
for i in $(seq 0 20);
do
#./sls_detector_put thresholdnotb 5000 ##this is still too slow as it loads the module
./sls_detector_put 0:vrf 3199 #need to know the appropriate vrf at every energy
./sls_detector_put 1:vrf 3199 #need to know the appropriate vrf at every energy
./sls_detector_put status trigger
#sleep 0.005
done
./sls_detector_put receiver stop
./sls_detector_put resetframescaught 0
./sls_detector_put timing auto
\end{verbatim}
\section{Troubleshooting}
\subsection{Cannot successfully finish an acquisition}
@ -1215,7 +1425,7 @@ Scroll up in the terminal till you find:\\
*************** MASTER/SLAVE ***************\\
*************** NORMAL/SPECIAL ***************\\
There is also an easier way, that is that only the master module will reaturn 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.
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
@ -1225,10 +1435,14 @@ for i in $(seq 0 36); do sls_detector_put $i:vhighvoltage; done
\subsection{'Cannot connect to socket'}
This error is typically due to the detector server not running. For why, see section~\ref{servernot}.
\subsection{Running at low frame rate, the communication to receiver stops}
If running in 32-bit mode (or even in 16-bit mode), if more memory than what your machine can handle is asked for, the receiver process could be terminated by the kernel of your machine. It would loook like you had executed a clean control-c on the receiver executable. This has been the case, when setting up by mistake
\tt{rx\_fifodepth} to 10000 images in 32 bit mode. In 32 bit mode it will assign 40~GB of memory, which is more than what normal PC would have. So make sure you do not require too much memory. The same is tru also for smaller values of {\tt{rx\_fifodepth}} if your machine has not much memory.
\subsection{Detector server is not running}\label{servernot}
The detector server could not be running: either the detector was powered off, or it powered off itself due to too high temperature or, in the case of the 9M, if the waterflow sensor detected no flux and powered it off (the chiller stops occasionally as cSAXS).
If the powering and the temperature are OK, instead, it can be that the firmware version is incompatible to the server version and/or the client software version. So check the consistency of firmware/software/server versions.
If the powering and the temperature are OK, instead, it can be that the firmware version is incompatible to the server version and/or the client software version. In software packages 3.x.y, the eigerDetectorServer was killed automatically. So check the consistency of firmware/software/server versions if using this version of the software. From 4.x.y onwards, the server, if associated to a wrong firmware, does not kill itself.
\subsection{'Acquire has already started' error message}
If you see the client returning the following error message:\\
@ -1239,10 +1453,10 @@ If you see the client returning the following error message:\\
\end{verbatim}
\subsection{There is noise running the detector in 32-bit}
If you are running the detector in 32-bit (autosumming), there might be some noise, particularly at lower thereshold energies. This is due to the fact that the analog part of the chips require some latency time to settle which is larger than the readout time. It is possible to run the detector only in {\tt{parallel}} or {\tt{nonparallel}} mode, respectively with readout times between frames of 12~$\mu$s and 504~$\mu$s. If you switch {\tt{flags}} to non {\tt{nonparallel}} mode you will give enough time for the signals to settle. From release 4.0.0, there is a configurable delay that can be set through the {\tt{subdeadtime}} variable, such that you can remain with the {\tt{parallel}} flag, but can obtain a configurable dead time between frames. Ask the SLS detector group for an appropriate dead time for your detector, but typically a dead time of 20-50~$\mu$s should be enough. Note that this {\tt{subdeadtime}} need to include the 12~$\mu$s minimum readout time, so it has to be larger than 12~$\mu$s to do anything.
If you are running the detector in 32-bit (autosumming), there might be some noise, particularly at lower threshold energies. This is due to the fact that the analog part of the chips require some latency time to settle which is larger than the readout time. It is possible to run the detector only in {\tt{parallel}} or {\tt{nonparallel}} mode, respectively with readout times between frames of 12~$\mu$s and 504~$\mu$s. If you switch {\tt{flags}} to non {\tt{nonparallel}} mode you will give enough time for the signals to settle. From release 4.0.0, there is a configurable delay that can be set through the {\tt{subdeadtime}} variable, such that you can remain with the {\tt{parallel}} flag, but can obtain a configurable dead time between frames. Ask the SLS detector group for an appropriate dead time for your detector, but typically a dead time of 20-50~$\mu$s should be enough. Note that this {\tt{subdeadtime}} need to include the 12~$\mu$s minimum readout time, so it has to be larger than 12~$\mu$s to do anything.
\subsection{There is noise running the detector at high frame rate(4,8,16 bit)}
If are running in {\tt{parallel}} mode, in particular at low thereshold energies, you might encounter some noise. The reason is that the analog part of the chips require some latency time to settle which is larger than the readout time.
If are running in {\tt{parallel}} mode, in particular at low threshold energies, you might encounter some noise. The reason is that the analog part of the chips require some latency time to settle which is larger than the readout time.
\begin{enumerate}
\item You can lower the frame rate and relax requirements on period:
At low frame rate, you normally leave enough time between the end of the acquisition and the starting of the next, so you should not see this effect. In any case setting a {\tt{period}}={\tt{exptime}}+readout time from Table~\ref{tchipro} +extra 20$\mu$s cures the problem. The 20$\mu$s could also be 10~$\mu$s, they are very hardware dependent.

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,6 +1,6 @@
package:
name: sls_detector_software
version: 4.0.2
version: 4.1.1
source:
- path: ..
@ -50,14 +50,14 @@ requirements:
outputs:
- name: sls_detector_lib
version: 4.0.2
version: 4.1.1
script: copy_lib.sh
requirements:
build:
- {{ compiler('c') }}
- {{compiler('cxx')}}
- name: sls_detector_gui
version: 4.0.2
version: 4.1.1
script: copy_gui.sh
requirements:
build:
@ -81,5 +81,5 @@ outputs:
- {{ cdt('libxdamage') }} # [linux]
- {{ cdt('libxxf86vm') }} # [linux]
run:
- sls_detector_lib=4.0.2
- sls_detector_lib=4.1.1
- qwt 6.1.4=hf484d3e_1001

View File

@ -1 +0,0 @@
../slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServerv4.0.1.22.1

View File

@ -0,0 +1 @@
../slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServerv4.1.0.24.5

View File

@ -1,9 +1,9 @@
Path: slsDetectorsPackage/slsDetectorGui
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: 7b70274d4f57977649e4f4a69c21238f335561fc
Revision: 527
Branch: 4.0.2
Repsitory UUID: b0fd4f4c44ac378744e724cce684aca4a56fe0fc
Revision: 536
Branch: 4.1.1
Last Changed Author: Dhanya_Thattil
Last Changed Rev: 4109
Last Changed Date: 2019-06-13 08:55:33.000000002 +0200 ./src/qTabMeasurement.cpp
Last Changed Rev: 4153
Last Changed Date: 2020-01-14 15:47:24.000000001 +0100 ./src/qTabSettings.cpp

View File

@ -1,6 +1,6 @@
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
#define GITREPUUID "7b70274d4f57977649e4f4a69c21238f335561fc"
#define GITREPUUID "b0fd4f4c44ac378744e724cce684aca4a56fe0fc"
#define GITAUTH "Dhanya_Thattil"
#define GITREV 0x4109
#define GITDATE 0x20190613
#define GITBRANCH "4.0.2"
#define GITREV 0x4153
#define GITDATE 0x20200114
#define GITBRANCH "4.1.1"

View File

@ -121,12 +121,24 @@ void qDrawPlot::SetupWidgetWindow(){
nPixelsX = myDet->getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::X);
nPixelsY = myDet->getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::Y);
if (detType == slsDetectorDefs::JUNGFRAUCTB) {
npixelsy_jctb = (myDet->setTimer(slsDetectorDefs::SAMPLES_JCTB, -1) * 2)/25;// for moench 03
nPixelsX = npixelsx_jctb;
nPixelsY = npixelsy_jctb;
switch(detType) {
case slsDetectorDefs::JUNGFRAUCTB:
npixelsy_jctb = (myDet->setTimer(slsDetectorDefs::SAMPLES_JCTB, -1) * 2)/25;// for moench 03
nPixelsX = npixelsx_jctb;
nPixelsY = npixelsy_jctb;
break;
case slsDetectorDefs::EIGER:
if (myDet->setQuad()) {
nPixelsX /= 2;
nPixelsY *= 2;
if (nPixelsX != nPixelsY) {
--nPixelsX;
}
}
break;
default:
break;
}
cout<<"nPixelsX:"<<nPixelsX<<endl;
cout<<"nPixelsY:"<<nPixelsY<<endl;
@ -361,6 +373,9 @@ void qDrawPlot::SetupWidgetWindow(){
// callbacks
// Setting the callback function to get data from detector class
if (myDet->setReceiverOnline() == slsDetectorDefs::ONLINE_FLAG) {
myDet->enableDataStreamingFromReceiver(1);
}
myDet->registerDataCallback(&(GetDataCallBack),this); // also enables data streaming in client and receiver (if receiver exists)
//Setting the callback function to alert when acquisition finished from detector class
myDet->registerAcquisitionFinishedCallback(&(GetAcquisitionFinishedCallBack),this);
@ -583,13 +598,29 @@ void qDrawPlot::SetScanArgument(int scanArg){
maxPixelsY = 0;
minPixelsY = 0;
nPixelsX = myDet->getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::X);
nPixelsY = myDet->getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::Y);
if (detType == slsDetectorDefs::JUNGFRAUCTB) {
npixelsy_jctb = (myDet->setTimer(slsDetectorDefs::SAMPLES_JCTB, -1) * 2)/25; // for moench 03
nPixelsX = npixelsx_jctb;
nPixelsY = npixelsy_jctb;
switch(detType) {
case slsDetectorDefs::JUNGFRAUCTB:
npixelsy_jctb = (myDet->setTimer(slsDetectorDefs::SAMPLES_JCTB, -1) * 2)/25;// for moench 03
nPixelsX = npixelsx_jctb;
nPixelsY = npixelsy_jctb;
break;
case slsDetectorDefs::EIGER:
if (myDet->setQuad()) {
nPixelsX /= 2;
nPixelsY *= 2;
if (nPixelsX != nPixelsY) {
--nPixelsX;
}
}
break;
default:
break;
}
cout<<"nPixelsX:"<<nPixelsX<<endl;
cout<<"nPixelsY:"<<nPixelsY<<endl;
//cannot do this in between measurements , so update instantly
if(scanArgument==qDefs::Level0){
@ -1215,7 +1246,6 @@ int qDrawPlot::GetData(detectorData *data,int fIndex, int subIndex){
}else
gainPlotEnable = false;
//recalculating pedestal
if(startPedestalCal){
//start adding frames to get to the pedestal value

View File

@ -25,6 +25,8 @@
#define MULTI_DETECTORS_NOT_ADDED 0x8000000000000000ULL
#define MULTI_HAVE_DIFFERENT_VALUES 0x4000000000000000ULL
#define MULTI_CONFIG_FILE_ERROR 0x2000000000000000ULL
#define MULTI_PARM_FILE_ERROR 0x1000000000000000ULL
// sls errors
#define CRITICAL_ERROR_MASK 0xFFFFFFF
@ -52,6 +54,7 @@
#define CLEANUP_ACQUISITION 0x0000080000000000ULL
#define REGISER_WRITE_READ 0x0000040000000000ULL
#define VERSION_COMPATIBILITY 0x0000020000000000ULL
#define SOME_ERROR 0x0000010000000000ULL
// 0xFFFFFF0000000000ULL
// 0x000000FFFFFFFFFFULL
@ -174,6 +177,10 @@ public:
if(slsErrorMask&VERSION_COMPATIBILITY)
retval.append("Incompatible versions with detector or receiver. Please check log for more details.\n");
if(slsErrorMask&SOME_ERROR)
retval.append("Some error has occurred. Please check log for more details.\n");
if(slsErrorMask&COULD_NOT_CONFIGURE_MAC)
@ -297,7 +304,7 @@ public:
retval.append("Could not set/get auto comparator disable\n");
if(slsErrorMask&CONFIG_FILE)
retval.append("Could not load/write config file\n");
retval.append("Could not load/write config/parameter file\n");
//------------------------------------------------------ length of message

View File

@ -123,6 +123,8 @@ enum detFuncs{
F_CHECK_VERSION, /** < check version compatibility */
F_SOFTWARE_TRIGGER, /** < software trigger */
F_QUAD,
F_INTERRUPT_SUBFRAME,
/* Always append functions hereafter!!! */
/* Always append functions before!!! */

View File

@ -50,6 +50,8 @@
uint32_t Beb_detid = 0;
int Beb_top =0;
int Beb_quadEnable = 0;
int Beb_positions[3] = {0, 0, 0};
@ -1210,16 +1212,38 @@ void Beb_SetDetectorNumber(uint32_t detid) {
printf("detector id %d has been set in udp header\n", detid);
}
int Beb_SetQuad(int val) {
if (val < 0)
return OK;
printf("Setting Quad to %d in Beb\n", val);
Beb_quadEnable = (val == 0 ? 0 : 1);
return Beb_SetDetectorPosition(Beb_positions);
}
int Beb_GetQuad() {
return Beb_quadEnable;
}
int Beb_SetDetectorPosition(int pos[]) {
if(!Beb_activated)
return OK;
cprintf(BLUE,"Got Position values %d %d %d...\n", pos[0],pos[1], pos[2]);
pos[0] = Beb_swap_uint16(pos[0]);
//pos[1] = Beb_swap_uint16(pos[1]);
pos[2] = Beb_swap_uint16(pos[2]);
cprintf(BLUE,"Got Position values [%d %d %d]\n", pos[0], pos[1], pos[2]);
// save positions
Beb_positions[0] = pos[0];
Beb_positions[1] = pos[1];
Beb_positions[2] = pos[2];
// get left and right
int posLeft[3] = {pos[0], Beb_top ? pos[1] : pos[1] + 1, pos[2]};
int posRight[3] = {pos[0], Beb_top ? pos[1] + 1 : pos[1], pos[2]};
if (Beb_quadEnable) {
posRight[0] = 1; // right is next row
posRight[1] = 0; // right same first column
}
int ret = FAIL;
//mapping new memory to read master top module configuration
@ -1233,26 +1257,28 @@ int Beb_SetDetectorPosition(int pos[]) {
uint32_t value = 0;
ret = OK;
// x left
int posval = Beb_swap_uint16(posLeft[0]);
value = Beb_Read32(csp0base, UDP_HEADER_A_LEFT_OFST);
value &= UDP_HEADER_ID_MSK; // to keep previous id value
Beb_Write32(csp0base, UDP_HEADER_A_LEFT_OFST, value | ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK));
Beb_Write32(csp0base, UDP_HEADER_A_LEFT_OFST, value | ((posval << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK));
value = Beb_Read32(csp0base, UDP_HEADER_A_LEFT_OFST);
if((value & UDP_HEADER_X_MSK) != ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK))
if((value & UDP_HEADER_X_MSK) != ((posval << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK))
ret = FAIL;
// x right
posval = Beb_swap_uint16(posRight[0]);
value = Beb_Read32(csp0base, UDP_HEADER_A_RIGHT_OFST);
value &= UDP_HEADER_ID_MSK; // to keep previous id value
Beb_Write32(csp0base, UDP_HEADER_A_RIGHT_OFST, value | ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK));
Beb_Write32(csp0base, UDP_HEADER_A_RIGHT_OFST, value | ((posval << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK));
value = Beb_Read32(csp0base, UDP_HEADER_A_RIGHT_OFST);
if((value & UDP_HEADER_X_MSK) != ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK))
if((value & UDP_HEADER_X_MSK) != ((posval << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK))
ret = FAIL;
// y left (column)
// overwriting z anyway, so no need to look at previous z value
int posval = Beb_swap_uint16(Beb_top ? pos[1] : (pos[1]+1));
posval = Beb_swap_uint16(posLeft[1]);
Beb_Write32(csp0base, UDP_HEADER_B_LEFT_OFST, ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK));
value = Beb_Read32(csp0base, UDP_HEADER_B_LEFT_OFST);
if(value != ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK))
@ -1260,7 +1286,7 @@ int Beb_SetDetectorPosition(int pos[]) {
// y right
// overwriting z anyway, so no need to look at previous z value
posval = Beb_swap_uint16(Beb_top ? (pos[1]+1) : pos[1]);
posval = Beb_swap_uint16(posRight[1]);
Beb_Write32(csp0base, UDP_HEADER_B_RIGHT_OFST, ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK));
value = Beb_Read32(csp0base, UDP_HEADER_B_RIGHT_OFST);
if(value != ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK))
@ -1269,19 +1295,21 @@ int Beb_SetDetectorPosition(int pos[]) {
// z left
posval = Beb_swap_uint16(posLeft[2]);
value = Beb_Read32(csp0base, UDP_HEADER_B_LEFT_OFST);
value &= UDP_HEADER_Y_MSK; // to keep previous y value
Beb_Write32(csp0base, UDP_HEADER_B_LEFT_OFST, value | ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK));
Beb_Write32(csp0base, UDP_HEADER_B_LEFT_OFST, value | ((posval << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK));
value = Beb_Read32(csp0base, UDP_HEADER_B_LEFT_OFST);
if((value & UDP_HEADER_Z_MSK) != ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK))
if((value & UDP_HEADER_Z_MSK) != ((posval << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK))
ret = FAIL;
// z right
posval = Beb_swap_uint16(posRight[2]);
value = Beb_Read32(csp0base, UDP_HEADER_B_RIGHT_OFST);
value &= UDP_HEADER_Y_MSK; // to keep previous y value
Beb_Write32(csp0base, UDP_HEADER_B_RIGHT_OFST, value | ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK));
Beb_Write32(csp0base, UDP_HEADER_B_RIGHT_OFST, value | ((posval << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK));
value = Beb_Read32(csp0base, UDP_HEADER_B_RIGHT_OFST);
if((value & UDP_HEADER_Z_MSK) != ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK))
if((value & UDP_HEADER_Z_MSK) != ((posval << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK))
ret = FAIL;
@ -1292,8 +1320,7 @@ int Beb_SetDetectorPosition(int pos[]) {
cprintf(BLUE, "Position set to...\n"
"Left: [%d, %d, %d]\n"
"Right:[%d, %d, %d]\n",
Beb_swap_uint16(pos[0]), Beb_top ? pos[1] : (pos[1]+1), Beb_swap_uint16(pos[2]),
Beb_swap_uint16(pos[0]), Beb_top ? (pos[1]+1) : pos[1], Beb_swap_uint16(pos[2]));
posLeft[0], posLeft[1], posLeft[2], posRight[0], posRight[1], posRight[2]);
}
return ret;

View File

@ -91,6 +91,8 @@ struct BebInfo{
int Beb_GetBebFPGATemp();
void Beb_SetDetectorNumber(uint32_t detid);
int Beb_SetQuad(int val);
int Beb_GetQuad();
int Beb_SetDetectorPosition(int pos[]);
uint16_t Beb_swap_uint16( uint16_t val);

View File

@ -2009,64 +2009,172 @@ int Feb_Control_SoftwareTrigger() {
return 1;
}
int Feb_Control_SetInterruptSubframe(int val) {
printf("Setting Interrupt Subframe to %d\n", val);
uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
uint32_t value=0;
if(Module_TopAddressIsValid(&modules[1])){
if(!Feb_Interface_WriteRegister(Module_GetTopRightAddress (&modules[1]),offset, data,0, 0)) {
cprintf(RED,"Could not read tr value. Value read:%d\n", value);
value = 0;
}
if(!Feb_Interface_WriteRegister(Module_GetTopLeftAddress (&modules[1]),offset, data,0, 0)) {
cprintf(RED,"Could not read tl value. Value read:%d\n", value);
value = 0;
}
// they need to be written separately because the left and right registers have different values for this particular register
uint32_t offset = DAQ_REG_HRDWRE;
uint32_t regVal = 0;
char side[2][10] = {"right", "left"};
char isTop[10]; strcpy(isTop, Module_TopAddressIsValid(&modules[1]) ? "top" : "bottom");
unsigned int addr[2];
addr[0] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopRightAddress (&modules[1]) : Module_GetBottomRightAddress (&modules[1]);
addr[1] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopLeftAddress (&modules[1]) : Module_GetBottomLeftAddress (&modules[1]);
} else {
if(!Feb_Interface_WriteRegister(Module_GetBottomRightAddress (&modules[1]),offset, data,0, 0)) {
cprintf(RED,"Could not read br value. Value read:%d\n", value);
value = 0;
int iloop = 0;
for(iloop = 0; iloop < 2; ++iloop) {
// get previous value to keep it
if(!Feb_Interface_ReadRegister(addr[iloop], offset, &regVal)) {
cprintf(RED, "Could not read %s %s interrupt subframe\n", isTop, side[iloop]);
return 0;
}
if(!Feb_Interface_WriteRegister(Module_GetBottomLeftAddress (&modules[1]),offset, data,0, 0)) {
cprintf(RED,"Could not read bl value. Value read:%d\n", value);
value = 0;
uint32_t data = ((val == 0) ? (regVal &~ DAQ_REG_HRDWRE_INTRRPT_SF_MSK) : (regVal | DAQ_REG_HRDWRE_INTRRPT_SF_MSK));
if(!Feb_Interface_WriteRegister(addr[iloop], offset, data, 0, 0)) {
cprintf(RED, "Could not write 0x%x to %s %s interrupt subframe addr 0x%x\n", data, isTop, side[iloop], offset);
return 0;
}
}
return Feb_Control_ReadRegister(offset);
return 1;
}
int Feb_Control_GetInterruptSubframe() {
// they need to be written separately because the left and right registers have different values for this particular register
uint32_t offset = DAQ_REG_HRDWRE;
uint32_t regVal = 0;
char side[2][10] = {"right", "left"};
char isTop[10]; strcpy(isTop, Module_TopAddressIsValid(&modules[1]) ? "top" : "bottom");
unsigned int addr[2];
addr[0] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopRightAddress (&modules[1]) : Module_GetBottomRightAddress (&modules[1]);
addr[1] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopLeftAddress (&modules[1]) : Module_GetBottomLeftAddress (&modules[1]);
uint32_t value[2] = {0, 0};
int iloop = 0;
for(iloop = 0; iloop < 2; ++iloop) {
if(!Feb_Interface_ReadRegister(addr[iloop], offset, &regVal)) {
cprintf(RED, "Could not read back %s %s interrupt subframe\n", isTop, side[iloop]);
return -1;
}
value[iloop] = (regVal & DAQ_REG_HRDWRE_INTRRPT_SF_MSK) >> DAQ_REG_HRDWRE_INTRRPT_SF_OFST;
}
// inconsistent
if (value[0] != value[1]) {
cprintf(RED, "Inconsistent values of interrupt subframe betweeen left %d and right %d\n", value[0], value[1]);
return -1;
}
return value[0];
}
int Feb_Control_SetQuad(int val) {
// no bottom for quad
if (!Module_TopAddressIsValid(&modules[1])) {
return 1;
}
uint32_t offset = DAQ_REG_HRDWRE;
printf("Setting Quad to %d in Feb\n", val);
unsigned int addr = Module_GetTopRightAddress (&modules[1]);
uint32_t regVal = 0;
if(!Feb_Interface_ReadRegister(addr, offset, &regVal)) {
cprintf(RED, "Could not read top right quad reg\n");
return 0;
}
uint32_t data = ((val == 0) ? (regVal &~ DAQ_REG_HRDWRE_OW_MSK) : ((regVal | DAQ_REG_HRDWRE_OW_MSK) &~ DAQ_REG_HRDWRE_TOP_MSK));
if(!Feb_Interface_WriteRegister(addr, offset, data, 0, 0)) {
cprintf(RED, "Could not write 0x%x to top right quad addr 0x%x\n", data, offset);
return 0;
}
return 1;
}
uint32_t Feb_Control_ReadRegister(uint32_t offset) {
uint32_t value=0;
uint32_t value1=0;
if(Module_TopAddressIsValid(&modules[1])){
if(!Feb_Interface_ReadRegister(Module_GetTopRightAddress (&modules[1]),offset, &value)) {
cprintf(RED,"Could not read value. Value read:%d\n", value);
value = 0;
}
printf("Read top right addr: 0x%08x\n", value);
if(!Feb_Interface_ReadRegister(Module_GetTopLeftAddress (&modules[1]),offset, &value1)) {
cprintf(RED,"Could not read value. Value read:%d\n", value1);
value1 = 0;
}
printf("Read top left addr: 0x%08x\n", value1);
if (value != value1)
value = -1;
} else {
if(!Feb_Interface_ReadRegister(Module_GetBottomRightAddress (&modules[1]),offset, &value)) {
cprintf(RED,"Could not read value. Value read:%d\n", value);
value = 0;
}
printf("Read bottom right addr: 0x%08x\n", value);
if(!Feb_Interface_ReadRegister(Module_GetBottomLeftAddress (&modules[1]),offset, &value1)) {
cprintf(RED,"Could not read value. Value read:%d\n", value1);
value1 = 0;
}
printf("Read bottom left addr: 0x%08x\n", value1);
if (value != value1)
value = -1;
int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
uint32_t actualOffset = offset;
char side[2][10] = {"right", "left"};
char isTop[10]; strcpy(isTop, Module_TopAddressIsValid(&modules[1]) ? "top" : "bottom");
unsigned int addr[2];
addr[0] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopRightAddress (&modules[1]) : Module_GetBottomRightAddress (&modules[1]);
addr[1] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopLeftAddress (&modules[1]) : Module_GetBottomLeftAddress (&modules[1]);
int run[2] = {0, 0};
// both registers
if (offset < 0x100) {
run[0] = 1;
run[1] = 1;
}
// right registers only
else if (offset >= 0x200) {
run[0] = 1;
actualOffset = offset - 0x200;
}
// left registers only
else {
run[1] = 1;
actualOffset = offset - 0x100;
}
return value;
int iloop = 0;
for(iloop = 0; iloop < 2; ++iloop) {
if(run[iloop]) {
printf("Writing 0x%x to %s %s 0x%x\n", data, isTop, side[iloop], actualOffset);
if(!Feb_Interface_WriteRegister(addr[iloop],actualOffset, data, 0, 0)) {
cprintf(RED, "Could not write 0x%x to %s %s addr 0x%x\n", data, isTop, side[iloop], actualOffset);
return 0;
}
}
}
return 1;
}
int Feb_Control_ReadRegister(uint32_t offset, uint32_t* retval) {
uint32_t actualOffset = offset;
char side[2][10] = {"right", "left"};
char isTop[10]; strcpy(isTop, Module_TopAddressIsValid(&modules[1]) ? "top" : "bottom");
unsigned int addr[2];
addr[0] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopRightAddress (&modules[1]) : Module_GetBottomRightAddress (&modules[1]);
addr[1] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopLeftAddress (&modules[1]) : Module_GetBottomLeftAddress (&modules[1]);
uint32_t value[2] = {0, 0};
int run[2] = {0, 0};
// both registers
if (offset < 0x100) {
run[0] = 1;
run[1] = 1;
}
// right registers only
else if (offset >= 0x200) {
run[0] = 1;
actualOffset = offset - 0x200;
}
// left registers only
else {
run[1] = 1;
actualOffset = offset - 0x100;
}
int iloop = 0;
for(iloop = 0; iloop < 2; ++iloop) {
if(run[iloop]) {
if(!Feb_Interface_ReadRegister(addr[iloop],actualOffset, &value[iloop])) {
cprintf(RED, "Could not read from %s %s addr 0x%x\n", isTop, side[iloop], actualOffset);
return 0;
}
printf("Read 0x%x from %s %s 0x%x\n", value[iloop], isTop, side[iloop], actualOffset);
*retval = value[iloop];
// if not the other (left, not right OR right, not left), return the value
if (!run[iloop ? 0 : 1]) {
return 1;
}
}
}
// Inconsistent values
if (value[0] != value[1]) {
cprintf(RED, "Inconsistent values read from left 0x%x and right 0x%x\n", value[0], value[1]);
return 0;
}
return 1;
}

View File

@ -204,7 +204,10 @@ int Feb_Control_GetModuleNumber();
int64_t Feb_Control_GetSubMeasuredPeriod();
int Feb_Control_SoftwareTrigger();
int Feb_Control_SetInterruptSubframe(int val);
int Feb_Control_GetInterruptSubframe();
int Feb_Control_SetQuad(int val);
uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data);
uint32_t Feb_Control_ReadRegister(uint32_t offset);
int Feb_Control_WriteRegister(uint32_t offset, uint32_t data);
int Feb_Control_ReadRegister(uint32_t offset, uint32_t* retval);
#endif

View File

@ -20,8 +20,16 @@
#define DAQ_REG_SUBFRAME_EXPOSURES 6
#define DAQ_REG_SUBFRAME_PERIOD 7 //also pg and fifo status register
#define DAQ_REG_HRDWRE 12
#define DAQ_REG_RO_OFFSET 12
#define DAQ_REG_HRDWRE_OW_OFST (0)
#define DAQ_REG_HRDWRE_OW_MSK (0x00000001 << DAQ_REG_HRDWRE_OW_OFST)
#define DAQ_REG_HRDWRE_TOP_OFST (1)
#define DAQ_REG_HRDWRE_TOP_MSK (0x00000001 << DAQ_REG_HRDWRE_TOP_OFST)
#define DAQ_REG_HRDWRE_INTRRPT_SF_OFST (2)
#define DAQ_REG_HRDWRE_INTRRPT_SF_MSK (0x00000001 << DAQ_REG_HRDWRE_INTRRPT_SF_OFST)
#define DAQ_REG_RO_OFFSET 20
#define DAQ_REG_STATUS (DAQ_REG_RO_OFFSET + 0) //also pg and fifo status register
#define FEB_REG_STATUS (DAQ_REG_RO_OFFSET + 3)
#define MEAS_SUBPERIOD_REG (DAQ_REG_RO_OFFSET + 4)
@ -29,6 +37,7 @@
#define DAQ_CTRL_RESET 0x80000000
#define DAQ_CTRL_START 0x40000000
#define ACQ_CTRL_START 0x50000000 //this is 0x10000000 (acq) | 0x40000000 (daq)

View File

@ -1,9 +1,9 @@
Path: slsDetectorsPackage/slsDetectorSoftware/eigerDetectorServer
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: ef3e01b9bdf3a6a08367e2448bcc92bd13cf73ad
Revision: 351
Branch: 4.0.1-rc
Last Changed Author: Dhanya_Thattil
Last Changed Rev: 4068
Last Changed Date: 2019-02-06 14:44:47.000000002 +0100 ./xparameters.h
Repsitory UUID: e4645a8273c8265bc584579d5f7f8eb6dc4379f7
Revision: 360
Branch: 4.1.0-rc
Last Changed Author: GitHub_GitHub
Last Changed Rev: 4138
Last Changed Date: 2019-10-04 09:28:27.000000001 +0200 ./xparameters.h

View File

@ -1,6 +1,6 @@
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
#define GITREPUUID "ef3e01b9bdf3a6a08367e2448bcc92bd13cf73ad"
#define GITAUTH "Dhanya_Thattil"
#define GITREV 0x4068
#define GITDATE 0x20190206
#define GITBRANCH "4.0.1-rc"
#define GITREPUUID "e4645a8273c8265bc584579d5f7f8eb6dc4379f7"
#define GITAUTH "GitHub_GitHub"
#define GITREV 0x4138
#define GITDATE 0x20191004
#define GITBRANCH "4.1.0-rc"

View File

@ -10,11 +10,11 @@
#endif
#include "slsDetectorFunctionList.h"
#ifndef VIRTUAL
#include "versionAPI.h"
#include "gitInfoEiger.h"
#ifndef VIRTUAL
#include "FebControl.h"
#include "Beb.h"
#include "versionAPI.h"
#endif
int default_tau_from_file= -1;
@ -200,19 +200,18 @@ void checkFirmwareCompatibility(int flag){
/* Ids */
int64_t getDetectorId(enum idMode arg){
#ifdef VIRTUAL
return 0;
#else
int64_t retval = -1;
int64_t retval = 0;
switch(arg){
case DETECTOR_SERIAL_NUMBER:
retval = getDetectorNumber();/** to be implemented with mac? */
break;
case DETECTOR_FIRMWARE_VERSION:
return (int64_t)getFirmwareVersion();
return (int64_t)getFirmwareVersion();
case SOFTWARE_FIRMWARE_API_VERSION:
#ifndef VIRTUAL
return (int64_t)Beb_GetFirmwareSoftwareAPIVersion();
#endif
case DETECTOR_SOFTWARE_VERSION:
return (GITDATE & 0xFFFFFF);
case CLIENT_SOFTWARE_API_VERSION:
@ -220,9 +219,7 @@ int64_t getDetectorId(enum idMode arg){
default:
break;
}
return retval;
#endif
return retval;
}
u_int64_t getFirmwareVersion() {
@ -486,19 +483,25 @@ void setupDetector() {
/* advanced read/write reg */
uint32_t writeRegister(uint32_t offset, uint32_t data) {
int writeRegister(uint32_t offset, uint32_t data) {
#ifdef VIRTUAL
return 0;
return OK;
#else
return Feb_Control_WriteRegister(offset, data);
if(!Feb_Control_WriteRegister(offset, data)) {
return FAIL;
}
return OK;
#endif
}
uint32_t readRegister(uint32_t offset) {
int readRegister(uint32_t offset, uint32_t* retval) {
#ifdef VIRTUAL
return 0;
return OK;
#else
return Feb_Control_ReadRegister(offset);
if(!Feb_Control_ReadRegister(offset, retval)) {
return FAIL;
}
return OK;
#endif
}
@ -1220,6 +1223,47 @@ int setDetectorPosition(int pos[]) {
int setQuad(int value) {
if (value < 0)
return OK;
#ifndef VIRTUAL
if (Beb_SetQuad(value) == FAIL) {
return FAIL;
}
if (!Feb_Control_SetQuad(value)) {
return FAIL;
}
#endif
return OK;
}
int getQuad() {
#ifdef VIRTUAL
return 0;
#else
return Beb_GetQuad();
#endif
}
int setInterruptSubframe(int value) {
if(value < 0)
return FAIL;
#ifndef VIRTUAL
if(!Feb_Control_SetInterruptSubframe(value)) {
return FAIL;
}
#endif
return OK;
}
int getInterruptSubframe() {
#ifdef VIRTUAL
return 0;
#else
return Feb_Control_GetInterruptSubframe();
#endif
}
/* eiger specific - iodelay, 10g, pulse, rate, temp, activate, delay nw parameter */

View File

@ -12,7 +12,7 @@
#include <stdint.h>
#define GOODBYE (-200)
#define REQUIRED_FIRMWARE_VERSION (22)
#define REQUIRED_FIRMWARE_VERSION (24)
#define IDFILECOMMAND "more /home/root/executables/detid.txt"
#define STATUS_IDLE 0

View File

@ -1,9 +1,9 @@
Path: slsDetectorsPackage/slsDetectorSoftware
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: 7b70274d4f57977649e4f4a69c21238f335561fc
Revision: 2082
Branch: 4.0.2
Repsitory UUID: b0fd4f4c44ac378744e724cce684aca4a56fe0fc
Revision: 2101
Branch: 4.1.1
Last Changed Author: Dhanya_Thattil
Last Changed Rev: 4109
Last Changed Date: 2019-06-13 09:00:22.000000002 +0200 ./threadFiles/ThreadPool.o
Last Changed Rev: 4153
Last Changed Date: 2020-01-14 16:16:00.000000001 +0100 ./threadFiles/ThreadPool.o

View File

@ -1,9 +1,9 @@
Path: slsDetectorsPackage/slsDetectorSoftware/jungfrauDetectorServer
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: 4be0b5d4366440449ad86fc78fa04e618d56df5f
Revision: 171
Branch: 4.0.2-rc
Repsitory UUID: 74c08cd74240c08b395c9acf8897d5254839d9c3
Revision: 172
Branch: 4.1.0-rc
Last Changed Author: Dhanya_Thattil
Last Changed Rev: 4097
Last Changed Date: 2019-04-08 17:12:59.000000002 +0200 ./RegisterDefs.h
Last Changed Rev: 4140
Last Changed Date: 2019-10-04 09:28:27.000000001 +0200 ./RegisterDefs.h

View File

@ -1,6 +1,6 @@
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
#define GITREPUUID "4be0b5d4366440449ad86fc78fa04e618d56df5f"
#define GITREPUUID "74c08cd74240c08b395c9acf8897d5254839d9c3"
#define GITAUTH "Dhanya_Thattil"
#define GITREV 0x4097
#define GITDATE 0x20190408
#define GITBRANCH "4.0.2-rc"
#define GITREV 0x4140
#define GITDATE 0x20191004
#define GITBRANCH "4.1.0-rc"

View File

@ -26,6 +26,7 @@ ID: $Id$
#include <rapidjson/document.h> //json header in zmq stream
#include <sys/ipc.h>
#include <sys/shm.h>
#include <iterator>
@ -523,7 +524,10 @@ std::string multiSlsDetector::getErrorMessage(int& critical) {
retval.append("Could not load Config File\n");
critical = 0;
}
if (multiMask & MULTI_PARM_FILE_ERROR) {
retval.append("Could not load parameter File\n");
critical = 0;
}
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
//if the detector has error
if (multiMask & (1 << idet)) {
@ -1441,176 +1445,382 @@ int multiSlsDetector::readConfigurationFile(std::string const fname) {
freeSharedMemory();
setupMultiDetector();
multiSlsDetectorClient* cmd;
std::string ans;
std::string str;
std::ifstream infile;
int iargval;
int interrupt = 0;
char* args[1000];
char myargs[1000][1000];
std::string sargname, sargval;
int iline = 0;
std::cout << "config file name " << fname << std::endl;
infile.open(fname.c_str(), std::ios_base::in);
if (infile.is_open()) {
while (infile.good() and interrupt == 0) {
sargname = "none";
sargval = "0";
getline(infile, str);
++iline;
// remove comments that come after
if (str.find('#') != std::string::npos)
str.erase(str.find('#'));
#ifdef VERBOSE
std::cout << "string:" << str << std::endl;
#endif
if (str.length() < 2) {
#ifdef VERBOSE
std::cout << "Empty line or Comment " << std::endl;
#endif
continue;
} else {
std::istringstream ssstr(str);
iargval = 0;
while (ssstr.good()) {
ssstr >> sargname;
#ifdef VERBOSE
std::cout << iargval << " " << sargname << std::endl;
#endif
strcpy(myargs[iargval], sargname.c_str());
args[iargval] = myargs[iargval];
#ifdef VERBOSE
std::cout << "--" << iargval << " " << args[iargval] << std::endl;
#endif
++iargval;
}
#ifdef VERBOSE
cout << endl;
for (int ia = 0; ia < iargval; ia++)
cout << args[ia] << " ??????? ";
cout << endl;
#endif
cmd = new multiSlsDetectorClient(iargval, args, PUT_ACTION, this);
delete cmd;
}
++iline;
}
infile.close();
} else {
std::cout << "Error opening configuration file " << fname << " for reading" << std::endl;
setErrorMask(getErrorMask() | MULTI_CONFIG_FILE_ERROR);
return FAIL;
std::ifstream inFile;
inFile.open(fname.c_str(), std::ifstream::in);
if (!inFile.is_open()) {
cprintf(RED, "Cannot open config file %s\n", fname.c_str());
setErrorMask(getErrorMask() | MULTI_CONFIG_FILE_ERROR);
return FAIL;
}
#ifdef VERBOSE
std::cout << "Read configuration file of " << iline << " lines" << std::endl;
#endif
while(inFile.good()) {
std::string sLine;
getline(inFile,sLine);
// delete lines after comments
if (sLine.find('#') != std::string::npos) {
sLine.erase(sLine.find('#'));
}
// scan arguments
std::istringstream iss(sLine);
std::vector<std::string> vec = std::vector<std::string>(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>());
// blank lines
if (vec.size() == 0 || vec[0].empty()) {
continue;
}
int iarg = vec.size();
// copy to char array
char arr[iarg][MAX_STR_LENGTH];
memset(arr, 0, sizeof(arr));
char* args[iarg];
for (int i = 0; i < iarg; ++i) {
args[i] = arr[i];
strcpy(args[i], vec[i].c_str());
}
// execute command
multiSlsDetectorClient(iarg, args, PUT_ACTION, this);
}
inFile.close();
setNumberOfModules(-1);
getMaxNumberOfModules();
// check error
if (getErrorMask()) {
int c;
cprintf(RED, "\n----------------\n Error Messages\n----------------\n%s\n",
getErrorMessage(c).c_str());
return FAIL;
}
return OK;
}
int multiSlsDetector::writeConfigurationFile(std::string const fname) {
std::vector <std::string> commands;
commands.push_back("master");
commands.push_back("sync");
commands.push_back("outdir");
commands.push_back("ffdir");
commands.push_back("headerbefore");
commands.push_back("headerafter");
commands.push_back("headerbeforepar");
commands.push_back("headerafterpar");
commands.push_back("badchannels");
commands.push_back("angconv");
commands.push_back("globaloff");
commands.push_back("binsize");
commands.push_back("threaded");
std::ofstream outfile;
outfile.open(fname.c_str(), std::ios_base::out);
if (!outfile.is_open()) {
cprintf(RED, "Cannot open config file %s for writing\n", fname.c_str());
setErrorMask(getErrorMask() | MULTI_CONFIG_FILE_ERROR);
return FAIL;
}
int ret = OK;
slsDetectorCommand* cmd = new slsDetectorCommand(this);
char arr[MAX_STR_LENGTH];
char* args[1];
args[0] = arr;
// detsizechan
memset(args[0], 0, MAX_STR_LENGTH);
strcpy(args[0], "detsizechan");
outfile << args[0] << ' ' << cmd->executeLine(1, args, GET_ACTION) << std::endl;
// hostname
memset(args[0], 0, MAX_STR_LENGTH);
strcpy(args[0], "hostname");
outfile << args[0] << ' ' << cmd->executeLine(1, args, GET_ACTION) << std::endl;
// single detector configuration
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
outfile << endl;
int ret1 = detectors[idet]->writeConfigurationFile(outfile, idet);
if (detectors[idet]->getErrorMask())
setErrorMask(getErrorMask() | (1 << idet));
if (ret1 == FAIL)
ret = FAIL;
}
// other configurations
outfile << endl;
for (unsigned int i = 0; i < commands.size(); ++i) {
memset(args[0], 0, MAX_STR_LENGTH);
strcpy(args[0], commands[i].c_str());
outfile << commands[i] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl;
}
delete cmd;
outfile.close();
if (ret == FAIL || getErrorMask()) {
int c;
cprintf(RED, "\n----------------\n Error Messages\n----------------\n%s\n",
getErrorMessage(c).c_str());
return FAIL;
}
return OK;
}
int multiSlsDetector::writeConfigurationFile(std::string const fname) {
int multiSlsDetector::retrieveDetectorSetup(std::string const fname1, int level){
std::string fname = fname1;
// setup
if (level==2) {
fname += std::string(".det");
}
std::string names[] = {
"detsizechan",
"hostname",
"master",
"sync",
"outdir",
"ffdir",
"headerbefore",
"headerafter",
"headerbeforepar",
"headerafterpar",
"badchannels",
"angconv",
"globaloff",
"binsize",
"threaded"
};
int nvar = 15;
char* args[100];
for (int ia = 0; ia < 100; ++ia) {
args[ia] = new char[1000];
std::ifstream inFile;
inFile.open(fname.c_str(), std::ifstream::in);
if (!inFile.is_open()) {
cprintf(RED, "Cannot open parameter file %s\n", fname.c_str());
setErrorMask(getErrorMask() | MULTI_PARM_FILE_ERROR);
return FAIL;
}
int ret = OK, ret1 = OK;
std::ofstream outfile;
int iline = 0;
outfile.open(fname.c_str(), std::ios_base::out);
if (outfile.is_open()) {
slsDetectorCommand* cmd = new slsDetectorCommand(this);
// complete size of detector
cout << iline << " " << names[iline] << endl;
strcpy(args[0], names[iline].c_str());
outfile << names[iline] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl;
++iline;
// hostname of the detectors
cout << iline << " " << names[iline] << endl;
strcpy(args[0], names[iline].c_str());
outfile << names[iline] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl;
++iline;
// single detector configuration
for (unsigned int idet = 0; idet < detectors.size(); ++idet) {
outfile << endl;
ret1 = detectors[idet]->writeConfigurationFile(outfile, idet);
if (detectors[idet]->getErrorMask())
setErrorMask(getErrorMask() | (1 << idet));
if (ret1 == FAIL)
ret = FAIL;
while(inFile.good()) {
std::string sLine;
getline(inFile,sLine);
// delete lines after comments
if (sLine.find('#') != std::string::npos) {
sLine.erase(sLine.find('#'));
}
// scan arguments
std::istringstream iss(sLine);
std::vector<std::string> vec = std::vector<std::string>(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>());
// blank lines
if (vec.size() == 0 || vec[0].empty()) {
continue;
}
outfile << endl;
//other configurations
while (iline < nvar) {
cout << iline << " " << names[iline] << endl;
strcpy(args[0], names[iline].c_str());
outfile << names[iline] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl;
++iline;
// skip commands according to level (setup=2)
if (level!=2) {
if (vec[0] == "flatfield" ||
vec[0] == "badchannels" ||
vec[0] == "trimbits") {
continue;
}
}
delete cmd;
outfile.close();
#ifdef VERBOSE
std::cout << "wrote " << iline << " lines to configuration file " << std::endl;
#endif
} else {
std::cout << "Error opening configuration file " << fname << " for writing" << std::endl;
setErrorMask(getErrorMask() | MULTI_CONFIG_FILE_ERROR);
ret = FAIL;
int iarg = vec.size();
// copy to char array
char arr[iarg][MAX_STR_LENGTH];
memset(arr, 0, sizeof(arr));
char* args[iarg];
for (int i = 0; i < iarg; ++i) {
args[i] = arr[i];
strcpy(args[i], vec[i].c_str());
}
// execute command
multiSlsDetectorClient(iarg, args, PUT_ACTION, this);
}
for (int ia = 0; ia < 100; ++ia) {
delete[] args[ia];
}
inFile.close();
return ret;
// check error
if (getErrorMask()) {
int c;
cprintf(RED, "\n----------------\n Error Messages\n----------------\n%s\n",
getErrorMessage(c).c_str());
return FAIL;
}
return OK;
}
int multiSlsDetector::dumpDetectorSetup(std::string const fname1, int level){
std::vector <std::string> commands;
// common config
commands.push_back("fname");
commands.push_back("index");
commands.push_back("enablefwrite");
commands.push_back("overwrite");
commands.push_back("dr");
commands.push_back("settings");
commands.push_back("exptime");
commands.push_back("period");
commands.push_back("frames");
commands.push_back("cycles");
commands.push_back("measurements");
commands.push_back("timing");
switch (getDetectorsType()) {
case EIGER:
commands.push_back("flags");
commands.push_back("clkdivider");
commands.push_back("threshold");
commands.push_back("ratecorr");
break;
case GOTTHARD:
case PROPIX:
commands.push_back("flags");
commands.push_back("delay");
commands.push_back("gates");
commands.push_back("ratecorr");
break;
case JUNGFRAU:
commands.push_back("flags");
commands.push_back("delay");
commands.push_back("gates");
commands.push_back("ratecorr");
commands.push_back("clkdivider");
break;
case MYTHEN:
commands.push_back("flags");
commands.push_back("threshold");
commands.push_back("delay");
commands.push_back("gates");
commands.push_back("probes");
commands.push_back("fineoff");
commands.push_back("ratecorr");
break;
case JUNGFRAUCTB:
commands.push_back("dac:0");
commands.push_back("dac:1");
commands.push_back("dac:2");
commands.push_back("dac:3");
commands.push_back("dac:4");
commands.push_back("dac:5");
commands.push_back("dac:6");
commands.push_back("dac:7");
commands.push_back("dac:8");
commands.push_back("dac:9");
commands.push_back("dac:10");
commands.push_back("dac:11");
commands.push_back("dac:12");
commands.push_back("dac:13");
commands.push_back("dac:14");
commands.push_back("dac:15");
commands.push_back("adcvpp");
commands.push_back("adcclk");
commands.push_back("clkdivider");
commands.push_back("adcphase");
commands.push_back("adcpipeline");
commands.push_back("adcinvert"); //
commands.push_back("adcdisable");
commands.push_back("patioctrl");
commands.push_back("patclkctrl");
commands.push_back("patlimits");
commands.push_back("patloop0");
commands.push_back("patnloop0");
commands.push_back("patwait0");
commands.push_back("patwaittime0");
commands.push_back("patloop1");
commands.push_back("patnloop1");
commands.push_back("patwait1");
commands.push_back("patwaittime1");
commands.push_back("patloop2");
commands.push_back("patnloop2");
commands.push_back("patwait2");
commands.push_back("patwaittime2");
break;
default:
break;
}
// more common config
commands.push_back("startscript");
commands.push_back("startscriptpar");
commands.push_back("stopscript");
commands.push_back("stopscriptpar");
commands.push_back("scriptbefore");
commands.push_back("scriptbeforepar");
commands.push_back("scriptafter");
commands.push_back("scriptafterpar");
commands.push_back("scan0script");
commands.push_back("scan0par");
commands.push_back("scan0prec");
commands.push_back("scan0steps");
commands.push_back("scan1script");
commands.push_back("scan1par");
commands.push_back("scan1prec");
commands.push_back("scan1steps");
std::string fname = fname1;
// setup
if (level == 2) {
// config
fname += std::string(".config");
writeConfigurationFile(fname);
// parameters
fname = fname1 + std::string(".det");
}
std::ofstream outfile;
outfile.open(fname.c_str(), std::ios_base::out);
if (!outfile.is_open()) {
cprintf(RED, "Cannot open parameter file %s for writing\n", fname.c_str());
setErrorMask(getErrorMask() | MULTI_PARM_FILE_ERROR);
return FAIL;
}
slsDetectorCommand* cmd = new slsDetectorCommand(this);
char arr[2][MAX_STR_LENGTH];
char* args[2];
args[0] = arr[0];
args[1] = arr[1];
memset(args[1], 0, MAX_STR_LENGTH);
for (unsigned int i = 0; i < commands.size(); ++i) {
memset(args[0], 0, MAX_STR_LENGTH);
strcpy(args[0], commands[i].c_str());
outfile << commands[i] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl;
}
if (getDetectorsType() == MYTHEN) {
// flatfield
memset(args[0], 0, MAX_STR_LENGTH);
strcpy(args[0], "flatfield ");
if (level == 2) {
fname = fname1 + std::string(".ff");
memset(args[1], 0, MAX_STR_LENGTH);
strcpy(args[1], fname.c_str());
}
outfile << "flatfield " << cmd->executeLine(2, args, GET_ACTION) << std::endl;
// badchannels
memset(args[0], 0, MAX_STR_LENGTH);
strcpy(args[0], "badchannels ");
if (level == 2) {
fname = fname1 + std::string(".bad");
memset(args[1], 0, MAX_STR_LENGTH);
strcpy(args[1], fname.c_str());
}
outfile << "badchannels " << cmd->executeLine(2, args, GET_ACTION) << std::endl;
// trimbits
if (level == 2) {
size_t c = fname1.rfind('/');
if (c < std::string::npos) {
fname = fname1.substr(0, c + 1) + std::string("trim_") + fname.substr(c + 1);
} else {
fname = std::string("trim_") + fname1;
}
memset(args[0], 0, MAX_STR_LENGTH);
strcpy(args[0], "trimbits ");
memset(args[1], 0, MAX_STR_LENGTH);
strcpy(args[1], fname.c_str());
outfile << "trimbits " << cmd->executeLine(2, args, GET_ACTION) << std::endl;
}
}
delete cmd;
outfile.close();
if (getErrorMask()) {
int c;
cprintf(RED, "\n----------------\n Error Messages\n----------------\n%s\n",
getErrorMessage(c).c_str());
return FAIL;
}
return OK;
}
std::string multiSlsDetector::getSettingsFile() {
return callDetectorMember(&slsDetector::getSettingsFile);
@ -4983,17 +5193,13 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) {
}
void multiSlsDetector::readFrameFromReceiver() {
int nX = thisMultiDetector->numberOfDetector[X]; // to copy data in multi module
int nY = thisMultiDetector->numberOfDetector[Y]; // for eiger, to reverse the data
int nX = 0;
int nY = 0;
int nDetPixelsX = 0;
int nDetPixelsY = 0;
bool gappixelsenable = false;
bool eiger = false;
if (getDetectorsType() == EIGER) {
eiger = true;
nX *= 2;
gappixelsenable = detectors[0]->enableGapPixels(-1) >= 1 ? true : false;
}
bool quadEnable = false;
bool eiger = false;
bool runningList[zmqSocket.size()], connectList[zmqSocket.size()];
int numRunning = 0;
for (unsigned int i = 0; i < zmqSocket.size(); ++i) {
@ -5068,6 +5274,16 @@ void multiSlsDetector::readFrameFromReceiver() {
// shape
nPixelsX = doc["shape"][0].GetUint();
nPixelsY = doc["shape"][1].GetUint();
// detector shape
nX = doc["detshape"][0].GetUint();
nY = doc["detshape"][1].GetUint();
nDetPixelsX = nX * nPixelsX;
nDetPixelsY = nY * nPixelsY;
// det type
eiger = (doc["detType"].GetUint() == (int)EIGER) ? true : false;
// gap pixels enable
gappixelsenable = (doc["gappixels"].GetUint() == 0) ? false : true;
quadEnable = (doc["quad"].GetUint() == 0) ? false : true;
#ifdef VERBOSE
cprintf(BLUE, "(Debug) One Time Header Info:\n"
@ -5076,9 +5292,14 @@ void multiSlsDetector::readFrameFromReceiver() {
"dynamicRange: %u\n"
"bytesPerPixel: %f\n"
"nPixelsX: %u\n"
"nPixelsY: %u\n",
"nPixelsY: %u\n"
"nX: %u\n"
"nY: %u\n"
"eiger: %d\n"
"gappixelsenable: %d\n"
"quadEnable: %d\n",
size, multisize, dynamicRange, bytesPerPixel,
nPixelsX, nPixelsY);
nPixelsX, nPixelsY, nX, nY, eiger, gappixelsenable, quadEnable);
#endif
}
// each time, parse rest of header
@ -5146,23 +5367,32 @@ void multiSlsDetector::readFrameFromReceiver() {
}
}
}
#ifdef VERBOSE
cprintf(BLUE,"nPixelsX:%d, nPixelsY:%d nx:%d ny:%d quadEnable:%d\n", nDetPixelsX, nDetPixelsY, nX, nY, quadEnable);
#endif
//send data to callback
if (data) {
int nCompletePixelsX = thisMultiDetector->numberOfChannelInclGapPixels[X];
int nCompletePixelsY = thisMultiDetector->numberOfChannelInclGapPixels[Y];
if (data) {
// 4bit gap pixels
if (dynamicRange == 4 && gappixelsenable) {
int n = processImageWithGapPixels(multiframe, multigappixels);
if (quadEnable) {
nDetPixelsX += 2;
nDetPixelsY += 2;
} else {
nDetPixelsX = nX * (nPixelsX + 3);
nDetPixelsY = nY * (nPixelsY + 1);
}
#ifdef VERBOSE
cprintf(RED,"Corrected nPixelsX:%d, nPixelsY:%d quadEnable:%d\n", nDetPixelsX, nDetPixelsY, quadEnable);
#endif
int n = processImageWithGapPixels(multiframe, multigappixels, quadEnable);
thisData = new detectorData(NULL, NULL, NULL, getCurrentProgress(),
currentFileName.c_str(), nCompletePixelsX, nCompletePixelsY,
currentFileName.c_str(), nDetPixelsX, nDetPixelsY,
multigappixels, n, dynamicRange, currentFileIndex);
}
// normal pixels
else {
thisData = new detectorData(NULL, NULL, NULL, getCurrentProgress(),
currentFileName.c_str(), nCompletePixelsX, nCompletePixelsY,
currentFileName.c_str(), nDetPixelsX, nDetPixelsY,
multiframe, multisize, dynamicRange, currentFileIndex);
}
dataReady(thisData, currentFrameIndex,
@ -5206,14 +5436,23 @@ void multiSlsDetector::readFrameFromReceiver() {
delete[] multigappixels;
}
int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) {
// eiger 4 bit mode
int nxb = thisMultiDetector->numberOfDetector[X] * (512 + 3);
int nyb = thisMultiDetector->numberOfDetector[Y] * (256 + 1);
int gapdatabytes = nxb * nyb;
int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage, bool quadEnable) {
// eiger 4 bit mode (divided by 2 already)
int nxb = thisMultiDetector->numberOfDetector[X] * (512 + 3);
int nyb = thisMultiDetector->numberOfDetector[Y] * (256 + 1);
int nchipInRow = 4;
int nxchip = thisMultiDetector->numberOfDetector[X] * 4;
int nychip = thisMultiDetector->numberOfDetector[Y] * 1;
if (quadEnable) {
nxb = thisMultiDetector->numberOfDetector[X] * (256 + 1);
nyb = thisMultiDetector->numberOfDetector[Y] * (512 + 2);
nxchip /= 2;
nychip *= 2;
nchipInRow /= 2;
}
int gapdatabytes = nxb * nyb;
// allocate
if (gpImage == NULL)
@ -5229,13 +5468,13 @@ int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) {
// copying line by line
src = image;
dst = gpImage;
for (int row = 0; row < nychip; ++row) { // for each chip in a row
for (int row = 0; row < nychip; ++row) { // for each chip row
for (int ichipy = 0; ichipy < b1chipy; ++ichipy) { //for each row in a chip
for (int col = 0; col < nxchip; ++col) {
for (int col = 0; col < nxchip; ++col) { // for each chip in a row
memcpy(dst, src, b1chipx);
src += b1chipx;
dst += b1chipx;
if ((col + 1) % 4)
if ((col + 1) % nchipInRow) // 1, 2, and 3rd chip, skip gap pixels
++dst;
}
}
@ -5248,11 +5487,11 @@ int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) {
uint8_t temp, g1, g2;
int mod;
dst = gpImage;
for (int row = 0; row < nychip; ++row) { // for each chip in a row
for (int row = 0; row < nychip; ++row) { // for each chip row
for (int ichipy = 0; ichipy < b1chipy; ++ichipy) { //for each row in a chip
for (int col = 0; col < nxchip; ++col) {
for (int col = 0; col < nxchip; ++col) { // for each chip in a row
dst += b1chipx;
mod = (col + 1) % 4;
mod = (col + 1) % nchipInRow; // 1, 2, and 3rd chip, get gap pixels
// copy gap pixel(chip 0, 1, 2)
if (mod) {
// neighbouring gap pixels to left
@ -5283,8 +5522,8 @@ int multiSlsDetector::processImageWithGapPixels(char* image, char*& gpImage) {
{
uint8_t temp, g1, g2;
char* dst_prevline = 0;
dst = gpImage;
for (int row = 0; row < nychip; ++row) { // for each chip in a row
dst = gpImage;
for (int row = 0; row < nychip; ++row) { // for each chip row
dst += (b1chipy * nxb);
// horizontal copying of gap pixels from neighboring past line (bottom parts)
if (row < nychip - 1) {
@ -5429,3 +5668,13 @@ int multiSlsDetector::setCTBPatWaitAddr(int level, int addr) {
int multiSlsDetector::setCTBPatWaitTime(int level, uint64_t t) {
return callDetectorMember(&slsDetector::setCTBPatWaitTime, level, t);
}
int multiSlsDetector::setQuad(int val) {
if (getNumberOfDetectors() > 1)
val = 0;
return callDetectorMember(&slsDetector::setQuad, val);
}
int multiSlsDetector::setInterruptSubframe(int val) {
return callDetectorMember(&slsDetector::setInterruptSubframe, val);
}

View File

@ -795,6 +795,26 @@ public:
*/
int writeConfigurationFile(std::string const fname);
/**
* Saves the detector setup to file
* @param fname file to write to
* @param level if 2 reads also trimbits, flat field, angular
* correction etc. and writes them to files with automatically
* added extension
* @returns OK or FAIL
*/
int dumpDetectorSetup(std::string const fname1, int level=0);
/**
* Loads the detector setup from file
* @param fname file to read from
* @param level if 2 reads also reads trimbits, angular
* conversion coefficients etc. from files with default
* extensions as generated by dumpDetectorSetup
* @returns OK or FAIL
*/
int retrieveDetectorSetup(std::string const fname1, int level=0);
/**
* Returns the trimfile or settings file name (Useless??)
* @returns the trimfile or settings file name
@ -1869,6 +1889,20 @@ public:
*/
int setCTBPatWaitTime(int level, uint64_t t=-1);
/**
* Set or Get Quad Type (Only for Eiger Quad detector hardware)
* @param val 1 if quad type set, else 0, -1 gets
* @returns 1 if quad type set, else 0
*/
int setQuad(int val = -1);
/**
* Set or Get Interrupt last sub frame(Only for Eiger)
* @param val 1 if interrupt last subframe set, else 0, -1 gets
* @returns 1 if interrupt last subframe set, else 0, -1 different values
*/
int setInterruptSubframe(int val = -1);
private:
/**
@ -1912,9 +1946,10 @@ private:
* add gap pixels to the image (only for Eiger in 4 bit mode)
* @param image pointer to image without gap pixels
* @param gpImage poiner to image with gap pixels, if NULL, allocated inside function
* @param quadEnable quad enabled
* @returns number of data bytes of image with gap pixels
*/
int processImageWithGapPixels(char* image, char*& gpImage);
int processImageWithGapPixels(char* image, char*& gpImage, bool quadEnable);
/** Multi detector Id */

View File

@ -1,6 +1,6 @@
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
#define GITREPUUID "7b70274d4f57977649e4f4a69c21238f335561fc"
#define GITREPUUID "b0fd4f4c44ac378744e724cce684aca4a56fe0fc"
#define GITAUTH "Dhanya_Thattil"
#define GITREV 0x4109
#define GITDATE 0x20190613
#define GITBRANCH "4.0.2"
#define GITREV 0x4153
#define GITDATE 0x20200114
#define GITBRANCH "4.1.1"

View File

@ -752,6 +752,7 @@ void slsDetector::initializeDetectorStructure(detectorType type) {
thisDetector->activated = true;
thisDetector->receiver_deactivatedPaddingEnable = true;
thisDetector->receiver_silentMode = false;
thisDetector->quadEnable = false;
// get the detector parameters based on type
detParameterList detlist;
@ -2367,6 +2368,12 @@ int slsDetector::updateDetectorNoWait() {
getTotalNumberOfChannels();
}
if(thisDetector->myDetectorType == EIGER){
n += controlSocket->ReceiveDataOnly( &nm,sizeof(int32_t));
thisDetector->quadEnable = nm;
}
if (!n)
printf("n: %d\n", n);
@ -2400,254 +2407,126 @@ int slsDetector::updateDetector() {
int slsDetector::readConfigurationFile(string const fname) {
string ans;
string str;
ifstream infile;
//char *args[1000];
string sargname, sargval;
#ifdef VERBOSE
int iline=0;
std::cout<< "config file name "<< fname << std::endl;
#endif
infile.open(fname.c_str(), ios_base::in);
if (infile.is_open()) {
#ifdef VERBOSE
iline=readConfigurationFile(infile);
#else
readConfigurationFile(infile);
#endif
infile.close();
} else {
std::cout<< "Error opening configuration file " << fname <<
" for reading" << std::endl;
setErrorMask((getErrorMask())|(CONFIG_FILE));
return FAIL;
}
#ifdef VERBOSE
std::cout<< "Read configuration file of " << iline << " lines" << std::endl;
#endif
return OK;
std::cout << "Cannot read config file from slsDetector level" << std::endl;
setErrorMask((getErrorMask())|(CONFIG_FILE));
return FAIL;
}
int slsDetector::readConfigurationFile(ifstream &infile) {
slsDetectorCommand *cmd=new slsDetectorCommand(this);
string ans;
string str;
int iargval;
int interrupt=0;
char *args[100];
char myargs[1000][1000];
string sargname, sargval;
int iline=0;
while (infile.good() and interrupt==0) {
sargname="none";
sargval="0";
getline(infile,str);
++iline;
#ifdef VERBOSE
std::cout<< str << std::endl;
#endif
if (str.find('#')!=string::npos) {
#ifdef VERBOSE
std::cout<< "Line is a comment " << std::endl;
std::cout<< str << std::endl;
#endif
continue;
} else if (str.length()<2) {
#ifdef VERBOSE
std::cout<< "Empty line " << std::endl;
#endif
continue;
} else {
istringstream ssstr(str);
iargval=0;
while (ssstr.good()) {
ssstr >> sargname;
//if (ssstr.good()) {
#ifdef VERBOSE
std::cout<< iargval << " " << sargname << std::endl;
#endif
strcpy(myargs[iargval],sargname.c_str());
args[iargval]=myargs[iargval];
++iargval;
//}
}
ans=cmd->executeLine(iargval,args,PUT_ACTION);
#ifdef VERBOSE
std::cout<< ans << std::endl;
#endif
}
++iline;
}
delete cmd;
return OK;
}
int slsDetector::writeConfigurationFile(string const fname) {
ofstream outfile;
#ifdef VERBOSE
int ret;
#endif
outfile.open(fname.c_str(),ios_base::out);
if (outfile.is_open()) {
#ifdef VERBOSE
ret=writeConfigurationFile(outfile);
#else
writeConfigurationFile(outfile);
#endif
outfile.close();
}
else {
std::cout<< "Error opening configuration file " << fname <<
" for writing" << std::endl;
setErrorMask((getErrorMask())|(CONFIG_FILE));
return FAIL;
}
#ifdef VERBOSE
std::cout<< "wrote " <<ret << " lines to configuration file " << std::endl;
#endif
return OK;
std::cout << "Cannot write config file from slsDetector level" << std::endl;
setErrorMask((getErrorMask())|(CONFIG_FILE));
return FAIL;
}
int slsDetector::writeConfigurationFile(ofstream &outfile, int id) {
;
slsDetectorCommand *cmd=new slsDetectorCommand(this);
detectorType type = thisDetector->myDetectorType;
string names[100];
int nvar=0;
std::vector <std::string> commands;
// common config
names[nvar++] = "hostname";
names[nvar++] = "port";
names[nvar++] = "stopport";
names[nvar++] = "settingsdir";
names[nvar++] = "caldir";
names[nvar++] = "ffdir";
names[nvar++] = "outdir";
names[nvar++] = "angdir";
names[nvar++] = "moveflag";
names[nvar++] = "lock";
commands.push_back("port");
commands.push_back("stopport");
commands.push_back("settingsdir");
commands.push_back("caldir");
commands.push_back("ffdir");
commands.push_back("outdir");
commands.push_back("angdir");
commands.push_back("moveflag");
commands.push_back("lock");
// receiver config
if (type != MYTHEN) {
names[nvar++] = "detectormac";
names[nvar++] = "detectorip";
names[nvar++] = "zmqport";
names[nvar++] = "rx_zmqport";
names[nvar++] = "zmqip";
names[nvar++] = "rx_zmqip";
names[nvar++] = "rx_tcpport";
names[nvar++] = "rx_udpport";
names[nvar++] = "rx_udpport2";
names[nvar++] = "rx_udpip";
names[nvar++] = "rx_hostname";
names[nvar++] = "r_readfreq";
if (thisDetector->myDetectorType != MYTHEN) {
commands.push_back("detectormac");
commands.push_back("detectorip");
commands.push_back("zmqport");
commands.push_back("rx_zmqport");
commands.push_back("zmqip");
commands.push_back("rx_zmqip");
commands.push_back("rx_tcpport");
commands.push_back("rx_udpport");
commands.push_back("rx_udpport2");
commands.push_back("rx_udpip");
commands.push_back("rx_hostname");
commands.push_back("r_readfreq");
}
// detector specific config
switch (type) {
switch (thisDetector->myDetectorType) {
case MYTHEN:
names[nvar++] = "nmod";
names[nvar++] = "waitstates";
names[nvar++] = "setlength";
names[nvar++] = "clkdivider";
names[nvar++] = "extsig";
commands.push_back("waitstates");
commands.push_back("setlength");
commands.push_back("clkdivider");
commands.push_back("extsig");
break;
case GOTTHARD:
case PROPIX:
names[nvar++] = "extsig";
names[nvar++] = "vhighvoltage";
break;
break;
case MOENCH:
names[nvar++] = "extsig";
names[nvar++] = "vhighvoltage";
commands.push_back("vhighvoltage");
break;
case EIGER:
names[nvar++] = "vhighvoltage";
names[nvar++] = "trimen";
names[nvar++] = "iodelay";
names[nvar++] = "tengiga";
commands.push_back("vhighvoltage");
commands.push_back("trimen");
commands.push_back("iodelay");
commands.push_back("tengiga");
break;
case JUNGFRAU:
names[nvar++] = "powerchip";
names[nvar++] = "vhighvoltage";
break;
case JUNGFRAUCTB:
names[nvar++] = "powerchip";
names[nvar++] = "vhighvoltage";
commands.push_back("powerchip");
commands.push_back("vhighvoltage");
break;
default:
std::cout << "detector type " <<
getDetectorType(thisDetector->myDetectorType) << " not implemented in "
"writing config file" << std::endl;
nvar = 0;
break;
return FAIL;
}
int nsig=4;
int iv=0;
char *args[100];
char myargs[100][1000];
for (int ia=0; ia<100; ++ia) {
args[ia]=myargs[ia];
}
for (iv=0; iv<nvar; ++iv) {
cout << iv << " " << names[iv] << endl;
if (names[iv]=="extsig") {
for (int is=0; is<nsig; ++is) {
sprintf(args[0],"%s:%d",names[iv].c_str(),is);
if (id>=0)
slsDetectorCommand *cmd = new slsDetectorCommand(this);
char* args[2];
args[0] = new char[MAX_STR_LENGTH];
for (unsigned int i = 0; i < commands.size(); ++i) {
if (commands[i] == "extsig") {
for (int is = 0; is < 4; ++is) {
if (id >= 0) {
outfile << id << ":";
outfile << args[0] << " " << cmd->executeLine(1,args,GET_ACTION)
<< std::endl;
}
memset(args[0], 0, MAX_STR_LENGTH);
sprintf(args[0],"extsig:%d", is);
outfile << args[0] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl;
}
} else {
strcpy(args[0],names[iv].c_str());
if (id>=0)
if (id >= 0) {
outfile << id << ":";
outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION)
<< std::endl;
}
memset(args[0], 0, MAX_STR_LENGTH);
strcpy(args[0], commands[i].c_str());
outfile << commands[i] << " " << cmd->executeLine(1, args, GET_ACTION) << std::endl;
}
}
delete cmd;
delete args[0];
delete cmd;
if (getErrorMask()) {
int c = 0;
cprintf(RED, "\n----------------\n Error Messages\n----------------\n%s\n",
getErrorMessage(c).c_str());
return FAIL;
}
return OK;
}
int slsDetector::retrieveDetectorSetup(std::string const fname, int level) {
std::cout << "Cannot read parameter file from slsDetector level" << std::endl;
setErrorMask((getErrorMask())|(CONFIG_FILE));
return FAIL;
}
int slsDetector::dumpDetectorSetup(std::string const fname, int level) {
std::cout << "Cannot write parameter file from slsDetector level" << std::endl;
setErrorMask((getErrorMask())|(CONFIG_FILE));
return FAIL;
}
string slsDetector::getSettingsFile() {
@ -3688,16 +3567,16 @@ int slsDetector::sendSoftwareTrigger() {
#endif
thisDetector->stoppedFlag=0;
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK){
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
std::cout<< "Detector returned error: " << mess << std::endl;
if (stopSocket) {
if (connectStop() == OK){
stopSocket->SendDataOnly(&fnum,sizeof(fnum));
stopSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
stopSocket->ReceiveDataOnly(mess,sizeof(mess));
std::cout<< "Detector returned error: " << mess << std::endl;
}
disconnectStop();
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
@ -5306,6 +5185,9 @@ string slsDetector::setReceiver(string receiverIP) {
if(thisDetector->myDetectorType == GOTTHARD)
sendROI(-1, NULL);
if (thisDetector->myDetectorType == EIGER) {
setQuad(-1);
}
}
}
@ -9756,5 +9638,83 @@ int slsDetector::setCTBPatWaitTime(int level, uint64_t t) {
}
int slsDetector::setQuad(int val) {
int fnum = F_QUAD, fnum2 = F_RECEIVER_QUAD;
int ret = FAIL;
int retval = -1;
#ifdef VERBOSE
std::cout<<"Setting Quad to " <<val << std::endl;
#endif
// set row column header in detector
if (val >= 0) {
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK){
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&val,sizeof(val));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL){
char mess[MAX_STR_LENGTH] = {};
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
std::cout<< "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(SOME_ERROR));
}
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
thisDetector->quadEnable = retval;
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
} else
ret = OK;
// set quad type to receiver (flipped data and detector shape, numdet)
if (ret != FAIL) {
ret = FAIL;
if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){
if(val ==-1) {
val = thisDetector->quadEnable;
}
#ifdef VERBOSE
std::cout<< "Setting Receiver Quad Mode to " << val << endl;
#endif
if (connectData() == OK){
ret=thisReceiver->sendInt(fnum2,retval,val);
disconnectData();
}
if(ret==FAIL)
setErrorMask((getErrorMask())|(RECEIVER_PARAMETER_NOT_SET));
}
}
return retval;
}
int slsDetector::setInterruptSubframe(int val) {
int fnum = F_INTERRUPT_SUBFRAME;
int ret = FAIL;
int retval = -1;
#ifdef VERBOSE
std::cout<<"Setting Interrupt Sub frame to " <<val << std::endl;
#endif
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK){
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->SendDataOnly(&val,sizeof(val));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL){
char mess[MAX_STR_LENGTH] = {};
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
std::cout<< "Detector returned error: " << mess << std::endl;
setErrorMask((getErrorMask())|(SOME_ERROR));
}
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return retval;
}

View File

@ -19,7 +19,7 @@ class multiSlsDetector;
class SharedMemory;
class receiverInterface;
#define SLS_SHMVERSION 0x180629
#define SLS_SHMVERSION 0x180630
#define NMODMAXX 24
#define NMODMAXY 24
#define NCHIPSMAX 10
@ -384,6 +384,9 @@ private:
/** silent receiver */
bool receiver_silentMode;
/** quad enable */
bool quadEnable;
} sharedSlsDetector;
@ -849,20 +852,11 @@ public:
int updateDetector();
/**
* Load configuration from a configuration File
* calls readConfigurationFile and gives it the stream
* @param fname configuration file name
* @return OK or FAIL
* should not be called at this level
* @return FAIL
*/
int readConfigurationFile(std::string const fname);
/**
* Load configuration from a stream
* @param infile stream
* @return OK or FAIL
*/
int readConfigurationFile(std::ifstream &infile);
/**
* Write current configuration to a file
* calls writeConfigurationFile giving it a stream to write to
@ -879,6 +873,26 @@ public:
*/
int writeConfigurationFile(std::ofstream &outfile, int id=-1);
/**
* Loads the detector setup from file
* @param fname file to read from
* @param level if 2 reads also reads trimbits, angular
* conversion coefficients etc. from files with default
* extensions as generated by dumpDetectorSetup
* @returns OK or FAIL
*/
int retrieveDetectorSetup(std::string const fname, int level=0);
/**
* Saves the detector setup to file
* @param fname file to write to
* @param level if 2 reads also trimbits, flat field, angular
* correction etc. and writes them to files with automatically
* added extension
* @returns OK or FAIL
*/
int dumpDetectorSetup(std::string const fname, int level=0);
/**
* Returns the trimfile or settings file name (Useless??)
* @returns the trimfile or settings file name
@ -2274,6 +2288,20 @@ public:
*/
int setCTBPatWaitTime(int level, uint64_t t=-1);
/**
* Set or Get Quad Type (Only for Eiger Quad detector hardware)
* @param val 1 if quad type set, else 0, -1 gets
* @returns 1 if quad type set, else 0
*/
int setQuad(int val = -1);
/**
* Set or Get Interrupt last sub frame(Only for Eiger)
* @param val 1 if interrupt last subframe set, else 0, -1 gets
* @returns 1 if interrupt last subframe set, else 0, -1 different values
*/
int setInterruptSubframe(int val = -1);
private:
/**

View File

@ -540,10 +540,8 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef
*/
virtual int readConfigurationFile(std::string const fname)=0;
virtual int dumpDetectorSetup(std::string const fname, int level)=0;
int dumpDetectorSetup(std::string const fname){return dumpDetectorSetup(fname,0);};
virtual int retrieveDetectorSetup(std::string const fname, int level)=0;
int retrieveDetectorSetup(std::string const fname){return retrieveDetectorSetup(fname,0);};
virtual int dumpDetectorSetup(std::string const fname, int level = 0)=0;
virtual int retrieveDetectorSetup(std::string const fname, int level = 0)=0;
/**
@short
\returns the default output file index

View File

@ -378,6 +378,13 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) {
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDetectorSize;
++i;
/*! \page config
- <b>quad [i] </b> if 1, sets the detector size to a quad (Specific to an EIGER quad hardware). 0 by default. \c Returns \c (int)
*/
descrToFuncMap[i].m_pFuncName="quad"; //
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDetectorSize;
++i;
/*! \page config
- <b>roimask [i]</b> ?? \c Returns \c (int) in hexadecimal
*/
@ -421,6 +428,14 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) {
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced;
++i;
/*! \page config
- <b>interruptsubframe [i]</b> sets/gets the interrupt subframe flag. Setting it to 1 will interrupt the last subframe at the required exposure time. By default, this is disabled and set to 0, ie. it will wait for the last sub frame to finish exposing. Used for EIGER in 32 bit mode only. \c Returns \c (int).
*/
descrToFuncMap[i].m_pFuncName="interruptsubframe";
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced;
++i;
/*! \page config
- <b>extsig:[i] [flag]</b> sets/gets the mode of the external signal i. Options: \c off, \c gate_in_active_high, \c gate_in_active_low, \c trigger_in_rising_edge, \c trigger_in_falling_edge,
\c ro_trigger_in_rising_edge, \c ro_trigger_in_falling_edge, \c gate_out_active_high, \c gate_out_active_low, \c trigger_out_rising_edge, \c trigger_out_falling_edge, \c ro_trigger_out_rising_edge,
@ -4458,7 +4473,7 @@ string slsDetectorCommand::cmdDetectorSize(int narg, char *args[], int action) {
myDet->setOnline(ONLINE_FLAG);
if (cmd == "roi")
if (cmd == "roi" || cmd == "quad")
myDet->setReceiverOnline(ONLINE_FLAG);
if (action==PUT_ACTION) {
@ -4494,6 +4509,13 @@ string slsDetectorCommand::cmdDetectorSize(int narg, char *args[], int action) {
myDet->setMaxNumberOfChannelsPerDetector(Y,val);
}
if(cmd=="quad"){
if (val >=0 ) {
sprintf(ans, "%d", myDet->setQuad(val));
return string(ans);
}
}
if(cmd=="flippeddatax"){
if ((!sscanf(args[1],"%d",&val)) || (val!=0 && val != 1))
return string ("cannot scan flippeddata x mode: must be 0 or 1");
@ -4533,7 +4555,13 @@ string slsDetectorCommand::cmdDetectorSize(int narg, char *args[], int action) {
} else if (cmd=="detsizechan") {
sprintf(ans,"%d %d",myDet->getMaxNumberOfChannelsPerDetector(X),myDet->getMaxNumberOfChannelsPerDetector(Y));
return string(ans);
}
else if (cmd=="quad") {
sprintf(ans, "%d", myDet->setQuad());
return string(ans);
}
else if(cmd=="flippeddatax"){
myDet->setReceiverOnline(ONLINE_FLAG);
ret = myDet->getFlippedData(X);
@ -4571,6 +4599,7 @@ string slsDetectorCommand::helpDetectorSize(int narg, char *args[], int action)
os << "dr i \n sets the dynamic range of the detector"<< std::endl;
os << "roi i xmin xmax ymin ymax \n sets region of interest where i is number of rois;i=0 to clear rois"<< std::endl;
os << "detsizechan x y \n sets the maximum number of channels for complete detector set in both directions; -1 is no limit"<< std::endl;
os << "quad i \n if i = 1, sets the detector size to a quad (Specific to an EIGER quad hardware). 0 by default."<< std::endl;
os << "flippeddatax x \n sets if the data should be flipped on the x axis"<< std::endl;
os << "flippeddatay y \n sets if the data should be flipped on the y axis"<< std::endl;
os << "gappixels i \n enables/disables gap pixels in system (detector & receiver). 1 sets, 0 unsets. Used in EIGER only and multidetector level." << std::endl;
@ -4581,6 +4610,7 @@ string slsDetectorCommand::helpDetectorSize(int narg, char *args[], int action)
os << "dr \n gets the dynamic range of the detector"<< std::endl;
os << "roi \n gets region of interest"<< std::endl;
os << "detsizechan \n gets the maximum number of channels for complete detector set in both directions; -1 is no limit"<< std::endl;
os << "quad \n returns 1 if the detector size is a quad (Specific to an EIGER quad hardware). 0 by default."<< std::endl;
os << "flippeddatax\n gets if the data will be flipped on the x axis"<< std::endl;
os << "flippeddatay\n gets if the data will be flipped on the y axis"<< std::endl;
os << "gappixels\n gets if gap pixels is enabled in system. Used in EIGER only and multidetector level." << std::endl;
@ -5820,18 +5850,14 @@ string slsDetectorCommand::cmdTimeLeft(int narg, char *args[], int action) {
if ((ret!=-1) && (index==ACQUISITION_TIME || index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER
|| index==ACTUAL_TIME || index==MEASUREMENT_TIME ||
MEASURED_PERIOD || MEASURED_SUBPERIOD))
MEASURED_PERIOD || MEASURED_SUBPERIOD)) {
rval=(double)ret*1E-9;
else rval=ret;
sprintf(answer,"%0.9f",rval);
} else {
sprintf(answer,"%lld",(long long int)ret);
}
sprintf(answer,"%0.9f",rval);
return string(answer);
}
@ -6044,7 +6070,18 @@ string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action) {
return string("unknown");
} else if (cmd=="extsig") {
} else if (cmd=="interruptsubframe") {
myDet->setOnline(ONLINE_FLAG);
if (action==PUT_ACTION) {
int ival = -1;
if (!sscanf(args[1],"%d",&ival))
return string("could not scan interrupt sub frame parameter " + string(args[1]));
myDet->setInterruptSubframe(ival);
}
char ans[100];
sprintf(ans,"%d",myDet->setInterruptSubframe(-1));
return std::string(ans);
} else if (cmd=="extsig") {
externalSignalFlag flag=GET_EXTERNAL_SIGNAL_FLAG;
int is=-1;
if (sscanf(args[0],"extsig:%d",&is))
@ -6144,6 +6181,7 @@ string slsDetectorCommand::helpAdvanced(int narg, char *args[], int action) {
os << "extsig:i mode \t sets the mode of the external signal i. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl;
os << "flags mode \t sets the readout flags to mode. can be none, storeinram, tot, continous, parallel, nonparallel, safe, digital, analog_digital, overlow, nooverflow, unknown." << std::endl;
os << "interruptsubframe flag \t sets the interrupt subframe flag. Setting it to 1 will interrupt the last subframe at the required exposure time. By default, this is disabled and set to 0, ie. it will wait for the last sub frame to finish exposing. Used for EIGER in 32 bit mode only." << std::endl;
os << "programfpga f \t programs the fpga with file f (with .pof extension)." << std::endl;
os << "resetfpga f \t resets fpga, f can be any value" << std::endl;
@ -6157,6 +6195,7 @@ string slsDetectorCommand::helpAdvanced(int narg, char *args[], int action) {
os << "extsig:i \t gets the mode of the external signal i. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl;
os << "flags \t gets the readout flags. can be none, storeinram, tot, continous, parallel, nonparallel, safe, digital, analog_digital, overflow, nooverflow, unknown" << std::endl;
os << "interruptsubframe \t gets the interrupt subframe flag. Setting it to 1 will interrupt the last subframe at the required exposure time. By default, this is disabled and set to 0, ie. it will wait for the last sub frame to finish exposing. Used for EIGER in 32 bit mode only." << std::endl;
os << "led \t returns led status (0 off, 1 on)" << std::endl;
os << "powerchip \t gets if the chip has been powered on or off" << std::endl;
os << "auto_comp_disable \t Currently not implemented. gets if the automatic comparator diable mode is enabled/disabled" << std::endl;

View File

@ -10,6 +10,7 @@
#include <sys/shm.h>
#include <time.h> //clock()
#include <string>
#include <iterator>
using namespace std;
slsDetectorUtils::slsDetectorUtils() {
@ -64,9 +65,12 @@ int slsDetectorUtils::acquire(int delflag){
if(!receiver){
setDetectorIndex(-1);
}
pthread_mutex_lock(&mg);
int nc=setTimer(CYCLES_NUMBER,-1);
int nf=setTimer(FRAME_NUMBER,-1);
pthread_mutex_unlock(&mg);
if (nc==0) nc=1;
if (nf==0) nf=1;
int multiframe = nc*nf;
@ -635,316 +639,5 @@ void slsDetectorUtils::setCurrentProgress(int i){
}
int slsDetectorUtils::retrieveDetectorSetup(string const fname1, int level){
slsDetectorCommand *cmd;
// char ext[100];
int skip=0;
string fname;
string str;
ifstream infile;
int iargval;
int interrupt=0;
char *args[10];
char myargs[10][1000];
//args[0]=myargs[0];
//args[1]=myargs[1];
string sargname, sargval;
int iline=0;
if (level==2) {
// fname=fname1+string(".config");
// readConfigurationFile(fname);
#ifdef VERBOSE
cout << "config file read" << endl;
#endif
fname=fname1+string(".det");
} else
fname=fname1;
infile.open(fname.c_str(), ios_base::in);
if (infile.is_open()) {
cmd=new slsDetectorCommand(this);
while (infile.good() and interrupt==0) {
sargname="none";
sargval="0";
getline(infile,str);
iline++;
#ifdef VERBOSE
std::cout<< str << std::endl;
#endif
if (str.find('#')!=string::npos) {
#ifdef VERBOSE
std::cout<< "Line is a comment " << std::endl;
std::cout<< str << std::endl;
#endif
continue;
} else {
istringstream ssstr(str);
iargval=0;
while (ssstr.good()) {
ssstr >> sargname;
// if (ssstr.good()) {
strcpy(myargs[iargval],sargname.c_str());
args[iargval]=myargs[iargval];
#ifdef VERBOSE
std::cout<< args[iargval] << std::endl;
#endif
iargval++;
// }
skip=0;
}
if (level!=2) {
if (string(args[0])==string("flatfield"))
skip=1;
else if (string(args[0])==string("badchannels"))
skip=1;
else if (string(args[0])==string("trimbits"))
skip=1;
}
if (skip==0)
cmd->executeLine(iargval,args,PUT_ACTION);
}
iline++;
}
delete cmd;
infile.close();
} else {
std::cout<< "Error opening " << fname << " for reading" << std::endl;
return FAIL;
}
#ifdef VERBOSE
std::cout<< "Read " << iline << " lines" << std::endl;
#endif
if (getErrorMask())
return FAIL;
return OK;
}
int slsDetectorUtils::dumpDetectorSetup(string const fname, int level){
slsDetectorCommand *cmd;
detectorType type = getDetectorsType();
string names[100];
int nvar=0;
// common config
names[nvar++]="fname";
names[nvar++]="index";
names[nvar++]="enablefwrite";
names[nvar++]="overwrite";
names[nvar++]="dr";
names[nvar++]="settings";
names[nvar++]="exptime";
names[nvar++]="period";
names[nvar++]="frames";
names[nvar++]="cycles";
names[nvar++]="measurements";
names[nvar++]="timing";
names[nvar++]="flatfield";
names[nvar++]="badchannels";
switch (type) {
case EIGER:
names[nvar++]="flags";
names[nvar++]="clkdivider";
names[nvar++]="threshold";
names[nvar++]="ratecorr";
names[nvar++]="trimbits";
break;
case GOTTHARD:
case PROPIX:
names[nvar++]="flags";
names[nvar++]="delay";
names[nvar++]="gates";
names[nvar++]="ratecorr";
break;
case JUNGFRAU:
names[nvar++]="flags";
names[nvar++]="delay";
names[nvar++]="gates";
names[nvar++]="ratecorr";
names[nvar++]="clkdivider";
break;
case MYTHEN:
names[nvar++]="flags";
names[nvar++]="threshold";
names[nvar++]="delay";
names[nvar++]="gates";
names[nvar++]="probes";
names[nvar++]="fineoff";
names[nvar++]="ratecorr";
names[nvar++]="trimbits";
break;
case JUNGFRAUCTB:
names[nvar++]="dac:0";
names[nvar++]="dac:1";
names[nvar++]="dac:2";
names[nvar++]="dac:3";
names[nvar++]="dac:4";
names[nvar++]="dac:5";
names[nvar++]="dac:6";
names[nvar++]="dac:7";
names[nvar++]="dac:8";
names[nvar++]="dac:9";
names[nvar++]="dac:10";
names[nvar++]="dac:11";
names[nvar++]="dac:12";
names[nvar++]="dac:13";
names[nvar++]="dac:14";
names[nvar++]="dac:15";
names[nvar++]="adcvpp";
names[nvar++]="adcclk";
names[nvar++]="clkdivider";
names[nvar++]="adcphase";
names[nvar++]="adcpipeline";
names[nvar++]="adcinvert"; //
names[nvar++]="adcdisable";
names[nvar++]="patioctrl";
names[nvar++]="patclkctrl";
names[nvar++]="patlimits";
names[nvar++]="patloop0";
names[nvar++]="patnloop0";
names[nvar++]="patwait0";
names[nvar++]="patwaittime0";
names[nvar++]="patloop1";
names[nvar++]="patnloop1";
names[nvar++]="patwait1";
names[nvar++]="patwaittime1";
names[nvar++]="patloop2";
names[nvar++]="patnloop2";
names[nvar++]="patwait2";
names[nvar++]="patwaittime2";
break;
default:
break;
}
names[nvar++]="startscript";
names[nvar++]="startscriptpar";
names[nvar++]="stopscript";
names[nvar++]="stopscriptpar";
names[nvar++]="scriptbefore";
names[nvar++]="scriptbeforepar";
names[nvar++]="scriptafter";
names[nvar++]="scriptafterpar";
names[nvar++]="scan0script";
names[nvar++]="scan0par";
names[nvar++]="scan0prec";
names[nvar++]="scan0steps";
names[nvar++]="scan1script";
names[nvar++]="scan1par";
names[nvar++]="scan1prec";
names[nvar++]="scan1steps";
int iv=0;
string fname1;
ofstream outfile;
char *args[4];
for (int ia=0; ia<4; ia++) {
args[ia]=new char[1000];
}
int nargs;
if (level==2)
nargs=2;
else
nargs=1;
if (level==2) {
fname1=fname+string(".config");
writeConfigurationFile(fname1);
fname1=fname+string(".det");
} else
fname1=fname;
outfile.open(fname1.c_str(),ios_base::out);
if (outfile.is_open()) {
cmd=new slsDetectorCommand(this);
for (iv=0; iv<nvar-3; iv++) {
strcpy(args[0],names[iv].c_str());
outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl;
}
strcpy(args[0],names[iv].c_str());
if (level==2) {
fname1=fname+string(".ff");
strcpy(args[1],fname1.c_str());
}
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
strcpy(args[0],names[iv].c_str());
if (level==2) {
fname1=fname+string(".bad");
strcpy(args[1],fname1.c_str());
}
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
if (level==2) {
strcpy(args[0],names[iv].c_str());
size_t c=fname.rfind('/');
if (c<string::npos) {
fname1=fname.substr(0,c+1)+string("trim_")+fname.substr(c+1);
} else {
fname1=string("trim_")+fname;
}
strcpy(args[1],fname1.c_str());
#ifdef VERBOSE
std::cout<< "writing to file " << fname1 << std::endl;
#endif
outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl;
iv++;
}
delete cmd;
outfile.close();
}
else {
std::cout<< "Error opening parameters file " << fname1 << " for writing" << std::endl;
return FAIL;
}
#ifdef VERBOSE
std::cout<< "wrote " <<iv << " lines to "<< fname1 << std::endl;
#endif
return OK;
}

View File

@ -709,25 +709,6 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing {
void registerProgressCallback(int( *func)(double,void*), void *pArg){progress_call=func; pProgressCallArg=pArg;};
/**
Saves the detector setup to file
\param fname file to write to
\param level if 2 reads also trimbits, flat field, angular correction etc. and writes them to files with automatically added extension
\returns OK or FAIL
*/
int dumpDetectorSetup(std::string const fname, int level=0);
/**
Loads the detector setup from file
\param fname file to read from
\param level if 2 reads also reads trimbits, angular conversion coefficients etc. from files with default extensions as generated by dumpDetectorSetup
\returns OK or FAIL
*/
int retrieveDetectorSetup(std::string const fname, int level=0);
static int dummyAcquisitionFinished(double prog,int status,void* p){cout <<"Acquisition finished callback! " << prog << " " << status << endl; return 0;}
static int dummyMeasurementFinished(int im,int findex,void* p){cout <<"Measurement finished callback! " << im << " " << findex << endl; return 0;}
@ -1021,11 +1002,22 @@ virtual int setReceiverSilentMode(int i = -1)=0;
*/
virtual int checkVersionCompatibility(portType t) = 0;
/**
* Set or Get Quad Type (Only for Eiger Quad detector hardware)
* @param val 1 if quad type set, else 0, -1 gets
* @returns 1 if quad type set, else 0
*/
virtual int setQuad(int val = -1) = 0;
/**
* Set or Get Interrupt last sub frame(Only for Eiger)
* @param val 1 if interrupt last subframe set, else 0, -1 gets
* @returns 1 if interrupt last subframe set, else 0, -1 different values
*/
virtual int setInterruptSubframe(int val = -1) = 0;
protected:
static const int64_t thisSoftwareVersion=0x20141013;
//protected:

View File

@ -239,10 +239,7 @@ s
void registerDataCallback(int( *userCallback)(detectorData*, int, int, void*), void *pArg) { \
dataReady = userCallback; \
pCallbackArg = pArg; \
if (setReceiverOnline() == slsDetectorDefs::ONLINE_FLAG) { \
enableDataStreamingToClient(1); \
enableDataStreamingFromReceiver(1);}}; \
enableDataStreamingToClient(dataReady == NULL ? 0 : 1);}; \
void registerRawDataCallback(int( *userCallback)(double*, int, void*), void *pArg) {rawDataReady = userCallback; pRawDataArg = pArg;};

View File

@ -73,8 +73,8 @@ int setDefaultDacs();
extern u_int32_t writeRegister(u_int32_t offset, u_int32_t data); // blackfin.h
extern u_int32_t readRegister(u_int32_t offset); // blackfin.h
#else
uint32_t writeRegister(uint32_t offset, uint32_t data);
uint32_t readRegister(uint32_t offset);
int writeRegister(uint32_t offset, uint32_t data);
int readRegister(uint32_t offset, uint32_t* retval);
#endif
@ -194,6 +194,12 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32
#if defined(JUNGFRAUD) || defined(EIGERD)
int setDetectorPosition(int pos[]);
#endif
#ifdef EIGERD
int setQuad(int val);
int getQuad();
int setInterruptSubframe(int val);
int getInterruptSubframe();
#endif
// very detector specific

View File

@ -211,6 +211,8 @@ const char* getFunctionName(enum detFuncs func) {
case F_STORAGE_CELL_START: return "F_STORAGE_CELL_START";
case F_CHECK_VERSION: return "F_CHECK_VERSION";
case F_SOFTWARE_TRIGGER: return "F_SOFTWARE_TRIGGER";
case F_QUAD: return "F_QUAD";
case F_INTERRUPT_SUBFRAME: return "F_INTERRUPT_SUBFRAME";
default: return "Unknown Function";
}
@ -297,6 +299,8 @@ void function_table() {
flist[F_STORAGE_CELL_START] = &storage_cell_start;
flist[F_CHECK_VERSION] = &check_version;
flist[F_SOFTWARE_TRIGGER] = &software_trigger;
flist[F_QUAD] = &set_quad;
flist[F_INTERRUPT_SUBFRAME] = &set_interrupt_subframe;
// check
if (NUM_DET_FUNCTIONS >= TOO_MANY_FUNCTIONS_DEFINED) {
@ -1454,8 +1458,22 @@ int write_register(int file_des) {
#ifdef VERBOSE
printf("writing to register 0x%x data 0x%x\n", addr, val);
#endif
#ifdef EIGERD
if(writeRegister(addr, val) == FAIL) {
ret = FAIL;
sprintf(mess,"Could not write to register 0x%x.\n", addr);
cprintf(RED, "Warning: %s", mess);
} else {
if(readRegister(addr, &retval) == FAIL) {
ret = FAIL;
sprintf(mess,"Could not read register 0x%x.\n", addr);
cprintf(RED, "Warning: %s", mess);
}
}
#else
retval=writeRegister(addr,val);
if (retval!=val) {
#endif
if (ret == OK && retval!=val) {
ret = FAIL;
sprintf(mess,"Writing to register 0x%x failed: wrote 0x%x but read 0x%x\n", addr, val, retval);
cprintf(RED, "Warning: %s", mess);
@ -1505,8 +1523,16 @@ int read_register(int file_des) {
printf("reading register 0x%x\n", addr);
#endif
#ifdef SLS_DETECTOR_FUNCTION_LIST
#ifdef EIGERD
if(readRegister(addr, &retval) == FAIL) {
ret = FAIL;
sprintf(mess,"Could not read register 0x%x.\n", addr);
cprintf(RED, "Warning: %s", mess);
}
#else
retval=readRegister(addr);
#endif
#endif
#ifdef VERBOSE
printf("Returned value 0x%x\n", retval);
#endif
@ -3708,6 +3734,14 @@ int send_update(int file_des) {
if (n < 0) return printSocketReadError();
#ifdef EIGERD
#ifdef SLS_DETECTOR_FUNCTION_LIST
nm=getQuad();
#endif
n = sendData(file_des,&nm,sizeof(int32_t),INT32);
if (n < 0) return printSocketReadError();
#endif
if (lockStatus==0) {
strcpy(lastClientIP,thisClientIP);
}
@ -5926,3 +5960,133 @@ int software_trigger(int file_des) {
return ret;
}
int set_quad(int file_des) {
int ret=OK,ret1=OK;
int n=0;
int retval=-1;
sprintf(mess,"Setting quad failed\n");
// execute action
#ifndef EIGERD
//to receive any arguments
while (n > 0)
n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER);
ret = FAIL;
sprintf(mess,"Function (set_quad) is not implemented for this detector\n");
cprintf(RED, "Warning: %s", mess);
#else
// receive arguments
int arg=-1;
n = receiveData(file_des,&arg,sizeof(arg),INT32);
if (n < 0) return printSocketReadError();
// execute action
if (differentClients && lockStatus && arg!=-1) {
ret = FAIL;
sprintf(mess,"Detector locked by %s\n",lastClientIP);
cprintf(RED, "Warning: %s", mess);
}
#ifdef SLS_DETECTOR_FUNCTION_LIST
else {
#ifdef VERBOSE
printf("Setting Quad :%d \n",arg);
#endif
if(arg != -1 && setQuad(arg) == FAIL) {
ret=FAIL;
strcpy(mess, "setting quad failed\n");
cprintf(RED, "Warning: %s", mess);
}
retval = getQuad();
if(ret == OK && (arg != -1) && (retval != arg)) {
ret=FAIL;
cprintf(RED, "Warning: %s", mess);
}
}
#endif
if (ret==OK && differentClients)
ret=FORCE_UPDATE;
#endif
// ret could be swapped during sendData
ret1 = ret;
// send ok / fail
n = sendData(file_des,&ret1,sizeof(ret),INT32);
// send return argument
if (ret==FAIL) {
n += sendData(file_des,mess,sizeof(mess),OTHER);
}
n += sendData(file_des,&retval,sizeof(retval),INT32);
// return ok / fail
return ret;
}
int set_interrupt_subframe(int file_des) {
int ret=OK,ret1=OK;
int n=0;
int retval=-1;
sprintf(mess,"Setting interrupt subframe failed\n");
// execute action
#ifndef EIGERD
//to receive any arguments
while (n > 0)
n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER);
ret = FAIL;
sprintf(mess,"Function (set_interrupt_subframe) is not implemented for this detector\n");
cprintf(RED, "Warning: %s", mess);
#else
// receive arguments
int arg=-1;
n = receiveData(file_des,&arg,sizeof(arg),INT32);
if (n < 0) return printSocketReadError();
// execute action
if (differentClients && lockStatus && arg!=-1) {
ret = FAIL;
sprintf(mess,"Detector locked by %s\n",lastClientIP);
cprintf(RED, "Warning: %s", mess);
}
#ifdef SLS_DETECTOR_FUNCTION_LIST
else {
#ifdef VERBOSE
printf("Setting Interrupt subframe :%d \n",arg);
#endif
if (arg != -1 && setInterruptSubframe(arg) == FAIL) {
ret=FAIL;
strcpy(mess, "setting interrupt subframe failed\n");
cprintf(RED, "Warning: %s", mess);
}
retval = getInterruptSubframe();
#ifdef VERBOSE
printf("retval Interrupt subframe :%d \n",retval);
#endif
if(ret == OK && (arg != -1) && (retval != arg)) {
ret=FAIL;
sprintf(mess, "setting interrupt subframe failed. Set %d, got %d\n", arg, retval);
cprintf(RED, "Warning: %s", mess);
}
}
#endif
if (ret==OK && differentClients)
ret=FORCE_UPDATE;
#endif
// ret could be swapped during sendData
ret1 = ret;
// send ok / fail
n = sendData(file_des,&ret1,sizeof(ret),INT32);
// send return argument
if (ret==FAIL) {
n += sendData(file_des,mess,sizeof(mess),OTHER);
}
n += sendData(file_des,&retval,sizeof(retval),INT32);
// return ok / fail
return ret;
}

View File

@ -97,5 +97,7 @@ int auto_comp_disable(int);
int storage_cell_start(int);
int check_version(int);
int software_trigger(int);
int set_quad(int);
int set_interrupt_subframe(int);
#endif

View File

@ -1,9 +1,9 @@
Path: slsDetectorsPackage/slsReceiverSoftware
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: 46533b041195591b1a09b2662895e084821ba886
Revision: 863
Branch: 4.0.2
Repsitory UUID: b0fd4f4c44ac378744e724cce684aca4a56fe0fc
Revision: 872
Branch: 4.1.1
Last Changed Author: Dhanya_Thattil
Last Changed Rev: 4107
Last Changed Date: 2019-06-12 14:40:27.000000002 +0200 ./updateAPIVersion.sh
Last Changed Rev: 4153
Last Changed Date: 2020-01-14 15:47:26.000000001 +0100 ./updateAPIVersion.sh

View File

@ -58,19 +58,10 @@ class BinaryFile : private virtual slsReceiverDefs, public File, public BinaryFi
/**
* Create master file
* @param en ten giga enable
* @param size image size
* @param nx number of pixels in x direction
* @param ny number of pixels in y direction
* @param at acquisition time
* @param st sub exposure time
* @param sp sub period
* @param ap acquisition period
* @param attr master file attributes
* @returns OK or FAIL
*/
int CreateMasterFile(bool en, uint32_t size,
uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t sp,
uint64_t ap);
int CreateMasterFile(masterAttributes& attr);
/**
* Close Current File

View File

@ -100,26 +100,11 @@ class BinaryFileStatic {
* @param fd pointer to file handle
* @param fname master file name
* @param owenable overwrite enable
* @param dr dynamic range
* @param tenE ten giga enable
* @param size image size
* @param nPixelsX number of pixels in x direction
* @param nPixelsY number of pixels in y direction
* @param nf number of images
* @param maxf maximum frames per file
* @param acquisitionTime acquisition time
* @param acquisitionPeriod acquisition period
* @param subexposuretime sub exposure time
* @param subperiod sub period
* @param version version of software for binary writing
* @param attr master file attributes
* @returns 0 for success and 1 for fail
*/
static int CreateMasterDataFile(FILE*& fd, std::string fname, bool owenable,
uint32_t dr, bool tenE, uint32_t size,
uint32_t nPixelsX, uint32_t nPixelsY, uint64_t nf,
uint32_t maxf,
uint64_t acquisitionTime, uint64_t subexposuretime,
uint64_t subperiod, uint64_t acquisitionPeriod, double version)
masterAttributes& attr)
{
if(!owenable){
if (NULL == (fd = fopen((const char *) fname.c_str(), "wx"))){
@ -136,17 +121,20 @@ class BinaryFileStatic {
char message[MAX_MASTER_FILE_LENGTH];
sprintf(message,
"Version : %.1f\n"
"Detector Type : %d\n"
"Dynamic Range : %d\n"
"Ten Giga : %d\n"
"Image Size : %d bytes\n"
"row : %d pixels\n"
"col : %d pixels\n"
"Max. Frames Per File : %u\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"
"Gap Pixels Enable : %d\n"
"Quad Enable : %d\n"
"Timestamp : %s\n\n"
"#Frame Header\n"
@ -165,18 +153,21 @@ class BinaryFileStatic {
"Header Version : 1 byte\n"
"Packets Caught Mask : 64 bytes\n"
,
version,
dr,
tenE,
size,
nPixelsX,
nPixelsY,
maxf,
(long long int)nf,
(long long int)acquisitionTime,
(long long int)subexposuretime,
(long long int)subperiod,
(long long int)acquisitionPeriod,
attr.version,
attr.detectorType,
attr.dynamicRange,
attr.tenGiga,
attr.imageSize,
attr.nPixelsX,
attr.nPixelsY,
attr.maxFramesPerFile,
(long long int)attr.totalFrames,
(long long int)attr.exptimeNs,
(long long int)attr.subExptimeNs,
(long long int)attr.subPeriodNs,
(long long int)attr.periodNs,
attr.gapPixelsEnable,
attr.quadEnable,
ctime(&t));
if (strlen(message) > MAX_MASTER_FILE_LENGTH) {
cprintf(RED,"Master File Size %d is greater than max str size %d\n",

View File

@ -10,6 +10,7 @@
*/
#include "ThreadObject.h"
#include "receiver_defs.h"
class GeneralData;
class Fifo;
@ -38,6 +39,7 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject {
* @param act pointer to activated
* @param depaden pointer to deactivated padding enable
* @param sm pointer to silent mode
* @param qe pointer to quad Enable
* @param dataReadycb pointer to data ready call back function
* @param dataModifyReadycb pointer to data ready call back function with modified
* @param pDataReadycb pointer to arguments of data ready call back function. To write/stream a smaller size of processed data, change this value (only smaller value is allowed).
@ -45,7 +47,7 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject {
DataProcessor(int ind, detectorType dtype, Fifo*& f, fileFormat* ftype,
bool fwenable, bool* dsEnable, bool* gpEnable, uint32_t* dr,
uint32_t* freq, uint32_t* timer,
bool* fp, bool* act, bool* depaden, bool* sm,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
void (*dataReadycb)(char*, char*, uint32_t, void*),
void (*dataModifyReadycb)(char*, char*, uint32_t &, void*),
void *pDataReadycb);
@ -175,16 +177,10 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject {
/**
* Create New File
* @param en ten giga enable
* @param nf number of frames
* @param at acquisition time
* @param st sub exposure time
* @param sp sub period
* @param ap acquisition period
* @param attr master file attributes
* @returns OK or FAIL
*/
int CreateNewFile(bool en, uint64_t nf, uint64_t at, uint64_t st,
uint64_t sp, uint64_t ap);
int CreateNewFile(masterAttributes& attr);
/**
* Closes files
@ -341,6 +337,9 @@ class DataProcessor : private virtual slsReceiverDefs, public ThreadObject {
/** Silent Mode */
bool* silentMode;
/** quad enable */
bool* quadEnable;
/** frame padding */
bool* framePadding;

View File

@ -27,12 +27,15 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject {
* @param dr pointer to dynamic range
* @param r roi
* @param fi pointer to file index
* @param fd flipped data enable for x and y dimensions
* @param fd flipped data enable for x dimension
* @param ajh additional json header
* @param sm pointer to silent mode
* @param nd pointer to number of detectors in each dimension
* @param gpEnable pointer to gap pixels enable
* @param qe pointer to quad Enable
*/
DataStreamer(int ind, Fifo*& f, uint32_t* dr, std::vector<ROI>* r,
uint64_t* fi, int* fd, char* ajh, bool* sm);
uint64_t* fi, int fd, char* ajh, bool* sm, int* nd, bool* gpEnable, bool* qe);
/**
* Destructor
@ -88,6 +91,18 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject {
*/
int SetThreadPriority(int priority);
/**
* Set number of detectors
* @param number of detectors in both dimensions
*/
void SetNumberofDetectors(int* nd);
/**
* Set Flipped data enable across x dimension
* @param flipped data enable in x dimension
*/
void SetFlippedDataX(int fd);
/**
* Creates Zmq Sockets
* (throws an exception if it couldnt create zmq sockets)
@ -183,8 +198,8 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject {
/** Pointer to file index */
uint64_t* fileIndex;
/** flipped data across both dimensions enable */
int* flippedData;
/** flipped data across x dimension */
int flippedDataX;
/** additional json header */
char* additionJsonHeader;
@ -207,5 +222,13 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject {
/** Complete buffer used for roi, eg. shortGotthard */
char* completeBuffer;
/** Number of Detectors in X and Y dimension */
int numDet[2];
/** Gap Pixels Enable */
bool* gapPixelsEnable;
/** quad enable */
bool* quadEnable;
};

View File

@ -10,6 +10,7 @@
#include "sls_receiver_defs.h"
#include "logger.h"
#include "receiver_defs.h"
#include <string>
@ -121,19 +122,10 @@ class File : private virtual slsReceiverDefs {
/**
* Create master file
* @param en ten giga enable
* @param size image size
* @param nx number of pixels in x direction
* @param ny number of pixels in y direction
* @param at acquisition time
* @param st sub exposure time
* @param sp sub period
* @param ap acquisition period
* @param attr master file attributes
* @returns OK or FAIL
*/
virtual int CreateMasterFile(bool en, uint32_t size,
uint32_t nx, uint32_t ny, uint64_t at, uint64_t st,
uint64_t sp, uint64_t ap) {
virtual int CreateMasterFile(masterAttributes& attr) {
cprintf(RED,"This is a generic function CreateMasterFile that "
"should be overloaded by a derived class\n");
return OK;

View File

@ -190,8 +190,10 @@ public:
/**
* Enable Gap Pixels changes member variables
* @param enable true if gap pixels enable, else false
* @param dr dynamic range
* @param q quad enable
*/
virtual void SetGapPixelsEnable(bool b, int dr) {
virtual void SetGapPixelsEnable(bool b, int dr, bool q) {
cprintf(RED,"This is a generic function that should be overloaded by a derived class\n");
};
@ -646,13 +648,17 @@ class EigerData : public GeneralData {
* Enable Gap Pixels changes member variables
* @param enable true if gap pixels enable, else false
* @param dr dynamic range
* @param q quad enable
*/
void SetGapPixelsEnable(bool b, int dr) {
void SetGapPixelsEnable(bool b, int dr, bool q) {
if (dr == 4)
b = 0;
switch((int)b) {
case 1:
nPixelsX = (256 * 2) + 3;
if (q) {
--nPixelsX; // if quad, remove last line
}
nPixelsY = 256 + 1;
imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit
((dr > 8) ? 2 : // 16 bit

View File

@ -93,19 +93,10 @@ class HDF5File : private virtual slsReceiverDefs, public File, public HDF5FileSt
/**
* Create master file
* @param en ten giga enable
* @param size image size
* @param nx number of pixels in x direction
* @param ny number of pixels in y direction
* @param at acquisition time
* @param st sub exposure time
* @param sp sub period
* @param ap acquisition period
* @param attr master file attributes
* @returns OK or FAIL
*/
int CreateMasterFile(bool en, uint32_t size,
uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t sp,
uint64_t ap);
int CreateMasterFile(masterAttributes& attr);
/**
* End of Acquisition

View File

@ -294,26 +294,12 @@ public:
* Create master file
* @param fname master file name
* @param owenable overwrite enable
* @param dr dynamic range
* @param tenE ten giga enable
* @param size image size
* @param nx number of pixels in x direction
* @param ny number of pixels in y direction
* @param nf number of images
* @param maxf maximum frames per file
* @param acquisitionTime acquisition time
* @param subexposuretime sub exposure time
* @param subperiod sub period
* @param acquisitionPeriod acquisition period
* @param attr master file attributes
* @param version version of software for hdf5 writing
* @returns 0 for success and 1 for fail
*/
static int CreateMasterDataFile(H5File*& fd, std::string fname, bool owenable,
uint32_t dr, bool tenE, uint32_t size,
uint32_t nPixelsx, uint32_t nPixelsy, uint64_t nf,
uint32_t maxf,
uint64_t acquisitionTime, uint64_t subexposuretime,
uint64_t subperiod, uint64_t acquisitionPeriod, double version)
masterAttributes& attr)
{
try {
Exception::dontPrint(); //to handle errors
@ -340,7 +326,7 @@ public:
//create attributes
//version
dValue=version;
dValue=attr.version;
attribute = fd->createAttribute("version",PredType::NATIVE_DOUBLE, dataspace);
attribute.write(PredType::NATIVE_DOUBLE, &dValue);
@ -352,63 +338,75 @@ public:
Group group5( group3.createGroup("detector") );
Group group6( group1.createGroup("sample") );
//Detector Type
dataset = group5.createDataSet ( "detector type", PredType::NATIVE_INT, dataspace );
dataset.write ( &(attr.detectorType), PredType::NATIVE_INT);
//Dynamic Range
dataset = group5.createDataSet ( "dynamic range", PredType::NATIVE_INT, dataspace );
dataset.write ( &dr, PredType::NATIVE_INT);
dataset.write ( &(attr.dynamicRange), PredType::NATIVE_INT);
attribute = dataset.createAttribute("unit",strdatatype, dataspace);
attribute.write(strdatatype, std::string("bits"));
//Ten Giga
iValue = tenE;
iValue = attr.tenGiga;
dataset = group5.createDataSet ( "ten giga enable", PredType::NATIVE_INT, dataspace );
dataset.write ( &iValue, PredType::NATIVE_INT);
//Image Size
dataset = group5.createDataSet ( "image size", PredType::NATIVE_INT, dataspace );
dataset.write ( &size, PredType::NATIVE_INT);
dataset.write ( &(attr.imageSize), PredType::NATIVE_INT);
attribute = dataset.createAttribute("unit",strdatatype, dataspace);
attribute.write(strdatatype, std::string("bytes"));
//x
dataset = group5.createDataSet ( "number of pixels in x axis", PredType::NATIVE_INT, dataspace );
dataset.write ( &nPixelsx, PredType::NATIVE_INT);
dataset.write ( &(attr.nPixelsX), PredType::NATIVE_INT);
//y
dataset = group5.createDataSet ( "number of pixels in y axis", PredType::NATIVE_INT, dataspace );
dataset.write ( &nPixelsy, PredType::NATIVE_INT);
dataset.write ( &(attr.nPixelsY), PredType::NATIVE_INT);
//Maximum frames per file
dataset = group5.createDataSet ( "maximum frames per file", PredType::NATIVE_INT, dataspace );
dataset.write ( &maxf, PredType::NATIVE_INT);
dataset.write ( &(attr.maxFramesPerFile), PredType::NATIVE_INT);
//Total Frames
dataset = group5.createDataSet ( "total frames", PredType::STD_U64LE, dataspace );
dataset.write ( &nf, PredType::STD_U64LE);
dataset.write ( &(attr.totalFrames), PredType::STD_U64LE);
//Exptime
dataset = group5.createDataSet ( "exposure time", PredType::STD_U64LE, dataspace );
dataset.write ( &acquisitionTime, PredType::STD_U64LE);
dataset.write ( &(attr.exptimeNs), PredType::STD_U64LE);
attribute = dataset.createAttribute("unit",strdatatype, dataspace);
attribute.write(strdatatype, std::string("ns"));
//SubExptime
dataset = group5.createDataSet ( "sub exposure time", PredType::STD_U64LE, dataspace );
dataset.write ( &subexposuretime, PredType::STD_U64LE);
dataset.write ( &(attr.subExptimeNs), PredType::STD_U64LE);
attribute = dataset.createAttribute("unit",strdatatype, dataspace);
attribute.write(strdatatype, std::string("ns"));
//SubPeriod
dataset = group5.createDataSet ( "sub period", PredType::STD_U64LE, dataspace );
dataset.write ( &subperiod, PredType::STD_U64LE);
dataset.write ( &(attr.subPeriodNs), PredType::STD_U64LE);
attribute = dataset.createAttribute("unit",strdatatype, dataspace);
attribute.write(strdatatype, std::string("ns"));
//Period
dataset = group5.createDataSet ( "acquisition period", PredType::STD_U64LE, dataspace );
dataset.write ( &acquisitionPeriod, PredType::STD_U64LE);
dataset.write ( &(attr.periodNs), PredType::STD_U64LE);
attribute = dataset.createAttribute("unit",strdatatype, dataspace);
attribute.write(strdatatype, std::string("ns"));
//Gap Pixels Enable
dataset = group5.createDataSet ( "gap pixels enable", PredType::NATIVE_INT, dataspace );
dataset.write ( &(attr.gapPixelsEnable), PredType::NATIVE_INT);
//Quad Enable
dataset = group5.createDataSet ( "quad enable", PredType::NATIVE_INT, dataspace );
dataset.write ( &(attr.quadEnable), PredType::NATIVE_INT);
//Timestamp
time_t t = time(0);
dataset = group5.createDataSet ( "timestamp", strdatatype, dataspace );

View File

@ -72,6 +72,12 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter
*/
bool getGapPixelsEnable() const;
/**
* Get Quad type Enable (eiger and hardware specific)
* @return true if quad enabled, else false
*/
bool getQuad() const;
//***file parameters***
/**
@ -341,7 +347,7 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter
void setMultiDetectorSize(const int* size);
/*
* Get flipped data across 'axis'
* Set flipped data across 'axis'
* @return if data is flipped across 'axis'
*/
void setFlippedData(int axis=0, int enable=-1);
@ -353,6 +359,13 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter
*/
int setGapPixelsEnable(const bool b);
/**
* Set Quad type Enable (eiger and hardware specific)
* @param true if quad enabled, else false
* @return OK or FAIL
*/
int setQuad(const bool b);
//***file parameters***
/**
@ -735,10 +748,12 @@ class UDPBaseImplementation : protected virtual slsReceiverDefs, public UDPInter
bool tengigaEnable;
/** Fifo Depth */
uint32_t fifoDepth;
/** enable for flipping data across both axes */
int flippedData[2];
/** enable for flipping data across x axis */
int flippedDataX;
/** gap pixels enable */
bool gapPixelsEnable;
/** quad type enable */
bool quadEnable;
//***receiver parameters***
/** Maximum Number of Listening Threads/ UDP Ports */

View File

@ -162,6 +162,12 @@ class UDPInterface {
*/
virtual bool getGapPixelsEnable() const = 0;
/**
* Get Quad type Enable (eiger and hardware specific)
* @return true if quad enabled, else false
*/
virtual bool getQuad() const = 0;
//***file parameters***
/**
@ -444,6 +450,13 @@ class UDPInterface {
*/
virtual int setGapPixelsEnable(const bool b) = 0;
/**
* Set Quad type Enable (eiger and hardware specific)
* @param true if quad enabled, else false
* @return OK or FAIL
*/
virtual int setQuad(const bool b) = 0;
//***file parameters***
/**

View File

@ -53,6 +53,18 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase
*/
int64_t getAcquisitionIndex() const;
/*
* Set multi detector size
* @param pointer to array of multi detector size in every dimension
*/
void setMultiDetectorSize(const int* size);
/*
* Set flipped data across 'axis'
* @return if data is flipped across 'axis'
*/
void setFlippedData(int axis=0, int enable=-1);
/**
* Set Gap Pixels Enable (eiger specific)
* @param b true for gap pixels enable, else false
@ -60,6 +72,13 @@ class UDPStandardImplementation: private virtual slsReceiverDefs, public UDPBase
*/
int setGapPixelsEnable(const bool b);
/**
* Set Quad type Enable (eiger and hardware specific)
* @param true if quad enabled, else false
* @return OK or FAIL
*/
int setQuad(const bool b);
/**
* Set File Format
* @param f fileformat binary or hdf5

View File

@ -238,20 +238,43 @@ public:
/**
* Send Message Header
* @param buf message
* @param length length of message
* @param dummy true if end of acquistion else false
* @param index self index for debugging
* @param dummy true if a dummy message for end of acquisition
* @param jsonversion json version
* @param dynamicrange dynamic range
* @param fileIndex file or acquisition index
* @param ndetx number of detectors in x axis
* @param ndety number of detectors in y axis
* @param npixelsx number of pixels/channels in x axis for this zmq socket
* @param npixelsy number of pixels/channels in y axis for this zmq socket
* @param imageSize number of bytes for an image in this socket
* @param frameNumber current frame number
* @param expLength exposure length or subframe index if eiger
* @param packetNumber number of packets caught for this frame
* @param bunchId bunch id
* @param timestamp time stamp
* @param modId module Id
* @param row row index in complete detector
* @param column column index in complete detector
* @param reserved reserved
* @param debug debug
* @param roundRNumber not used yet
* @param detType detector enum
* @param version detector header version
* @param gapPixelsEnable gap pixels enable (exception: if gap pixels enable for 4 bit mode, data is not yet gap pixel enabled in receiver)
* @param flippedData int array of 2 elements for x and y, if it is flipped across x or y axis
* @param additionalJsonHeader additional json header
* @returns 0 if error, else 1
*/
int SendHeaderData ( int index, bool dummy, uint32_t jsonversion, uint32_t dynamicrange = 0, uint64_t fileIndex = 0,
uint32_t npixelsx = 0, uint32_t npixelsy = 0, uint32_t imageSize = 0,
uint32_t ndetx = 0, uint32_t ndety = 0, uint32_t npixelsx = 0, uint32_t npixelsy = 0, uint32_t imageSize = 0,
uint64_t acqIndex = 0, uint64_t fIndex = 0, char* fname = NULL,
uint64_t frameNumber = 0, uint32_t expLength = 0, uint32_t packetNumber = 0,
uint64_t bunchId = 0, uint64_t timestamp = 0,
uint16_t modId = 0, uint16_t row = 0, uint16_t column = 0, uint16_t reserved = 0,
uint32_t debug = 0, uint16_t roundRNumber = 0,
uint8_t detType = 0, uint8_t version = 0, int* flippedData = 0,
char* additionalJsonHeader = 0) {
uint8_t detType = 0, uint8_t version = 0, uint32_t gapPixelsEnable = 0, uint32_t flippedDataX = 0,
uint32_t quadEnable = 0, char* additionalJsonHeader = 0) {
char buf[MAX_STR_LENGTH] = "";
@ -261,6 +284,7 @@ public:
"\"jsonversion\":%u, "
"\"bitmode\":%u, "
"\"fileIndex\":%llu, "
"\"detshape\":[%u, %u], "
"\"shape\":[%u, %u], "
"\"size\":%u, "
"\"acqIndex\":%llu, "
@ -283,11 +307,13 @@ public:
"\"version\":%u, "
//additional stuff
"\"flippedDataX\":%u"
"\"gappixels\":%u, "
"\"flippedDataX\":%u, "
"\"quad\":%u"
;//"}\n";
int length = sprintf(buf, jsonHeaderFormat,
jsonversion, dynamicrange, fileIndex, npixelsx, npixelsy, imageSize,
jsonversion, dynamicrange, fileIndex, ndetx, ndety, npixelsx, npixelsy, imageSize,
acqIndex, fIndex, (fname == NULL)? "":fname, dummy?0:1,
frameNumber, expLength, packetNumber, bunchId, timestamp,
@ -295,7 +321,9 @@ public:
detType, version,
//additional stuff
((flippedData == 0 ) ? 0 :flippedData[0])
gapPixelsEnable,
flippedDataX,
quadEnable
);
if (additionalJsonHeader && strlen(additionalJsonHeader)) {
length = sprintf(buf, "%s, %s}\n", buf, additionalJsonHeader);
@ -304,7 +332,7 @@ public:
}
#ifdef VERBOSE
//if(!index)
if(!index)
cprintf(BLUE,"%d : Streamer: buf: %s\n", index, buf);
#endif

View File

@ -1,6 +1,6 @@
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
#define GITREPUUID "46533b041195591b1a09b2662895e084821ba886"
#define GITREPUUID "b0fd4f4c44ac378744e724cce684aca4a56fe0fc"
#define GITAUTH "Dhanya_Thattil"
#define GITREV 0x4107
#define GITDATE 0x20190612
#define GITBRANCH "4.0.2"
#define GITREV 0x4153
#define GITDATE 0x20200114
#define GITBRANCH "4.1.1"

View File

@ -28,8 +28,8 @@
#define MAX_CHUNKED_IMAGES 1
//versions
#define HDF5_WRITER_VERSION 3.0 //1 decimal places
#define BINARY_WRITER_VERSION 3.0 //1 decimal places
#define HDF5_WRITER_VERSION 4.0 //1 decimal places
#define BINARY_WRITER_VERSION 4.0 //1 decimal places
//parameters to calculate fifo depth
@ -48,3 +48,21 @@
#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 gapPixelsEnable;
uint32_t quadEnable;
};

View File

@ -284,6 +284,9 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs {
/** set deactivated receiver padding enable */
int set_deactivated_receiver_padding_enable();
/** set quad type */
int set_quad_type();
/** detector type */
detectorType myDetectorType;

View File

@ -71,6 +71,7 @@ enum recFuncs{
F_RECEIVER_DISCARD_POLICY, /** < frames discard policy */
F_RECEIVER_PADDING_ENABLE, /** < partial frames padding enable */
F_RECEIVER_DEACTIVATED_PADDING_ENABLE, /** < deactivated receiver padding enable */
F_RECEIVER_QUAD,
/* Always append functions hereafter!!! */

View File

@ -114,9 +114,7 @@ int BinaryFile::WriteToFile(char* buffer, int buffersize, uint64_t fnum, uint32_
}
int BinaryFile::CreateMasterFile(bool en, uint32_t size,
uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t sp,
uint64_t ap) {
int BinaryFile::CreateMasterFile(masterAttributes& attr) {
//beginning of every acquisition
numFramesInFile = 0;
numActualPacketsInFile = 0;
@ -127,10 +125,9 @@ int BinaryFile::CreateMasterFile(bool en, uint32_t size,
if(!(*silentMode)) {
FILE_LOG(logINFO) << "Master File: " << masterFileName;
}
attr.version = BINARY_WRITER_VERSION;
return BinaryFileStatic::CreateMasterDataFile(masterfd, masterFileName,
*overWriteEnable,
*dynamicRange, en, size, nx, ny, *numImages, *maxFramesPerFile,
at, st, sp, ap, BINARY_WRITER_VERSION);
*overWriteEnable, attr);
}
return OK;
}

View File

@ -26,7 +26,7 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo*& f,
fileFormat* ftype, bool fwenable,
bool* dsEnable, bool* gpEnable, uint32_t* dr,
uint32_t* freq, uint32_t* timer,
bool* fp, bool* act, bool* depaden, bool* sm,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
void (*dataReadycb)(char*, char*, uint32_t, void*),
void (*dataModifyReadycb)(char*, char*, uint32_t &, void*),
void *pDataReadycb) :
@ -49,6 +49,7 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo*& f,
activated(act),
deactivatedPaddingEnable(depaden),
silentMode(sm),
quadEnable(qe),
framePadding(fp),
acquisitionStartedFlag(false),
measurementStartedFlag(false),
@ -248,14 +249,11 @@ void DataProcessor::SetupFileWriter(bool fwe, int* nd, uint32_t* maxf,
}
// only the first file
int DataProcessor::CreateNewFile(bool en, uint64_t nf, uint64_t at, uint64_t st,
uint64_t sp, uint64_t ap) {
int DataProcessor::CreateNewFile(masterAttributes& attr) {
if (file == NULL)
return FAIL;
file->CloseAllFiles();
if (file->CreateMasterFile(en, generalData->imageSize,
generalData->nPixelsX, generalData->nPixelsY,
at, st, sp, ap) == FAIL)
if (file->CreateMasterFile(attr) == FAIL)
return FAIL;
if (file->CreateFile(currentFrameIndex) == FAIL)
return FAIL;
@ -511,31 +509,34 @@ void DataProcessor::InsertGapPixels(char* buf, uint32_t dr) {
memset(tempBuffer, 0xFF, generalData->imageSize);
int rightChip = ((*quadEnable) ? 0 : index); // quad enable, then faking both to be left chips
const uint32_t nx = generalData->nPixelsX;
const uint32_t ny = generalData->nPixelsY;
const uint32_t npx = nx * ny;
bool group3 = (*quadEnable) ? false : true; // if quad enabled, no last line for left chips
char* srcptr = 0;
char* dstptr = 0;
const uint32_t b1px = generalData->imageSize / (npx); // not double as not dealing with 4 bit mode
const uint32_t b2px = 2 * b1px;
const uint32_t b1pxofst = (index ? b1px : 0); // left fpga (index 0) has no extra 1px offset, but right fpga has
const uint32_t b1pxofst = (rightChip ? b1px : 0); // left fpga (chipIndex 0) has no extra 1px offset, but right fpga has
const uint32_t b1chip = 256 * b1px;
const uint32_t b1line = (nx * b1px);
const uint32_t bgroup3chip = b1chip + (group3 ? b1px : 0);
// copying line by line
srcptr = buf;
dstptr = tempBuffer + b1line + b1pxofst; // left fpga (index 0) has no extra 1px offset, but right fpga has
dstptr = tempBuffer + b1line + b1pxofst; // left fpga (chipIndex 0) has no extra 1px offset, but right fpga has
for (uint32_t i = 0; i < (ny-1); ++i) {
memcpy(dstptr, srcptr, b1chip);
srcptr += b1chip;
dstptr += (b1chip + b2px);
memcpy(dstptr, srcptr, b1chip);
srcptr += b1chip;
dstptr += (b1chip + b1px);
dstptr += bgroup3chip;
}
// vertical filling of values
{
char* srcgp1 = 0; char* srcgp2 = 0; char* srcgp3 = 0;
@ -550,28 +551,36 @@ void DataProcessor::InsertGapPixels(char* buf, uint32_t dr) {
dstgp1 = srcgp1 + b1px;
srcgp2 = srcgp1 + b3px;
dstgp2 = dstgp1 + b1px;
if (!index) {
srcgp3 = srcptr + b1line - b2px;
dstgp3 = srcgp3 + b1px;
} else {
srcgp3 = srcptr + b1px;
dstgp3 = srcptr;
if (group3) {
if (!rightChip) {
srcgp3 = srcptr + b1line - b2px;
dstgp3 = srcgp3 + b1px;
} else {
srcgp3 = srcptr + b1px;
dstgp3 = srcptr;
}
}
switch (dr) {
case 8:
(*((uint8_t*)srcgp1)) = (*((uint8_t*)srcgp1))/2; (*((uint8_t*)dstgp1)) = (*((uint8_t*)srcgp1));
(*((uint8_t*)srcgp2)) = (*((uint8_t*)srcgp2))/2; (*((uint8_t*)dstgp2)) = (*((uint8_t*)srcgp2));
(*((uint8_t*)srcgp3)) = (*((uint8_t*)srcgp3))/2; (*((uint8_t*)dstgp3)) = (*((uint8_t*)srcgp3));
if (group3) {
(*((uint8_t*)srcgp3)) = (*((uint8_t*)srcgp3))/2; (*((uint8_t*)dstgp3)) = (*((uint8_t*)srcgp3));
}
break;
case 16:
(*((uint16_t*)srcgp1)) = (*((uint16_t*)srcgp1))/2; (*((uint16_t*)dstgp1)) = (*((uint16_t*)srcgp1));
(*((uint16_t*)srcgp2)) = (*((uint16_t*)srcgp2))/2; (*((uint16_t*)dstgp2)) = (*((uint16_t*)srcgp2));
(*((uint16_t*)srcgp3)) = (*((uint16_t*)srcgp3))/2; (*((uint16_t*)dstgp3)) = (*((uint16_t*)srcgp3));
if (group3) {
(*((uint16_t*)srcgp3)) = (*((uint16_t*)srcgp3))/2; (*((uint16_t*)dstgp3)) = (*((uint16_t*)srcgp3));
}
break;
default:
(*((uint32_t*)srcgp1)) = (*((uint32_t*)srcgp1))/2; (*((uint32_t*)dstgp1)) = (*((uint32_t*)srcgp1));
(*((uint32_t*)srcgp2)) = (*((uint32_t*)srcgp2))/2; (*((uint32_t*)dstgp2)) = (*((uint32_t*)srcgp2));
(*((uint32_t*)srcgp3)) = (*((uint32_t*)srcgp3))/2; (*((uint32_t*)dstgp3)) = (*((uint32_t*)srcgp3));
if (group3) {
(*((uint32_t*)srcgp3)) = (*((uint32_t*)srcgp3))/2; (*((uint32_t*)dstgp3)) = (*((uint32_t*)srcgp3));
}
break;
}
srcptr += b1line;

View File

@ -16,7 +16,7 @@ const std::string DataStreamer::TypeName = "DataStreamer";
DataStreamer::DataStreamer(int ind, Fifo*& f, uint32_t* dr, std::vector<ROI>* r,
uint64_t* fi, int* fd, char* ajh, bool* sm) :
uint64_t* fi, int fd, char* ajh, bool* sm, int* nd, bool* gpEnable, bool* qe) :
ThreadObject(ind),
runningFlag(0),
generalData(0),
@ -26,14 +26,19 @@ DataStreamer::DataStreamer(int ind, Fifo*& f, uint32_t* dr, std::vector<ROI>* r,
roi(r),
adcConfigured(-1),
fileIndex(fi),
flippedData(fd),
flippedDataX(fd),
additionJsonHeader(ajh),
acquisitionStartedFlag(false),
measurementStartedFlag(false),
firstAcquisitionIndex(0),
firstMeasurementIndex(0),
completeBuffer(0)
completeBuffer(0),
gapPixelsEnable(gpEnable),
quadEnable(qe)
{
numDet[0] = nd[0];
numDet[1] = nd[1];
if(ThreadObject::CreateThread() == FAIL)
throw std::exception();
@ -130,6 +135,15 @@ int DataStreamer::SetThreadPriority(int priority) {
return OK;
}
void DataStreamer::SetNumberofDetectors(int* nd) {
numDet[0] = nd[0];
numDet[1] = nd[1];
}
void DataStreamer::SetFlippedDataX(int fd) {
flippedDataX = fd;
}
void DataStreamer::CreateZmqSockets(int* nunits, uint32_t port, const char* srcip) {
uint32_t portnum = port + index;
@ -235,7 +249,6 @@ void DataStreamer::ProcessAnImage(char* buf) {
//normal
else {
if (!SendHeader(header, (uint32_t)(*((uint32_t*)buf)),
generalData->nPixelsX, generalData->nPixelsY, false)) // new size possibly from callback
cprintf(RED,"Error: Could not send zmq header for fnum %lld and streamer %d\n",
@ -261,13 +274,13 @@ int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32
uint64_t acquisitionIndex = header.frameNumber - firstAcquisitionIndex;
return zmqSocket->SendHeaderData(index, dummy, SLS_DETECTOR_JSON_HEADER_VERSION, *dynamicRange, *fileIndex,
nx, ny, size,
numDet[0], numDet[1], nx, ny, size,
acquisitionIndex, frameIndex, fileNametoStream,
header.frameNumber, header.expLength, header.packetNumber, header.bunchId, header.timestamp,
header.modId, header.row, header.column, header.reserved,
header.debug, header.roundRNumber,
header.detType, header.version,
flippedData,
*gapPixelsEnable ? 1 : 0, flippedDataX, *quadEnable,
additionJsonHeader
);
}

View File

@ -243,9 +243,7 @@ int HDF5File::WriteToFile(char* buffer, int buffersize, uint64_t fnum, uint32_t
}
int HDF5File::CreateMasterFile(bool en, uint32_t size,
uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t sp,
uint64_t ap) {
int HDF5File::CreateMasterFile(masterAttributes& attr) {
//beginning of every acquisition
numFramesInFile = 0;
@ -260,11 +258,9 @@ int HDF5File::CreateMasterFile(bool en, uint32_t size,
FILE_LOG(logINFO) << "Master File: " << masterFileName;
}
pthread_mutex_lock(&Mutex);
attr.version = HDF5_WRITER_VERSION;
int ret = HDF5FileStatic::CreateMasterDataFile(masterfd, masterFileName,
*overWriteEnable,
*dynamicRange, en, size, nx, ny, *numImages, *maxFramesPerFile,
at, st, sp, ap,
HDF5_WRITER_VERSION);
*overWriteEnable, attr);
pthread_mutex_unlock(&Mutex);
return ret;
}

View File

@ -50,9 +50,9 @@ void UDPBaseImplementation::initializeMembers(){
dynamicRange = 16;
tengigaEnable = false;
fifoDepth = 0;
flippedData[0] = 0;
flippedData[1] = 0;
flippedDataX = 0;
gapPixelsEnable = false;
quadEnable = false;
//***receiver parameters***
status = IDLE;
@ -128,8 +128,14 @@ char *UDPBaseImplementation::getDetectorHostname() const{
int UDPBaseImplementation::getFlippedData(int axis) const{
FILE_LOG(logDEBUG) << __AT__ << " starting";
if(axis<0 || axis > 1) return -1;
return flippedData[axis];
switch(axis) {
case 0:
return flippedDataX;
case 1:
return 0;
default:
return -1;
}
}
bool UDPBaseImplementation::getGapPixelsEnable() const {
@ -137,6 +143,11 @@ bool UDPBaseImplementation::getGapPixelsEnable() const {
return gapPixelsEnable;
}
bool UDPBaseImplementation::getQuad() const {
FILE_LOG(logDEBUG) << __AT__ << " starting";
return quadEnable;
}
/***file parameters***/
slsReceiverDefs::fileFormat UDPBaseImplementation::getFileFormat() const{
FILE_LOG(logDEBUG) << __AT__ << " starting";
@ -392,13 +403,18 @@ void UDPBaseImplementation::setMultiDetectorSize(const int* size) {
}
strcat(message,")");
FILE_LOG(logINFO) << message;
// overridden
}
void UDPBaseImplementation::setFlippedData(int axis, int enable){
FILE_LOG(logDEBUG) << __AT__ << " starting";
if(axis<0 || axis>1) return;
flippedData[axis] = enable==0?0:1;
FILE_LOG(logINFO) << "Flipped Data: " << flippedData[0] << " , " << flippedData[1];
if (axis != 0)
return;
flippedDataX = enable==0?0:1;
FILE_LOG(logINFO) << "Flipped Data X: " << flippedDataX;
// overridden
}
int UDPBaseImplementation::setGapPixelsEnable(const bool b) {
@ -410,6 +426,15 @@ int UDPBaseImplementation::setGapPixelsEnable(const bool b) {
return OK;
}
int UDPBaseImplementation::setQuad(const bool b) {
FILE_LOG(logDEBUG) << __AT__ << " starting";
quadEnable = b;
FILE_LOG(logINFO) << "Quad Enable: " << quadEnable;
// overridden
return OK;
}
/***file parameters***/
void UDPBaseImplementation::setFileFormat(const fileFormat f){
FILE_LOG(logDEBUG) << __AT__ << " starting";

View File

@ -111,13 +111,60 @@ int64_t UDPStandardImplementation::getAcquisitionIndex() const {
}
void UDPStandardImplementation::setMultiDetectorSize(const int* size) {
char message[100];
strcpy(message, "Detector Size: (");
for (int i = 0; i < MAX_DIMENSIONS; ++i) {
if (myDetectorType == EIGER && (!i))
numDet[i] = size[i]*2;
else
numDet[i] = size[i];
sprintf(message,"%s%d",message,numDet[i]);
if (i < MAX_DIMENSIONS-1 )
strcat(message,",");
}
strcat(message,")");
int nd[2] = {numDet[0], numDet[1]};
if (quadEnable) {
nd[0] = 1;
nd[1] = 2;
}
for (std::vector<DataStreamer*>::const_iterator it = dataStreamer.begin(); it != dataStreamer.end(); ++it){
(*it)->SetNumberofDetectors(nd);
}
FILE_LOG(logINFO) << message;
}
void UDPStandardImplementation::setFlippedData(int axis, int enable){
if (axis != 0)
return;
flippedDataX = enable == 0 ? 0 : 1;
if (!quadEnable) {
for (std::vector<DataStreamer*>::const_iterator it = dataStreamer.begin(); it != dataStreamer.end(); ++it){
(*it)->SetFlippedDataX(flippedDataX);
}
}
else {
if (dataStreamer.size() == 2) {
dataStreamer[0]->SetFlippedDataX(0);
dataStreamer[1]->SetFlippedDataX(1);
}
}
FILE_LOG(logINFO) << "Flipped Data X: " << flippedDataX;
}
int UDPStandardImplementation::setGapPixelsEnable(const bool b) {
if (gapPixelsEnable != b) {
gapPixelsEnable = b;
// side effects
generalData->SetGapPixelsEnable(b, dynamicRange);
generalData->SetGapPixelsEnable(b, dynamicRange, quadEnable);
// to update npixelsx, npixelsy in file writer
for (std::vector<DataProcessor*>::const_iterator it = dataProcessor.begin(); it != dataProcessor.end(); ++it)
(*it)->SetPixelDimension();
@ -130,6 +177,38 @@ int UDPStandardImplementation::setGapPixelsEnable(const bool b) {
return OK;
}
int UDPStandardImplementation::setQuad(const bool b) {
if (quadEnable != b) {
quadEnable = b;
generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, b);
// to update npixelsx, npixelsy in file writer
for (std::vector<DataProcessor*>::const_iterator it = dataProcessor.begin(); it != dataProcessor.end(); ++it)
(*it)->SetPixelDimension();
numberofJobs = -1; //changes to imagesize has to be noted to recreate fifo structure
if (SetupFifoStructure() == FAIL)
return FAIL;
if (!quadEnable) {
for (std::vector<DataStreamer*>::const_iterator it = dataStreamer.begin(); it != dataStreamer.end(); ++it){
(*it)->SetNumberofDetectors(numDet);
(*it)->SetFlippedDataX(flippedDataX);
}
} else {
int size[2] = {1, 2};
for (std::vector<DataStreamer*>::const_iterator it = dataStreamer.begin(); it != dataStreamer.end(); ++it){
(*it)->SetNumberofDetectors(size);
}
if (dataStreamer.size() == 2) {
dataStreamer[0]->SetFlippedDataX(0);
dataStreamer[1]->SetFlippedDataX(1);
}
}
}
FILE_LOG(logINFO) << "Quad Enable: " << quadEnable;
return OK;
}
void UDPStandardImplementation::setFileFormat(const fileFormat f){
switch(f){
@ -251,8 +330,15 @@ int UDPStandardImplementation::setDataStreamEnable(const bool enable) {
if (enable) {
for ( int i = 0; i < numThreads; ++i ) {
try {
int fd = flippedDataX;
int nd[2] = {numDet[0], numDet[1]};
if (quadEnable) {
fd = i;
nd[0] = 1;
nd[1] = 2;
}
DataStreamer* s = new DataStreamer(i, fifo[i], &dynamicRange,
&roi, &fileIndex, flippedData, additionalJsonHeader, &silentMode);
&roi, &fileIndex, fd, additionalJsonHeader, &silentMode, (int*)nd, &gapPixelsEnable, &quadEnable);
dataStreamer.push_back(s);
dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets(&numThreads, streamingPort, streamingSrcIP);
@ -295,7 +381,7 @@ int UDPStandardImplementation::setDynamicRange(const uint32_t i) {
//side effects
generalData->SetDynamicRange(i,tengigaEnable);
generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange);
generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable);
// to update npixelsx, npixelsy in file writer
for (std::vector<DataProcessor*>::const_iterator it = dataProcessor.begin(); it != dataProcessor.end(); ++it)
(*it)->SetPixelDimension();
@ -314,6 +400,7 @@ int UDPStandardImplementation::setTenGigaEnable(const bool b) {
tengigaEnable = b;
//side effects
generalData->SetTenGigaEnable(b,dynamicRange);
generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable);
numberofJobs = -1; //changes to imagesize has to be noted to recreate fifo structure
if (SetupFifoStructure() == FAIL)
@ -396,7 +483,7 @@ int UDPStandardImplementation::setDetectorType(const detectorType d) {
DataProcessor* p = new DataProcessor(i, myDetectorType, fifo[i], &fileFormatType,
fileWriteEnable, &dataStreamEnable, &gapPixelsEnable,
&dynamicRange, &frameToGuiFrequency, &frameToGuiTimerinMS,
&framePadding, &activated, &deactivatedPaddingEnable, &silentMode,
&framePadding, &activated, &deactivatedPaddingEnable, &silentMode, &quadEnable,
rawDataReadyCallBack, rawDataModifyReadyCallBack, pRawDataReady);
dataProcessor.push_back(p);
}
@ -789,9 +876,23 @@ int UDPStandardImplementation::CreateUDPSockets() {
int UDPStandardImplementation::SetupWriter() {
bool error = false;
masterAttributes attr;
attr.detectorType = myDetectorType;
attr.dynamicRange = dynamicRange;
attr.tenGiga = tengigaEnable;
attr.imageSize = generalData->imageSize;
attr.nPixelsX = generalData->nPixelsX;
attr.nPixelsY = generalData->nPixelsY;
attr.maxFramesPerFile = framesPerFile;
attr.totalFrames = numberOfFrames;
attr.exptimeNs = acquisitionTime;
attr.subExptimeNs = subExpTime;
attr.subPeriodNs = subPeriod;
attr.periodNs = acquisitionPeriod;
attr.gapPixelsEnable = gapPixelsEnable;
attr.quadEnable = quadEnable;
for (unsigned int i = 0; i < dataProcessor.size(); ++i)
if (dataProcessor[i]->CreateNewFile(tengigaEnable,
numberOfFrames, acquisitionTime, subExpTime, subPeriod, acquisitionPeriod) == FAIL) {
if (dataProcessor[i]->CreateNewFile(attr) == FAIL) {
error = true;
break;
}

View File

@ -246,6 +246,7 @@ const char* slsReceiverTCPIPInterface::getFunctionName(enum recFuncs func) {
case F_RECEIVER_DISCARD_POLICY: return "F_RECEIVER_DISCARD_POLICY";
case F_RECEIVER_PADDING_ENABLE: return "F_RECEIVER_PADDING_ENABLE";
case F_RECEIVER_DEACTIVATED_PADDING_ENABLE: return "F_RECEIVER_DEACTIVATED_PADDING_ENABLE";
case F_RECEIVER_QUAD: return "F_RECEIVER_QUAD";
default: return "Unknown Function";
}
@ -303,7 +304,7 @@ int slsReceiverTCPIPInterface::function_table(){
flist[F_RECEIVER_DISCARD_POLICY] = &slsReceiverTCPIPInterface::set_discard_policy;
flist[F_RECEIVER_PADDING_ENABLE] = &slsReceiverTCPIPInterface::set_padding_enable;
flist[F_RECEIVER_DEACTIVATED_PADDING_ENABLE] = &slsReceiverTCPIPInterface::set_deactivated_receiver_padding_enable;
flist[F_RECEIVER_QUAD] = &slsReceiverTCPIPInterface::set_quad_type;
#ifdef VERYVERBOSE
for (int i = 0; i < NUM_REC_FUNCTIONS ; i++) {
@ -2982,3 +2983,57 @@ int slsReceiverTCPIPInterface::set_deactivated_receiver_padding_enable() {
// return ok/fail
return ret;
}
int slsReceiverTCPIPInterface::set_quad_type() {
ret = OK;
memset(mess, 0, sizeof(mess));
int value = -1;
int retval = -1;
// receive arguments
if (mySock->ReceiveDataOnly(&value,sizeof(value)) < 0 )
return printSocketReadError();
// execute action
#ifdef SLS_RECEIVER_UDP_FUNCTIONS
if (receiverBase == NULL)
invalidReceiverObject();
else {
// set
if(value >= 0) {
if (mySock->differentClients && lockStatus)
receiverlocked();
else if (receiverBase->getStatus() != IDLE)
receiverNotIdle();
else {
ret = receiverBase->setQuad(value);
if (ret == FAIL) {
strcpy(mess, "Could not set Quad due to fifo structure.\n");
FILE_LOG(logERROR) << mess;
}
}
}
//get
retval = (int)receiverBase->getQuad(); // no check required
}
#endif
#ifdef VERYVERBOSE
FILE_LOG(logINFO) << "Quad mode:" << retval;
#endif
if (ret == OK && mySock->differentClients)
ret = FORCE_UPDATE;
// send answer
mySock->SendDataOnly(&ret,sizeof(ret));
if (ret == FAIL)
mySock->SendDataOnly(mess,sizeof(mess));
mySock->SendDataOnly(&retval,sizeof(retval));
// return ok/fail
return ret;
}