Compare commits

...

47 Commits

Author SHA1 Message Date
cfbe3c86cc 7.0.3.rc2 (#866) (#867)
*7.0.3.rc2
* moench: handling bug in post processing from receiver when partial_frames policy and empty frame happens, only json header without data is sent
2023-11-14 11:32:33 +01:00
4b414bfddb release notes 2023-11-12 15:39:58 +01:00
5ab64efe3e added python 3.12 to the conda build variants 2023-11-10 14:18:38 +01:00
bfe53c6693 udpated release notes 2023-11-09 15:10:17 +01:00
c64e87a2b6 7.0.3.rc: fix server logic in checking detector idle (#859)
* fix buggy logic in checking detector idle and an argument check
2023-11-09 14:21:11 +01:00
14e11e8b5b formatting and versioning 2023-11-08 11:43:09 +01:00
af3dc1e7f4 7.0.3.rc: execute command inside server fixed (from fix simulator tests and exec command PR) (#855)
* execute command inside server fixed (from fix simulator tests and exec command PR)
2023-11-08 09:25:52 +01:00
8174fc9691 Update RELEASE.txt 2023-11-07 12:34:10 +01:00
d6eac6da71 updated release notes 2023-11-07 11:22:09 +01:00
9b9b09ceaf 703rc/tests/fix execute command (#842)
* fix execute command
* fix for tests for ctb
2023-11-07 09:29:48 +01:00
4613c54f57 handling inconsistent fnums to be -1 in gui, so when one sets 0 (change of value) will also give an exception (#852) 2023-11-06 16:11:25 +01:00
58ac7ac280 7.0.3.rc: gui acq finished callback for different status (#847)
* fix acquisition finished status to have different status for different modules, but does not have to be error. for eg. jf sync fw (2.4.1 gives idle for master and stopped for slaves when stopping acquiistion)
2023-11-06 16:07:38 +01:00
82edfa75d3 7.0.3.rc: process the raw data files as a list (#848)
* Added file list option for moenchRawDataProcess
2023-11-03 12:10:20 +01:00
b6ef3bc39e updated release notest 2023-10-25 09:15:10 +02:00
2035666792 versioning and binaries updated 2023-10-25 08:43:23 +02:00
1ff4d806e7 minor 2023-10-25 08:25:02 +02:00
3861379653 updated release notes 2023-10-24 17:39:47 +02:00
91140bbb71 formatting 2023-10-24 11:17:18 +02:00
d44329117d fix warning for prev_val (variable size array) in tests (#836) 2023-10-23 15:52:59 +02:00
6c67025ea8 7.0.3.rc eiger: fw version to 32 (quad blocking trigger) (#832)
* eiger required fw version to 32: fix for blocking trigger in quad
2023-10-18 16:51:17 +02:00
37ce3d6f59 7.0.3.rc: jf sync: stopping master gives idle (#822)
* jf sync mode master could return idle when stopped and so not all modules return the same value and must check for 'stopped or idle', Also must throw if any of the module gives an error ( not jungfrau, but eiger could)

* added contains_only to sls::Result (#827)

* added variadic template for checking if a result contains only specified values

* fix for gcc4.8

* renamed to Result::contains_only

* stop on only the positions

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@gmail.com>
2023-10-13 12:27:43 +02:00
1484d038de 7.03.rc: update 2d gain plot color map (if no x and ymin/max changes or window resizing): setFixedWidth was updating for window resize, updated virtual servers for g2 and jungfrau to keep changing gain and data for every frame. the data value (#818) 2023-10-03 17:22:03 +02:00
fb0090c79e removing the misleading word 'Simulating' when programmig fpga (#814) 2023-09-28 16:20:59 +02:00
adc68cd519 formatting 2023-09-28 15:51:40 +02:00
1566eef247 703rc/fix numeric limits (#812)
* fixed compilation for fedora for numeric_limits

* formatting
2023-09-28 10:49:02 +02:00
e7cd90db78 fixed crashing of moench03RawDataProcess when nframes>0 (#810) 2023-09-27 09:22:40 +02:00
45414149fe binaries in for the previous PR 2023-09-22 15:59:35 +02:00
48759f440e 703rc/fix port size (#802)
* validate port numbers in client

* validate port numbers created at virtual servers and receiver process as tcp ports
2023-09-18 08:59:53 +02:00
b367b7e431 fixed some interpolation issues (#796) 2023-08-28 13:38:19 +02:00
f0b2a6f6f9 update release notes 2023-08-25 14:02:50 +02:00
f761046bfc updated docs and versions 2023-07-12 16:50:13 +02:00
1a859b83db formatting 2023-07-12 16:06:31 +02:00
70bfc875a6 updating release notes 2023-07-11 17:02:27 +02:00
c0755308a4 updating release notes 2023-07-11 17:01:14 +02:00
ab5509e10c updating release notes 2023-07-11 17:00:42 +02:00
004cb26646 updated firmware versions for 7.0.2 2023-07-10 12:21:19 +02:00
a4f47a5945 synced master status running when setting to slave (#747)
* jf: unsync before setting master/slave and then sync (if it was set) to overcome master going into running state when making it a slave and synced

* add tests for this condition

* updated release notes, updated min fw version requirement for v1.0 boards
2023-05-25 11:04:05 +02:00
312f3f473d fix that only master starts second and not all (for start acq), typo with pos and masters list (#743) 2023-05-11 10:20:17 +02:00
5871086cd6 formatting 2023-05-08 17:04:04 +02:00
6a0fe823b3 enable fix g0 when in expert mode (when gain mode enabled and not just visible) (#736) 2023-05-08 14:20:21 +02:00
5912aae53e Rx roi zmq (#726)
adding rx_roi also in the zmq header for external guis to put the "yellow box".. sending full roi instead of -1, and sending for each zmq port. "(multiple yellow boxes)".
2023-05-08 12:23:05 +02:00
8833ccf5cc 7.0.2.rc (#721)
* row and column for jungfrau mixed up

* multi module jungfrau sync must do slaves first then master for start acquisition and send software trigger, and master first and then slaves for stopacquisition

* non blocking to slaves first and only then blocking/nonblocking to the master for sending software trigger(jungfrau multi mod sync)

* fixed get/set timing jungfrau when sync enabled, getsync during blocking acquire (for trigger or stop) will get stuck as it should ask the stop server

* switching between 1 and 2 interfaces did not set gui/client zmq port properly. Resulted in dummy streaming forever. fixed

* formatting, refactoring: const & for positions, multi mod M3 stop first master first

* adding missing cstdint for gcc 13

* Refactoring handle sync out, handling synchronization also for softwaretrigger for m3, for start/sync/stop for g2/g1

---------

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
2023-05-08 12:11:19 +02:00
77c558a7be formatting 2023-03-24 12:54:55 +01:00
378fc301b8 updating client version, release version and project_version in CMakeLists.txt 2023-03-23 15:43:17 +01:00
87d6e16090 7.0.1 fix det server version (#702)
* check server version before initial checks, catch old server version exception, get old server version as 64 bit and print it along with exception
2023-03-23 15:37:01 +01:00
2ef021041c rx_arping sigchld (#701)
* rx_arping pclose gave -1 due to sigchld being ignored, fixed with sig handler doing a wait
2023-03-23 13:58:40 +01:00
574127b5ac fix hdf5 compilation using det spec fields in header (#700)
* fix hdf5 compilation using det spec fields in header
2023-03-23 12:30:38 +01:00
78 changed files with 889 additions and 1150 deletions

View File

@ -2,7 +2,7 @@
# Copyright (C) 2021 Contributors to the SLS Detector Package # Copyright (C) 2021 Contributors to the SLS Detector Package
cmake_minimum_required(VERSION 3.12) cmake_minimum_required(VERSION 3.12)
project(slsDetectorPackage) project(slsDetectorPackage)
set(PROJECT_VERSION 7.0.0) set(PROJECT_VERSION 7.0.3)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,5 @@ python:
- 3.9 - 3.9
- 3.10 - 3.10
- 3.11 - 3.11
- 3.12
numpy:
- 1.17

View File

@ -140,14 +140,21 @@ ZMQ: Json Header Format
"quad": unsigned int, "quad": unsigned int,
"addJsonHeader": { "addJsonHeader": {
string : string string : string
} },
"rx_roi": [
unsigned int,
unsigned int,
unsigned int,
unsigned int
]
} }
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
| Field | Description | | Field | Description |
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
| jsonversion | Version of the json header. | | jsonversion | Version of the json header. |
| | Value at 4 for v6.x.x and v7.x.x | | | Value at 4 for v6.x.x - v7.0.1 |
| | Value at 5 for v7.0.2 |
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
| bitmode | Bits per pixel [4|8|16|32] | | bitmode | Bits per pixel [4|8|16|32] |
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
@ -222,7 +229,10 @@ ZMQ: Json Header Format
| addJsonHeader| Optional custom parameters that is required | | addJsonHeader| Optional custom parameters that is required |
| | for processing code. | | | for processing code. |
+--------------+----------------------------------------------+ +--------------+----------------------------------------------+
| rx_roi | ROI in the receiver per port (xmin, xmax, |
| | ymin, ymax). For external guis to know |
| | what is saved |
+--------------+----------------------------------------------+
SLS Receiver Header Format SLS Receiver Header Format
-------------------------- --------------------------

View File

@ -3,33 +3,34 @@
### edit with hostname or IP address of your detector ### edit with hostname or IP address of your detector
############################################ ############################################
#hostname bchip181+ #hostname bchip181+
hostname bchip135 hostname bchip076
############################################# #############################################
### edit with hostname or 1Gbs IP address of your server ### edit with hostname or 1Gbs IP address of your server
############################################ ############################################
rx_hostname mpc2011 rx_hostname mpc2011:7777
############################################# #############################################
### edit with 10 Gbs IP of your server ### edit with 10 Gbs IP of your server
############################################ ############################################
udp_dstip 10.1.1.102 udp_dstip 10.1.2.102
############################################# #############################################
### edit with any number in the subnet of your server (first 3 numbers as above) ### edit with any number in the subnet of your server (first 3 numbers as above)
############################################ ############################################
udp_srcip 10.1.1.19 udp_srcip 10.1.2.19
udp_dstport 32411 udp_dstport 32777
############################################# #############################################
### edit with 10 Gbs IP of your server ### edit with 10 Gbs IP of your server
############################################ ############################################
rx_zmqip 10.1.1.102 rx_zmqip 10.1.2.102
rx_zmqport 50003 rx_zmqport 9003
############################################# #############################################
### edit with 1 Gbs IP of PC where you will run the GUI ### edit with 1 Gbs IP of PC where you will run the GUI
############################################ ############################################
zmqip 129.129.202.57 zmqip 129.129.202.57
zmqport 50001 zmqport 9005
@ -38,7 +39,7 @@ rx_zmqstream 1
frames 100000 frames 1
period 0.0006 period 0.0006
exptime 0.00035 exptime 0.00035
@ -49,7 +50,7 @@ fpath /mnt/moench_data/scratch1/
fwrite 0 fwrite 0
rx_jsonpara frameMode frame rx_jsonpara frameMode newPedestal
rx_jsonpara detectorMode counting rx_jsonpara detectorMode counting
rx_discardpolicy discardpartial rx_discardpolicy discardpartial

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -42,7 +42,7 @@ class moench03T1ReceiverDataNew : public slsDetectorData<uint16_t> {
int sc_width; int sc_width;
int sc_height; int sc_height;
const int nSamples; const int nSamples;
int headerSize;
double ghost[200][25]; double ghost[200][25];
// Single point of definition if we need to customize // Single point of definition if we need to customize
@ -62,7 +62,7 @@ class moench03T1ReceiverDataNew : public slsDetectorData<uint16_t> {
moench03T1ReceiverDataNew(int ns = 5000) moench03T1ReceiverDataNew(int ns = 5000)
: slsDetectorData<uint16_t>(400, 400, ns * 2 * 32 + sizeof(header)), : slsDetectorData<uint16_t>(400, 400, ns * 2 * 32 + sizeof(header)),
nSamples(ns) { nSamples(ns) {
headerSize=112;
int nadc = 32; int nadc = 32;
int sc_width = 25; int sc_width = 25;
int sc_height = 200; int sc_height = 200;
@ -250,13 +250,22 @@ class moench03T1ReceiverDataNew : public slsDetectorData<uint16_t> {
virtual char *readNextFrame(std::ifstream &filebin, int &ff, int &np, virtual char *readNextFrame(std::ifstream &filebin, int &ff, int &np,
char *data) { char *data) {
np = 0; np = 0;
if (filebin.is_open()) { if (filebin.is_open()) {
if (filebin.read(data, dataSize)) {
ff = getFrameNumber(data); if (filebin.read(data, headerSize)) {
np = getPacketNumber(data); ff = getFrameNumber(data);
return data; np = getPacketNumber(data);
} if (np>0)
} filebin.read(data+headerSize, dataSize-headerSize);
return data;
}
/* if (filebin.read(data, dataSize)) { */
/* ff = getFrameNumber(data); */
/* np = getPacketNumber(data); */
/* return data; */
/* } */
}
return nullptr; return nullptr;
} }

View File

@ -13,22 +13,7 @@ class etaInterpolationGlobal : public etaInterpolationBase {
virtual void prepareInterpolation(int &ok) { virtual void prepareInterpolation(int &ok) {
ok = 1; ok = 1;
#ifdef MYROOT1
if (hhx)
delete hhx;
if (hhy)
delete hhy;
hhx = new TH2D("hhx", "hhx", heta->GetNbinsX(),
heta->GetXaxis()->GetXmin(), heta->GetXaxis()->GetXmax(),
heta->GetNbinsY(), heta->GetYaxis()->GetXmin(),
heta->GetYaxis()->GetXmax());
hhy = new TH2D("hhy", "hhy", heta->GetNbinsX(),
heta->GetXaxis()->GetXmin(), heta->GetXaxis()->GetXmax(),
heta->GetNbinsY(), heta->GetYaxis()->GetXmin(),
heta->GetYaxis()->GetXmax());
#endif
///*Eta Distribution Rebinning*/// ///*Eta Distribution Rebinning*///
double bsize = 1. / nSubPixels; // precision double bsize = 1. / nSubPixels; // precision

View File

@ -357,6 +357,16 @@ class slsInterpolation {
} }
} }
/* cout << "(((" << totquad << "\t" << corner << endl; */
/* for (int iy=0; iy<3; iy++) { */
/* for (int ix=0; ix<3; ix++) */
/* cout << cl[ix+iy*3] <<"\t"; */
/* cout << endl; */
/* } */
/* cout << ")))" << endl; */
return corner; return corner;
} }
@ -370,6 +380,10 @@ class slsInterpolation {
etax = r / totquad; etax = r / totquad;
etay = t / totquad; etay = t / totquad;
} }
/* cout << "************" << endl; */
/* cout << sDum[0][0]<< "\t"<<sDum[0][1] << endl << sDum[1][0]<< "\t"<<sDum[1][1] << endl; */
/* cout << "***************" <<endl; */
/* cout << etax << " " << etay << endl; */
return 0; return 0;
} }

View File

@ -33,7 +33,7 @@ int main(int argc, char *argv[]) {
#ifndef FF #ifndef FF
if (argc < 9) { if (argc < 9) {
cout << "Wrong usage! Should be: " << argv[0] cout << "Wrong usage! Should be: " << argv[0]
<< " infile etafile outfile runmin runmax ns cmin cmax" << endl; << " infile etafile outfile runmin runmax ns [cmin cmax xmin xmax ymin ymax]" << endl;
return 1; return 1;
} }
#endif #endif
@ -41,7 +41,7 @@ int main(int argc, char *argv[]) {
#ifdef FF #ifdef FF
if (argc < 7) { if (argc < 7) {
cout << "Wrong usage! Should be: " << argv[0] cout << "Wrong usage! Should be: " << argv[0]
<< " infile etafile runmin runmax cmin cmax" << endl; << " infile etafile runmin runmax [cmin cmax xmin xmax ymin ymax]" << endl;
return 1; return 1;
} }
#endif #endif
@ -65,13 +65,30 @@ int main(int argc, char *argv[]) {
nsubpix = atoi(argv[iarg++]); nsubpix = atoi(argv[iarg++]);
cout << "Subpix: " << nsubpix << endl; cout << "Subpix: " << nsubpix << endl;
#endif #endif
float cmin = atof(argv[iarg++]);
float cmax = atof(argv[iarg++]); float cmin = 0;
float cmax=1000000;
if (argc>iarg)
cmin=atof(argv[iarg++]);
if (argc>iarg)
cmax= atof(argv[iarg++]);
cout << "Energy min: " << cmin << endl; cout << "Energy min: " << cmin << endl;
cout << "Energy max: " << cmax << endl; cout << "Energy max: " << cmax << endl;
int xmin=0, xmax=NC, ymin=0, ymax=NR;
if (argc>iarg)
xmin=atof(argv[iarg++]);
if (argc>iarg)
xmax= atof(argv[iarg++]);
if (argc>iarg)
ymin=atof(argv[iarg++]);
if (argc>iarg)
ymax= atof(argv[iarg++]);
// int etabins=500; // int etabins=500;
int etabins = 1000; // nsubpix*2*100; int etabins = 1000; // nsubpix*2*100;
double etamin = -1, etamax = 2; double etamin = -0.25, etamax = 1.25;
// double etamin=-0.1, etamax=1.1; // double etamin=-0.1, etamax=1.1;
// double eta3min = -2, eta3max = 2; // double eta3min = -2, eta3max = 2;
double sum, totquad; double sum, totquad;
@ -80,7 +97,7 @@ int main(int argc, char *argv[]) {
// double eta3x, eta3y, int3_x, int3_y, noint_x, noint_y; // double eta3x, eta3y, int3_x, int3_y, noint_x, noint_y;
int ix, iy, isx, isy; int ix, iy, isx, isy;
int nframes = 0, lastframe = -1; int nframes = 0, lastframe = -1, iframe, nphFrame;
//double d_x, d_y, res = 5, xx, yy; //double d_x, d_y, res = 5, xx, yy;
int nph = 0, totph = 0; int nph = 0, totph = 0;
//badph = 0, //badph = 0,
@ -98,7 +115,7 @@ int main(int argc, char *argv[]) {
// int nSubPixels = nsubpix; // int nSubPixels = nsubpix;
#ifndef NOINTERPOLATION #ifndef NOINTERPOLATION
eta2InterpolationPosXY *interp = eta2InterpolationPosXY *interp =
new eta2InterpolationPosXY(NC, NR, nsubpix, etabins, etamin, etamax); new eta2InterpolationPosXY(NC, NR, nsubpix, nsubpix, etabins, etabins, etamin, etamax);
// eta2InterpolationCleverAdaptiveBins *interp=new // eta2InterpolationCleverAdaptiveBins *interp=new
// eta2InterpolationCleverAdaptiveBins(NC, NR, nsubpix, etabins, etamin, // eta2InterpolationCleverAdaptiveBins(NC, NR, nsubpix, etabins, etamin,
// etamax); // etamax);
@ -107,8 +124,8 @@ int main(int argc, char *argv[]) {
noInterpolation *interp = new noInterpolation(NC, NR, nsubpix); noInterpolation *interp = new noInterpolation(NC, NR, nsubpix);
#endif #endif
#ifndef FF
int quad; int quad;
#ifndef FF
#ifndef NOINTERPOLATION #ifndef NOINTERPOLATION
char fname[10000]; char fname[10000];
int ok; int ok;
@ -142,19 +159,26 @@ int main(int argc, char *argv[]) {
#endif #endif
int irun; int irun;
for (irun = runmin; irun < runmax; irun++) { for (irun = runmin; irun <= runmax; irun++) {
sprintf(infname, argv[1], irun); sprintf(infname, argv[1], irun);
#ifndef FF #ifndef FF
sprintf(outfname, argv[3], irun); sprintf(outfname, argv[3], irun);
#endif #endif
f = fopen(infname, "r"); f = fopen(infname, "r");
if (f) { if (f) {
cout << infname << endl; cout << infname << endl;
nframes = 0; nframes = 0;
//f0 = -1; //f0 = -1;
while (cl.read(f)) { //iff=0;
while (fread((void*)&iframe, 1, sizeof(int), f)) {
//n=0;
if (fread((void*)&nphFrame, 1, sizeof(int), f)) {
for (int iph=0; iph<nphFrame; iph++) {
//while (cl.read(f)) {
if (cl.read(f)) {
totph++; totph++;
if (lastframe != cl.iframe) { if (lastframe != cl.iframe) {
lastframe = cl.iframe; lastframe = cl.iframe;
@ -165,18 +189,28 @@ int main(int argc, char *argv[]) {
nframes++; nframes++;
} }
// quad=interp->calcQuad(cl.get_cluster(), sum, totquad, sDum); // quad=interp->calcQuad(cl.get_cluster(), sum, totquad, sDum);
#ifndef FF // #ifndef FF
// quad = interp->calcEta(cl.get_cluster(), etax, etay, sum,
// totquad, sDum);
// #endif
// #ifdef FF
quad = interp->calcEta(cl.get_cluster(), etax, etay, sum, quad = interp->calcEta(cl.get_cluster(), etax, etay, sum,
totquad, sDum); totquad, sDum);
#endif
#ifdef FF
interp->calcEta(cl.get_cluster(), etax, etay, sum, /* cl.print();
totquad, sDum); cout << "(" << etax <<","<< etay <<")"<< quad<< endl;
#endif */
//#endif
if (sum > cmin && totquad / sum > 0.8 && totquad / sum < 1.2 && if (totquad > cmin && cl.x >= xmin && cl.x <= xmax &&
sum < cmax) { cl.y >= ymin && cl.y <= ymax &&
nph++; totquad < cmax) {
// if (sum > cmin && totquad / sum > 0.8 && totquad / sum < 1.2 &&
// sum < cmax) {
nph++;
// if (sum>200 && sum<580) { // if (sum>200 && sum<580) {
// interp->getInterpolatedPosition(cl.x,cl.y, // interp->getInterpolatedPosition(cl.x,cl.y,
// totquad,quad,cl.get_cluster(),int_x, int_y); // totquad,quad,cl.get_cluster(),int_x, int_y);
@ -227,9 +261,12 @@ int main(int argc, char *argv[]) {
#ifdef FF #ifdef FF
interp->writeFlatField(outfname); interp->writeFlatField(outfname);
#endif #endif
}
} }
} }
} }
}
}
fclose(f); fclose(f);
#ifdef FF #ifdef FF

View File

@ -304,18 +304,38 @@ int main(int argc, char *argv[]) {
int ifile = 0; int ifile = 0;
mt->setFrameMode(eFrame); mt->setFrameMode(eFrame);
int filelist=0;
ifstream flist;
flist.open (fformat, std::ifstream::in);
if (flist.is_open()) {
runmin=0;
runmax=0;
while (flist.getline(ffname,10000)){
cout << ffname << endl;
runmax++;
}
runmax--;
flist.close();
cout << "Found " << runmax << " files " << endl;
flist.open (fformat, std::ifstream::in);
}
for (int irun = runmin; irun <= runmax; irun++) { for (int irun = runmin; irun <= runmax; irun++) {
cout << "DATA "; cout << "DATA ";
// sprintf(fn,fformat,irun); // sprintf(fn,fformat,irun);
sprintf(ffname, "%s/%s.raw", indir, fformat); if (flist.is_open()) {
sprintf(fname, (const char*)ffname, irun); flist.getline(ffname,10000);
sprintf(ffname, "%s/%s.tiff", outdir, fformat); cout << "file list " << ffname << endl;
sprintf(imgfname, (const char*)ffname, irun); } else {
sprintf(ffname, "%s/%s.clust", outdir, fformat); sprintf(ffname,(const char*)fformat,irun);
sprintf(cfname, (const char*)ffname, irun); cout << "loop " << ffname << endl;
}
cout << "ffname "<<ffname << endl;
sprintf(fname, "%s/%s.raw",indir,ffname);
sprintf(imgfname, "%s/%s.tiff",outdir,ffname);
sprintf(cfname, "%s/%s.clust",outdir,ffname);
cout << fname << " "; cout << fname << " ";
cout << imgfname << endl; cout << imgfname << " " << cfname << endl;
std::time(&end_time); std::time(&end_time);
cout << std::ctime(&end_time) << endl; cout << std::ctime(&end_time) << endl;
// cout << fname << " " << outfname << " " << imgfname << endl; // cout << fname << " " << outfname << " " << imgfname << endl;
@ -349,13 +369,15 @@ int main(int argc, char *argv[]) {
mt->popFree(buff); mt->popFree(buff);
ifr++; ifr++;
if (ifr % 100 == 0) if (ifr % 10000 == 0)
cout << ifr << " " << ff << endl; cout << ifr << " " << ff << endl;
if (nframes > 0) { if (nframes > 0) {
if (ifr % nframes == 0) { if (ifr % nframes == 0) {
sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat,
ifile); sprintf(imgfname, "%s/%s_f%05d.tiff",outdir,ffname,ifile);
sprintf(imgfname, (const char*)ffname, irun);
while (mt->isBusy())
;
mt->writeImage(imgfname, thr1); mt->writeImage(imgfname, thr1);
mt->clearImage(); mt->clearImage();
ifile++; ifile++;
@ -374,13 +396,13 @@ int main(int argc, char *argv[]) {
} }
if (nframes >= 0) { if (nframes >= 0) {
if (nframes > 0) { if (nframes > 0) {
sprintf(ffname, "%s/%s_f%05d.tiff", outdir, fformat, ifile); sprintf(imgfname, "%s/%s_f%05d.tiff",outdir,ffname,ifile);
sprintf(imgfname, (const char*)ffname, irun);
} else { } else {
sprintf(ffname, "%s/%s.tiff", outdir, fformat); sprintf(imgfname, "%s/%s_f%05d.tiff",outdir,ffname,ifile);
sprintf(imgfname, (const char*)ffname, irun);
} }
cout << "Writing tiff to " << imgfname << " " << thr1 << endl; cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
while (mt->isBusy())
;
mt->writeImage(imgfname, thr1); mt->writeImage(imgfname, thr1);
mt->clearImage(); mt->clearImage();
if (of) { if (of) {
@ -395,11 +417,12 @@ int main(int argc, char *argv[]) {
cout << "Could not open " << fname << " for reading " << endl; cout << "Could not open " << fname << " for reading " << endl;
} }
if (nframes < 0) { if (nframes < 0) {
sprintf(ffname, "%s/%s.tiff", outdir, fformat); sprintf(imgfname, "%s/%s_tot.tiff",outdir,ffname);
strcpy(imgfname, ffname); cout << "Writing tiff to " << imgfname << " " << thr1 << endl;
cout << "Writing tiff to " << imgfname << " " << thr1 << endl; mt->writeImage(imgfname, thr1);
mt->writeImage(imgfname, thr1); }
if (flist.is_open()) {
flist.close();
} }
return 0; return 0;
} }

View File

@ -720,6 +720,22 @@ int main(int argc, char *argv[]) {
ymin >> ymax; ymin >> ymax;
} }
if (addJsonHeader.find("xMin") != addJsonHeader.end()) {
istringstream(addJsonHeader.at("xMin")) >> xmin;
}
if (addJsonHeader.find("yMin") != addJsonHeader.end()) {
istringstream(addJsonHeader.at("yMin")) >> ymin;
}
if (addJsonHeader.find("xMax") != addJsonHeader.end()) {
istringstream(addJsonHeader.at("xMax")) >> xmax;
}
if (addJsonHeader.find("yMax") != addJsonHeader.end()) {
istringstream(addJsonHeader.at("yMax")) >> ymax;
}
cprintf(MAGENTA, "%d %d %d %d\n", xmin, xmax, ymin, ymax); cprintf(MAGENTA, "%d %d %d %d\n", xmin, xmax, ymin, ymax);
mt->setROI(xmin, xmax, ymin, ymax); mt->setROI(xmin, xmax, ymin, ymax);
if (addJsonHeader.find("dynamicRange") != addJsonHeader.end()) { if (addJsonHeader.find("dynamicRange") != addJsonHeader.end()) {

View File

@ -533,7 +533,7 @@ class singlePhotonDetector : public analogDetector<uint16_t> {
(clusters + nph)->print(); (clusters + nph)->print();
cout << max << " " << val[iy * nx + ix] << endl; cout << max << " " << val[iy * nx + ix] << endl;
} }
good = 1; //good = 1;
if (eMin > 0 && tot < eMin) if (eMin > 0 && tot < eMin)
good = 0; good = 0;
if (eMax > 0 && tot > eMax) if (eMax > 0 && tot > eMax)
@ -542,7 +542,7 @@ class singlePhotonDetector : public analogDetector<uint16_t> {
nph++; nph++;
image[iy * nx + ix]++; image[iy * nx + ix]++;
} }
good=1;
} else if (ee == PEDESTAL) { } else if (ee == PEDESTAL) {
addToPedestal(data, ix, iy, cm); addToPedestal(data, ix, iy, cm);
} /*else { } /*else {

View File

@ -193,6 +193,7 @@ void qDrawPlot::SetupPlots() {
gainplot2d = new SlsQt2DPlot(boxPlot, true); gainplot2d = new SlsQt2DPlot(boxPlot, true);
gainplot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5, gainplot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5,
nPixelsY - 0.5, gainData); nPixelsY - 0.5, gainData);
gainplot2d->Update();
gainplot2d->hide(); gainplot2d->hide();
connect(plot2d, SIGNAL(PlotZoomedSignal(const QRectF &)), this, connect(plot2d, SIGNAL(PlotZoomedSignal(const QRectF &)), this,
SLOT(Zoom2DGainPlot(const QRectF &))); SLOT(Zoom2DGainPlot(const QRectF &)));
@ -1009,6 +1010,7 @@ void qDrawPlot::Update2dPlot() {
if (isGainDataExtracted) { if (isGainDataExtracted) {
gainplot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5, gainplot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5,
nPixelsY - 0.5, gainData); nPixelsY - 0.5, gainData);
gainplot2d->Update();
if (!gainplot2d->isVisible()) { if (!gainplot2d->isVisible()) {
gainplot2d->setFixedWidth(plot2d->width() / gainplot2d->setFixedWidth(plot2d->width() /
qDefs::DATA_GAIN_PLOT_RATIO); qDefs::DATA_GAIN_PLOT_RATIO);

View File

@ -849,8 +849,9 @@ void qTabMeasurement::GetNextFrameNumber() {
"Inconsistent starting frame number for all detectors."); "Inconsistent starting frame number for all detectors.");
spinNextFrameNumber->setValue(retval); spinNextFrameNumber->setValue(retval);
} }
CATCH_DISPLAY("Could not get starting frame number.", CATCH_HANDLE("Could not get starting frame number.",
"qTabMeasurement::GetNextFrameNumber") "qTabMeasurement::GetNextFrameNumber", spinNextFrameNumber,
&QSpinBox::setValue, -1)
connect(spinNextFrameNumber, SIGNAL(valueChanged(int)), this, connect(spinNextFrameNumber, SIGNAL(valueChanged(int)), this,
SLOT(SetNextFrameNumber(int))); SLOT(SetNextFrameNumber(int)));
} }

View File

@ -132,7 +132,7 @@ void qTabSettings::SetupWidgetWindow() {
} }
void qTabSettings::SetExportMode(bool exportMode) { void qTabSettings::SetExportMode(bool exportMode) {
if (comboGainMode->isVisible()) { if (comboGainMode->isEnabled()) {
ShowFixG0(exportMode); ShowFixG0(exportMode);
} }
} }

View File

@ -5,7 +5,7 @@
#define LINKED_SERVER_NAME "eigerDetectorServer" #define LINKED_SERVER_NAME "eigerDetectorServer"
#define REQUIRED_FIRMWARE_VERSION (31) #define REQUIRED_FIRMWARE_VERSION (32)
// virtual ones renamed for consistency // virtual ones renamed for consistency
// real ones keep previous name for compatibility (already in production) // real ones keep previous name for compatibility (already in production)
#ifdef VIRTUAL #ifdef VIRTUAL

View File

@ -3323,6 +3323,27 @@ void *start_timer(void *arg) {
break; break;
} }
// change gain and data for every frame
{
const int nchannels = NCHIP * NCHAN;
int gainVal = 0;
for (int i = 0; i < nchannels; ++i) {
if ((i % nchannels) < 400) {
gainVal = 1 + frameNr;
} else if ((i % nchannels) < 800) {
gainVal = 2 + frameNr;
} else {
gainVal = 3 + frameNr;
}
int dataVal =
*((uint16_t *)(imageData + i * sizeof(uint16_t)));
dataVal += frameNr;
int channelVal =
(dataVal & ~GAIN_VAL_MSK) | (gainVal << GAIN_VAL_OFST);
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
(uint16_t)channelVal;
}
}
// sleep for exposure time // sleep for exposure time
struct timespec begin, end; struct timespec begin, end;
clock_gettime(CLOCK_REALTIME, &begin); clock_gettime(CLOCK_REALTIME, &begin);

View File

@ -1388,14 +1388,18 @@ int setMaster(enum MASTERINDEX m) {
char *master_names[] = {MASTER_NAMES}; char *master_names[] = {MASTER_NAMES};
LOG(logINFOBLUE, ("Setting up as %s in (%s server)\n", master_names[m], LOG(logINFOBLUE, ("Setting up as %s in (%s server)\n", master_names[m],
(isControlServer ? "control" : "stop"))); (isControlServer ? "control" : "stop")));
int prevSync = getSynchronization();
setSynchronization(0);
int retval = -1; int retval = -1;
int retMaster = OK;
switch (m) { switch (m) {
case OW_MASTER: case OW_MASTER:
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_MASTER_MSK); bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_MASTER_MSK);
isMaster(&retval); isMaster(&retval);
if (retval != 1) { if (retval != 1) {
LOG(logERROR, ("Could not set master\n")); LOG(logERROR, ("Could not set master\n"));
return FAIL; retMaster = FAIL;
} }
break; break;
case OW_SLAVE: case OW_SLAVE:
@ -1403,15 +1407,16 @@ int setMaster(enum MASTERINDEX m) {
isMaster(&retval); isMaster(&retval);
if (retval != 0) { if (retval != 0) {
LOG(logERROR, ("Could not set slave\n")); LOG(logERROR, ("Could not set slave\n"));
return FAIL; retMaster = FAIL;
} }
break; break;
default: default:
LOG(logERROR, ("Cannot reset to hardware settings from client. Restart " LOG(logERROR, ("Cannot reset to hardware settings from client. Restart "
"detector server.\n")); "detector server.\n"));
return FAIL; retMaster = FAIL;
} }
return OK; setSynchronization(prevSync);
return retMaster;
} }
int isMaster(int *retval) { int isMaster(int *retval) {
@ -1449,7 +1454,7 @@ void setTiming(enum timingMode arg) {
} }
enum timingMode getTiming() { enum timingMode getTiming() {
if (bus_r(EXT_SIGNAL_REG) == EXT_SIGNAL_MSK) if ((bus_r(EXT_SIGNAL_REG) & EXT_SIGNAL_MSK) >> EXT_SIGNAL_OFST)
return TRIGGER_EXPOSURE; return TRIGGER_EXPOSURE;
return AUTO_TIMING; return AUTO_TIMING;
} }
@ -1736,40 +1741,40 @@ int setDetectorPosition(int pos[]) {
detPos[2] = outerPos[X]; detPos[2] = outerPos[X];
detPos[3] = outerPos[Y]; detPos[3] = outerPos[Y];
// row // row [Y]
// outer // outer
uint32_t addr = COORD_ROW_REG; uint32_t addr = COORD_ROW_REG;
bus_w(addr, bus_w(addr,
(bus_r(addr) & ~COORD_ROW_OUTER_MSK) | (bus_r(addr) & ~COORD_ROW_OUTER_MSK) |
((outerPos[X] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK)); ((outerPos[Y] << COORD_ROW_OUTER_OFST) & COORD_ROW_OUTER_MSK));
if (((bus_r(addr) & COORD_ROW_OUTER_MSK) >> COORD_ROW_OUTER_OFST) != if (((bus_r(addr) & COORD_ROW_OUTER_MSK) >> COORD_ROW_OUTER_OFST) !=
outerPos[X])
ret = FAIL;
// inner
bus_w(addr,
(bus_r(addr) & ~COORD_ROW_INNER_MSK) |
((innerPos[X] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK));
if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) !=
innerPos[X])
ret = FAIL;
// col
// outer
addr = COORD_COL_REG;
bus_w(addr,
(bus_r(addr) & ~COORD_COL_OUTER_MSK) |
((outerPos[Y] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK));
if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) !=
outerPos[Y]) outerPos[Y])
ret = FAIL; ret = FAIL;
// inner // inner
bus_w(addr, bus_w(addr,
(bus_r(addr) & ~COORD_COL_INNER_MSK) | (bus_r(addr) & ~COORD_ROW_INNER_MSK) |
((innerPos[Y] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK)); ((innerPos[Y] << COORD_ROW_INNER_OFST) & COORD_ROW_INNER_MSK));
if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) != if (((bus_r(addr) & COORD_ROW_INNER_MSK) >> COORD_ROW_INNER_OFST) !=
innerPos[Y]) innerPos[Y])
ret = FAIL; ret = FAIL;
// col [X]
// outer
addr = COORD_COL_REG;
bus_w(addr,
(bus_r(addr) & ~COORD_COL_OUTER_MSK) |
((outerPos[X] << COORD_COL_OUTER_OFST) & COORD_COL_OUTER_MSK));
if (((bus_r(addr) & COORD_COL_OUTER_MSK) >> COORD_COL_OUTER_OFST) !=
outerPos[X])
ret = FAIL;
// inner
bus_w(addr,
(bus_r(addr) & ~COORD_COL_INNER_MSK) |
((innerPos[X] << COORD_COL_INNER_OFST) & COORD_COL_INNER_MSK));
if (((bus_r(addr) & COORD_COL_INNER_MSK) >> COORD_COL_INNER_OFST) !=
innerPos[X])
ret = FAIL;
if (ret == OK) { if (ret == OK) {
if (getNumberofUDPInterfaces() == 1) { if (getNumberofUDPInterfaces() == 1) {
LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n", LOG(logINFOBLUE, ("Position set to [%d, %d] #(col, row)\n",
@ -2627,6 +2632,7 @@ void *start_timer(void *arg) {
if (i % pixelsPerPacket == 0) { if (i % pixelsPerPacket == 0) {
++dataVal; ++dataVal;
} }
if ((i % 1024) < 300) { if ((i % 1024) < 300) {
gainVal = 1; gainVal = 1;
} else if ((i % 1024) < 600) { } else if ((i % 1024) < 600) {
@ -2667,6 +2673,28 @@ void *start_timer(void *arg) {
clock_gettime(CLOCK_REALTIME, &begin); clock_gettime(CLOCK_REALTIME, &begin);
usleep(expUs); usleep(expUs);
// change gain and data for every frame
{
const int npixels = (NCHAN * NCHIP);
for (int i = 0; i < npixels; ++i) {
int gainVal = 0;
if ((i % 1024) < 300) {
gainVal = 1 + iframes;
} else if ((i % 1024) < 600) {
gainVal = 2 + iframes;
} else {
gainVal = 3 + iframes;
}
int dataVal =
*((uint16_t *)(imageData + i * sizeof(uint16_t)));
dataVal += iframes;
int pixelVal =
(dataVal & ~GAIN_VAL_MSK) | (gainVal << GAIN_VAL_OFST);
*((uint16_t *)(imageData + i * sizeof(uint16_t))) =
(uint16_t)pixelVal;
}
}
int srcOffset = 0; int srcOffset = 0;
int srcOffset2 = DATA_BYTES / 2; int srcOffset2 = DATA_BYTES / 2;
int row0 = (numInterfaces == 1 ? detPos[1] : detPos[3]); int row0 = (numInterfaces == 1 ? detPos[1] : detPos[3]);

View File

@ -5,8 +5,8 @@
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#define MIN_REQRD_VRSN_T_RD_API 0x171220 #define MIN_REQRD_VRSN_T_RD_API 0x171220
#define REQRD_FRMWRE_VRSN_BOARD2 0x221104 // 1.0 pcb (version = 010) #define REQRD_FRMWRE_VRSN_BOARD2 0x230516 // 1.0 pcb (version = 010)
#define REQRD_FRMWRE_VRSN 0x221103 // 2.0 pcb (version = 011) #define REQRD_FRMWRE_VRSN 0x230515 // 2.0 pcb (version = 011)
#define NUM_HARDWARE_VERSIONS (2) #define NUM_HARDWARE_VERSIONS (2)
#define HARDWARE_VERSION_NUMBERS \ #define HARDWARE_VERSION_NUMBERS \

View File

@ -13,6 +13,7 @@
#include "slsDetectorServer_funcs.h" #include "slsDetectorServer_funcs.h"
#include <getopt.h> #include <getopt.h>
#include <limits.h>
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -276,6 +277,14 @@ int main(int argc, char *argv[]) {
LOG(logERROR, ("Could not set handler function for SIGINT")); LOG(logERROR, ("Could not set handler function for SIGINT"));
} }
// validate control and stop port number
if (0 >= portno || portno > USHRT_MAX || 0 >= (portno + 1) ||
(portno + 1) > USHRT_MAX) {
LOG(logERROR, ("Invalid control server or stop server port "
"numbers (%d, %d). It must be in range 1 - %d",
portno, portno + 1, USHRT_MAX));
return -1;
}
if (sharedMemory_create(portno) == FAIL) { if (sharedMemory_create(portno) == FAIL) {
return -1; return -1;
} }

View File

@ -515,6 +515,11 @@ int executeCommand(char *command, char *result, enum TLogLevel level) {
fflush(stdout); fflush(stdout);
FILE *sysFile = popen(cmd, "r"); FILE *sysFile = popen(cmd, "r");
if (sysFile == NULL) {
ret = FAIL;
sprintf(mess, "Executing cmd[%s] failed\n", cmd);
return ret;
}
while (fgets(temp, tempsize, sysFile) != NULL) { while (fgets(temp, tempsize, sysFile) != NULL) {
// size left excludes terminating character // size left excludes terminating character
size_t sizeleft = MAX_STR_LENGTH - strlen(result) - 1; size_t sizeleft = MAX_STR_LENGTH - strlen(result) - 1;
@ -530,17 +535,15 @@ int executeCommand(char *command, char *result, enum TLogLevel level) {
if (strlen(result) == 0) { if (strlen(result) == 0) {
strcpy(result, "No result"); strcpy(result, "No result");
} }
int retval = OK;
int success = pclose(sysFile); int success = pclose(sysFile);
if (success) { if (success == -1) {
retval = FAIL; ret = FAIL;
LOG(logERROR, ("Executing cmd[%s]:%s\n", cmd, result)); strcpy(mess, result);
LOG(logERROR, ("Executing cmd[%s] failed:%s\n", cmd, mess));
} else { } else {
LOG(level, ("Result:\n[%s]\n", result)); LOG(level, ("Result:\n[%s]\n", result));
} }
return ret;
return retval;
} }
int M_nofunc(int file_des) { int M_nofunc(int file_des) {
@ -568,7 +571,7 @@ int exec_command(int file_des) {
// set // set
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
ret = executeCommand(cmd, retval, logINFO); executeCommand(cmd, retval, logINFO);
} }
return Server_SendResult(file_des, OTHER, retval, sizeof(retval)); return Server_SendResult(file_des, OTHER, retval, sizeof(retval));
} }
@ -4664,7 +4667,8 @@ int set_read_n_rows(int file_des) {
functionNotImplemented(); functionNotImplemented();
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if ((Server_VerifyLock() == OK) &&
(check_detector_idle("set number of rows") == OK)) {
if (arg <= 0 || arg > MAX_ROWS_PER_READOUT) { if (arg <= 0 || arg > MAX_ROWS_PER_READOUT) {
ret = FAIL; ret = FAIL;
sprintf(mess, sprintf(mess,
@ -4696,8 +4700,7 @@ int set_read_n_rows(int file_des) {
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else } else
#elif JUNGFRAUD #elif JUNGFRAUD
if ((check_detector_idle("set number of rows") == OK) && if (arg % READ_N_ROWS_MULTIPLE != 0) {
(arg % READ_N_ROWS_MULTIPLE != 0)) {
ret = FAIL; ret = FAIL;
sprintf(mess, sprintf(mess,
"Could not set number of rows. %d must be a multiple " "Could not set number of rows. %d must be a multiple "
@ -8280,9 +8283,9 @@ int set_master(int file_des) {
functionNotImplemented(); functionNotImplemented();
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if ((Server_VerifyLock() == OK) &&
if ((check_detector_idle("set master") == OK) && (check_detector_idle("set master") == OK)) {
(arg != 0 && arg != 1)) { if (arg != 0 && arg != 1) {
ret = FAIL; ret = FAIL;
sprintf(mess, "Could not set master. Invalid argument %d.\n", arg); sprintf(mess, "Could not set master. Invalid argument %d.\n", arg);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
@ -8836,9 +8839,9 @@ int set_flip_rows(int file_des) {
functionNotImplemented(); functionNotImplemented();
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if ((Server_VerifyLock() == OK) &&
if ((check_detector_idle("set flip rows") == OK) && (check_detector_idle("set flip rows") == OK)) {
(arg != 0 && arg != 1)) { if (arg != 0 && arg != 1) {
ret = FAIL; ret = FAIL;
sprintf(mess, "Could not set flip rows. Invalid argument %d.\n", sprintf(mess, "Could not set flip rows. Invalid argument %d.\n",
arg); arg);
@ -10160,9 +10163,9 @@ int set_synchronization(int file_des) {
functionNotImplemented(); functionNotImplemented();
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if ((Server_VerifyLock() == OK) &&
if ((check_detector_idle("set synchronization") == OK) && (check_detector_idle("set synchronization") == OK)) {
(arg != 0 && arg != 1)) { if (arg != 0 && arg != 1) {
ret = FAIL; ret = FAIL;
sprintf(mess, sprintf(mess,
"Could not set synchronization. Invalid argument %d.\n", "Could not set synchronization. Invalid argument %d.\n",

View File

@ -2008,7 +2008,7 @@ class Detector {
///@} ///@}
private: private:
std::vector<int> getPortNumbers(int start_port); std::vector<int> getValidPortNumbers(int start_port);
void updateRxRateCorrections(); void updateRxRateCorrections();
void setNumberofUDPInterfaces_(int n, Positions pos); void setNumberofUDPInterfaces_(int n, Positions pos);
}; };

View File

@ -16,6 +16,7 @@
#include <vector> #include <vector>
#include "sls/ToString.h" #include "sls/ToString.h"
#include "sls/TypeTraits.h"
#include "sls/container_utils.h" #include "sls/container_utils.h"
namespace sls { namespace sls {
@ -128,6 +129,25 @@ template <class T, class Allocator = std::allocator<T>> class Result {
/** Test whether all elements of the result are equal */ /** Test whether all elements of the result are equal */
bool equal() const noexcept { return allEqual(vec); } bool equal() const noexcept { return allEqual(vec); }
/** Test whether any element of the result are equal to a value */
bool any(const T &value) const noexcept { return anyEqualTo(vec, value); }
template <typename V, typename... Args, typename = AllSame<V, Args...>>
typename std::enable_if<std::is_same<V, T>::value, bool>::type
contains_only(const V &a, const Args &...args) const noexcept {
auto values = {a, args...};
for (const auto &element : vec) {
int found = 0;
for (const auto &value : values) {
if (value == element)
found++;
}
if (!found)
return false;
}
return true;
}
/** Convert Result<T> to std::vector<T> */ /** Convert Result<T> to std::vector<T> */
operator std::vector<T>() { return vec; } operator std::vector<T>() { return vec; }
}; };

View File

@ -18,6 +18,7 @@
#include <chrono> #include <chrono>
#include <fstream> #include <fstream>
#include <set>
#include <thread> #include <thread>
namespace sls { namespace sls {
@ -108,6 +109,9 @@ void Detector::setHostname(const std::vector<std::string> &hostname) {
} }
void Detector::setVirtualDetectorServers(int numServers, int startingPort) { void Detector::setVirtualDetectorServers(int numServers, int startingPort) {
for (int i = 0; i != numServers; ++i) {
validatePortNumber(startingPort + i * 2);
}
pimpl->setVirtualDetectorServers(numServers, startingPort); pimpl->setVirtualDetectorServers(numServers, startingPort);
} }
@ -845,18 +849,26 @@ void Detector::startDetectorReadout() {
void Detector::stopDetector(Positions pos) { void Detector::stopDetector(Positions pos) {
// stop and check status X times
int retries{0}; int retries{0};
// avoid default construction of runStatus::IDLE on squash auto status = getDetectorStatus(pos);
auto status = getDetectorStatus().squash(defs::runStatus::RUNNING);
while (status != defs::runStatus::IDLE && // jf sync fix: status [stopped or idle] = [stopped]
status != defs::runStatus::STOPPED) { // sync issue: (master idle sometimes, slaves stopped)
if (status == defs::runStatus::ERROR) {
throw RuntimeError( // eiger fix: stop multiple times from multi client till all modules stopped
"Could not stop detector. Returned error status."); // issue: asynchronous start and stop scripts with a module being started
// (stop before) and waiting for the other to be done. So a module that was
// idle before stopping will return running (after async start script) when
// getting status after, which will then be stopped again.
while (!status.contains_only(defs::runStatus::IDLE,
defs::runStatus::STOPPED)) {
if (status.any(defs::runStatus::ERROR)) {
throw RuntimeError("Could not stop detector. At least one module "
"returned error status.");
} }
pimpl->Parallel(&Module::stopAcquisition, pos); pimpl->stopDetector(pos);
status = getDetectorStatus().squash(defs::runStatus::RUNNING); status = getDetectorStatus(pos);
++retries; ++retries;
if (retries == 10) if (retries == 10)
@ -875,7 +887,7 @@ void Detector::stopDetector(Positions pos) {
for (auto it : res) { for (auto it : res) {
maxVal = std::max(maxVal, it); maxVal = std::max(maxVal, it);
} }
setNextFrameNumber(maxVal + 1); setNextFrameNumber(maxVal + 1, pos);
} }
} break; } break;
default: default:
@ -914,7 +926,7 @@ void Detector::setNextFrameNumber(uint64_t value, Positions pos) {
} }
void Detector::sendSoftwareTrigger(const bool block, Positions pos) { void Detector::sendSoftwareTrigger(const bool block, Positions pos) {
pimpl->Parallel(&Module::sendSoftwareTrigger, pos, block); pimpl->sendSoftwareTrigger(block, pos);
} }
Result<defs::scanParameters> Detector::getScan(Positions pos) const { Result<defs::scanParameters> Detector::getScan(Positions pos) const {
@ -951,18 +963,23 @@ void Detector::setNumberofUDPInterfaces(int n, Positions pos) {
} }
void Detector::setNumberofUDPInterfaces_(int n, Positions pos) { void Detector::setNumberofUDPInterfaces_(int n, Positions pos) {
if (!size()) {
throw RuntimeError("No modules added.");
}
bool previouslyClientStreaming = pimpl->getDataStreamingToClient(); bool previouslyClientStreaming = pimpl->getDataStreamingToClient();
int clientStartingPort = getClientZmqPort({0}).squash(0);
bool useReceiver = getUseReceiverFlag().squash(false); bool useReceiver = getUseReceiverFlag().squash(false);
bool previouslyReceiverStreaming = false; bool previouslyReceiverStreaming = false;
int startingPort = 0; int rxStartingPort = 0;
if (useReceiver) { if (useReceiver) {
previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true); previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(true);
startingPort = getRxZmqPort({0}).squash(0); rxStartingPort = getRxZmqPort({0}).squash(0);
} }
pimpl->Parallel(&Module::setNumberofUDPInterfaces, pos, n); pimpl->Parallel(&Module::setNumberofUDPInterfaces, pos, n);
// ensure receiver zmq socket ports are multiplied by 2 (2 interfaces) // ensure receiver zmq socket ports are multiplied by 2 (2 interfaces)
if (getUseReceiverFlag().squash(false) && size()) { setClientZmqPort(clientStartingPort, -1);
setRxZmqPort(startingPort, -1); if (getUseReceiverFlag().squash(false)) {
setRxZmqPort(rxStartingPort, -1);
} }
// redo the zmq sockets if enabled // redo the zmq sockets if enabled
if (previouslyClientStreaming) { if (previouslyClientStreaming) {
@ -1082,12 +1099,13 @@ Result<int> Detector::getDestinationUDPPort(Positions pos) const {
void Detector::setDestinationUDPPort(int port, int module_id) { void Detector::setDestinationUDPPort(int port, int module_id) {
if (module_id == -1) { if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port); std::vector<int> port_list = getValidPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) { for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setDestinationUDPPort, {idet}, pimpl->Parallel(&Module::setDestinationUDPPort, {idet},
port_list[idet]); port_list[idet]);
} }
} else { } else {
validatePortNumber(port);
pimpl->Parallel(&Module::setDestinationUDPPort, {module_id}, port); pimpl->Parallel(&Module::setDestinationUDPPort, {module_id}, port);
} }
} }
@ -1098,12 +1116,13 @@ Result<int> Detector::getDestinationUDPPort2(Positions pos) const {
void Detector::setDestinationUDPPort2(int port, int module_id) { void Detector::setDestinationUDPPort2(int port, int module_id) {
if (module_id == -1) { if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port); std::vector<int> port_list = getValidPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) { for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setDestinationUDPPort2, {idet}, pimpl->Parallel(&Module::setDestinationUDPPort2, {idet},
port_list[idet]); port_list[idet]);
} }
} else { } else {
validatePortNumber(port);
pimpl->Parallel(&Module::setDestinationUDPPort2, {module_id}, port); pimpl->Parallel(&Module::setDestinationUDPPort2, {module_id}, port);
} }
} }
@ -1215,9 +1234,11 @@ void Detector::setRxPort(int port, int module_id) {
it = port++; it = port++;
} }
for (int idet = 0; idet < size(); ++idet) { for (int idet = 0; idet < size(); ++idet) {
validatePortNumber(port_list[idet]);
pimpl->Parallel(&Module::setReceiverPort, {idet}, port_list[idet]); pimpl->Parallel(&Module::setReceiverPort, {idet}, port_list[idet]);
} }
} else { } else {
validatePortNumber(port);
pimpl->Parallel(&Module::setReceiverPort, {module_id}, port); pimpl->Parallel(&Module::setReceiverPort, {module_id}, port);
} }
} }
@ -1415,12 +1436,13 @@ void Detector::setRxZmqPort(int port, int module_id) {
bool previouslyReceiverStreaming = bool previouslyReceiverStreaming =
getRxZmqDataStream(std::vector<int>{module_id}).squash(false); getRxZmqDataStream(std::vector<int>{module_id}).squash(false);
if (module_id == -1) { if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port); std::vector<int> port_list = getValidPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) { for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setReceiverStreamingPort, {idet}, pimpl->Parallel(&Module::setReceiverStreamingPort, {idet},
port_list[idet]); port_list[idet]);
} }
} else { } else {
validatePortNumber(port);
pimpl->Parallel(&Module::setReceiverStreamingPort, {module_id}, port); pimpl->Parallel(&Module::setReceiverStreamingPort, {module_id}, port);
} }
if (previouslyReceiverStreaming) { if (previouslyReceiverStreaming) {
@ -1449,12 +1471,13 @@ Result<int> Detector::getClientZmqPort(Positions pos) const {
void Detector::setClientZmqPort(int port, int module_id) { void Detector::setClientZmqPort(int port, int module_id) {
bool previouslyClientStreaming = pimpl->getDataStreamingToClient(); bool previouslyClientStreaming = pimpl->getDataStreamingToClient();
if (module_id == -1) { if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port); std::vector<int> port_list = getValidPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) { for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setClientStreamingPort, {idet}, pimpl->Parallel(&Module::setClientStreamingPort, {idet},
port_list[idet]); port_list[idet]);
} }
} else { } else {
validatePortNumber(port);
pimpl->Parallel(&Module::setClientStreamingPort, {module_id}, port); pimpl->Parallel(&Module::setClientStreamingPort, {module_id}, port);
} }
if (previouslyClientStreaming) { if (previouslyClientStreaming) {
@ -2458,6 +2481,7 @@ Result<int> Detector::getControlPort(Positions pos) const {
} }
void Detector::setControlPort(int value, Positions pos) { void Detector::setControlPort(int value, Positions pos) {
validatePortNumber(value);
pimpl->Parallel(&Module::setControlPort, pos, value); pimpl->Parallel(&Module::setControlPort, pos, value);
} }
@ -2466,6 +2490,7 @@ Result<int> Detector::getStopPort(Positions pos) const {
} }
void Detector::setStopPort(int value, Positions pos) { void Detector::setStopPort(int value, Positions pos) {
validatePortNumber(value);
pimpl->Parallel(&Module::setStopPort, pos, value); pimpl->Parallel(&Module::setStopPort, pos, value);
} }
@ -2500,13 +2525,17 @@ Result<ns> Detector::getMeasurementTime(Positions pos) const {
std::string Detector::getUserDetails() const { return pimpl->getUserDetails(); } std::string Detector::getUserDetails() const { return pimpl->getUserDetails(); }
std::vector<int> Detector::getPortNumbers(int start_port) { std::vector<int> Detector::getValidPortNumbers(int start_port) {
int num_sockets_per_detector = getNumberofUDPInterfaces({}).tsquash( int num_sockets_per_detector = getNumberofUDPInterfaces({}).tsquash(
"Number of UDP Interfaces is not consistent among modules"); "Number of UDP Interfaces is not consistent among modules");
std::vector<int> res; std::vector<int> res;
res.reserve(size()); res.reserve(size());
for (int idet = 0; idet < size(); ++idet) { for (int idet = 0; idet < size(); ++idet) {
res.push_back(start_port + (idet * num_sockets_per_detector)); int port = start_port + (idet * num_sockets_per_detector);
for (int i = 0; i != num_sockets_per_detector; ++i) {
validatePortNumber(port + i);
}
res.push_back(port);
} }
return res; return res;
} }

View File

@ -288,6 +288,7 @@ void DetectorImpl::addModule(const std::string &hostname) {
if (res.size() > 1) { if (res.size() > 1) {
host = res[0]; host = res[0];
port = StringTo<int>(res[1]); port = StringTo<int>(res[1]);
validatePortNumber(port);
} }
if (host != "localhost") { if (host != "localhost") {
@ -769,7 +770,7 @@ void DetectorImpl::readFrameFromReceiver() {
int nDetActualPixelsY = nDetPixelsY; int nDetActualPixelsY = nDetPixelsY;
if (gapPixels) { if (gapPixels) {
int n = InsertGapPixels(multiframe.get(), multigappixels, int n = insertGapPixels(multiframe.get(), multigappixels,
quadEnable, dynamicRange, quadEnable, dynamicRange,
nDetActualPixelsX, nDetActualPixelsY); nDetActualPixelsX, nDetActualPixelsY);
callbackImage = multigappixels; callbackImage = multigappixels;
@ -808,7 +809,7 @@ void DetectorImpl::readFrameFromReceiver() {
delete[] multigappixels; delete[] multigappixels;
} }
int DetectorImpl::InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int DetectorImpl::insertGapPixels(char *image, char *&gpImage, bool quadEnable,
int dr, int &nPixelsx, int &nPixelsy) { int dr, int &nPixelsx, int &nPixelsy) {
LOG(logDEBUG) << "Insert Gap pixels:" LOG(logDEBUG) << "Insert Gap pixels:"
@ -1233,10 +1234,26 @@ int DetectorImpl::acquire() {
dataProcessingThread.join(); dataProcessingThread.join();
if (acquisition_finished != nullptr) { if (acquisition_finished != nullptr) {
int status = Parallel(&Module::getRunStatus, {}).squash(ERROR); // status
runStatus status = IDLE;
auto statusList = Parallel(&Module::getRunStatus, {});
status = statusList.squash(ERROR);
// difference, but none error
if (status == ERROR && (!statusList.any(ERROR))) {
// handle jf sync issue (master idle, slaves stopped)
if (statusList.contains_only(IDLE, STOPPED)) {
status = STOPPED;
} else
status = statusList.squash(RUNNING);
}
// progress
auto a = Parallel(&Module::getReceiverProgress, {}); auto a = Parallel(&Module::getReceiverProgress, {});
double progress = (*std::max_element(a.begin(), a.end())); double progress = (*std::max_element(a.begin(), a.end()));
acquisition_finished(progress, status, acqFinished_p);
// callback
acquisition_finished(progress, static_cast<int>(status),
acqFinished_p);
} }
clock_gettime(CLOCK_REALTIME, &end); clock_gettime(CLOCK_REALTIME, &end);
@ -1256,43 +1273,104 @@ int DetectorImpl::acquire() {
return OK; return OK;
} }
void DetectorImpl::startAcquisition(bool blocking, std::vector<int> positions) { bool DetectorImpl::handleSynchronization(Positions pos) {
// handle Mythen3 synchronization bool handleSync = false;
if (shm()->detType == defs::MYTHEN3 && size() > 1) { // multi module m3 or multi module sync enabled jungfrau
std::vector<int> master; if (size() > 1) {
std::vector<int> slaves; switch (shm()->detType) {
if (positions.empty() || case defs::MYTHEN3:
(positions.size() == 1 && positions[0] == -1)) { case defs::GOTTHARD2:
positions.resize(modules.size()); case defs::GOTTHARD:
std::iota(begin(positions), end(positions), 0); handleSync = true;
} break;
// could be all slaves in positions case defs::JUNGFRAU:
slaves.reserve(positions.size()); if (Parallel(&Module::getSynchronizationFromStopServer, pos)
auto is_master = Parallel(&Module::isMaster, positions); .tsquash("Inconsistent synchronization among modules")) {
for (size_t i : positions) { handleSync = true;
if (is_master[i]) }
master.push_back(i); break;
else default:
slaves.push_back(i); break;
} }
}
return handleSync;
}
void DetectorImpl::getMasterSlaveList(std::vector<int> positions,
std::vector<int> &masters,
std::vector<int> &slaves) {
// expand positions list
if (positions.empty() || (positions.size() == 1 && positions[0] == -1)) {
positions.resize(modules.size());
std::iota(begin(positions), end(positions), 0);
}
// could be all slaves in positions
slaves.reserve(positions.size());
auto is_master = Parallel(&Module::isMaster, positions);
for (size_t i : positions) {
if (is_master[i])
masters.push_back(i);
else
slaves.push_back(i);
}
}
void DetectorImpl::startAcquisition(const bool blocking, Positions pos) {
// slaves first
if (handleSynchronization(pos)) {
std::vector<int> masters;
std::vector<int> slaves;
getMasterSlaveList(pos, masters, slaves);
if (!slaves.empty()) { if (!slaves.empty()) {
Parallel(&Module::startAcquisition, slaves); Parallel(&Module::startAcquisition, slaves);
} }
if (!master.empty()) { if (!masters.empty()) {
if (blocking) { Parallel((blocking ? &Module::startAndReadAll
Parallel(&Module::startAndReadAll, master); : &Module::startAcquisition),
} else { masters);
Parallel(&Module::startAcquisition, master);
}
}
} else {
if (blocking) {
Parallel(&Module::startAndReadAll, positions);
} else {
Parallel(&Module::startAcquisition, positions);
} }
} }
// all in parallel
else {
Parallel(
(blocking ? &Module::startAndReadAll : &Module::startAcquisition),
pos);
}
}
void DetectorImpl::sendSoftwareTrigger(const bool block, Positions pos) {
// slaves first
if (handleSynchronization(pos)) {
std::vector<int> masters;
std::vector<int> slaves;
getMasterSlaveList(pos, masters, slaves);
if (!slaves.empty())
Parallel(&Module::sendSoftwareTrigger, slaves, false);
if (!masters.empty())
Parallel(&Module::sendSoftwareTrigger, masters, block);
}
// all in parallel
else {
Parallel(&Module::sendSoftwareTrigger, pos, block);
}
}
void DetectorImpl::stopDetector(Positions pos) {
// masters first
if (handleSynchronization(pos)) {
std::vector<int> masters;
std::vector<int> slaves;
getMasterSlaveList(pos, masters, slaves);
if (!masters.empty())
Parallel(&Module::stopAcquisition, masters);
if (!slaves.empty())
Parallel(&Module::stopAcquisition, slaves);
}
// all in parallel
else {
Parallel(&Module::stopAcquisition, pos);
}
} }
void DetectorImpl::printProgress(double progress) { void DetectorImpl::printProgress(double progress) {
@ -1324,7 +1402,7 @@ void DetectorImpl::processData(bool receiver) {
if (fgetc(stdin) == 'q') { if (fgetc(stdin) == 'q') {
LOG(logINFO) LOG(logINFO)
<< "Caught the command to stop acquisition"; << "Caught the command to stop acquisition";
Parallel(&Module::stopAcquisition, {}); stopDetector({});
} }
} }
// get and print progress // get and print progress
@ -1397,7 +1475,8 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
default: default:
throw RuntimeError( throw RuntimeError(
"Unknown detector type. Did the 'hostname' command execute " "Unknown detector type. Did the 'hostname' command execute "
"successfully? Or use update mode in the detector server side."); "successfully? Or use update mode in the detector server "
"side.");
} }
LOG(logINFO) << "This can take awhile. Please be patient."; LOG(logINFO) << "This can take awhile. Please be patient.";
@ -1425,10 +1504,9 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
int dst = mkstemp(destfname); // create temporary file and open it in r/w int dst = mkstemp(destfname); // create temporary file and open it in r/w
if (dst == -1) { if (dst == -1) {
fclose(src); fclose(src);
throw RuntimeError( throw RuntimeError(std::string("Could not create destination file "
std::string( "in /tmp for programming: ") +
"Could not create destination file in /tmp for programming: ") + destfname);
destfname);
} }
// convert src to dst rawbin // convert src to dst rawbin
@ -1480,8 +1558,8 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
} }
// validate pof: read less than footer offset // validate pof: read less than footer offset
if (isPof && dstFilePos < pofFooterOfst) { if (isPof && dstFilePos < pofFooterOfst) {
throw RuntimeError( throw RuntimeError("Could not convert programming file. EOF "
"Could not convert programming file. EOF before end of flash"); "before end of flash");
} }
} }
if (fclose(src) != 0) { if (fclose(src) != 0) {

View File

@ -278,7 +278,13 @@ class DetectorImpl : public virtual slsDetectorDefs {
int acquire(); int acquire();
/** also takes care of master and slave for multi module mythen */ /** also takes care of master and slave for multi module mythen */
void startAcquisition(bool blocking, std::vector<int> positions); void startAcquisition(const bool blocking, Positions pos);
/** also takes care of master and slave for multi module mythen */
void sendSoftwareTrigger(const bool block, Positions pos);
/** also takes care of master and slave for multi module mythen */
void stopDetector(Positions pos);
/** /**
* Combines data from all readouts and gives it to the gui * Combines data from all readouts and gives it to the gui
@ -368,9 +374,14 @@ class DetectorImpl : public virtual slsDetectorDefs {
* @param nPixelsy number of pixels in Y axis (updated) * @param nPixelsy number of pixels in Y axis (updated)
* @returns total data bytes for updated image * @returns total data bytes for updated image
*/ */
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr, int insertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
int &nPixelsx, int &nPixelsy); int &nPixelsx, int &nPixelsy);
bool handleSynchronization(Positions pos);
void getMasterSlaveList(std::vector<int> positions,
std::vector<int> &masters,
std::vector<int> &slaves);
void printProgress(double progress); void printProgress(double progress);
void startProcessingThread(bool receiver); void startProcessingThread(bool receiver);

View File

@ -73,8 +73,8 @@ void Module::setHostname(const std::string &hostname,
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.close(); client.close();
try { try {
initialDetectorServerChecks();
checkDetectorVersionCompatibility(); checkDetectorVersionCompatibility();
initialDetectorServerChecks();
LOG(logINFO) << "Module Version Compatibility - Success"; LOG(logINFO) << "Module Version Compatibility - Success";
} catch (const RuntimeError &e) { } catch (const RuntimeError &e) {
if (!initialChecks) { if (!initialChecks) {
@ -93,9 +93,28 @@ int64_t Module::getFirmwareVersion() const {
} }
std::string Module::getControlServerLongVersion() const { std::string Module::getControlServerLongVersion() const {
char retval[MAX_STR_LENGTH]{}; try {
sendToDetector(F_GET_SERVER_VERSION, nullptr, retval); char retval[MAX_STR_LENGTH]{};
return retval; sendToDetector(F_GET_SERVER_VERSION, nullptr, retval);
return retval;
}
// throw with old server version (sends 8 bytes)
catch (RuntimeError &e) {
std::string emsg = std::string(e.what());
if (emsg.find(F_GET_SERVER_VERSION) && emsg.find("8 bytes")) {
throwDeprecatedServerVersion();
}
throw;
}
}
void Module::throwDeprecatedServerVersion() const {
uint64_t res = sendToDetectorStop<int64_t>(F_GET_SERVER_VERSION);
std::cout << std::endl;
std::ostringstream os;
os << "Detector Server (Control) version (0x" << std::hex << res
<< ") is incompatible with this client. Please update detector server!";
throw RuntimeError(os.str());
} }
std::string Module::getStopServerLongVersion() const { std::string Module::getStopServerLongVersion() const {
@ -519,8 +538,15 @@ bool Module::getSynchronization() const {
return sendToDetector<int>(F_GET_SYNCHRONIZATION); return sendToDetector<int>(F_GET_SYNCHRONIZATION);
} }
bool Module::getSynchronizationFromStopServer() const {
return sendToDetectorStop<int>(F_GET_SYNCHRONIZATION);
}
void Module::setSynchronization(const bool value) { void Module::setSynchronization(const bool value) {
sendToDetector(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr); sendToDetector(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr);
// to deal with virtual servers as well
// (get sync from stop server during blocking acquisition)
sendToDetectorStop(F_SET_SYNCHRONIZATION, static_cast<int>(value), nullptr);
} }
std::vector<int> Module::getBadChannels() const { std::vector<int> Module::getBadChannels() const {
@ -1324,7 +1350,9 @@ void Module::setReceiverHostname(const std::string &receiverIP,
auto res = split(host, ':'); auto res = split(host, ':');
if (res.size() > 1) { if (res.size() > 1) {
host = res[0]; host = res[0];
shm()->rxTCPPort = std::stoi(res[1]); int port = StringTo<int>(res[1]);
validatePortNumber(port);
shm()->rxTCPPort = port;
} }
strcpy_safe(shm()->rxHostname, host.c_str()); strcpy_safe(shm()->rxHostname, host.c_str());
shm()->useReceiverFlag = true; shm()->useReceiverFlag = true;
@ -3845,8 +3873,8 @@ void Module::sendProgram(bool blackfin, std::vector<char> buffer,
void Module::simulatingActivityinDetector(const std::string &functionType, void Module::simulatingActivityinDetector(const std::string &functionType,
const int timeRequired) { const int timeRequired) {
LOG(logINFO) << "(Simulating) " << functionType << " for module " LOG(logINFO) << functionType << " for module " << moduleIndex << " ("
<< moduleIndex << " (" << shm()->hostname << ")"; << shm()->hostname << ")";
printf("%d%%\r", 0); printf("%d%%\r", 0);
std::cout << std::flush; std::cout << std::flush;
const int ERASE_TIME = timeRequired; const int ERASE_TIME = timeRequired;

View File

@ -92,6 +92,7 @@ class Module : public virtual slsDetectorDefs {
int64_t getFirmwareVersion() const; int64_t getFirmwareVersion() const;
std::string getControlServerLongVersion() const; std::string getControlServerLongVersion() const;
std::string getStopServerLongVersion() const; std::string getStopServerLongVersion() const;
void throwDeprecatedServerVersion() const;
std::string getDetectorServerVersion() const; std::string getDetectorServerVersion() const;
std::string getHardwareVersion() const; std::string getHardwareVersion() const;
std::string getKernelVersion() const; std::string getKernelVersion() const;
@ -128,6 +129,7 @@ class Module : public virtual slsDetectorDefs {
bool isMaster() const; bool isMaster() const;
void setMaster(const bool master); void setMaster(const bool master);
bool getSynchronization() const; bool getSynchronization() const;
bool getSynchronizationFromStopServer() const;
void setSynchronization(const bool value); void setSynchronization(const bool value);
std::vector<int> getBadChannels() const; std::vector<int> getBadChannels() const;
void setBadChannels(std::vector<int> list); void setBadChannels(std::vector<int> list);

View File

@ -11,6 +11,31 @@ namespace sls {
using test::GET; using test::GET;
using test::PUT; using test::PUT;
void test_valid_port(const std::string &command,
const std::vector<std::string> &arguments, int detector_id,
int action, int port_number) {
Detector det;
CmdProxy proxy(&det);
std::string string_port_number = std::to_string(port_number);
REQUIRE_THROWS_WITH(proxy.Call(command, arguments, detector_id, action),
"Invalid port number " + string_port_number +
". It must be in range 1 - 65535");
}
void test_valid_port(const std::string &command,
const std::vector<std::string> &arguments, int detector_id,
int action) {
std::vector<std::string> arg(arguments);
arg.push_back("0");
int test_values[2] = {77797, -1};
for (int i = 0; i != 2; ++i) {
int port_number = test_values[i];
arg[arg.size() - 1] = std::to_string(port_number);
test_valid_port(command, arg, detector_id, action, port_number);
}
}
void test_dac(defs::dacIndex index, const std::string &dacname, int dacvalue) { void test_dac(defs::dacIndex index, const std::string &dacname, int dacvalue) {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);

View File

@ -5,6 +5,14 @@
namespace sls { namespace sls {
void test_valid_port(const std::string &command,
const std::vector<std::string> &arguments, int detector_id,
int action, int port_number);
void test_valid_port(const std::string &command,
const std::vector<std::string> &arguments, int detector_id,
int action);
void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname,
int dacvalue); int dacvalue);
void test_onchip_dac(slsDetectorDefs::dacIndex index, void test_onchip_dac(slsDetectorDefs::dacIndex index,

View File

@ -689,10 +689,11 @@ TEST_CASE("confadc", "[.cmd]") {
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) { if (det_type == defs::GOTTHARD2) {
int ndet = det.size(); const int ndet = det.size();
int nchip = 10; const int nchip = 10;
int nadc = 32; const int nadc = 32;
int prev_val[ndet][nchip][nadc]; std::vector<std::vector<std::vector<int>>> prev_val(
ndet, std::vector<std::vector<int>>(nchip, std::vector<int>(nadc)));
for (int i = 0; i != ndet; ++i) { for (int i = 0; i != ndet; ++i) {
for (int j = 0; j != nchip; ++j) { for (int j = 0; j != nchip; ++j) {
for (int k = 0; k != nadc; ++k) { for (int k = 0; k != nadc; ++k) {

View File

@ -523,11 +523,61 @@ TEST_CASE("sync", "[.cmd]") {
proxy.Call("sync", {"1"}, -1, PUT, oss); proxy.Call("sync", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "sync 1\n"); REQUIRE(oss.str() == "sync 1\n");
} }
// setting to master or slave when synced
{
// get previous master
int prevMaster = 0;
auto previous = det.getMaster();
for (int i = 0; i != det.size(); ++i) {
if (previous[i] == 1) {
prevMaster = i;
break;
}
}
proxy.Call("master", {"1"}, 0, PUT);
proxy.Call("master", {"0"}, 0, PUT);
std::ostringstream oss;
proxy.Call("status", {}, -1, GET, oss);
REQUIRE(oss.str() != "status running\n");
// set all to slaves, and then master
for (int i = 0; i != det.size(); ++i) {
det.setMaster(0, {i});
}
det.setMaster(1, prevMaster);
}
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("sync", {}, -1, GET, oss); proxy.Call("sync", {}, -1, GET, oss);
REQUIRE(oss.str() == "sync 1\n"); REQUIRE(oss.str() == "sync 1\n");
} }
// setting sync when running
{
auto prev_timing =
det.getTimingMode().tsquash("inconsistent timing mode in test");
auto prev_frames =
det.getNumberOfFrames().tsquash("inconsistent #frames in test");
auto prev_exptime =
det.getExptime().tsquash("inconsistent exptime in test");
auto prev_period =
det.getPeriod().tsquash("inconsistent period in test");
det.setTimingMode(defs::AUTO_TIMING);
det.setNumberOfFrames(10000);
det.setExptime(std::chrono::microseconds(200));
det.setPeriod(std::chrono::milliseconds(1000));
det.setSynchronization(1);
det.startDetector();
REQUIRE_THROWS(proxy.Call("sync", {"0"}, -1, PUT));
{
std::ostringstream oss;
proxy.Call("sync", {}, -1, GET, oss);
REQUIRE(oss.str() == "sync 1\n");
}
det.stopDetector();
det.setTimingMode(prev_timing);
det.setNumberOfFrames(prev_frames);
det.setExptime(prev_exptime);
det.setPeriod(prev_period);
}
det.setSynchronization(prev_val); det.setSynchronization(prev_val);
} else { } else {
REQUIRE_THROWS(proxy.Call("sync", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("sync", {}, -1, GET));

View File

@ -5,6 +5,7 @@
#include "sls/Detector.h" #include "sls/Detector.h"
#include "sls/Version.h" #include "sls/Version.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "test-CmdProxy-global.h"
#include <sstream> #include <sstream>
#include "sls/versionAPI.h" #include "sls/versionAPI.h"
@ -237,6 +238,22 @@ TEST_CASE("rx_tcpport", "[.cmd][.rx]") {
proxy.Call("rx_tcpport", {}, i, GET, oss); proxy.Call("rx_tcpport", {}, i, GET, oss);
REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n'); REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
} }
test_valid_port("rx_tcpport", {}, -1, PUT);
test_valid_port("rx_tcpport", {}, 0, PUT);
// should fail for the second module
if (det.size() > 1) {
test_valid_port("rx_tcpport", {"65535"}, -1, PUT, 65536);
auto rxHostname = det.getRxHostname().squash("none");
if (rxHostname != "none") {
std::ostringstream oss;
for (int i = 0; i != det.size(); ++i) {
oss << rxHostname << ":" << 65536 + i << "+";
}
test_valid_port("rx_hostname", {oss.str()}, -1, PUT, 65536);
}
}
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setRxPort(prev_val[i], i); det.setRxPort(prev_val[i], i);
} }
@ -828,6 +845,12 @@ TEST_CASE("rx_zmqport", "[.cmd][.rx]") {
std::to_string(port + i * socketsperdetector) + std::to_string(port + i * socketsperdetector) +
'\n'); '\n');
} }
test_valid_port("rx_zmqport", {}, -1, PUT);
test_valid_port("rx_zmqport", {}, 0, PUT);
// should fail for the second module
if (det.size() > 1) {
test_valid_port("rx_zmqport", {"65535"}, -1, PUT, 65536);
}
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setRxZmqPort(prev_val_zmqport[i], i); det.setRxZmqPort(prev_val_zmqport[i], i);
} }

View File

@ -5,6 +5,7 @@
#include "sls/Detector.h" #include "sls/Detector.h"
#include "sls/file_utils.h" #include "sls/file_utils.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "test-CmdProxy-global.h"
#include <chrono> #include <chrono>
#include <sstream> #include <sstream>
@ -76,7 +77,13 @@ TEST_CASE("hostname", "[.cmd]") {
REQUIRE_NOTHROW(proxy.Call("hostname", {}, -1, GET)); REQUIRE_NOTHROW(proxy.Call("hostname", {}, -1, GET));
} }
// virtual: not testing TEST_CASE("virtual", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
REQUIRE_THROWS(proxy.Call("virtual", {}, -1, GET));
test_valid_port("virtual", {"1"}, -1, PUT);
test_valid_port("virtual", {"3", "65534"}, -1, PUT, 65536);
}
TEST_CASE("versions", "[.cmd]") { TEST_CASE("versions", "[.cmd]") {
Detector det; Detector det;
@ -1221,10 +1228,10 @@ TEST_CASE("dbitphase", "[.cmd]") {
} }
{ {
std::ostringstream oss1, oss2; std::ostringstream oss1, oss2;
proxy.Call("dbitphase", {"20", "deg"}, -1, PUT, oss1); proxy.Call("dbitphase", {"23", "deg"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "dbitphase 20 deg\n"); REQUIRE(oss1.str() == "dbitphase 23 deg\n");
proxy.Call("dbitphase", {"deg"}, -1, GET, oss2); proxy.Call("dbitphase", {"deg"}, -1, GET, oss2);
REQUIRE(oss2.str() == "dbitphase 20 deg\n"); REQUIRE(oss2.str() == "dbitphase 23 deg\n");
} }
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setDBITPhase(prev_val[i], {i}); det.setDBITPhase(prev_val[i], {i});
@ -2618,6 +2625,13 @@ TEST_CASE("udp_dstport", "[.cmd]") {
proxy.Call("udp_dstport", {"50084"}, -1, PUT, oss); proxy.Call("udp_dstport", {"50084"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_dstport 50084\n"); REQUIRE(oss.str() == "udp_dstport 50084\n");
} }
test_valid_port("udp_dstport", {}, -1, PUT);
test_valid_port("udp_dstport", {}, 0, PUT);
// should fail for the second module
if (det.size() > 1) {
test_valid_port("udp_dstport", {"65535"}, -1, PUT, 65536);
}
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setDestinationUDPPort(prev_val[i], {i}); det.setDestinationUDPPort(prev_val[i], {i});
} }
@ -2702,8 +2716,18 @@ TEST_CASE("udp_dstport2", "[.cmd]") {
proxy.Call("udp_dstport2", {"50084"}, -1, PUT, oss); proxy.Call("udp_dstport2", {"50084"}, -1, PUT, oss);
REQUIRE(oss.str() == "udp_dstport2 50084\n"); REQUIRE(oss.str() == "udp_dstport2 50084\n");
} }
test_valid_port("udp_dstport2", {}, -1, PUT);
test_valid_port("udp_dstport2", {}, 0, PUT);
// should fail for the second module
if (det.size() > 1) {
test_valid_port("udp_dstport2", {"65535"}, -1, PUT, 65536);
}
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setDestinationUDPPort2(prev_val[i], {i}); if (prev_val[i] != 0) {
det.setDestinationUDPPort2(prev_val[i], {i});
}
} }
} else { } else {
REQUIRE_THROWS(proxy.Call("udp_dstport2", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("udp_dstport2", {}, -1, GET));
@ -2922,6 +2946,13 @@ TEST_CASE("zmqport", "[.cmd]") {
std::to_string(port + i * socketsperdetector) + std::to_string(port + i * socketsperdetector) +
'\n'); '\n');
} }
test_valid_port("zmqport", {}, -1, PUT);
test_valid_port("zmqport", {}, 0, PUT);
// should fail for the second module
if (det.size() > 1) {
test_valid_port("zmqport", {"65535"}, -1, PUT, 65536);
}
if (det_type == defs::JUNGFRAU) { if (det_type == defs::JUNGFRAU) {
det.setNumberofUDPInterfaces(prev); det.setNumberofUDPInterfaces(prev);
} }
@ -3266,6 +3297,13 @@ TEST_CASE("port", "[.cmd]") {
proxy.Call("port", {}, 0, GET, oss); proxy.Call("port", {}, 0, GET, oss);
REQUIRE(oss.str() == "port 1942\n"); REQUIRE(oss.str() == "port 1942\n");
} }
test_valid_port("port", {}, -1, PUT);
test_valid_port("port", {}, 0, PUT);
// should fail for the second module
if (det.size() > 1) {
test_valid_port("port", {"65536"}, -1, PUT, 65536);
}
det.setControlPort(prev_val, {0}); det.setControlPort(prev_val, {0});
} }
@ -3283,6 +3321,12 @@ TEST_CASE("stopport", "[.cmd]") {
proxy.Call("stopport", {}, 0, GET, oss); proxy.Call("stopport", {}, 0, GET, oss);
REQUIRE(oss.str() == "stopport 1942\n"); REQUIRE(oss.str() == "stopport 1942\n");
} }
test_valid_port("stopport", {}, -1, PUT);
test_valid_port("stopport", {}, 0, PUT);
// should fail for the second module
if (det.size() > 1) {
test_valid_port("stopport", {"65536"}, -1, PUT, 65536);
}
det.setStopPort(prev_val, {0}); det.setStopPort(prev_val, {0});
} }
@ -3313,7 +3357,7 @@ TEST_CASE("lock", "[.cmd]") {
TEST_CASE("execcommand", "[.cmd]") { TEST_CASE("execcommand", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
REQUIRE_NOTHROW(proxy.Call("execcommand", {"ls"}, -1, PUT)); REQUIRE_NOTHROW(proxy.Call("execcommand", {"ls *.txt"}, -1, PUT));
} }
TEST_CASE("framecounter", "[.cmd]") { TEST_CASE("framecounter", "[.cmd]") {

View File

@ -196,4 +196,24 @@ TEST_CASE("String conversions") {
"[{one: 1}, {one: 1, three: 3, two: 2}, {one: 1}]"); "[{one: 1}, {one: 1, three: 3, two: 2}, {one: 1}]");
} }
TEST_CASE("Any element is equal") {
Result<int> r{1, 2, 3, 4, 5};
REQUIRE(r.any(3));
REQUIRE_FALSE(r.any(9));
}
TEST_CASE("Result contains only the specified elements") {
Result<int> r{1, 1, 1};
REQUIRE(r.contains_only(1));
REQUIRE(r.contains_only(1, 1));
}
TEST_CASE("Only with multiple values") {
Result<int> r{1, 1, 2, 1, 2, 1, 1};
REQUIRE_FALSE(r.contains_only(1));
REQUIRE_FALSE(r.contains_only(2));
REQUIRE(r.contains_only(1, 2));
REQUIRE(r.contains_only(2, 1));
}
} // namespace sls } // namespace sls

View File

@ -5,6 +5,7 @@
#include <chrono> #include <chrono>
#include <signal.h> #include <signal.h>
#include <sys/wait.h>
#include <thread> #include <thread>
#include <unistd.h> #include <unistd.h>
@ -16,6 +17,8 @@ namespace sls {
#define gettid() syscall(SYS_gettid) #define gettid() syscall(SYS_gettid)
#endif #endif
void func(int signum) { wait(NULL); }
Arping::Arping() {} Arping::Arping() {}
Arping::~Arping() { Arping::~Arping() {
@ -44,10 +47,11 @@ pid_t Arping::GetProcessId() const { return childPid; }
bool Arping::IsRunning() const { return runningFlag; } bool Arping::IsRunning() const { return runningFlag; }
void Arping::StartProcess() { void Arping::StartProcess() {
TestCommands();
// to prevent zombies from child processes being killed // to prevent zombies from child processes being killed
signal(SIGCHLD, SIG_IGN); signal(SIGCHLD, func);
// test once to throw exception if arping failed
TestForErrors();
// Needs to be a fork and udp socket deleted after Listening threads // Needs to be a fork and udp socket deleted after Listening threads
// done running to prevent udp socket cannot bind because of popen // done running to prevent udp socket cannot bind because of popen
@ -90,7 +94,7 @@ void Arping::ProcessExecution() {
} }
} }
void Arping::TestCommands() { void Arping::TestForErrors() {
// atleast one interface must be set up // atleast one interface must be set up
if (commands[0].empty()) { if (commands[0].empty()) {
throw RuntimeError( throw RuntimeError(
@ -116,7 +120,8 @@ std::string Arping::ExecuteCommands() {
FILE *sysFile = popen(cmd.c_str(), "r"); FILE *sysFile = popen(cmd.c_str(), "r");
if (sysFile == NULL) { if (sysFile == NULL) {
std::ostringstream os; std::ostringstream os;
os << "Could not Arping [" << cmd << " ] : Popen fail"; os << "Could not Arping (" << cmd << " ) : Popen fail ("
<< strerror(errno) << ')';
return os.str(); return os.str();
} }
@ -128,7 +133,7 @@ std::string Arping::ExecuteCommands() {
// check exit status of command // check exit status of command
if (pclose(sysFile)) { if (pclose(sysFile)) {
std::ostringstream os; std::ostringstream os;
os << "Could not arping[" << cmd << "] : " << output; os << "Could not arping (" << cmd << ") : " << strerror(errno);
return os.str(); return os.str();
} else { } else {
LOG(logDEBUG) << output; LOG(logDEBUG) << output;

View File

@ -28,7 +28,7 @@ class Arping {
void StopProcess(); void StopProcess();
private: private:
void TestCommands(); void TestForErrors();
std::string ExecuteCommands(); std::string ExecuteCommands();
void ProcessExecution(); void ProcessExecution();

View File

@ -45,6 +45,7 @@ ClientInterface::ClientInterface(int portNumber)
: detType(GOTTHARD), : detType(GOTTHARD),
portNumber(portNumber > 0 ? portNumber : DEFAULT_TCP_RX_PORTNO), portNumber(portNumber > 0 ? portNumber : DEFAULT_TCP_RX_PORTNO),
server(portNumber) { server(portNumber) {
validatePortNumber(portNumber);
functionTable(); functionTable();
parentThreadId = gettid(); parentThreadId = gettid();
tcpThread = tcpThread =

View File

@ -56,6 +56,8 @@ void DataStreamer::SetAdditionalJsonHeader(
isAdditionalJsonUpdated = true; isAdditionalJsonUpdated = true;
} }
void DataStreamer::SetReceiverROI(ROI roi) { receiverRoi = roi; }
void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) { void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
StopRunning(); StopRunning();
startedFlag = false; startedFlag = false;
@ -249,6 +251,7 @@ int DataStreamer::SendDataHeader(sls_detector_header header, uint32_t size,
isAdditionalJsonUpdated = false; isAdditionalJsonUpdated = false;
} }
zHeader.addJsonHeader = localAdditionalJsonHeader; zHeader.addJsonHeader = localAdditionalJsonHeader;
zHeader.rx_roi = receiverRoi.getIntArray();
return zmqSocket->SendHeader(index, zHeader); return zmqSocket->SendHeader(index, zHeader);
} }

View File

@ -38,6 +38,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
void SetNumberofTotalFrames(uint64_t value); void SetNumberofTotalFrames(uint64_t value);
void void
SetAdditionalJsonHeader(const std::map<std::string, std::string> &json); SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
void SetReceiverROI(ROI roi);
void ResetParametersforNewAcquisition(const std::string &fname); void ResetParametersforNewAcquisition(const std::string &fname);
/** /**
@ -92,6 +93,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
uint64_t fileIndex{0}; uint64_t fileIndex{0};
bool flipRows{false}; bool flipRows{false};
std::map<std::string, std::string> additionalJsonHeader; std::map<std::string, std::string> additionalJsonHeader;
ROI receiverRoi{};
/** Used by streamer thread to update local copy (reduce number of locks /** Used by streamer thread to update local copy (reduce number of locks
* during streaming) */ * during streaming) */

View File

@ -14,14 +14,14 @@ HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib)
"frame number", "frame number",
"exp length or sub exposure time", "exp length or sub exposure time",
"packets caught", "packets caught",
"bunch id", "detector specific 1",
"timestamp", "timestamp",
"mod id", "mod id",
"row", "row",
"column", "column",
"reserved", "detector specific 2",
"debug", "detector specific 3",
"round robin number", "detector specific 4",
"detector type", "detector type",
"detector header version", "detector header version",
"packets caught bit mask", "packets caught bit mask",
@ -317,7 +317,7 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
dataSetPara[2]->write(&header.packetNumber, parameterDataTypes[2], dataSetPara[2]->write(&header.packetNumber, parameterDataTypes[2],
memspace, *dataSpacePara); memspace, *dataSpacePara);
i = 3; i = 3;
dataSetPara[3]->write(&header.bunchId, parameterDataTypes[3], memspace, dataSetPara[3]->write(&header.detSpec1, parameterDataTypes[3], memspace,
*dataSpacePara); *dataSpacePara);
i = 4; i = 4;
dataSetPara[4]->write(&header.timestamp, parameterDataTypes[4], dataSetPara[4]->write(&header.timestamp, parameterDataTypes[4],
@ -332,13 +332,13 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
dataSetPara[7]->write(&header.column, parameterDataTypes[7], memspace, dataSetPara[7]->write(&header.column, parameterDataTypes[7], memspace,
*dataSpacePara); *dataSpacePara);
i = 8; i = 8;
dataSetPara[8]->write(&header.reserved, parameterDataTypes[8], memspace, dataSetPara[8]->write(&header.detSpec2, parameterDataTypes[8], memspace,
*dataSpacePara); *dataSpacePara);
i = 9; i = 9;
dataSetPara[9]->write(&header.debug, parameterDataTypes[9], memspace, dataSetPara[9]->write(&header.detSpec3, parameterDataTypes[9], memspace,
*dataSpacePara); *dataSpacePara);
i = 10; i = 10;
dataSetPara[10]->write(&header.roundRNumber, parameterDataTypes[10], dataSetPara[10]->write(&header.detSpec4, parameterDataTypes[10],
memspace, *dataSpacePara); memspace, *dataSpacePara);
i = 11; i = 11;
dataSetPara[11]->write(&header.detType, parameterDataTypes[11], dataSetPara[11]->write(&header.detType, parameterDataTypes[11],

View File

@ -216,6 +216,8 @@ void Implementation::SetupDataStreamer(int i) {
dataStreamer[i]->SetNumberofPorts(numPorts); dataStreamer[i]->SetNumberofPorts(numPorts);
dataStreamer[i]->SetQuadEnable(quadEnable); dataStreamer[i]->SetQuadEnable(quadEnable);
dataStreamer[i]->SetNumberofTotalFrames(numberOfTotalFrames); dataStreamer[i]->SetNumberofTotalFrames(numberOfTotalFrames);
dataStreamer[i]->SetReceiverROI(
portRois[i].completeRoi() ? GetMaxROIPerPort() : portRois[i]);
} }
slsDetectorDefs::xy Implementation::getDetectorSize() const { slsDetectorDefs::xy Implementation::getDetectorSize() const {
@ -231,6 +233,11 @@ const slsDetectorDefs::xy Implementation::GetPortGeometry() const {
return portGeometry; return portGeometry;
} }
const slsDetectorDefs::ROI Implementation::GetMaxROIPerPort() const {
return slsDetectorDefs::ROI{0, (int)generalData->nPixelsX - 1, 0,
(int)generalData->nPixelsY - 1};
}
void Implementation::setDetectorSize(const slsDetectorDefs::xy size) { void Implementation::setDetectorSize(const slsDetectorDefs::xy size) {
xy portGeometry = GetPortGeometry(); xy portGeometry = GetPortGeometry();
@ -458,6 +465,10 @@ void Implementation::setReceiverROI(const slsDetectorDefs::ROI arg) {
listener[i]->SetNoRoi(portRois[i].noRoi()); listener[i]->SetNoRoi(portRois[i].noRoi());
for (size_t i = 0; i != dataProcessor.size(); ++i) for (size_t i = 0; i != dataProcessor.size(); ++i)
dataProcessor[i]->SetReceiverROI(portRois[i]); dataProcessor[i]->SetReceiverROI(portRois[i]);
for (size_t i = 0; i != dataStreamer.size(); ++i) {
dataStreamer[i]->SetReceiverROI(
portRois[i].completeRoi() ? GetMaxROIPerPort() : portRois[i]);
}
LOG(logINFO) << "receiver roi: " << ToString(receiverRoi); LOG(logINFO) << "receiver roi: " << ToString(receiverRoi);
if (generalData->numUDPInterfaces == 2 && if (generalData->numUDPInterfaces == 2 &&
generalData->detType != slsDetectorDefs::GOTTHARD2) { generalData->detType != slsDetectorDefs::GOTTHARD2) {

View File

@ -282,6 +282,7 @@ class Implementation : private virtual slsDetectorDefs {
void SetupFifoStructure(); void SetupFifoStructure();
const xy GetPortGeometry() const; const xy GetPortGeometry() const;
const ROI GetMaxROIPerPort() const;
void ResetParametersforNewAcquisition(); void ResetParametersforNewAcquisition();
void CreateUDPSockets(); void CreateUDPSockets();
void SetupWriter(); void SetupWriter();

View File

@ -19,8 +19,8 @@ namespace sls {
// files // files
// versions // versions
#define HDF5_WRITER_VERSION (6.5) // 1 decimal places #define HDF5_WRITER_VERSION (6.6) // 1 decimal places
#define BINARY_WRITER_VERSION (7.1) // 1 decimal places #define BINARY_WRITER_VERSION (7.2) // 1 decimal places
#define MAX_FRAMES_PER_FILE 20000 #define MAX_FRAMES_PER_FILE 20000
#define SHORT_MAX_FRAMES_PER_FILE 100000 #define SHORT_MAX_FRAMES_PER_FILE 100000

View File

@ -103,4 +103,13 @@ template <typename T> struct is_vector : public std::false_type {};
template <typename T> template <typename T>
struct is_vector<std::vector<T>> : public std::true_type {}; struct is_vector<std::vector<T>> : public std::true_type {};
template <class...> struct Conjunction : std::true_type {};
template <class B1> struct Conjunction<B1> : B1 {};
template <class B1, class... Bn>
struct Conjunction<B1, Bn...>
: std::conditional<bool(B1::value), Conjunction<Bn...>, B1>::type {};
template <typename T, typename... Ts>
using AllSame =
typename std::enable_if<Conjunction<std::is_same<T, Ts>...>::value>::type;
} // namespace sls } // namespace sls

View File

@ -12,6 +12,7 @@
#include "sls/container_utils.h" #include "sls/container_utils.h"
#include "sls/sls_detector_exceptions.h" #include "sls/sls_detector_exceptions.h"
#include <array>
#include <map> #include <map>
#include <memory> #include <memory>
@ -83,6 +84,8 @@ struct zmqHeader {
bool completeImage{false}; bool completeImage{false};
/** additional json header */ /** additional json header */
std::map<std::string, std::string> addJsonHeader; std::map<std::string, std::string> addJsonHeader;
/** (xmin, xmax, ymin, ymax) roi only in files written */
std::array<int, 4> rx_roi{};
}; };
class ZmqSocket { class ZmqSocket {

View File

@ -2,6 +2,7 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once #pragma once
#include <array> #include <array>
#include <cstdint>
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -87,5 +88,5 @@ IpAddr HostnameToIp(const char *hostname);
std::string IpToInterfaceName(const std::string &ip); std::string IpToInterfaceName(const std::string &ip);
MacAddr InterfaceNameToMac(const std::string &inf); MacAddr InterfaceNameToMac(const std::string &inf);
IpAddr InterfaceNameToIp(const std::string &ifn); IpAddr InterfaceNameToIp(const std::string &ifn);
void validatePortNumber(int port);
} // namespace sls } // namespace sls

View File

@ -46,7 +46,7 @@
#define MAX_UDP_DESTINATION 32 #define MAX_UDP_DESTINATION 32
#define SLS_DETECTOR_HEADER_VERSION 0x2 #define SLS_DETECTOR_HEADER_VERSION 0x2
#define SLS_DETECTOR_JSON_HEADER_VERSION 0x4 #define SLS_DETECTOR_JSON_HEADER_VERSION 0x5
// ctb/ moench 1g udp (read from fifo) // ctb/ moench 1g udp (read from fifo)
#define UDP_PACKET_DATA_BYTES (1344) #define UDP_PACKET_DATA_BYTES (1344)

View File

@ -1,13 +1,13 @@
// SPDX-License-Identifier: LGPL-3.0-or-other // SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
/** API versions */ /** API versions */
#define RELEASE "7.0.0" #define RELEASE "7.0.3"
#define APICTB "7.0.0 0x230222" #define APILIB "7.0.3 0x231108"
#define APIGOTTHARD "7.0.0 0x230222" #define APIRECEIVER "7.0.3 0x231108"
#define APIGOTTHARD2 "7.0.0 0x230222" #define APICTB "7.0.3 0x231109"
#define APIJUNGFRAU "7.0.0 0x230222" #define APIGOTTHARD "7.0.3 0x231109"
#define APIMYTHEN3 "7.0.0 0x230222" #define APIGOTTHARD2 "7.0.3 0x231109"
#define APIMOENCH "7.0.0 0x230222" #define APIJUNGFRAU "7.0.3 0x231109"
#define APIEIGER "7.0.0 0x230222" #define APIMYTHEN3 "7.0.3 0x231109"
#define APILIB "7.0.0 0x230223" #define APIMOENCH "7.0.3 0x231109"
#define APIRECEIVER "7.0.0 0x230222" #define APIEIGER "7.0.3 0x231109"

View File

@ -254,6 +254,8 @@ int ZmqSocket::SendHeader(int index, zmqHeader header) {
} }
oss << " } "; oss << " } ";
} }
oss << ", \"rx_roi\":[" << header.rx_roi[0] << ", " << header.rx_roi[1]
<< ", " << header.rx_roi[2] << ", " << header.rx_roi[3] << "]";
oss << "}\n"; oss << "}\n";
std::string message = oss.str(); std::string message = oss.str();
int length = message.length(); int length = message.length();
@ -375,6 +377,11 @@ int ZmqSocket::ParseHeader(const int index, int length, char *buff,
} }
} }
const Value &a = document["rx_roi"].GetArray();
for (SizeType i = 0; i != a.Size(); ++i) {
zHeader.rx_roi[i] = a[i].GetInt();
}
return 1; return 1;
} }

View File

@ -10,6 +10,7 @@
#include <cstring> #include <cstring>
#include <ifaddrs.h> #include <ifaddrs.h>
#include <iomanip> #include <iomanip>
#include <limits>
#include <net/if.h> #include <net/if.h>
#include <netdb.h> #include <netdb.h>
#include <sstream> #include <sstream>
@ -203,4 +204,13 @@ MacAddr InterfaceNameToMac(const std::string &inf) {
return MacAddr(mac); return MacAddr(mac);
} }
void validatePortNumber(int port) {
if (0 >= port || port > std::numeric_limits<uint16_t>::max()) {
std::ostringstream oss;
oss << "Invalid port number " << port << ". It must be in range 1 - "
<< std::numeric_limits<uint16_t>::max();
throw RuntimeError(oss.str());
}
}
} // namespace sls } // namespace sls