Compare commits

..

74 Commits

Author SHA1 Message Date
c4c2866905 WIP 2020-04-27 17:21:22 +02:00
b90f9b046f getHostname 2020-04-27 17:03:52 +02:00
d66df844e5 added parallel and container3 2020-04-27 15:20:13 +02:00
4f712fcd70 WIP 2020-04-24 15:28:41 +02:00
bb32b2f653 rxr done WIP 2020-04-24 15:13:37 +02:00
085cbbf0d6 WIP, separated rxr from module 2020-04-23 16:09:40 +02:00
45a770cf38 WIP 2020-04-23 15:16:14 +02:00
990008c9d9 WIP 2020-04-23 12:20:04 +02:00
5339e16101 port sequences and client zmq implementation needs revisit, WIP 2020-04-22 17:55:02 +02:00
c976c63fb5 WIP udp 2020-04-22 14:05:20 +02:00
9ee2d389fb WIP 2020-04-22 13:43:10 +02:00
8d0146949c WIP 2020-04-22 12:54:55 +02:00
6de68eacc2 WIP 2020-04-21 18:48:04 +02:00
94103a05b1 parallel3 fix, software version check 2020-04-21 18:27:52 +02:00
1185f1ea17 WIP, a in shm name 2020-04-21 18:02:27 +02:00
d3f420ffd4 WIP, indexstring 2020-04-21 17:14:09 +02:00
6b5511c9e5 WIP, moved bool primaryinterface to an int interface_id 2020-04-21 14:34:48 +02:00
d8aa1ab08e json para and header added 2020-04-21 14:10:07 +02:00
b4c31327d6 WIP, temp fix 2020-04-21 12:35:08 +02:00
c408f9807a Merge branch 'developer' into separateRxr 2020-04-21 11:30:23 +02:00
c1ae67ac46 Small refactor on ThreadObject and listener (#93)
* removed pointer, slight cleaning of loop

* removed semaphore, use getters

* removed redundant log msg

* removed comment

* added const

* removed comment

* changed header
2020-04-21 09:45:29 +02:00
9df128fced WIP, cant compile squash for rxParameters 2020-04-20 18:35:30 +02:00
e39ec65d19 Merge branch 'developer' into separateRxr 2020-04-20 18:33:37 +02:00
601be462af WIP, rxhostname 2020-04-20 18:33:14 +02:00
68f76e5356 more like UdpRxSocket 2020-04-20 17:24:53 +02:00
8afa11ed33 removed pointer to server socket 2020-04-20 17:20:33 +02:00
bc389f4825 moved data members to top 2020-04-20 14:51:48 +02:00
095ced153c removed need for pointer 2020-04-20 14:31:10 +02:00
1d31695cc1 WIP 2020-04-17 12:15:16 +02:00
df63a6dffe rx_statusL unknown, but others good WIP 2020-04-17 12:09:23 +02:00
cfa9049ed3 WIP: none to remove receivers 2020-04-17 10:34:10 +02:00
a1a5a20845 from thread sanitizer 2020-04-17 09:35:38 +02:00
9a208caca8 WIP: first connect to rxr 2020-04-16 18:20:04 +02:00
78fb8080ce WIP: some bug fixes and reducing redundant code 2020-04-16 18:07:11 +02:00
cd45f9d45b WIP, parallel 2020-04-16 16:18:50 +02:00
c725a05ef8 fix RH7 2020-04-16 15:51:28 +02:00
d536ad2b5b WIP, rxr constr done 2020-04-16 13:58:59 +02:00
815b6a37aa moved flag to base class 2020-04-16 13:22:51 +02:00
655a410d43 cleaned up UdpRxSocket 2020-04-16 09:45:44 +02:00
97ba81d923 fixed test 2020-04-14 16:58:37 +02:00
3d00eed0f0 Change SetTrimbits() and SaveAllTrimbits() to rely on top/bottom signal instead of TopAddressIsValid() for further cleanup. 2020-04-14 16:13:26 +02:00
2921cbfac8 WIP 2020-04-14 12:44:43 +02:00
a7f5300455 Merge pull request #92 from slsdetectorgroup/setrxhostname
Setrxhostname
2020-04-09 11:52:46 +02:00
2f33a1a479 updated binaries 2020-04-09 09:35:46 +02:00
39fa5e0185 client recieve rx parameters as a struct 2020-04-09 09:34:20 +02:00
ba4985ed4d Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into developer 2020-04-09 09:32:09 +02:00
f811c065d1 corrected a delete [] in multiThreadedAnalogDetector 2020-04-09 09:31:43 +02:00
3a1d87728c updated client api 2020-04-09 08:38:37 +02:00
0652ff6b5a updated binaries 2020-04-09 08:37:27 +02:00
373e177274 WIP 2020-04-09 08:35:30 +02:00
6dd6685e7d minor 2020-04-09 08:24:16 +02:00
38c31fdada WIP 2020-04-08 20:27:10 +02:00
b3fe0e79bc WIP 2020-04-08 16:43:28 +02:00
215e4a56fd Merge branch 'developer' into setrxhostname 2020-04-08 12:00:21 +02:00
71a68c2022 eiger transmitting fix in 10g mode (stop servers informed about 10g mode) 2020-04-08 11:58:59 +02:00
55f8497eac WIP 2020-04-08 11:05:06 +02:00
738f341265 eiger server compiled from previous commit 2020-04-08 08:41:39 +02:00
c4ae876ca7 Add Eiger server Init() modification also to initStopServer() 2020-04-07 17:45:53 +02:00
07cd71f0c7 removed update shared memory from detector, check if eiger firmware >=26: have same top and bottom addresses 2020-04-07 17:19:47 +02:00
9f3ad4e2f4 merge from 4.2.0 2020-04-07 15:14:27 +02:00
ab9fed45fb Merge pull request #91 from slsdetectorgroup/testing
Testing
2020-04-07 12:15:37 +02:00
a86ae0cb47 WIP 2020-04-07 12:14:22 +02:00
bdf0f9e2b9 fixed start stop tests 2020-04-07 10:39:50 +02:00
fad10273ed fix for server crashing when sending udp packets if no udp server present to listen to it (receiver): cannot use connect and write 2020-04-07 09:57:22 +02:00
83283b672a WIP 2020-04-06 19:38:35 +02:00
456b96446f WIP 2020-04-06 17:59:06 +02:00
80e55cd4da WIP 2020-04-06 17:28:05 +02:00
47b0e46f15 Merge branch 'developer' into testing 2020-04-06 10:55:41 +02:00
fdb6e3f3d4 Removeshm (#90)
* eiger: moved rate correction outside, fixed threshold energy bug in client (binaries not  updated yet)

* removed dr and deadtiem from shm

* help for rx_status and status to point them to rx_Start, rx_stop, start and stop

* moved progress to receiver

* removed currentsettings from eiger shm

* updated server binaries, and client api

* moench and ctb virtual servers compile fix

* gui: moved acquire to a concurrent qt thread so it doesnt block updateplot
2020-04-06 10:44:44 +02:00
eeed102bf3 somewhere between fork and pipes, crashes at sendingudppacket at print 2020-04-03 20:18:16 +02:00
7c7f7e8c70 testing WIP 2020-04-03 16:20:05 +02:00
262b4b0b16 more tests 2020-03-31 18:19:32 +02:00
83010de9f4 updated all binaries, previous ones may not work 2020-03-31 16:58:35 +02:00
f2dd146e56 updates on servers (mainly virtual): indices, dbit clock not allowed for moench anymore 2020-03-31 16:54:35 +02:00
101 changed files with 7314 additions and 5400 deletions

View File

@ -320,7 +320,7 @@ public:
// int nnx, nny, ns;
int nn=dets[0]->getImageSize(nnx, nny,ns, nsy);
if (image) {
delete image;
delete [] image;
image=NULL;
}
image=new int[nn];

View File

@ -429,7 +429,7 @@ int *getClusters(char *data, int *ph=NULL) {
max=*v;
}
}
}
}

View File

@ -59,11 +59,9 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
private slots:
void SetSaveFileName(QString val);
void AcquireThread();
void UpdatePlot();
signals:
void StartAcquireSignal();
void AcquireFinishedSignal();
void AbortSignal();
void UpdateSignal();
@ -74,6 +72,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
void SetupPlots();
void GetStatistics(double &min, double &max, double &sum);
void DetachHists();
void AcquireThread();
static void GetAcquisitionFinishedCallBack(double currentProgress,
int detectorStatus,
void *this_pointer);

View File

@ -87,7 +87,6 @@ void qDrawPlot::SetupWidgetWindow() {
void qDrawPlot::Initialization() {
connect(this, SIGNAL(UpdateSignal()), this, SLOT(UpdatePlot()));
connect(this, SIGNAL(StartAcquireSignal()), this, SLOT(AcquireThread()));
}
void qDrawPlot::SetupPlots() {
@ -657,7 +656,8 @@ void qDrawPlot::StartAcquisition() {
xyRangeChanged = true;
}
emit StartAcquireSignal();
QtConcurrent::run(this, &qDrawPlot::AcquireThread);
LOG(logDEBUG) << "End of Starting Acquisition in qDrawPlot";
}

View File

@ -16,6 +16,7 @@ add_executable(ctbDetectorServer_virtual
../slsDetectorServer/src/LTC2620.c
../slsDetectorServer/src/MAX1932.c
../slsDetectorServer/src/programFpgaBlackfin.c
../slsDetectorServer/src/communication_virtual.c
)
include_directories(
@ -33,6 +34,7 @@ target_compile_definitions(ctbDetectorServer_virtual
target_link_libraries(ctbDetectorServer_virtual
PUBLIC pthread rt slsProjectCWarnings
m
)
set_target_properties(ctbDetectorServer_virtual PROPERTIES

View File

@ -10,6 +10,9 @@
#include "MAX1932.h" // hv
#include "INA226.h" // i2c
#include "ALTERA_PLL.h" // pll
#ifdef VIRTUAL
#include "communication_virtual.h"
#endif
#include <string.h>
#include <unistd.h> // usleep
@ -30,6 +33,7 @@ extern uint64_t udpFrameNumber;
extern uint32_t udpPacketNumber;
// Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip);
@ -427,6 +431,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE);
}
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
}
@ -469,7 +479,12 @@ void setupDetector() {
digitalEnable = 0;
naSamples = 1;
ndSamples = 1;
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
ALTERA_PLL_ResetPLLAndReconfiguration();
resetCore();
@ -1386,12 +1401,6 @@ int getADC(enum ADCINDEX ind){
int setHighVoltage(int val){
#ifdef VIRTUAL
if (val >= 0)
highvoltage = val;
return highvoltage;
#endif
// setting hv
if (val >= 0) {
LOG(logINFO, ("Setting High voltage: %d V\n", val));
@ -1400,7 +1409,7 @@ int setHighVoltage(int val){
// switch to external high voltage
bus_w(addr, bus_r(addr) & (~POWER_HV_INTERNAL_SLCT_MSK));
MAX1932_Set(val);
MAX1932_Set(&val);
// switch on internal high voltage, if set
if (val > 0)
@ -2159,10 +2168,21 @@ int startStateMachine(){
}
LOG(logINFOBLUE, ("Starting State Machine\n"));
virtual_status = 1;
virtual_stop = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL;
}
LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -2196,6 +2216,10 @@ int startStateMachine(){
#ifdef VIRTUAL
void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() *
getNumTriggers() );
@ -2222,6 +2246,8 @@ void* start_timer(void* arg) {
// loop over number of frames
for(frameNr = 0; frameNr != numFrames; ++frameNr ) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high
if(virtual_stop == 1){
break;
@ -2274,6 +2300,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0);
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL;
}
@ -2282,7 +2311,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK;
#endif
//stop state machine
@ -2301,7 +2341,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){
#ifdef VIRTUAL
if(virtual_status == 0){
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE;
}else{
@ -2573,6 +2616,9 @@ int readFrameFromFifo() {
uint32_t runBusy() {
#ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status;
#endif
uint32_t s = (bus_r(STATUS_REG) & STATUS_RN_BSY_MSK);

View File

@ -178,120 +178,100 @@ void Beb_GetModuleConfiguration(int* master, int* top, int* normal) {
void Beb_EndofDataSend(int tengiga) {
int Beb_IsTransmitting(int* retval, int tengiga, int waitForDelay) {
//mapping new memory
u_int32_t* csp0base=0;
int l_framepktLsbcounter, l_framepktMsbcounter, l_txndelaycounter, l_framedelaycounter;
int r_framepktLsbcounter, r_framepktMsbcounter, r_txndelaycounter, r_framedelaycounter;
int l_framepktLsbcounter_new, l_framepktMsbcounter_new, l_txndelaycounter_new, l_framedelaycounter_new;
int r_framepktLsbcounter_new, r_framepktMsbcounter_new, r_txndelaycounter_new, r_framedelaycounter_new;
int addr_l_framepktLsbcounter, addr_l_framepktMsbcounter, addr_l_txndelaycounter, addr_l_framedelaycounter;
int addr_r_framepktLsbcounter, addr_r_framepktMsbcounter, addr_r_txndelaycounter, addr_r_framedelaycounter;
switch(tengiga) {
case 0:
addr_l_framepktLsbcounter = ONE_GIGA_LEFT_INDEX_LSB_COUNTER;
addr_l_framepktMsbcounter = ONE_GIGA_LEFT_INDEX_MSB_COUNTER;
addr_l_txndelaycounter = ONE_GIGA_LEFT_TXN_DELAY_COUNTER;
addr_l_framedelaycounter = ONE_GIGA_LEFT_FRAME_DELAY_COUNTER;
addr_r_framepktLsbcounter = ONE_GIGA_RIGHT_INDEX_LSB_COUNTER;
addr_r_framepktMsbcounter = ONE_GIGA_RIGHT_INDEX_MSB_COUNTER;
addr_r_txndelaycounter = ONE_GIGA_RIGHT_TXN_DELAY_COUNTER;
addr_r_framedelaycounter = ONE_GIGA_RIGHT_FRAME_DELAY_COUNTER;
break;
case 1:
addr_l_framepktLsbcounter = TEN_GIGA_LEFT_INDEX_LSB_COUNTER;
addr_l_framepktMsbcounter = TEN_GIGA_LEFT_INDEX_MSB_COUNTER;
u_int32_t* csp0base = 0;
int addr_l_txndelaycounter = 0, addr_l_framedelaycounter = 0;
int addr_r_txndelaycounter = 0, addr_r_framedelaycounter = 0;
int addr_l_framepktLsbcounter = 0, addr_l_framepktMsbcounter = 0;
int addr_r_framepktLsbcounter = 0, addr_r_framepktMsbcounter = 0;
if (tengiga) {
addr_l_txndelaycounter = TEN_GIGA_LEFT_TXN_DELAY_COUNTER;
addr_l_framedelaycounter = TEN_GIGA_LEFT_FRAME_DELAY_COUNTER;
addr_r_framepktLsbcounter = TEN_GIGA_RIGHT_INDEX_LSB_COUNTER;
addr_r_framepktMsbcounter = TEN_GIGA_RIGHT_INDEX_MSB_COUNTER;
addr_r_txndelaycounter = TEN_GIGA_RIGHT_TXN_DELAY_COUNTER;
addr_r_framedelaycounter = TEN_GIGA_RIGHT_FRAME_DELAY_COUNTER;
break;
addr_l_framepktLsbcounter = TEN_GIGA_LEFT_INDEX_LSB_COUNTER;
addr_l_framepktMsbcounter = TEN_GIGA_LEFT_INDEX_MSB_COUNTER;
addr_r_framepktLsbcounter = TEN_GIGA_RIGHT_INDEX_LSB_COUNTER;
addr_r_framepktMsbcounter = TEN_GIGA_RIGHT_INDEX_MSB_COUNTER;
} else {
addr_l_txndelaycounter = ONE_GIGA_LEFT_TXN_DELAY_COUNTER;
addr_l_framedelaycounter = ONE_GIGA_LEFT_FRAME_DELAY_COUNTER;
addr_r_txndelaycounter = ONE_GIGA_RIGHT_TXN_DELAY_COUNTER;
addr_r_framedelaycounter = ONE_GIGA_RIGHT_FRAME_DELAY_COUNTER;
addr_l_framepktLsbcounter = ONE_GIGA_LEFT_INDEX_LSB_COUNTER;
addr_l_framepktMsbcounter = ONE_GIGA_LEFT_INDEX_MSB_COUNTER;
addr_r_framepktLsbcounter = ONE_GIGA_RIGHT_INDEX_LSB_COUNTER;
addr_r_framepktMsbcounter = ONE_GIGA_RIGHT_INDEX_MSB_COUNTER;
}
//open file pointer
int fd = Beb_open(&csp0base,XPAR_COUNTER_BASEADDR);
if (fd < 0) {
LOG(logERROR, ("Delay read counter fail\n"));
return;
if(fd < 0){
cprintf(BG_RED,"Could not read Beb Delay read counter\n");
return FAIL;
} else {
//read data first time
l_framepktLsbcounter = Beb_Read32(csp0base, addr_l_framepktLsbcounter);
l_framepktMsbcounter = Beb_Read32(csp0base, addr_l_framepktMsbcounter);
l_txndelaycounter = Beb_Read32(csp0base, addr_l_txndelaycounter);
l_framedelaycounter = Beb_Read32(csp0base, addr_l_framedelaycounter);
r_framepktLsbcounter = Beb_Read32(csp0base, addr_r_framepktLsbcounter);
r_framepktMsbcounter = Beb_Read32(csp0base, addr_r_framepktMsbcounter);
r_txndelaycounter = Beb_Read32(csp0base, addr_r_txndelaycounter);
r_framedelaycounter = Beb_Read32(csp0base, addr_r_framedelaycounter);
LOG(logDEBUG1, ("\nLeft\n"
"FramepacketLsbcounter: %d\n"
"FramepacketMsbcounter: %d\n"
"Txndelaycounter:%d\n"
"Framedelaycounter:%d\n"
"\nRight\n"
"FramepacketLsbcounter: %d\n"
"FramepacketMsbcounter: %d\n"
"Txndelaycounter:%d\n"
"Framedelaycounter:%d\n\n",
l_framepktLsbcounter,l_framepktMsbcounter,l_txndelaycounter,l_framedelaycounter,
r_framepktLsbcounter,r_framepktMsbcounter,r_txndelaycounter,r_framedelaycounter));
//keep comparing with previous values
int maxtimer;
while(1) {
maxtimer = MAX(MAX(l_txndelaycounter,l_framedelaycounter),MAX(r_txndelaycounter,r_framedelaycounter));
maxtimer /= 100;
LOG(logDEBUG1, ("Will wait for %d us\n",maxtimer));
usleep(maxtimer);
//read new values
l_framepktLsbcounter_new = Beb_Read32(csp0base, addr_l_framepktLsbcounter);
l_framepktMsbcounter_new = Beb_Read32(csp0base, addr_l_framepktMsbcounter);
l_txndelaycounter_new = Beb_Read32(csp0base, addr_l_txndelaycounter);
l_framedelaycounter_new = Beb_Read32(csp0base, addr_l_framedelaycounter);
r_framepktLsbcounter_new = Beb_Read32(csp0base, addr_r_framepktLsbcounter);
r_framepktMsbcounter_new = Beb_Read32(csp0base, addr_r_framepktMsbcounter);
r_txndelaycounter_new = Beb_Read32(csp0base, addr_r_txndelaycounter);
r_framedelaycounter_new = Beb_Read32(csp0base, addr_r_framedelaycounter);
LOG(logDEBUG1, ("\nLeft\n"
"FramepacketLsbcounter: %d\n"
"FramepacketMsbcounter: %d\n"
"Txndelaycounter:%d\n"
"Framedelaycounter:%d\n"
"\nRight\n"
"FramepacketLsbcounter: %d\n"
"FramepacketMsbcounter: %d\n"
"Txndelaycounter:%d\n"
"Framedelaycounter:%d\n\n",
l_framepktLsbcounter_new,l_framepktMsbcounter_new,l_txndelaycounter_new,l_framedelaycounter_new,
r_framepktLsbcounter_new,r_framepktMsbcounter_new,r_txndelaycounter_new,r_framedelaycounter_new));
if ((l_framepktLsbcounter == l_framepktLsbcounter_new) &&
(l_framepktMsbcounter == l_framepktMsbcounter_new) &&
(r_framepktLsbcounter == r_framepktLsbcounter_new) &&
(r_framepktMsbcounter == r_framepktMsbcounter_new))
break;
//update old values
l_framepktLsbcounter = l_framepktLsbcounter_new;
l_framepktMsbcounter = l_framepktMsbcounter_new;
l_txndelaycounter = l_txndelaycounter_new;
l_framedelaycounter = l_framedelaycounter_new;
r_framepktLsbcounter = r_framepktLsbcounter_new;
r_framepktMsbcounter = r_framepktMsbcounter_new;
r_txndelaycounter = r_txndelaycounter_new;
r_framedelaycounter = r_framedelaycounter_new;
int l_txndelaycounter = Beb_Read32(csp0base, addr_l_txndelaycounter);
int l_framedelaycounter = Beb_Read32(csp0base, addr_l_framedelaycounter);
int r_txndelaycounter = Beb_Read32(csp0base, addr_r_txndelaycounter);
int r_framedelaycounter = Beb_Read32(csp0base, addr_r_framedelaycounter);
int l_framepktLsbcounter = Beb_Read32(csp0base, addr_l_framepktLsbcounter);
int l_framepktMsbcounter = Beb_Read32(csp0base, addr_l_framepktMsbcounter);
int r_framepktLsbcounter = Beb_Read32(csp0base, addr_r_framepktLsbcounter);
int r_framepktMsbcounter = Beb_Read32(csp0base, addr_r_framepktMsbcounter);
#ifdef VERBOSE
printf("\nFirst Read:\n"
"\tLeft [Txndelaycounter:%d, Framedelaycounter:%d]\n"
"\tRight [Txndelaycounter:%d, Framedelaycounter:%d]\n",
"\tLeft [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n"
"\tRight [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n",
l_txndelaycounter,l_framedelaycounter, r_txndelaycounter,r_framedelaycounter,
l_framepktLsbcounter, l_framepktMsbcounter, r_framepktLsbcounter, r_framepktMsbcounter);
#endif
// wait for max counter delay
if (waitForDelay) {
int maxtimer = (MAX(MAX(l_txndelaycounter,l_framedelaycounter),MAX(r_txndelaycounter,r_framedelaycounter))) / 100; // counter values in 10 ns
printf("Will wait for %d us\n", maxtimer);
usleep (maxtimer);
}
// wait for 1 ms
else {
printf("Will wait for 1 ms\n");
usleep (1 * 1000);
}
LOG(logINFO, ("Detector has sent all data\n"));
// read values again
int l_txndelaycounter2 = Beb_Read32(csp0base, addr_l_txndelaycounter);
int l_framedelaycounter2 = Beb_Read32(csp0base, addr_l_framedelaycounter);
int r_txndelaycounter2 = Beb_Read32(csp0base, addr_r_txndelaycounter);
int r_framedelaycounter2 = Beb_Read32(csp0base, addr_r_framedelaycounter);
int l_framepktLsbcounter2 = Beb_Read32(csp0base, addr_l_framepktLsbcounter);
int l_framepktMsbcounter2 = Beb_Read32(csp0base, addr_l_framepktMsbcounter);
int r_framepktLsbcounter2 = Beb_Read32(csp0base, addr_r_framepktLsbcounter);
int r_framepktMsbcounter2 = Beb_Read32(csp0base, addr_r_framepktMsbcounter);
#ifdef VERBOSE
printf("\nSecond Read:\n"
"\tLeft [Txndelaycounter:%d, Framedelaycounter:%d]\n"
"\tRight [Txndelaycounter:%d, Framedelaycounter:%d]\n",
"\tLeft [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n"
"\tRight [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n",
l_txndelaycounter2,l_framedelaycounter2, r_txndelaycounter2,r_framedelaycounter2,
l_framepktLsbcounter2, l_framepktMsbcounter2, r_framepktLsbcounter2, r_framepktMsbcounter2);
#endif
// any change in values, it is still transmitting
if (l_txndelaycounter != l_txndelaycounter2 || l_framedelaycounter != l_framedelaycounter2 ||
r_txndelaycounter != r_txndelaycounter2 || r_framedelaycounter != r_framedelaycounter2 ||
l_framepktLsbcounter != l_framepktLsbcounter2 || l_framepktMsbcounter != l_framepktMsbcounter2 ||
r_framepktLsbcounter != r_framepktLsbcounter2 || r_framepktMsbcounter != r_framepktMsbcounter2) {
*retval = 1;
} else {
*retval = 0;
}
//close file pointer
Beb_close(fd,csp0base);
}
return OK;
}

View File

@ -34,7 +34,7 @@ unsigned int Beb_GetBebInfoIndex(unsigned int beb_numb);
void Beb_GetModuleConfiguration(int* master, int* top, int* normal);
void Beb_EndofDataSend(int tengiga);
int Beb_IsTransmitting(int* retval, int tengiga, int waitForDelay);
int Beb_SetMasterViaSoftware();
int Beb_SetSlaveViaSoftware();

View File

@ -5,6 +5,7 @@ set(src
../slsDetectorServer/src/communication_funcs.c
../slsDetectorServer/src/communication_funcs_UDP.c
../slsDetectorServer/src/common.c
../slsDetectorServer/src/communication_virtual.c
)
include_directories(

View File

@ -898,7 +898,7 @@ int Feb_Control_SendDACValue(unsigned int dst_num, unsigned int ch, unsigned int
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits) {
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits, int top) {
LOG(logINFO, ("Setting Trimbits\n"));
//for (int iy=10000;iy<20020;++iy)//263681
@ -963,7 +963,7 @@ int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits) {
int i;
for(i=0;i<8;i++) { // column loop i
if (Module_TopAddressIsValid(&modules[1])) {
if (top==1) {
trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_l+i])<<((7-i)*4);//low
trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_l+i])>>3)<<((7-i)*4);//upper
trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_r+i])<<((7-i)*4);//low
@ -1572,12 +1572,12 @@ int Feb_Control_StopAcquisition() {
int Feb_Control_SaveAllTrimbitsTo(int value) {
int Feb_Control_SaveAllTrimbitsTo(int value, int top) {
unsigned int chanregs[Feb_Control_trimbit_size];
int i;
for(i=0;i<Feb_Control_trimbit_size;i++)
chanregs[i] = value;
return Feb_Control_SetTrimbits(0,chanregs);
return Feb_Control_SetTrimbits(0,chanregs, top);
}

View File

@ -93,9 +93,9 @@ int Feb_Control_SetDAC(char* s, int value, int is_a_voltage_mv);
int Feb_Control_GetDAC(char* s, int* ret_value, int voltage_mv);
int Feb_Control_GetDACName(unsigned int dac_num,char* s);
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int* trimbits);
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int* trimbits, int top);
unsigned int* Feb_Control_GetTrimbits();
int Feb_Control_SaveAllTrimbitsTo(int value);
int Feb_Control_SaveAllTrimbitsTo(int value, int top);
int Feb_Control_Reset();
int Feb_Control_PrepareForAcquisition();

View File

@ -6,6 +6,8 @@
#ifndef VIRTUAL
#include "FebControl.h"
#include "Beb.h"
#else
#include "communication_virtual.h"
#endif
#include <unistd.h> //to gethostname
@ -67,9 +69,13 @@ int eiger_extgating = 0;
int eiger_extgatingpolarity = 0;
int eiger_nexposures = 1;
int eiger_ntriggers = 1;
int eiger_tau_ns = 0;
#ifdef VIRTUAL
pthread_t virtual_tid;
int virtual_status=0;
int virtual_stop = 0;
//values for virtual server
int64_t eiger_virtual_exptime = 0;
int64_t eiger_virtual_subexptime = 0;
@ -83,11 +89,8 @@ int eiger_virtual_transmission_delay_left=0;
int eiger_virtual_transmission_delay_right=0;
int eiger_virtual_transmission_delay_frame=0;
int eiger_virtual_transmission_flowcontrol_10g=0;
int eiger_virtual_status=0;
int eiger_virtual_activate=1;
pthread_t eiger_virtual_tid;
int eiger_virtual_stop = 0;
uint64_t eiger_virtual_startingframenumber = 0;
uint64_t eiger_virtual_startingframenumber = 1;
int eiger_virtual_detPos[2] = {0, 0};
int eiger_virtual_test_mode = 0;
int eiger_virtual_quad_mode = 0;
@ -324,7 +327,14 @@ void initControlServer() {
getModuleConfiguration();
Feb_Interface_FebInterface();
Feb_Control_FebControl();
Feb_Control_Init(master,top,normal, getDetectorNumber());
// different addresses for top and bottom
if (getFirmwareVersion() < FIRMWARE_VERSION_SAME_TOP_BOT_ADDR) {
Feb_Control_Init(master,top,normal, getDetectorNumber());
}
// same addresses for top and bottom
else {
Feb_Control_Init(master,1, normal, getDetectorNumber());
}
//master of 9M, check high voltage serial communication to blackfin
if (master && !normal) {
if (Feb_Control_OpenSerialCommunication())
@ -352,12 +362,23 @@ void initControlServer() {
void initStopServer() {
#ifdef VIRTUAL
getModuleConfiguration();
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
return;
#else
getModuleConfiguration();
Feb_Interface_FebInterface();
Feb_Control_FebControl();
Feb_Control_Init(master,top,normal,getDetectorNumber());
// different addresses for top and bottom
if (getFirmwareVersion() < FIRMWARE_VERSION_SAME_TOP_BOT_ADDR) {
Feb_Control_Init(master,top,normal, getDetectorNumber());
}
// same addresses for top and bottom
else {
Feb_Control_Init(master,1, normal, getDetectorNumber());
}
LOG(logDEBUG1, ("Stop server: FEB Initialization done\n"));
// activate (if it gets ip) (later FW will deactivate at startup)
// also needed for stop server for status
@ -468,6 +489,12 @@ void setupDetector() {
}
}
}
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
LOG(logINFOBLUE, ("Setting Default Parameters\n"));
//setting default measurement parameters
@ -477,6 +504,7 @@ void setupDetector() {
getSubExpTime(DEFAULT_SUBFRAME_DEADTIME);
setPeriod(DEFAULT_PERIOD);
setNumTriggers(DEFAULT_NUM_CYCLES);
eiger_dynamicrange = DEFAULT_DYNAMIC_RANGE;
setDynamicRange(DEFAULT_DYNAMIC_RANGE);
eiger_photonenergy = DEFAULT_PHOTON_ENERGY;
setParallelMode(DEFAULT_PARALLEL_MODE);
@ -488,6 +516,7 @@ void setupDetector() {
setStartingFrameNumber(DEFAULT_STARTING_FRAME_NUMBER);
setReadNLines(MAX_ROWS_PER_READOUT);
//SetPhotonEnergyCalibrationParameters(-5.8381e-5,1.838515,5.09948e-7,-4.32390e-11,1.32527e-15);
eiger_tau_ns = DEFAULT_RATE_CORRECTION;
setRateCorrection(DEFAULT_RATE_CORRECTION);
int enable[2] = {DEFAULT_EXT_GATING_ENABLE, DEFAULT_EXT_GATING_POLARITY};
setExternalGating(enable);//disable external gating
@ -532,31 +561,27 @@ int readRegister(uint32_t offset, uint32_t* retval) {
int setDynamicRange(int dr) {
#ifdef VIRTUAL
if (dr > 0) {
LOG(logINFO, ("Setting dynamic range: %d\n", dr));
eiger_dynamicrange = dr;
}
return eiger_dynamicrange;
#else
// setting dr
if (dr > 0) {
LOG(logDEBUG1, ("Setting dynamic range: %d\n", dr));
#ifndef VIRTUAL
if (Feb_Control_SetDynamicRange(dr)) {
//EigerSetBitMode(dr);
on_dst = 0;
int i;
for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested
if (Beb_SetUpTransferParameters(dr))
eiger_dynamicrange = dr;
else LOG(logERROR, ("Could not set bit mode in the back end\n"));
if (!Beb_SetUpTransferParameters(dr)) {
LOG(logERROR, ("Could not set bit mode in the back end\n"));
return eiger_dynamicrange;
}
}
}
//make sure back end and front end have the same bit mode
dr= Feb_Control_GetDynamicRange();
return dr;
#endif
eiger_dynamicrange = dr;
}
// getting dr
#ifndef VIRTUAL
eiger_dynamicrange = Feb_Control_GetDynamicRange();
#endif
return eiger_dynamicrange;
}
@ -734,7 +759,7 @@ int64_t getSubExpTime() {
#endif
}
int setDeadTime(int64_t val) {
int setSubDeadTime(int64_t val) {
LOG(logINFO, ("Setting subdeadtime %lld ns\n", (long long int)val));
#ifndef VIRTUAL
// get subexptime
@ -756,7 +781,7 @@ int setDeadTime(int64_t val) {
return OK;
}
int64_t getDeadTime() {
int64_t getSubDeadTime() {
#ifndef VIRTUAL
// get subexptime
int64_t subexptime = Feb_Control_GetSubFrameExposureTime();
@ -842,8 +867,9 @@ int setModule(sls_detector_module myMod, char* mess) {
}
}
}
// trimbits
#ifndef VIRTUAL
// trimbits
if (myMod.nchan == 0) {
LOG(logINFO, ("Setting module without trimbits\n"));
} else {
@ -864,7 +890,7 @@ int setModule(sls_detector_module myMod, char* mess) {
}
//set trimbits
if (!Feb_Control_SetTrimbits(Feb_Control_GetModuleNumber(), tt)) {
if (!Feb_Control_SetTrimbits(Feb_Control_GetModuleNumber(), tt,top)) {
sprintf(mess, "Could not set module. Could not set trimbits\n");
LOG(logERROR, (mess));
setSettings(UNDEFINED);
@ -872,6 +898,7 @@ int setModule(sls_detector_module myMod, char* mess) {
return FAIL;
}
}
#endif
//rate correction
@ -891,17 +918,24 @@ int setModule(sls_detector_module myMod, char* mess) {
else {
setDefaultSettingsTau_in_nsec(myMod.tau);
if (getRateCorrectionEnable()) {
int64_t retvalTau = setRateCorrection(myMod.tau);
if (myMod.tau != retvalTau) {
sprintf(mess, "Cannot set module. Could not set rate correction\n");
if (setRateCorrection(myMod.tau) == FAIL) {
sprintf(mess, "Cannot set module. Rate correction failed.\n");
LOG(logERROR, (mess));
setSettings(UNDEFINED);
LOG(logERROR, ("Settings has been changed to undefined (random trim file)\n"));
return FAIL;
return FAIL;
} else {
int64_t retvalTau = getCurrentTau();
if (myMod.tau != retvalTau) {
sprintf(mess, "Cannot set module. Could not set rate correction\n");
LOG(logERROR, (mess));
setSettings(UNDEFINED);
LOG(logERROR, ("Settings has been changed to undefined (random trim file)\n"));
return FAIL;
}
}
}
}
#endif
return OK;
}
@ -1246,7 +1280,7 @@ int configureMAC() {
int i=0;
/* for(i=0;i<32;i++) { modified for Aldo*/
if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) &&
if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,srcport) &&
Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) {
LOG(logDEBUG1, ("\tset up left ok\n"));
} else {
@ -1260,7 +1294,7 @@ int configureMAC() {
dst_port = dstport;
/*for(i=0;i<32;i++) {*//** modified for Aldo*/
if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) &&
if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,srcport) &&
Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) {
LOG(logDEBUG1, (" set up right ok\n"));
} else {
@ -1449,12 +1483,59 @@ int pulseChip(int n) {
return OK;
}
int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never be -1)
int updateRateCorrection(char* mess) {
int ret = OK;
// recalculates rate correction table, or switches off in wrong bit mode
if (eiger_tau_ns != 0) {
switch (eiger_dynamicrange) {
case 16:
case 32:
ret = setRateCorrection(eiger_tau_ns);
break;
default:
setRateCorrection(0);
strcpy(mess, "Rate correction Deactivated, must be in 32 or 16 bit mode");
ret = FAIL;
break;
}
}
getCurrentTau(); // update eiger_tau_ns
return ret;
}
int validateAndSetRateCorrection(int64_t tau_ns, char* mess) {
// switching on in wrong bit mode
if ((tau_ns != 0) &&
(eiger_dynamicrange != 32) && (eiger_dynamicrange != 16)) {
strcpy(mess,"Rate correction Deactivated, must be in 32 or 16 bit mode\n");
LOG(logERROR,(mess));
return FAIL;
}
// default tau (-1, get proper value)
if (tau_ns < 0) {
tau_ns = getDefaultSettingsTau_in_nsec();
if (tau_ns < 0) {
strcpy(mess,"Default settings file not loaded. No default tau yet\n");
LOG(logERROR,(mess));
return FAIL;
}
eiger_tau_ns = -1;
}
// user defined value (settings become undefined)
else if (tau_ns > 0) {
setSettings(UNDEFINED);
LOG(logERROR, ("Settings has been changed to undefined (tau changed)\n"));
eiger_tau_ns = tau_ns;
}
return setRateCorrection(tau_ns);
}
int setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never be -1)
#ifdef VIRTUAL
//deactivating rate correction
if (custom_tau_in_nsec==0) {
eiger_virtual_ratecorrection_variable = 0;
return 0;
return OK;
}
//when dynamic range changes, use old tau
@ -1484,22 +1565,21 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never
//different setting, calculate table
else {
eiger_virtual_ratetable_tau_in_ns = custom_tau_in_nsec;
double period_in_sec = (double)(eiger_virtual_subexptime*10)/(double)1e9;
eiger_virtual_ratetable_period_in_ns = eiger_virtual_subexptime*10;
if (eiger_dynamicrange == 16)
period_in_sec = eiger_virtual_exptime;
eiger_virtual_ratetable_period_in_ns = period_in_sec*1e9;
eiger_virtual_ratetable_period_in_ns = eiger_virtual_exptime;
}
//activating rate correction
eiger_virtual_ratecorrection_variable = 1;
LOG(logINFO, ("Rate Correction Value set to %lld ns\n",(long long int)eiger_virtual_ratetable_tau_in_ns));
return eiger_virtual_ratetable_tau_in_ns;
return OK;
#else
//deactivating rate correction
if (custom_tau_in_nsec==0) {
Feb_Control_SetRateCorrectionVariable(0);
return 0;
return OK;
}
//when dynamic range changes, use old tau
@ -1533,7 +1613,7 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never
if (ret<=0) {
LOG(logERROR, ("Rate correction failed. Deactivating rate correction\n"));
Feb_Control_SetRateCorrectionVariable(0);
return ret;
return FAIL;
}
}
//activating rate correction
@ -1541,7 +1621,7 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never
LOG(logINFO, ("Rate Correction Value set to %lld ns\n", (long long int)Feb_Control_Get_RateTable_Tau_in_nsec()));
Feb_Control_PrintCorrectedValues();
return Feb_Control_Get_RateTable_Tau_in_nsec();
return OK;
#endif
}
@ -1559,18 +1639,22 @@ int getDefaultSettingsTau_in_nsec() {
void setDefaultSettingsTau_in_nsec(int t) {
default_tau_from_file = t;
LOG(logINFO, ("Default tau set to %d\n", default_tau_from_file));
LOG(logINFOBLUE, ("Default tau set to %d\n", default_tau_from_file));
}
int64_t getCurrentTau() {
if (!getRateCorrectionEnable())
if (!getRateCorrectionEnable()) {
eiger_tau_ns = 0;
return 0;
else
}
else {
#ifndef VIRTUAL
return Feb_Control_Get_RateTable_Tau_in_nsec();
eiger_tau_ns = Feb_Control_Get_RateTable_Tau_in_nsec();
#else
return eiger_virtual_ratetable_tau_in_ns;
eiger_tau_ns = eiger_virtual_ratetable_tau_in_ns;
#endif
return eiger_tau_ns;
}
}
void setExternalGating(int enable[]) {
@ -1587,7 +1671,7 @@ void setExternalGating(int enable[]) {
int setAllTrimbits(int val) {
#ifndef VIRTUAL
if (!Feb_Control_SaveAllTrimbitsTo(val)) {
if (!Feb_Control_SaveAllTrimbitsTo(val,top)) {
LOG(logERROR, ("Could not set all trimbits\n"));
return FAIL;
}
@ -1745,11 +1829,22 @@ int startStateMachine() {
return FAIL;
}
LOG(logINFOBLUE, ("Starting State Machine\n"));
eiger_virtual_status = 1;
eiger_virtual_stop = 0;
if (pthread_create(&eiger_virtual_tid, NULL, &start_timer, NULL)) {
virtual_status = 1;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if (pthread_create(&virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
eiger_virtual_status = 0;
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL;
}
LOG(logINFO ,("Virtual Acquisition started\n"));
@ -1783,6 +1878,10 @@ int startStateMachine() {
#ifdef VIRTUAL
void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = eiger_virtual_period;
int numFrames = nimages_per_request;
int64_t expUs = eiger_virtual_exptime / 1000;
@ -1836,14 +1935,19 @@ void* start_timer(void* arg) {
// Send data
{
int frameNr = 1;
uint64_t frameNr = 0;
getStartingFrameNumber(&frameNr);
// loop over number of frames
for(frameNr = 1; frameNr <= numFrames; ++frameNr ) {
int iframes = 0;
for(iframes = 0; iframes != numFrames; ++iframes ) {
usleep(eiger_virtual_transmission_delay_frame);
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high
if(eiger_virtual_stop == 1){
if(virtual_stop == 1){
setStartingFrameNumber(frameNr + iframes + 1);
break;
}
@ -1865,7 +1969,7 @@ void* start_timer(void* arg) {
sls_detector_header* header = (sls_detector_header*)(packetData);
header->detType = 3;//(uint16_t)myDetectorType; updated when firmware updates
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
header->frameNumber = frameNr;
header->frameNumber = frameNr + iframes;
header->packetNumber = i;
header->row = row;
header->column = colLeft;
@ -1875,7 +1979,7 @@ void* start_timer(void* arg) {
header = (sls_detector_header*)(packetData2);
header->detType = 3;//(uint16_t)myDetectorType; updated when firmware updates
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
header->frameNumber = frameNr;
header->frameNumber = frameNr + iframes;
header->packetNumber = i;
header->row = row;
header->column = colRight;
@ -1921,25 +2025,29 @@ void* start_timer(void* arg) {
sendUDPPacket(1, packetData2, packetsize);
}
}
LOG(logINFO, ("Sent frame: %d\n", frameNr));
LOG(logINFO, ("Sent frame: %d\n", iframes));
clock_gettime(CLOCK_REALTIME, &end);
int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 +
(end.tv_nsec - begin.tv_nsec));
// sleep for (period - exptime)
if (frameNr < numFrames) { // if there is a next frame
if (iframes < numFrames) { // if there is a next frame
if (periodNs > timeNs) {
usleep((periodNs - timeNs)/ 1000);
}
}
}
setStartingFrameNumber(frameNr + numFrames);
}
closeUDPSocket(0);
closeUDPSocket(1);
eiger_virtual_status = 0;
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL;
}
@ -1951,7 +2059,18 @@ void* start_timer(void* arg) {
int stopStateMachine() {
LOG(logINFORED, ("Going to stop acquisition\n"));
#ifdef VIRTUAL
eiger_virtual_stop = 0;
if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK;
#else
if ((Feb_Control_StopAcquisition() != STATUS_IDLE) || (!Beb_StopAcquisition()) ) {
@ -2011,7 +2130,10 @@ int startReadOut() {
enum runStatus getRunStatus() {
#ifdef VIRTUAL
if (eiger_virtual_status == 0) {
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if (virtual_status == 0) {
LOG(logINFO, ("Status: IDLE\n"));
return IDLE;
} else {
@ -2021,19 +2143,23 @@ enum runStatus getRunStatus() {
#else
int i = Feb_Control_AcquisitionInProgress();
switch (i) {
case STATUS_ERROR:
if (i == STATUS_ERROR) {
LOG(logERROR, ("Status: ERROR reading status register\n"));
return ERROR;
case STATUS_IDLE:
} else if (i == STATUS_IDLE) {
int isTransmitting = 0;
if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 0) == FAIL) {
return ERROR;
}
if (isTransmitting) {
printf("Status: TRANSMITTING\n");
return TRANSMITTING;
}
LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE;
default:
LOG(logINFOBLUE, ("Status: RUNNING...\n"));
return RUNNING;
}
return IDLE;
LOG(logINFOBLUE, ("Status: RUNNING...\n"));
return RUNNING;
#endif
}
@ -2042,7 +2168,7 @@ enum runStatus getRunStatus() {
void readFrame(int *ret, char *mess) {
#ifdef VIRTUAL
// wait for status to be done
while(eiger_virtual_status == 1){
while(virtual_status == 1){
usleep(500);
}
LOG(logINFOGREEN, ("acquisition successfully finished\n"));
@ -2067,7 +2193,18 @@ void readFrame(int *ret, char *mess) {
}
//wait for detector to send
Beb_EndofDataSend(send_to_ten_gig);
int isTransmitting = 1;
while (isTransmitting) {
if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 1) == FAIL) {
strcpy(mess,"Could not read delay counters\n");
*ret = (int)FAIL;
return;
}
if (isTransmitting) {
printf("Transmitting...\n");
}
}
printf("Detector has sent all data\n");
LOG(logINFOGREEN, ("Acquisition successfully finished\n"));
#endif
}

View File

@ -3,6 +3,7 @@
#define REQUIRED_FIRMWARE_VERSION (24)
#define IDFILECOMMAND "more /home/root/executables/detid.txt"
#define FIRMWARE_VERSION_SAME_TOP_BOT_ADDR (26)
#define STATUS_IDLE 0
#define STATUS_RUNNING 1
@ -63,10 +64,10 @@ enum CLKINDEX {RUN_CLK, NUM_CLOCKS};
#define DEFAULT_SUBFRAME_DEADTIME (0)
#define DEFAULT_DYNAMIC_RANGE (16)
#define DEFAULT_PARALLEL_MODE (0)
#define DEFAULT_PARALLEL_MODE (1)
#define DEFAULT_READOUT_STOREINRAM_MODE (0)
#define DEFAULT_READOUT_OVERFLOW32_MODE (0)
#define DEFAULT_CLK_SPEED (HALF_SPEED)
#define DEFAULT_CLK_SPEED (FULL_SPEED)
#define DEFAULT_IO_DELAY (650)
#define DEFAULT_TIMING_MODE (AUTO_TIMING)
#define DEFAULT_PHOTON_ENERGY (-1)

View File

@ -11,6 +11,7 @@ add_executable(gotthard2DetectorServer_virtual
../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
../slsDetectorServer/src/ASIC_Driver.c
../slsDetectorServer/src/programFpgaNios.c
../slsDetectorServer/src/communication_virtual.c
)
include_directories(

View File

@ -9,6 +9,7 @@
#include "ASIC_Driver.h"
#ifdef VIRTUAL
#include "communication_funcs_UDP.h"
#include "communication_virtual.h"
#endif
#include <string.h>
@ -27,6 +28,7 @@ extern udpStruct udpDetails;
extern const enum detectorType myDetectorType;
// Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip);
@ -337,6 +339,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE);
}
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
}
@ -386,9 +394,13 @@ void setupDetector() {
}
}
}
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
#ifndef VIRTUAL
// pll defines
ALTERA_PLL_C10_SetDefines(REG_OFFSET, BASE_READOUT_PLL, BASE_SYSTEM_PLL, PLL_RESET_REG, PLL_RESET_REG, PLL_RESET_READOUT_MSK, PLL_RESET_SYSTEM_MSK, READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ);
ALTERA_PLL_C10_ResetPLL(READOUT_PLL);
@ -399,7 +411,6 @@ void setupDetector() {
LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC);
// on chip dacs
ASIC_Driver_SetDefines(ONCHIP_DAC_DRIVER_FILE_NAME);
#endif
setTimingSource(DEFAULT_TIMING_SOURCE);
// Default values
@ -436,12 +447,10 @@ void setupDetector() {
// power on chip
powerChip(1);
#ifndef VIRTUAL
// also sets default dac and on chip dac values
if (readConfigFile() == FAIL) {
return;
}
#endif
setBurstMode(DEFAULT_BURST_MODE);
setSettings(DEFAULT_SETTINGS);
@ -1333,6 +1342,9 @@ int* getDetectorPosition() {
// Detector Specific
int checkDetectorType() {
#ifdef VIRTUAL
return OK;
#endif
LOG(logINFO, ("Checking type of module\n"));
FILE* fd = fopen(TYPE_FILE_NAME, "r");
if (fd == NULL) {
@ -2007,10 +2019,21 @@ int startStateMachine(){
LOG(logINFOBLUE, ("Starting State Machine\n"));
// set status to running
virtual_status = 1;
virtual_stop = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL;
}
LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -2029,6 +2052,10 @@ int startStateMachine(){
#ifdef VIRTUAL
void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int numRepeats = getNumTriggers();
if (getTiming() == AUTO_TIMING) {
if (burstMode == BURST_OFF) {
@ -2068,6 +2095,8 @@ void* start_timer(void* arg) {
// loop over number of frames
for(frameNr = 0; frameNr != numFrames; ++frameNr ) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high
if(virtual_stop == 1){
break;
@ -2126,6 +2155,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0);
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL;
}
@ -2135,7 +2167,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK;
#endif
//stop state machine
@ -2146,7 +2189,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){
#ifdef VIRTUAL
if(virtual_status == 0){
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE;
}else{
@ -2220,6 +2266,9 @@ void readFrame(int *ret, char *mess) {
u_int32_t runBusy() {
#ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status;
#endif
u_int32_t s = (bus_r(FLOW_STATUS_REG) & FLOW_STATUS_RUN_BUSY_MSK);

View File

@ -10,6 +10,7 @@ add_executable(gotthardDetectorServer_virtual
../slsDetectorServer/src/common.c
../slsDetectorServer/src/commonServerFunctions.c
../slsDetectorServer/src/communication_funcs_UDP.c
../slsDetectorServer/src/communication_virtual.c
)
include_directories(

View File

@ -6,6 +6,7 @@
#include "LTC2620.h" // dacs
#ifdef VIRTUAL
#include "communication_funcs_UDP.h"
#include "communication_virtual.h"
#endif
#include "string.h"
@ -23,6 +24,7 @@ extern const enum detectorType myDetectorType;
int phaseShift = DEFAULT_PHASE_SHIFT;
// Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip);
@ -354,6 +356,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE);
}
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
}
@ -362,6 +370,13 @@ void initStopServer() {
void setupDetector() {
LOG(logINFO, ("This Server is for 1 Gotthard module (1280 channels)\n"));
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
// Initialization
setPhaseShiftOnce();
@ -1098,11 +1113,6 @@ int getADC(enum ADCINDEX ind){
}
int setHighVoltage(int val){
#ifdef VIRTUAL
if (val >= 0)
highvoltage = val;
return highvoltage;
#endif
u_int32_t addr = HV_REG;
u_int32_t sel = 0x0;
@ -1501,10 +1511,21 @@ int startStateMachine(){
}
LOG(logINFOBLUE, ("Starting State Machine\n"));
virtual_status = 1;
virtual_stop = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL;
}
LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -1524,6 +1545,10 @@ int startStateMachine(){
#ifdef VIRTUAL
void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() *
getNumTriggers() );
@ -1542,18 +1567,20 @@ void* start_timer(void* arg) {
if (adcConfigured == -1) {
*((uint32_t*)(imageData)) = 0xCACACACA;
}
for (i = 4; i < imageSize; i += sizeof(uint16_t)) {
*((uint16_t*)(imageData + i)) = i;
for (i = sizeof(uint32_t); i < imageSize; i += sizeof(uint16_t)) {
*((uint16_t*)(imageData + i)) = (uint16_t)i;
}
}
// Send data
{
int frameNr = 0;
int frameHeaderNr = 2;
uint16_t frameHeaderNr = 2;
// loop over number of frames
for(frameNr = 0; frameNr != numFrames; ++frameNr ) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high
if(virtual_stop == 1){
break;
@ -1600,6 +1627,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0);
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL;
}
@ -1608,7 +1638,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK;
#endif
//stop state machine
@ -1630,7 +1671,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){
#ifdef VIRTUAL
if(virtual_status == 0){
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE;
}else{
@ -1732,6 +1776,9 @@ void readFrame(int *ret, char *mess){
u_int32_t runBusy() {
#ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status;
#endif
return runState(logDEBUG1) & STATUS_RN_BSY_MSK;

View File

@ -12,6 +12,7 @@ add_executable(jungfrauDetectorServer_virtual
../slsDetectorServer/src/MAX1932.c
../slsDetectorServer/src/programFpgaBlackfin.c
../slsDetectorServer/src/communication_funcs_UDP.c
../slsDetectorServer/src/communication_virtual.c
)
target_include_directories(jungfrauDetectorServer_virtual

View File

@ -8,6 +8,7 @@
#include "common.h"
#ifdef VIRTUAL
#include "communication_funcs_UDP.h"
#include "communication_virtual.h"
#endif
#include <string.h>
@ -25,6 +26,7 @@ extern udpStruct udpDetails;
extern const enum detectorType myDetectorType;
// Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip);
@ -373,6 +375,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE);
}
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
}
@ -394,6 +402,13 @@ void setupDetector() {
clkPhase[i] = 0;
}
}
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
ALTERA_PLL_ResetPLL();
resetCore();
resetPeripheral();
@ -545,16 +560,24 @@ int selectStoragecellStart(int pos) {
int setStartingFrameNumber(uint64_t value) {
LOG(logINFO, ("Setting starting frame number: %llu\n",(long long unsigned int)value));
#ifdef VIRTUAL
setU64BitReg(value, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG);
#else
// decrement is for firmware
setU64BitReg(value - 1, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG);
// need to set it twice for the firmware to catch
setU64BitReg(value - 1, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG);
#endif
return OK;
}
int getStartingFrameNumber(uint64_t* retval) {
#ifdef VIRTUAL
*retval = getU64BitReg(FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG);
#else
// increment is for firmware
*retval = (getU64BitReg(GET_FRAME_NUMBER_LSB_REG, GET_FRAME_NUMBER_MSB_REG) + 1);
#endif
return OK;
}
@ -921,16 +944,10 @@ int getADC(enum ADCINDEX ind){
int setHighVoltage(int val){
#ifdef VIRTUAL
if (val >= 0)
highvoltage = val;
return highvoltage;
#endif
// setting hv
if (val >= 0) {
LOG(logINFO, ("Setting High voltage: %d V", val));
MAX1932_Set(val);
MAX1932_Set(&val);
highvoltage = val;
}
return highvoltage;
@ -1290,7 +1307,9 @@ int powerChip (int on){
bus_w(CHIP_POWER_REG, bus_r(CHIP_POWER_REG) & ~CHIP_POWER_ENABLE_MSK);
}
}
#ifdef VIRTUAL
return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_ENABLE_MSK) >> CHIP_POWER_ENABLE_OFST);
#endif
return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_STATUS_MSK) >> CHIP_POWER_STATUS_OFST);
}
@ -1629,10 +1648,21 @@ int startStateMachine(){
}
LOG(logINFOBLUE, ("starting state machine\n"));
virtual_status = 1;
virtual_stop = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL;
}
LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -1653,6 +1683,10 @@ int startStateMachine(){
#ifdef VIRTUAL
void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int numInterfaces = getNumberofUDPInterfaces();
int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() *
@ -1679,13 +1713,18 @@ void* start_timer(void* arg) {
// Send data
{
int frameNr = 0;
for(frameNr = 0; frameNr != numFrames; ++frameNr ) {
uint64_t frameNr = 0;
getStartingFrameNumber(&frameNr);
int iframes = 0;
for(iframes = 0; iframes != numFrames; ++iframes ) {
usleep(transmissionDelayUs);
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high
if(virtual_stop == 1){
setStartingFrameNumber(frameNr + iframes + 1);
break;
}
@ -1706,7 +1745,7 @@ void* start_timer(void* arg) {
sls_detector_header* header = (sls_detector_header*)(packetData);
header->detType = (uint16_t)myDetectorType;
header->version = SLS_DETECTOR_HEADER_VERSION - 1;
header->frameNumber = frameNr;
header->frameNumber = frameNr + iframes;
header->packetNumber = i;
header->modId = 0;
header->row = detPos[2];
@ -1741,18 +1780,19 @@ void* start_timer(void* arg) {
}
}
}
LOG(logINFO, ("Sent frame: %d\n", frameNr));
LOG(logINFO, ("Sent frame: %d\n", iframes));
clock_gettime(CLOCK_REALTIME, &end);
int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 +
(end.tv_nsec - begin.tv_nsec));
// sleep for (period - exptime)
if (frameNr < numFrames) { // if there is a next frame
if (iframes < numFrames) { // if there is a next frame
if (periodNs > timeNs) {
usleep((periodNs - timeNs)/ 1000);
}
}
}
setStartingFrameNumber(frameNr + numFrames);
}
closeUDPSocket(0);
@ -1761,6 +1801,9 @@ void* start_timer(void* arg) {
}
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL;
}
@ -1769,7 +1812,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK;
#endif
//stop state machine
@ -1787,7 +1841,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){
#ifdef VIRTUAL
if(virtual_status == 0){
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE;
}else{
@ -1861,6 +1918,9 @@ void readFrame(int *ret, char *mess){
u_int32_t runBusy() {
#ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status;
#endif
u_int32_t s = (bus_r(STATUS_REG) & RUN_BUSY_MSK);

View File

@ -14,6 +14,7 @@ add_executable(moenchDetectorServer_virtual
../slsDetectorServer/src/MAX1932.c
../slsDetectorServer/src/programFpgaBlackfin.c
../slsDetectorServer/src/readDefaultPattern.c
../slsDetectorServer/src/communication_virtual.c
)
include_directories(
@ -31,6 +32,7 @@ target_compile_definitions(moenchDetectorServer_virtual
target_link_libraries(moenchDetectorServer_virtual
PUBLIC pthread rt slsProjectCWarnings
m
)
set_target_properties(moenchDetectorServer_virtual PROPERTIES

View File

@ -8,6 +8,9 @@
#include "MAX1932.h" // hv
#include "ALTERA_PLL.h" // pll
#include "common.h"
#ifdef VIRTUAL
#include "communication_virtual.h"
#endif
#include <string.h>
#include <unistd.h> // usleep
@ -28,6 +31,7 @@ extern uint64_t udpFrameNumber;
extern uint32_t udpPacketNumber;
// Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip);
@ -422,6 +426,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE);
}
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
}
@ -474,6 +484,12 @@ void setupDetector() {
adcEnableMask_1g = 0;
adcEnableMask_10g = 0;
nSamples = 1;
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
ALTERA_PLL_ResetPLLAndReconfiguration();
resetCore();
@ -1049,12 +1065,6 @@ void setVLimit(int l) {
int setHighVoltage(int val){
#ifdef VIRTUAL
if (val >= 0)
highvoltage = val;
return highvoltage;
#endif
// setting hv
if (val >= 0) {
LOG(logINFO, ("Setting High voltage: %d V\n", val));
@ -1063,7 +1073,7 @@ int setHighVoltage(int val){
// switch to external high voltage
bus_w(addr, bus_r(addr) & (~POWER_HV_INTERNAL_SLCT_MSK));
MAX1932_Set(val);
MAX1932_Set(&val);
// switch on internal high voltage, if set
if (val > 0)
@ -1821,10 +1831,21 @@ int startStateMachine(){
}
LOG(logINFOBLUE, ("Starting State Machine\n"));
virtual_status = 1;
virtual_stop = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL;
}
LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -1858,6 +1879,10 @@ int startStateMachine(){
#ifdef VIRTUAL
void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() *
getNumTriggers() );
@ -1884,6 +1909,8 @@ void* start_timer(void* arg) {
// loop over number of frames
for(frameNr = 0; frameNr != numFrames; ++frameNr ) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high
if(virtual_stop == 1){
break;
@ -1935,6 +1962,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0);
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL;
}
@ -1943,7 +1973,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK;
#endif
//stop state machine
@ -1962,7 +2003,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){
#ifdef VIRTUAL
if(virtual_status == 0){
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE;
}else{
@ -2197,6 +2241,9 @@ int readFrameFromFifo() {
uint32_t runBusy() {
#ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status;
#endif
uint32_t s = (bus_r(STATUS_REG) & STATUS_RN_BSY_MSK);

View File

@ -10,6 +10,7 @@ add_executable(mythen3DetectorServer_virtual
../slsDetectorServer/src/LTC2620_Driver.c
../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
../slsDetectorServer/src/programFpgaNios.c
../slsDetectorServer/src/communication_virtual.c
)
include_directories(

View File

@ -8,6 +8,7 @@
#include "ALTERA_PLL_CYCLONE10.h"
#ifdef VIRTUAL
#include "communication_funcs_UDP.h"
#include "communication_virtual.h"
#endif
#include <string.h>
@ -24,6 +25,7 @@ extern udpStruct udpDetails;
extern const enum detectorType myDetectorType;
// Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip);
@ -324,6 +326,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE);
}
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
}
@ -348,8 +356,13 @@ void setupDetector() {
dacValues[i] = 0;
}
}
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
#ifndef VIRTUAL
// pll defines
ALTERA_PLL_C10_SetDefines(REG_OFFSET, BASE_READOUT_PLL, BASE_SYSTEM_PLL, PLL_RESET_REG, PLL_RESET_REG, PLL_RESET_READOUT_MSK, PLL_RESET_SYSTEM_MSK, READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ);
ALTERA_PLL_C10_ResetPLL(READOUT_PLL);
@ -358,7 +371,6 @@ void setupDetector() {
DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME);
//dac
LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC);
#endif
resetCore();
resetPeripheral();
@ -1114,6 +1126,9 @@ uint64_t getPatternBitMask() {
}
int checkDetectorType() {
#ifdef VIRTUAL
return OK;
#endif
LOG(logINFO, ("Checking type of module\n"));
FILE* fd = fopen(TYPE_FILE_NAME, "r");
if (fd == NULL) {
@ -1350,10 +1365,21 @@ int startStateMachine(){
LOG(logINFOBLUE, ("Starting State Machine\n"));
// set status to running
virtual_status = 1;
virtual_stop = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL;
}
LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -1374,6 +1400,10 @@ int startStateMachine(){
#ifdef VIRTUAL
void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() *
getNumTriggers() );
@ -1400,6 +1430,8 @@ void* start_timer(void* arg) {
// loop over number of frames
for (frameNr = 0; frameNr != numFrames; ++frameNr) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high
if(virtual_stop == 1){
break;
@ -1454,6 +1486,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0);
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL;
}
@ -1463,7 +1498,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK;
#endif
//stop state machine
@ -1474,10 +1520,13 @@ int stopStateMachine(){
enum runStatus getRunStatus(){
#ifdef VIRTUAL
if(virtual_status == 0){
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE;
}else{
} else{
LOG(logINFOBLUE, ("Status: RUNNING\n"));
return RUNNING;
}
@ -1549,6 +1598,9 @@ void readFrame(int *ret, char *mess) {
u_int32_t runBusy() {
#ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status;
#endif
u_int32_t s = (bus_r(PAT_STATUS_REG) & PAT_STATUS_RUN_BUSY_MSK);

View File

@ -21,11 +21,11 @@ void MAX1932_SetDefines(uint32_t reg, uint32_t cmsk, uint32_t clkmsk, uint32_t d
void MAX1932_Disable();
/**
* Set value
* @param val value to set
* Set value (value is updated to correct range)
* @param val pointer to value to set
* @return OK or FAIL
*/
int MAX1932_Set (int val) ;
int MAX1932_Set (int* val) ;

View File

@ -11,6 +11,13 @@ typedef enum{
OTHER
}intType;
// communciate with stop server
#ifdef VIRTUAL
#define FILE_STATUS "/tmp/Sls_virtual_server_status_"
#define FILE_STOP "/tmp/Sls_virtual_server_stop_"
#define FD_STATUS 0
#define FD_STOP 1
#endif
int bindSocket(unsigned short int port_number);
int acceptConnection(int socketDescriptor);
@ -45,12 +52,11 @@ int Server_VerifyLock();
* Server sends result to client (also set ret to force_update if different clients)
* @param fileDes file descriptor for the socket
* @param itype 32 or 64 or others to determine to swap data from big endian to little endian
* @param update 1 if one must update if different clients, else 0
* @param retval pointer to result
* @param retvalSize size of result
* @returns result of operation
*/
int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize);
int Server_SendResult(int fileDes, intType itype, void* retval, int retvalSize);
/**
* Convert mac address from integer to char array

View File

@ -0,0 +1,14 @@
#pragma once
#ifdef VIRTUAL
// communciate between control and stop server
int ComVirtual_createFiles(const int port);
void ComVirtual_setFileNames(const int port);
void ComVirtual_setStatus(int value);
int ComVirtual_getStatus();
void ComVirtual_setStop(int value);
int ComVirtual_getStop();
int ComVirtual_writeToFile(int value, const char* fname, const char* serverName);
int ComVirtual_readFromFile(int* value, const char* fname, const char* serverName);
#endif

View File

@ -206,8 +206,8 @@ int64_t getBurstPeriod();
#ifdef EIGERD
int setSubExpTime(int64_t val);
int64_t getSubExpTime();
int setDeadTime(int64_t val);
int64_t getDeadTime();
int setSubDeadTime(int64_t val);
int64_t getSubDeadTime();
int64_t getMeasuredPeriod();
int64_t getMeasuredSubPeriod();
#endif
@ -413,7 +413,9 @@ int setCounterBit(int val);
int pulsePixel(int n, int x, int y);
int pulsePixelNMove(int n, int x, int y);
int pulseChip(int n);
int64_t setRateCorrection(int64_t custom_tau_in_nsec);
int updateRateCorrection(char* mess);
int validateAndSetRateCorrection(int64_t tau_ns, char* mess);
int setRateCorrection(int64_t custom_tau_in_nsec);
int getRateCorrectionEnable();
int getDefaultSettingsTau_in_nsec();
void setDefaultSettingsTau_in_nsec(int t);

View File

@ -88,8 +88,6 @@ int exit_server(int);
int lock_server(int);
int get_last_client_ip(int);
int set_port(int);
int update_client(int);
int send_update(int);
int calibrate_pedestal(int);
int enable_ten_giga(int);
int set_all_trimbits(int);
@ -217,3 +215,6 @@ int set_current_source(int);
int get_timing_source(int);
int set_timing_source(int);
int get_num_channels(int);
int update_rate_correction(int);
int get_receiver_parameters(int);

View File

@ -42,9 +42,7 @@ int ASIC_Driver_Set (int index, int length, char* buffer) {
LOG(logDEBUG2, ("\t]\n"));
}
#ifdef VIRTUAL
return OK;
#endif
#ifndef VIRTUAL
int fd=open(fname, O_RDWR);
if (fd == -1) {
LOG(logERROR, ("Could not open file %s for writing to control ASIC (%d)\n", fname, index));
@ -66,6 +64,7 @@ int ASIC_Driver_Set (int index, int length, char* buffer) {
return FAIL;
}
close(fd);
#endif
return OK;
}

View File

@ -36,6 +36,7 @@ int DAC6571_Set (int val) {
LOG(logINFO, ("\t%dV (dacval %d)\n", val, dacvalue));
#ifndef VIRTUAL
//open file
FILE* fd=fopen(DAC6571_DriverFileName,"w");
if (fd==NULL) {
@ -45,6 +46,7 @@ int DAC6571_Set (int val) {
//convert to string, add 0 and write to file
fprintf(fd, "%d\n", dacvalue);
fclose(fd);
#endif
return OK;
}

View File

@ -72,6 +72,8 @@ int LTC2620_D_SetDACValue (int dacnum, int val, int mV, char* dacname, int* dacv
if ( (*dacval >= 0) || (*dacval == LTC2620_D_PWR_DOWN_VAL)) {
LOG(logINFO, ("Setting DAC %2d [%-12s] : %d dac (%d mV)\n",dacnum, dacname, *dacval, dacmV));
#ifndef VIRTUAL
char fname[MAX_STR_LENGTH];
strcpy(fname, LTC2620_D_DriverFileName);
char temp[20];
@ -89,6 +91,8 @@ int LTC2620_D_SetDACValue (int dacnum, int val, int mV, char* dacname, int* dacv
//convert to string, add 0 and write to file
fprintf(fd, "%d\n", *dacval);
fclose(fd);
#endif
}
return OK;
}

View File

@ -43,33 +43,33 @@ void MAX1932_Disable() {
& ~(MAX1932_DigMask));
}
int MAX1932_Set (int val) {
LOG(logDEBUG1, ("Setting high voltage to %d\n", val));
if (val < 0)
int MAX1932_Set (int* val) {
LOG(logDEBUG1, ("Setting high voltage to %d\n", *val));
if (*val < 0)
return FAIL;
int dacvalue = 0;
// limit values (normally < 60 => 0 (off))
if (val < MAX1932_MinVoltage) {
if (*val < MAX1932_MinVoltage) {
dacvalue = MAX1932_POWER_OFF_DAC_VAL;
val = 0;
*val = 0;
}
// limit values (normally > 200 => 0x1 (max))
else if (val > MAX1932_MaxVoltage) {
else if (*val > MAX1932_MaxVoltage) {
dacvalue = MAX1932_MAX_DAC_VAL;
val = MAX1932_MaxVoltage;
*val = MAX1932_MaxVoltage;
}
// convert value
else {
// no failure in conversion as limits handled (range from 0x1 to 0xFF)
ConvertToDifferentRange(MAX1932_MinVoltage, MAX1932_MaxVoltage,
MAX1932_MIN_DAC_VAL, MAX1932_MAX_DAC_VAL,
val, &dacvalue);
*val, &dacvalue);
dacvalue &= MAX1932_HV_DATA_MSK;
}
LOG(logINFO, ("\t%dV (dacval %d)\n", val, dacvalue));
LOG(logINFO, ("\t%dV (dacval %d)\n", *val, dacvalue));
serializeToSPI(MAX1932_Reg, dacvalue, MAX1932_CsMask, MAX1932_HV_NUMBITS,
MAX1932_ClkMask, MAX1932_DigMask, MAX1932_DigOffset, 0);
return OK;

View File

@ -577,11 +577,7 @@ int Server_VerifyLock() {
}
int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize) {
// update if different clients (ret can be ok or acquisition finished), not fail to not overwrite e message
if (update && isControlServer && ret != FAIL && differentClients)
ret = FORCE_UPDATE;
int Server_SendResult(int fileDes, intType itype, void* retval, int retvalSize) {
// send success of operation
int ret1 = ret;

View File

@ -37,7 +37,7 @@ int setUDPDestinationDetails(int index, const char* ip, unsigned short int port)
// convert ip to internet address
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
@ -83,19 +83,16 @@ int createUDPSocket(int index) {
LOG(logINFO, ("Udp client socket created for server (port %d, ip:%s)\n",
udpDestinationPort[index], udpDestinationIp[index]));
// Using connect expects that the receiver (udp server) exists to listen to these packets
// connecting allows to use "send/write" instead of "sendto", avoiding checking for server address for each packet
// using write without a connect will end in segv
if (connect(udpSockfd[index],udpServerAddrInfo[index]->ai_addr, udpServerAddrInfo[index]->ai_addrlen)==-1) {
LOG(logERROR, ("Could not connect to UDP server at ip:%s, port:%d. (Error code:%d, %s)\n",
udpDestinationIp[index], udpDestinationPort[index], errno, gai_strerror(errno)));
}
// using write without a connect will end in segv
LOG(logINFO, ("Udp client socket connected\n",
udpDestinationPort[index], udpDestinationIp[index]));
return OK;
}
int sendUDPPacket(int index, const char* buf, int length) {
int n = write(udpSockfd[index], buf, length);
int n = sendto(udpSockfd[index], buf, length, 0, udpServerAddrInfo[index]->ai_addr, udpServerAddrInfo[index]->ai_addrlen);
// udp sends atomically, no need to handle partial data
if (n == -1) {
LOG(logERROR, ("Could not send udp packet for socket %d. (Error code:%d, %s)\n",

View File

@ -0,0 +1,120 @@
#ifdef VIRTUAL
#include "communication_virtual.h"
#include "clogger.h"
#include <string.h>
#include <unistd.h> // usleep
#define FILE_STATUS "/tmp/sls_virtual_server_status_"
#define FILE_STOP "/tmp/sls_virtual_server_stop_"
#define FD_STATUS 0
#define FD_STOP 1
#define FILE_NAME_LENGTH 1000
FILE* fd[2] = {NULL, NULL};
char fnameStatus[FILE_NAME_LENGTH];
char fnameStop[FILE_NAME_LENGTH];
int portNumber = 0;
int ComVirtual_createFiles(const int port) {
portNumber = port;
// control server writign status file
memset(fnameStatus, 0, FILE_NAME_LENGTH);
sprintf(fnameStatus, "%s%d", FILE_STATUS, port);
FILE* fd = NULL;
if (NULL == (fd = fopen(fnameStatus, "w"))) {
LOG(logERROR, ("Could not open the file %s for virtual communication\n",
fnameStatus));
return 0;
}
fclose(fd);
LOG(logINFOBLUE, ("Created status file %s\n", fnameStatus));
// stop server writing stop file
memset(fnameStop, 0, FILE_NAME_LENGTH);
sprintf(fnameStop, "%s%d", FILE_STOP, port);
if (NULL == (fd = fopen(fnameStop, "w"))) {
LOG(logERROR, ("Could not open the file %s for virtual communication\n",
fnameStop));
return 0;
}
fclose(fd);
LOG(logINFOBLUE, ("Created stop file %s\n", fnameStop));
return 1;
}
void ComVirtual_setFileNames(const int port) {
portNumber = port;
memset(fnameStatus, 0, FILE_NAME_LENGTH);
memset(fnameStop, 0, FILE_NAME_LENGTH);
sprintf(fnameStatus, "%s%d", FILE_STATUS, port);
sprintf(fnameStop, "%s%d", FILE_STOP, port);
}
void ComVirtual_setStatus(int value) {
while (!ComVirtual_writeToFile(value, fnameStatus, "Control")) {
usleep(100);
}
}
int ComVirtual_getStatus() {
int retval = 0;
while (!ComVirtual_readFromFile(&retval, fnameStatus, "Stop")) {
usleep(100);
}
return retval;
}
void ComVirtual_setStop(int value) {
while (!ComVirtual_writeToFile(value, fnameStop, "Stop")) {
usleep(100);
}
}
int ComVirtual_getStop() {
int retval = 0;
while (!ComVirtual_readFromFile(&retval, fnameStop, "Control")) {
usleep(100);
}
return retval;
}
int ComVirtual_writeToFile(int value, const char* fname, const char* serverName) {
FILE* fd = NULL;
if (NULL == (fd = fopen(fname, "w"))) {
LOG(logERROR, ("Vritual %s Server [%d] could not open "
"the file %s for writing\n",
serverName, portNumber, fname));
return 0;
}
while (fwrite(&value, sizeof(value), 1, fd) < 1) {
LOG(logERROR, ("Vritual %s Server [%d] could not write "
"to file %s\n",
serverName, portNumber, fname));
return 0;
}
fclose(fd);
return 1;
}
int ComVirtual_readFromFile(int* value, const char* fname, const char* serverName) {
FILE* fd = NULL;
if (NULL == (fd = fopen(fname, "r"))) {
LOG(logERROR, ("Vritual %s Server [%d] could not open "
"the file %s for reading\n",
serverName, portNumber, fname));
return 0;
}
while (fread(value, sizeof(int), 1, fd) < 1) {
LOG(logERROR, ("Vritual %s Server [%d] could not read "
"from file %s\n",
serverName, portNumber, fname));
return 0;
}
fclose(fd);
return 1;
}
#endif

View File

@ -7,6 +7,9 @@
#include "slsDetectorServer_funcs.h"
#include "slsDetectorServer_defs.h"
#include "versionAPI.h"
#ifdef VIRTUAL
#include "communication_virtual.h"
#endif
#include <signal.h>
#include <string.h>
@ -31,7 +34,8 @@ void error(char *msg){
perror(msg);
}
int main(int argc, char *argv[]){
int main(int argc, char *argv[]) {
// print version
if (argc > 1 && !strcasecmp(argv[1], "-version")) {
int version = 0;
@ -50,8 +54,9 @@ int main(int argc, char *argv[]){
}
int portno = DEFAULT_PORTNO;
int retval = OK;
int fd = 0;
isControlServer = 1;
debugflag = 0;
checkModuleFlag = 1;
// if socket crash, ignores SISPIPE, prevents global signal handler
// subsequent read/write to socket gives error - must handle locally
@ -100,16 +105,19 @@ int main(int argc, char *argv[]){
}
}
#ifdef STOP_SERVER
char cmd[MAX_STR_LENGTH];
memset(cmd, 0, MAX_STR_LENGTH);
#endif
// control server
if (isControlServer) {
LOG(logINFO, ("Opening control server on port %d \n", portno));
#ifdef STOP_SERVER
// start stop server process
char cmd[MAX_STR_LENGTH];
memset(cmd, 0, MAX_STR_LENGTH);
{
int i;
for (i = 0; i < argc; ++i) {
if (!strcasecmp(argv[i], "-port")) {
i +=2;
continue;
}
if (i > 0) {
strcat(cmd, " ");
}
@ -123,31 +131,42 @@ int main(int argc, char *argv[]){
LOG(logDEBUG1, ("Command to start stop server:%s\n", cmd));
system(cmd);
}
LOG(logINFOBLUE, ("Control Server [%d]\n", portno));
#ifdef VIRTUAL
// creating files for virtual servers to communicate with each other
if (!ComVirtual_createFiles(portno)) {
return -1;
}
#endif
#endif
}
// stop server
else {
LOG(logINFOBLUE, ("Stop Server [%d]\n", portno));
#ifdef VIRTUAL
ComVirtual_setFileNames(portno - 1);
#endif
} else {
LOG(logINFO,("Opening stop server on port %d \n", portno));
}
init_detector();
{ // bind socket
sockfd = bindSocket(portno);
if (ret == FAIL)
return -1;
}
// bind socket
sockfd = bindSocket(portno);
if (ret == FAIL)
return -1;
// assign function table
function_table();
if (isControlServer) {
LOG(logINFOBLUE, ("Control Server Ready...\n\n"));
} else {
LOG(logINFO, ("Stop Server Ready...\n\n"));
LOG(logINFOBLUE, ("Stop Server Ready...\n\n"));
}
// waits for connection
int retval = OK;
while(retval != GOODBYE && retval != REBOOT) {
fd = acceptConnection(sockfd);
int fd = acceptConnection(sockfd);
if (fd > 0) {
retval = decode_function(fd);
closeConnection(fd);

View File

@ -3,6 +3,7 @@ set(SOURCES
src/slsDetectorUsers.cpp
src/Module.cpp
src/Detector.cpp
src/Receiver.cpp
src/CmdProxy.cpp
src/CmdParser.cpp
)

View File

@ -19,7 +19,7 @@ class IpAddr;
//Free function to avoid dependence on class
//and avoid the option to free another objects
//shm by mistake
void freeSharedMemory(int multiId, int detPos = -1);
void freeSharedMemory(int detectorId, int moduleId = -1);
/**
@ -57,6 +57,8 @@ class Detector {
/* Frees shared memory, adds detectors to the list
* and updates local detector cache */
void setHostname(const std::vector<std::string> &hostname);
void setHostname(const std::vector<std::string> &hostname,
const std::vector<int> &port);
/** connects to n servers at local host starting at specific control port */
void setVirtualDetectorServers(int numServers, int startingPort);
@ -344,11 +346,15 @@ class Detector {
Result<defs::runStatus> getDetectorStatus(Positions pos = {}) const;
Result<defs::runStatus> getReceiverStatus(Positions pos = {}) const;
Result<defs::runStatus> getReceiverStatus() const;
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
Result<defs::runStatus> getReceiverStatus(const int udpInterface,
Positions pos = {}) const;
Result<int64_t> getFramesCaught(Positions pos = {}) const;
Result<uint64_t> getFramesCaught(Positions pos = {}) const;
Result<std::vector<uint64_t>> getNumMissingPackets(Positions pos = {}) const;
Result<uint64_t> getNumMissingPackets(Positions pos = {}) const;
/** [Eiger][Jungfrau] */
Result<uint64_t> getStartingFrameNumber(Positions pos = {}) const;
@ -503,28 +509,40 @@ class Detector {
* *
* ************************************************/
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
void removeReceivers(const int udpInterface);
/** true when slsReceiver is used */
Result<bool> getUseReceiverFlag(Positions pos = {}) const;
Result<std::string> getRxHostname(Positions pos = {}) const;
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau]
*/
Result<std::string> getRxHostname(const int udpInterface, Positions pos = {}) const;
/**
* Validates and sets the receiver.
* Updates local receiver cache parameters
* Configures the detector to the receiver as UDP destination
* @param receiver receiver hostname or IP address, can include tcp port eg. hostname:port
* interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau]
*/
void setRxHostname(const std::string &receiver, Positions pos = {});
void setRxHostname(const int udpInterface, const std::string &hostname,
Positions pos = {});
/** cannot be for multiple detectors as port is unique */
void setRxHostname(const int udpInterface, const std::string &hostname,
const int port, int module_id);
/** multiple rx hostnames (same as setRxHostname) */
void setRxHostname(const std::vector<std::string> &name);
Result<int> getRxPort(Positions pos = {}) const;
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
Result<int> getRxPort(const int udpInterface, Positions pos = {}) const;
/** Receiver TCP port (for client communication with Receiver)
* module_id is -1 for all detectors, ports for each module is calculated
* (increments) */
void setRxPort(int port, int module_id = -1);
* (increments)
* interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
void setRxPort(const int udpInterface, const int port, int module_id = -1);
Result<int> getRxFifoDepth(Positions pos = {}) const;
@ -1352,8 +1370,6 @@ class Detector {
Result<uint64_t> getRxCurrentFrameIndex(Positions pos = {}) const;
private:
std::vector<int> getPortNumbers(int start_port);
};
} // namespace sls

View File

@ -115,13 +115,29 @@ std::string CmdProxy::ListCommands(int action) {
}
/* configuration */
std::pair<std::string, int>
CmdProxy::parseHostnameAndPort(std::string name) {
std::string host = name;
std::string hostname;
int port = 0;
auto res = sls::split(host, ':');
if (res.size() > 1) {
hostname = res[0];
port = StringTo<int>(res[1]);
} else {
hostname = host;
}
return std::make_pair(hostname, port);
}
std::string CmdProxy::Hostname(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "\n\tFrees shared memory and sets hostname (or IP address) of "
"all modules concatenated by +."
"all modules concatenated by +.\n\t"
"[hostname or ip address]:[tcp port] Use this for virtual servers\n\t"
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
@ -136,17 +152,35 @@ std::string CmdProxy::Hostname(int action) {
if (det_id != -1) {
throw sls::RuntimeError("Cannot execute this at module level");
}
std::vector<std::string> arguments;
// only args[0], but many hostames concatenated with +
if (args[0].find('+') != std::string::npos) {
auto t = sls::split(args[0], '+');
det->setHostname(t);
os << ToString(t) << '\n';
if (args.size() > 1) {
throw sls::RuntimeError("Cannot have concatenated hostnames and"
"multiple arguments");
}
arguments = sls::split(args[0], '+');
}
// either hostnames separated by space, or single hostname
else {
det->setHostname(args);
os << ToString(args) << '\n';
arguments.assign(args.begin(), args.end());
}
// separate hostname and port
std::vector<std::string> hostnames;
std::vector<int> ports;
for (size_t i = 0; i < arguments.size(); ++i) {
std::pair<std::string, int> res = parseHostnameAndPort(arguments[i]);
hostnames.push_back(res.first);
if (res.second == 0) {
ports.push_back(DEFAULT_PORTNO);
} else {
ports.push_back(res.second);
}
}
det->setHostname(hostnames, ports);
auto t = det->getHostname({det_id});
os << OutString(t) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
@ -402,37 +436,45 @@ std::string CmdProxy::Adcphase(int action) {
"resets adcphase and sets it to previous values.\n\t[Gotthard] "
"Relative phase shift"
<< '\n';
} else if (action == defs::GET_ACTION) {
Result<int> t;
if (args.empty()) {
t = det->getADCPhase({det_id});
os << OutString(t) << '\n';
} else if (args.size() == 1) {
if (args[0] != "deg") {
throw sls::RuntimeError("Unknown adcphase argument " + args[0] +
". Did you mean deg?");
} else {
auto det_type = det->getDetectorType().squash(defs::GENERIC);
if (det_type == defs::EIGER ||
det_type == defs::MYTHEN3 ||
det_type == defs::GOTTHARD2) {
throw sls::RuntimeError("adcphase not implemented for this detector");
}
t = det->getADCPhaseInDegrees({det_id});
os << OutString(t) << " deg\n";
} else {
WrongNumberOfParameters(0);
}
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
det->setADCPhase(StringTo<int>(args[0]), {det_id});
os << args.front() << '\n';
} else if (args.size() == 2) {
if (args[1] != "deg") {
throw sls::RuntimeError("Unknown adcphase 2nd argument " +
args[1] + ". Did you mean deg?");
if (action == defs::GET_ACTION) {
Result<int> t;
if (args.empty()) {
t = det->getADCPhase({det_id});
os << OutString(t) << '\n';
} else if (args.size() == 1) {
if (args[0] != "deg") {
throw sls::RuntimeError("Unknown adcphase argument " + args[0] +
". Did you mean deg? ");
}
t = det->getADCPhaseInDegrees({det_id});
os << OutString(t) << " deg\n";
} else {
WrongNumberOfParameters(0);
}
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
det->setADCPhase(StringTo<int>(args[0]), {det_id} );
os << args.front() << '\n';
} else if (args.size() == 2) {
if (args[1] != "deg") {
throw sls::RuntimeError("Unknown adcphase 2nd argument " +
args[1] + ". Did you mean deg?");
}
det->setADCPhaseInDegrees(StringTo<int>(args[0]) , {det_id});
os << args[0] << " " << args[1] << '\n';
} else {
WrongNumberOfParameters(1);
}
det->setADCPhaseInDegrees(StringTo<int>(args[0]), {det_id});
os << args[0] << args[1] << '\n';
} else {
WrongNumberOfParameters(1);
throw sls::RuntimeError("Unknown action");
}
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
@ -446,37 +488,45 @@ std::string CmdProxy::Dbitphase(int action) {
"shift in degrees. \n\t[Ctb]Changing dbitclk also resets dbitphase and "
"sets to previous values."
<< '\n';
} else if (action == defs::GET_ACTION) {
Result<int> t;
if (args.empty()) {
t = det->getDBITPhase({det_id});
os << OutString(t) << '\n';
} else if (args.size() == 1) {
if (args[0] != "deg") {
throw sls::RuntimeError("Unknown dbitphase argument " +
args[0] + ". Did you mean deg?");
}
t = det->getDBITPhaseInDegrees({det_id});
os << OutString(t) << " deg\n";
} else {
WrongNumberOfParameters(0);
} else {
auto det_type = det->getDetectorType().squash(defs::GENERIC);
if (det_type == defs::EIGER ||
det_type == defs::MYTHEN3 ||
det_type == defs::GOTTHARD2) {
throw sls::RuntimeError("dbitphase not implemented for this detector");
}
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
det->setDBITPhase(StringTo<int>(args[0]), {det_id});
os << args.front() << '\n';
} else if (args.size() == 2) {
if (args[1] != "deg") {
throw sls::RuntimeError("Unknown dbitphase 2nd argument " +
args[1] + ". Did you mean deg?");
if (action == defs::GET_ACTION) {
Result<int> t;
if (args.empty()) {
t = det->getDBITPhase({det_id});
os << OutString(t) << '\n';
} else if (args.size() == 1) {
if (args[0] != "deg") {
throw sls::RuntimeError("Unknown dbitphase argument " +
args[0] + ". Did you mean deg? ");
}
t = det->getDBITPhaseInDegrees({det_id});
os << OutString(t) << " deg\n";
} else {
WrongNumberOfParameters(0);
}
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
det->setDBITPhase(StringTo<int>(args[0]), {det_id});
os << args.front() << '\n';
} else if (args.size() == 2) {
if (args[1] != "deg") {
throw sls::RuntimeError("Unknown dbitphase 2nd argument " +
args[1] + ". Did you mean deg? ");
}
det->setDBITPhaseInDegrees(StringTo<int>(args[0]), {det_id} );
os << args[0] << " " << args[1] << '\n';
} else {
WrongNumberOfParameters(1);
}
det->setDBITPhaseInDegrees(StringTo<int>(args[0]), {det_id});
os << args[0] << args[1] << '\n';
} else {
WrongNumberOfParameters(1);
throw sls::RuntimeError("Unknown action");
}
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
@ -538,7 +588,7 @@ std::string CmdProxy::ClockPhase(int action) {
}
auto t =
det->getClockPhaseinDegrees(StringTo<int>(args[0]), {det_id});
os << OutString(t) << '\n';
os << OutString(t) << " deg\n";
} else {
WrongNumberOfParameters(1);
}
@ -554,7 +604,7 @@ std::string CmdProxy::ClockPhase(int action) {
}
det->setClockPhaseinDegrees(StringTo<int>(args[0]),
StringTo<int>(args[1]), {det_id});
os << args[1] << '\n';
os << args[1] << " " << args[2] << '\n';
} else {
WrongNumberOfParameters(1);
}
@ -769,6 +819,60 @@ std::vector<std::string> CmdProxy::DacCommands() {
}
/* acquisition */
std::string CmdProxy::ReceiverStatus(int action) {
int udpInterface = 1;
if (cmd == "rx_status") {
udpInterface = 1;
} else if (cmd == "rx_status2") {
udpInterface = 2;
} else {
throw sls::RuntimeError("Unknown command, use list to list all commands");
}
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
if (cmd == "rx_status") {
os << "running, idle]\n\tReceiver listener status."
<< '\n';
} else {
os << "running, idle]\n\tReceiver listener status for second udp port."
<< '\n';
}
} else if (action == defs::GET_ACTION) {
if (args.size() != 0) {
WrongNumberOfParameters(0);
}
auto t = det->getReceiverStatus(udpInterface, {det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
throw sls::RuntimeError("Cannot put. Did you mean to use command 'rx_start' or 'rx_stop'?");
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::DetectorStatus(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[running, error, transmitting, finished, waiting, idle]\n\tDetector status."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (args.size() != 0) {
WrongNumberOfParameters(0);
}
auto t = det->getDetectorStatus({det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
throw sls::RuntimeError("Cannot put. Did you mean to use command 'start' or 'stop'?");
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
/* Network Configuration (Detector<->Receiver) */
std::string CmdProxy::UDPDestinationIP(int action) {
@ -848,61 +952,76 @@ std::string CmdProxy::UDPDestinationIP2(int action) {
}
/* Receiver Config */
std::string CmdProxy::ReceiveHostname(int action) {
std::string CmdProxy::ReceiverHostname(int action) {
int udpInterface = 1;
if (cmd == "rx_hostname") {
udpInterface = 1;
} else if (cmd == "rx_hostname2") {
udpInterface = 2;
} else {
throw sls::RuntimeError("Unknown command, use list to list all commands");
}
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[hostname or ip address]\n\t"
"[hostname or ip address]:[tcp port]\n\t"
"[hostname1]:[tcp_port1]+[hostname2]:[tcp_port2]+\n\t"
"Receiver hostname or IP. If port included, then the receiver tcp port.\n\t"
"Used for TCP control communication between client and receiver "
"to configure receiver. Also updates receiver with detector parameters."
<< '\n';
if (cmd == "rx_hostname") {
os << "[hostname or ip address]\n\t"
"[hostname or ip address]:[tcp port]\n\t"
"Receiver hostname or IP. Port is the receiver tcp port (optional).\n\t"
"Use 'none' to remove receivers\n\t"
"Used for TCP control communication between client and receiver "
"to configure receiver. Also updates receiver with detector parameters.\n\t"
"TCP port must be unique, if included.\n\t"
"If port not included and not set earlier, then it takes default port 1954"
" and calculates from there. \n\t"
"[Eiger][Jungfrau] For the 2nd udp interface, use rx_hostname2."
<< '\n';
} else {
os << "[hostname or ip address]\n\t"
"[hostname or ip address]:[tcp port]\n\t"
"[Eiger][Jungfrau] Receiver hostname or IP for the second udp port. "
"Port is the receiver tcp port (optional).\n\t"
"Use 'none' to remove receivers\n\t"
"Refer rx_hostname help for details"
<< '\n';
}
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getRxHostname({det_id});
auto t = det->getRxHostname(udpInterface, {det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() < 1) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
// multiple arguments
if (args.size() > 1) {
// multiple in mulitple
if (args[0].find('+') != std::string::npos) {
throw sls::RuntimeError("Cannot add multiple receivers at module level");
}
if (det_id != -1) {
throw sls::RuntimeError("Cannot add multiple receivers at module level");
}
det->setRxHostname(args);
os << ToString(args) << '\n';
if (args[0].find('+') != std::string::npos) {
throw sls::RuntimeError("Cannot concatenate receiver hostnames");
}
std::pair<std::string, int> res = parseHostnameAndPort(args[0]);
// removing receivers
if (res.first == "none") {
det->removeReceivers(udpInterface);
os << "removed" << '\n';
}
// single argument
// adding receivers
else {
// multiple receivers concatenated with +
if (args[0].find('+') != std::string::npos) {
if (det_id != -1) {
throw sls::RuntimeError("Cannot add multiple receivers at module level");
}
auto t = sls::split(args[0], '+');
det->setRxHostname(t);
os << ToString(t) << '\n';
}
// single receiver
else {
det->setRxHostname(args[0], {det_id});
os << ToString(args) << '\n';
std::string hostname = res.first;
int port = res.second;
if (port == 0) {
det->setRxHostname(udpInterface, hostname, {det_id});
} else {
det->setRxHostname(udpInterface, hostname, port, det_id);
}
auto t = det->getRxHostname(udpInterface, {det_id});
os << OutString(t) << '\n';
}
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
/* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */
/* Eiger Specific */

View File

@ -691,8 +691,8 @@ class CmdProxy {
{"rx_stop", &CmdProxy::rx_stop},
{"start", &CmdProxy::start},
{"stop", &CmdProxy::stop},
{"rx_status", &CmdProxy::rx_status},
{"status", &CmdProxy::status},
{"rx_status", &CmdProxy::ReceiverStatus},
{"status", &CmdProxy::DetectorStatus},
{"rx_framescaught", &CmdProxy::rx_framescaught},
{"rx_missingpackets", &CmdProxy::rx_missingpackets},
{"startingfnum", &CmdProxy::startingfnum},
@ -719,8 +719,10 @@ class CmdProxy {
{"txndelay_right", &CmdProxy::txndelay_right},
/* Receiver Config */
{"rx_hostname", &CmdProxy::ReceiveHostname},
{"rx_hostname", &CmdProxy::ReceiverHostname},
{"rx_hostname2", &CmdProxy::ReceiverHostname},
{"rx_tcpport", &CmdProxy::rx_tcpport},
{"rx_tcpport2", &CmdProxy::rx_tcpport2},
{"rx_fifodepth", &CmdProxy::rx_fifodepth},
{"rx_silent", &CmdProxy::rx_silent},
{"rx_discardpolicy", &CmdProxy::rx_discardpolicy},
@ -911,6 +913,7 @@ class CmdProxy {
/* configuration */
std::string free(int action);
// std::string config2(int action);
std::pair<std::string, int> parseHostnameAndPort(std::string name);
std::string Hostname(int action);
std::string VirtualServer(int action);
std::string FirmwareVersion(int action);
@ -934,11 +937,13 @@ class CmdProxy {
std::string DacValues(int action);
std::vector<std::string> DacCommands();
/* acquisition */
std::string ReceiverStatus(int action);
std::string DetectorStatus(int action);
/* Network Configuration (Detector<->Receiver) */
std::string UDPDestinationIP(int action);
std::string UDPDestinationIP2(int action);
/* Receiver Config */
std::string ReceiveHostname(int action);
std::string ReceiverHostname(int action);
/* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */
/* Eiger Specific */
@ -1363,12 +1368,6 @@ class CmdProxy {
EXECUTE_SET_COMMAND_NOID(stop, stopDetector,
"\n\tStops detector state machine.");
GET_COMMAND(rx_status, getReceiverStatus,
"running, idle]\n\tReceiver listener status.");
GET_COMMAND(status, getDetectorStatus,
"[running, error, transmitting, finished, waiting, idle]\n\tDetector status.");
GET_COMMAND(rx_framescaught, getFramesCaught,
"\n\tNumber of frames caught by receiver.");
@ -1435,8 +1434,11 @@ class CmdProxy {
/* Receiver Config */
INTEGER_COMMAND(rx_tcpport, getRxPort, setRxPort, StringTo<int>,
INTEGER_IND_COMMAND(rx_tcpport, getRxPort, setRxPort, StringTo<int>, 1,
"[port]\n\tTCP port for client-receiver communication. Default is 1954. Must be different if multiple receivers on same pc. Must be first command to set a receiver parameter. Multi command will automatically increment for individual modules.");
INTEGER_IND_COMMAND(rx_tcpport2, getRxPort, setRxPort, StringTo<int>, 2,
"[port]\n\t[Eiger][Jungfrau] TCP port for client-receiver communication for 2nd udp port. For details, refer rx_tcpport.");
INTEGER_COMMAND(rx_fifodepth, getRxFifoDepth, setRxFifoDepth, StringTo<int>,
"[n_frames]\n\tSet the number of frames in the receiver fifo (buffer between listener and writer threads).");

View File

@ -0,0 +1,157 @@
#pragma once
#include <array>
#include <cstddef>
#include <iostream>
#include <numeric>
namespace sls{
template <typename T> class Container3 {
std::array<size_t, 3> shape_{0, 0, 0};
T *data_{nullptr};
public:
Container3(){};
Container3(std::array<size_t, 3> shape)
: Container3(shape[0], shape[1], shape[2]) {}
Container3(std::array<size_t, 3> shape, T value)
: Container3(shape[0], shape[1], shape[2], value) {}
Container3(size_t x, size_t y, size_t z)
: shape_{x, y, z}, data_(new T[size()]{}) {}
Container3(size_t x, size_t y, size_t z, const T &value)
: shape_{x, y, z}, data_(new T[size()]) {
std::fill_n(data_, size(), value);
}
// Copy constructor
Container3(const Container3 &other) {
shape_ = other.shape_;
data_ = new T[size()];
std::copy(other.data_, other.data_ + size(), data_);
}
// Move constructor
Container3(Container3 &&other) {
shape_ = other.shape_;
other.shape_ = {0, 0, 0};
data_ = other.data_;
other.data_ = nullptr;
}
// Copy assignment
Container3 &operator=(const Container3 &other) {
if (this != &other) {
Container3<T> tmp(other);
std::swap(shape_, tmp.shape_);
std::swap(data_, tmp.data_);
}
return *this;
}
// Move assignment
Container3 &operator=(Container3 &&other) {
if (this != &other) {
shape_ = other.shape_;
other.shape_ = {0, 0, 0};
delete[] data_;
data_ = other.data_;
other.data_ = nullptr;
}
return *this;
}
~Container3() { delete[] data_; }
size_t size() const noexcept {
return std::accumulate(std::begin(shape_), std::end(shape_), 1,
std::multiplies<size_t>());
}
size_t size(size_t i) const noexcept { return shape_[i]; }
std::array<size_t, 3> shape() const noexcept { return shape_; }
T *data() noexcept { return data_; }
const T *data() const noexcept { return data_; }
bool is_valid_index(size_t x, size_t y, size_t z) const noexcept {
return x < shape_[0] && y < shape_[1] && z < shape_[2];
}
// Will truncate if other is larger in any dimension
// In the future move object out of other, rename function
void copy_data(const Container3 &other) {
for (size_t i = 0; i < std::min(size(0), other.size(0)); ++i) {
for (size_t j = 0; j < std::min(size(1), other.size(1)); ++j) {
for (size_t k = 0; k < std::min(size(2), other.size(2)); ++k) {
(*this)(i, j, k) = other(i, j, k);
}
}
}
}
void move_data(Container3 &other) {
for (size_t i = 0; i < std::min(size(0), other.size(0)); ++i) {
for (size_t j = 0; j < std::min(size(1), other.size(1)); ++j) {
for (size_t k = 0; k < std::min(size(2), other.size(2)); ++k) {
(*this)(i, j, k) = std::move(other(i, j, k));
}
}
}
}
void resize(size_t x, size_t y, size_t z) {
Container3<T> tmp(x, y, z);
tmp.move_data(*this);
*this = std::move(tmp);
}
T &operator()(size_t x, size_t y, size_t z) noexcept {
return data_[element_offset(x, y, z)];
}
const T &operator()(size_t x, size_t y, size_t z) const noexcept {
return data_[element_offset(x, y, z)];
}
// throws on out of bounds access
const T &at(size_t x, size_t y, size_t z) const {
if (!is_valid_index(x, y, z))
throw std::runtime_error("Index error");
return data_[element_offset(x, y, z)];
}
T &at(size_t x, size_t y, size_t z) {
return const_cast<T &>(
static_cast<const Container3 &>(*this).at(x, y, z));
}
T &operator[](size_t i) { return data_[i]; }
const T &operator[](size_t i) const { return data_[i]; }
T *begin() { return data_; }
T *end() { return data_ + size(); }
void clear(){
*this = Container3<T>();
}
// reference to position, grow if needed, prefer resize and .at()
T &at_can_grow(size_t x, size_t y, size_t z) {
if (!is_valid_index(x, y, z)) {
resize(std::max(x + 1, size(0)), std::max(y + 1, size(1)),
std::max(z + 1, size(2)));
}
return data_[element_offset(x, y, z)];
}
private:
size_t element_offset(size_t x, size_t y, size_t z) const noexcept {
return x * shape_[1] * shape_[2] + y * shape_[2] + z;
}
};
} // namespace sls

View File

@ -6,36 +6,65 @@
#include "logger.h"
#include "DetectorImpl.h"
#include "Module.h"
#include "Receiver.h"
#include "sls_detector_defs.h"
#include "versionAPI.h"
#include "Parallel.h"
#include "MaskGenerator.h"
#include <fstream>
namespace sls {
void freeSharedMemory(int multiId, int detPos) {
void freeSharedMemory(int detectorId, int moduleId) {
// single
if (detPos >= 0) {
SharedMemory<sharedSlsDetector> temp_shm(multiId, detPos);
if (temp_shm.IsExisting()) {
temp_shm.RemoveSharedMemory();
if (moduleId >= 0) {
SharedMemory<sharedModule> moduleShm(detectorId, moduleId);
int numReceivers = 0, numReceivers2 = 0;
if (moduleShm.IsExisting()) {
moduleShm.OpenSharedMemory();
if (Module::hasSharedMemoryReceiverList(moduleShm()->shmversion)) {
numReceivers = moduleShm()->numberOfReceivers;
numReceivers2 = moduleShm()->numberOfReceivers2;
}
moduleShm.RemoveSharedMemory();
}
for (int iReceiver = 0; iReceiver < numReceivers + numReceivers2; ++iReceiver) {
SharedMemory<sharedModule> receiverShm(detectorId, moduleId, iReceiver);
if (receiverShm.IsExisting()) {
receiverShm.RemoveSharedMemory();
}
}
return;
}
// multi - get number of detectors from shm
SharedMemory<sharedMultiSlsDetector> multiShm(multiId, -1);
SharedMemory<sharedDetector> detectorShm(detectorId, -1);
int numDetectors = 0;
if (multiShm.IsExisting()) {
multiShm.OpenSharedMemory();
numDetectors = multiShm()->numberOfDetectors;
multiShm.RemoveSharedMemory();
if (detectorShm.IsExisting()) {
detectorShm.OpenSharedMemory();
numDetectors = detectorShm()->numberOfModules;
detectorShm.RemoveSharedMemory();
}
for (int i = 0; i < numDetectors; ++i) {
SharedMemory<sharedSlsDetector> shm(multiId, i);
shm.RemoveSharedMemory();
for (int iModule = 0; iModule < numDetectors; ++iModule) {
SharedMemory<sharedModule> moduleShm(detectorId, iModule);
int numReceivers = 0, numReceivers2 = 0;
if (moduleShm.IsExisting()) {
moduleShm.OpenSharedMemory();
if (Module::hasSharedMemoryReceiverList(moduleShm()->shmversion)) {
numReceivers = moduleShm()->numberOfReceivers;
numReceivers2 = moduleShm()->numberOfReceivers2;
}
moduleShm.RemoveSharedMemory();
}
for (int iReceiver = 0; iReceiver < numReceivers + numReceivers2; ++iReceiver) {
SharedMemory<sharedModule> receiverShm(detectorId, iModule, iReceiver);
if (receiverShm.IsExisting()) {
receiverShm.RemoveSharedMemory();
}
}
}
}
@ -91,11 +120,16 @@ void Detector::setHostname(const std::vector<std::string> &hostname) {
pimpl->setHostname(hostname);
}
void Detector::setHostname(const std::vector<std::string> &hostname,
const std::vector<int> &port) {
pimpl->setHostname(hostname, port);
}
void Detector::setVirtualDetectorServers(int numServers, int startingPort) {
pimpl->setVirtualDetectorServers(numServers, startingPort);
}
int Detector::getShmId() const { return pimpl->getMultiId(); }
int Detector::getShmId() const { return pimpl->getDetectorId(); }
std::string Detector::getPackageVersion() const {
return GITBRANCH;
@ -118,7 +152,7 @@ Result<int64_t> Detector::getSerialNumber(Positions pos) const {
}
Result<int64_t> Detector::getReceiverVersion(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverSoftwareVersion, pos);
return pimpl->Parallel3(&Receiver::getSoftwareVersion); //FIXME
}
Result<defs::detectorType> Detector::getDetectorType(Positions pos) const {
@ -183,6 +217,7 @@ Result<int64_t> Detector::getNumberOfFrames(Positions pos) const {
void Detector::setNumberOfFrames(int64_t value) {
pimpl->Parallel(&Module::setNumberOfFrames, {}, value);
pimpl->Parallel3(&Receiver::setNumberOfFrames, value); //FIXME
}
Result<int64_t> Detector::getNumberOfTriggers(Positions pos) const {
@ -191,6 +226,7 @@ Result<int64_t> Detector::getNumberOfTriggers(Positions pos) const {
void Detector::setNumberOfTriggers(int64_t value) {
pimpl->Parallel(&Module::setNumberOfTriggers, {}, value);
pimpl->Parallel3(&Receiver::setNumberOfTriggers, value);
}
Result<ns> Detector::getExptime(Positions pos) const {
@ -198,7 +234,18 @@ Result<ns> Detector::getExptime(Positions pos) const {
}
void Detector::setExptime(ns t, Positions pos) {
bool change = false;
if (getDetectorType().squash() == defs::EIGER) {
ns prevVal = getExptime(pos).squash();
if (getExptime(pos).squash() != t) {
change = true;
}
}
pimpl->Parallel(&Module::setExptime, pos, t.count());
pimpl->Parallel3(&Receiver::setExptime, t.count());
if (change) {
pimpl->Parallel(&Module::updateRateCorrection, pos);
}
}
Result<ns> Detector::getPeriod(Positions pos) const {
@ -207,6 +254,7 @@ Result<ns> Detector::getPeriod(Positions pos) const {
void Detector::setPeriod(ns t, Positions pos) {
pimpl->Parallel(&Module::setPeriod, pos, t.count());
pimpl->Parallel3(&Receiver::setPeriod, t.count());
}
Result<ns> Detector::getDelayAfterTrigger(Positions pos) const {
@ -234,12 +282,12 @@ Result<ns> Detector::getPeriodLeft(Positions pos) const {
}
Result<defs::timingMode> Detector::getTimingMode(Positions pos) const {
return pimpl->Parallel(&Module::setTimingMode, pos,
defs::GET_TIMING_MODE);
return pimpl->Parallel(&Module::getTimingMode, pos);
}
void Detector::setTimingMode(defs::timingMode value, Positions pos) {
pimpl->Parallel(&Module::setTimingMode, pos, value);
pimpl->Parallel3(&Receiver::setTimingMode, value);
}
Result<defs::speedLevel> Detector::getSpeed(Positions pos) const {
@ -432,11 +480,11 @@ void Detector::acquire() { pimpl->acquire(); }
void Detector::clearAcquiringFlag() { pimpl->setAcquiringFlag(0); }
void Detector::startReceiver() {
pimpl->Parallel(&Module::startReceiver, {});
pimpl->Parallel3(&Receiver::start);
}
void Detector::stopReceiver() {
pimpl->Parallel(&Module::stopReceiver, {});
pimpl->Parallel3(&Receiver::stop);
}
void Detector::startDetector() {
@ -447,23 +495,57 @@ void Detector::startDetector() {
}
void Detector::stopDetector() {
// get status before stopping acquisition
defs::runStatus s = defs::ERROR, r = defs::ERROR;
bool restreamStop = false;
if (pimpl->isReceiverInitialized(1) && getRxZmqDataStream().squash(true)) {
s = getDetectorStatus().squash(defs::ERROR);
r = getReceiverStatus().squash(defs::ERROR);
// if rxr streaming and acquisition finished, restream dummy stop packet
if (s == defs::IDLE && r == defs::IDLE) {
restreamStop = true;
}
}
pimpl->Parallel(&Module::stopAcquisition, {});
if (pimpl->isReceiverInitialized(1)) {
pimpl->Parallel1(&Receiver::setStoppedFlag, {}, {});
if (restreamStop) {
pimpl->Parallel1(&Receiver::restreamStop, {}, {});
}
} else if (pimpl->isReceiverInitialized(2)) {
pimpl->Parallel2(&Receiver::setStoppedFlag, {}, {});
if (restreamStop) {
pimpl->Parallel2(&Receiver::restreamStop, {}, {});
}
}
}
Result<defs::runStatus> Detector::getDetectorStatus(Positions pos) const {
return pimpl->Parallel(&Module::getRunStatus, pos);
}
Result<defs::runStatus> Detector::getReceiverStatus(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStatus, pos);
Result<defs::runStatus> Detector::getReceiverStatus() const {
return pimpl->Parallel3(&Receiver::getStatus);
}
Result<int64_t> Detector::getFramesCaught(Positions pos) const {
return pimpl->Parallel(&Module::getFramesCaughtByReceiver, pos);
Result<defs::runStatus> Detector::getReceiverStatus(const int udpInterface, Positions pos) const {
switch (udpInterface) {
case 1:
return pimpl->Parallel1(&Receiver::getStatus, pos, {});
case 2:
return pimpl->Parallel2(&Receiver::getStatus, pos, {});
default:
throw RuntimeError("Invalid udp interface number " +
std::to_string(udpInterface));
}
}
Result<std::vector<uint64_t>> Detector::getNumMissingPackets(Positions pos) const {
return pimpl->Parallel(&Module::getNumMissingPackets, pos);
Result<uint64_t> Detector::getFramesCaught(Positions pos) const {
return pimpl->Parallel3(&Receiver::getFramesCaught);
}
Result<uint64_t> Detector::getNumMissingPackets(Positions pos) const {
return pimpl->Parallel3(&Receiver::getNumMissingPackets);
}
Result<uint64_t> Detector::getStartingFrameNumber(Positions pos) const {
@ -554,6 +636,8 @@ Result<IpAddr> Detector::getDestinationUDPIP(Positions pos) const {
void Detector::setDestinationUDPIP(const IpAddr ip, Positions pos) {
pimpl->Parallel(&Module::setDestinationUDPIP, pos, ip);
auto mac = pimpl->Parallel1(&Receiver::setUDPIP, pos, {}, ip).squash();
setDestinationUDPMAC(mac, pos);
}
Result<IpAddr> Detector::getDestinationUDPIP2(Positions pos) const {
@ -562,6 +646,8 @@ Result<IpAddr> Detector::getDestinationUDPIP2(Positions pos) const {
void Detector::setDestinationUDPIP2(const IpAddr ip, Positions pos) {
pimpl->Parallel(&Module::setDestinationUDPIP2, pos, ip);
auto mac = pimpl->Parallel2(&Receiver::setUDPIP, pos, {}, ip).squash();
setDestinationUDPMAC2(mac, pos);
}
Result<MacAddr> Detector::getDestinationUDPMAC(Positions pos) const {
@ -586,13 +672,14 @@ Result<int> Detector::getDestinationUDPPort(Positions pos) const {
void Detector::setDestinationUDPPort(int port, int module_id) {
if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setDestinationUDPPort, {idet},
port_list[idet]);
for (int iModule = 0; iModule < size(); ++iModule) {
pimpl->Parallel(&Module::setDestinationUDPPort, {iModule}, port);
pimpl->Parallel1(&Receiver::setUDPPort, {iModule}, {}, port);
++port;
}
} else {
pimpl->Parallel(&Module::setDestinationUDPPort, {module_id}, port);
pimpl->Parallel1(&Receiver::setUDPPort, {module_id}, {}, port);
}
}
@ -602,28 +689,28 @@ Result<int> Detector::getDestinationUDPPort2(Positions pos) const {
void Detector::setDestinationUDPPort2(int port, int module_id) {
if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setDestinationUDPPort2, {idet},
port_list[idet]);
for (int iModule = 0; iModule < size(); ++iModule) {
pimpl->Parallel(&Module::setDestinationUDPPort2, {iModule}, port++);
pimpl->Parallel2(&Receiver::setUDPPort, {iModule}, {}, port);
++port;
}
} else {
pimpl->Parallel(&Module::setDestinationUDPPort2, {module_id},
port);
pimpl->Parallel(&Module::setDestinationUDPPort2, {module_id}, port);
pimpl->Parallel2(&Receiver::setUDPPort, {module_id}, {}, port);
}
}
Result<std::string> Detector::printRxConfiguration(Positions pos) const {
return pimpl->Parallel(&Module::printReceiverConfiguration, pos);
return pimpl->Parallel(&Module::printUDPConfiguration, pos);
}
Result<bool> Detector::getTenGiga(Positions pos) const {
return pimpl->Parallel(&Module::enableTenGigabitEthernet, pos, -1);
return pimpl->Parallel(&Module::getTenGiga, pos);
}
void Detector::setTenGiga(bool value, Positions pos) {
pimpl->Parallel(&Module::enableTenGigabitEthernet, pos,
static_cast<int>(value));
pimpl->Parallel(&Module::setTenGiga, pos, value);
pimpl->Parallel3(&Receiver::setTenGiga, value);
}
Result<bool> Detector::getTenGigaFlowControl(Positions pos) const {
@ -660,230 +747,235 @@ void Detector::setTransmissionDelayRight(int value, Positions pos) {
// Receiver
void Detector::removeReceivers(const int udpInterface) {
pimpl->removeReceivers(udpInterface);
}
Result<bool> Detector::getUseReceiverFlag(Positions pos) const {
return pimpl->Parallel(&Module::getUseReceiverFlag, pos);
return (pimpl->isReceiverInitialized(1) || pimpl->isReceiverInitialized(2));
}
Result<std::string> Detector::getRxHostname(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverHostname, pos);
Result<std::string> Detector::getRxHostname(const int udpInterface, Positions pos) const {
return pimpl->getRxHostname(pos, udpInterface);
}
void Detector::setRxHostname(const std::string &receiver, Positions pos) {
pimpl->Parallel(&Module::setReceiverHostname, pos, receiver);
void Detector::setRxHostname(const int udpInterface, const std::string &hostname, Positions pos) {
pimpl->configureReceiver(udpInterface, pos, hostname);
}
void Detector::setRxHostname(const std::vector<std::string> &name) {
// set all to same rx_hostname
if (name.size() == 1) {
pimpl->Parallel(&Module::setReceiverHostname, {}, name[0]);
} else {
if ((int)name.size() != size()) {
throw RuntimeError("Receiver hostnames size " +
std::to_string(name.size()) + " does not match detector size " +
std::to_string(size()));
}
// set each rx_hostname
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setReceiverHostname, {idet}, name[idet]);
}
void Detector::setRxHostname(const int udpInterface, const std::string &hostname, const int port,
int module_id) {
if (module_id == -1 && size() > 1) {
throw sls::RuntimeError("Cannot set same rx_tcpport and rx_hostname for multiple receivers");
}
pimpl->configureReceiver(udpInterface, module_id, hostname, port);
}
Result<int> Detector::getRxPort(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverPort, pos);
Result<int> Detector::getRxPort(const int udpInterface, Positions pos) const {
return pimpl->getRxPort(pos, udpInterface);
}
void Detector::setRxPort(int port, int module_id) {
if (module_id == -1) {
std::vector<int> port_list(size());
for (auto &it : port_list) {
it = port++;
}
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setReceiverPort, {idet},
port_list[idet]);
void Detector::setRxPort(const int udpInterface, int port, int module_id) {
if (!pimpl->isReceiverInitialized(udpInterface)) {
pimpl->initReceiver(udpInterface);
}
// return pimpl->setRxPort();
if (udpInterface == 1) {
if (module_id == -1) {
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel1(&Receiver::setTCPPort, {idet}, {},
port++);
}
} else {
pimpl->Parallel1(&Receiver::setTCPPort, {module_id}, {}, port);
}
} else {
pimpl->Parallel(&Module::setReceiverPort, {module_id}, port);
if (module_id == -1) {
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel2(&Receiver::setTCPPort, {idet}, {},
port++);
}
} else {
pimpl->Parallel2(&Receiver::setTCPPort, {module_id}, {}, port);
}
}
}
Result<int> Detector::getRxFifoDepth(Positions pos) const {
return pimpl->Parallel(&Module::setReceiverFifoDepth, pos, -1);
return pimpl->Parallel3(&Receiver::getFifoDepth);
}
void Detector::setRxFifoDepth(int nframes, Positions pos) {
pimpl->Parallel(&Module::setReceiverFifoDepth, pos, nframes);
pimpl->Parallel3(&Receiver::setFifoDepth, nframes);
}
Result<bool> Detector::getRxSilentMode(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverSilentMode, pos);
return pimpl->Parallel3(&Receiver::getSilentMode);
}
void Detector::setRxSilentMode(bool value, Positions pos) {
pimpl->Parallel(&Module::setReceiverSilentMode, pos, value);
pimpl->Parallel3(&Receiver::setSilentMode, value);
}
Result<defs::frameDiscardPolicy>
Detector::getRxFrameDiscardPolicy(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverFramesDiscardPolicy, pos);
return pimpl->Parallel3(&Receiver::getFramesDiscardPolicy);
}
void Detector::setRxFrameDiscardPolicy(defs::frameDiscardPolicy f,
Positions pos) {
pimpl->Parallel(&Module::setReceiverFramesDiscardPolicy, pos, f);
pimpl->Parallel3(&Receiver::setFramesDiscardPolicy, f);
}
Result<bool> Detector::getPartialFramesPadding(Positions pos) const {
return pimpl->Parallel(&Module::getPartialFramesPadding, pos);
return pimpl->Parallel3(&Receiver::getPartialFramesPadding);
}
void Detector::setPartialFramesPadding(bool value, Positions pos) {
pimpl->Parallel(&Module::setPartialFramesPadding, pos, value);
pimpl->Parallel3(&Receiver::setPartialFramesPadding, value);
}
Result<int64_t> Detector::getRxUDPSocketBufferSize(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverUDPSocketBufferSize, pos);
return pimpl->Parallel3(&Receiver::getUDPSocketBufferSize);
}
void Detector::setRxUDPSocketBufferSize(int64_t udpsockbufsize, Positions pos) {
pimpl->Parallel(&Module::setReceiverUDPSocketBufferSize, pos,
pimpl->Parallel3(&Receiver::setUDPSocketBufferSize,
udpsockbufsize);
}
Result<int64_t> Detector::getRxRealUDPSocketBufferSize(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverRealUDPSocketBufferSize,
pos);
return pimpl->Parallel3(&Receiver::getRealUDPSocketBufferSize);
}
Result<bool> Detector::getRxLock(Positions pos) {
return pimpl->Parallel(&Module::lockReceiver, pos, -1);
return pimpl->Parallel3(&Receiver::getLock);
}
void Detector::setRxLock(bool value, Positions pos) {
pimpl->Parallel(&Module::lockReceiver, pos, static_cast<int>(value));
pimpl->Parallel3(&Receiver::setLock, value);
}
Result<sls::IpAddr> Detector::getRxLastClientIP(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverLastClientIP, pos);
return pimpl->Parallel3(&Receiver::getLastClientIP);
}
// File
Result<defs::fileFormat> Detector::getFileFormat(Positions pos) const {
return pimpl->Parallel(&Module::getFileFormat, pos);
return pimpl->Parallel3(&Receiver::getFileFormat);
}
void Detector::setFileFormat(defs::fileFormat f, Positions pos) {
pimpl->Parallel(&Module::setFileFormat, pos, f);
pimpl->Parallel3(&Receiver::setFileFormat, f);
}
Result<std::string> Detector::getFilePath(Positions pos) const {
return pimpl->Parallel(&Module::getFilePath, pos);
return pimpl->Parallel3(&Receiver::getFilePath);
}
void Detector::setFilePath(const std::string &fpath, Positions pos) {
pimpl->Parallel(&Module::setFilePath, pos, fpath);
pimpl->Parallel3(&Receiver::setFilePath, fpath);
}
Result<std::string> Detector::getFileNamePrefix(Positions pos) const {
return pimpl->Parallel(&Module::getFileName, pos);
return pimpl->Parallel3(&Receiver::getFileName);
}
void Detector::setFileNamePrefix(const std::string &fname, Positions pos) {
pimpl->Parallel(&Module::setFileName, pos, fname);
pimpl->Parallel3(&Receiver::setFileName, fname);
}
Result<int64_t> Detector::getAcquisitionIndex(Positions pos) const {
return pimpl->Parallel(&Module::getFileIndex, pos);
return pimpl->Parallel3(&Receiver::getFileIndex);
}
void Detector::setAcquisitionIndex(int64_t i, Positions pos) {
pimpl->Parallel(&Module::setFileIndex, pos, i);
pimpl->Parallel3(&Receiver::setFileIndex, i);
}
Result<bool> Detector::getFileWrite(Positions pos) const {
return pimpl->Parallel(&Module::getFileWrite, pos);
return pimpl->Parallel3(&Receiver::getFileWrite);
}
void Detector::setFileWrite(bool value, Positions pos) {
pimpl->Parallel(&Module::setFileWrite, pos, value);
pimpl->Parallel3(&Receiver::setFileWrite, value);
}
void Detector::setMasterFileWrite(bool value, Positions pos) {
pimpl->Parallel(&Module::setMasterFileWrite, pos, value);
pimpl->Parallel3(&Receiver::setMasterFileWrite, value);
}
Result<bool> Detector::getMasterFileWrite(Positions pos) const {
return pimpl->Parallel(&Module::getMasterFileWrite, pos);
return pimpl->Parallel3(&Receiver::getMasterFileWrite);
}
Result<bool> Detector::getFileOverWrite(Positions pos) const {
return pimpl->Parallel(&Module::getFileOverWrite, pos);
return pimpl->Parallel3(&Receiver::getFileOverWrite);
}
void Detector::setFileOverWrite(bool value, Positions pos) {
pimpl->Parallel(&Module::setFileOverWrite, pos, value);
pimpl->Parallel3(&Receiver::setFileOverWrite, value);
}
Result<int> Detector::getFramesPerFile(Positions pos) const {
return pimpl->Parallel(&Module::getFramesPerFile, pos);
return pimpl->Parallel3(&Receiver::getFramesPerFile);
}
void Detector::setFramesPerFile(int n, Positions pos) {
pimpl->Parallel(&Module::setFramesPerFile, pos, n);
pimpl->Parallel3(&Receiver::setFramesPerFile, n);
}
// Zmq Streaming (Receiver<->Client)
Result<bool> Detector::getRxZmqDataStream(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStreaming, pos);
return pimpl->Parallel3(&Receiver::getZmq);
}
void Detector::setRxZmqDataStream(bool value, Positions pos) {
pimpl->Parallel(&Module::setReceiverStreaming, pos, value);
pimpl->Parallel3(&Receiver::setZmq, value);
}
Result<int> Detector::getRxZmqFrequency(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStreamingFrequency, pos);
return pimpl->Parallel3(&Receiver::getZmqFrequency);
}
void Detector::setRxZmqFrequency(int freq, Positions pos) {
pimpl->Parallel(&Module::setReceiverStreamingFrequency, pos, freq);
pimpl->Parallel3(&Receiver::setZmqFrequency, freq);
}
Result<int> Detector::getRxZmqTimer(Positions pos) const {
return pimpl->Parallel(&Module::setReceiverStreamingTimer, pos, -1);
return pimpl->Parallel3(&Receiver::getZmqTimer);
}
void Detector::setRxZmqTimer(int time_in_ms, Positions pos) {
pimpl->Parallel(&Module::setReceiverStreamingTimer, pos, time_in_ms);
pimpl->Parallel3(&Receiver::setZmqTimer, time_in_ms);
}
Result<int> Detector::getRxZmqPort(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStreamingPort, pos);
return pimpl->Parallel1(&Receiver::getZmqPort, pos, {});
}
void Detector::setRxZmqPort(int port, int module_id) {
if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setReceiverStreamingPort, {idet},
port_list[idet]);
pimpl->Parallel1(&Receiver::setZmqPort, {idet},
{}, port++);
}
} else {
pimpl->Parallel(&Module::setReceiverStreamingPort, {module_id},
port);
pimpl->Parallel1(&Receiver::setZmqPort, {module_id},
{}, port++);
}
}
Result<IpAddr> Detector::getRxZmqIP(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStreamingIP, pos);
return pimpl->Parallel3(&Receiver::getZmqIP);
}
void Detector::setRxZmqIP(const IpAddr ip, Positions pos) {
bool previouslyReceiverStreaming = getRxZmqDataStream(pos).squash(false);
pimpl->Parallel(&Module::setReceiverStreamingIP, pos, ip);
pimpl->Parallel3(&Receiver::setZmqIP, ip);
if (previouslyReceiverStreaming) {
setRxZmqDataStream(false, pos);
setRxZmqDataStream(true, pos);
@ -891,29 +983,28 @@ void Detector::setRxZmqIP(const IpAddr ip, Positions pos) {
}
Result<int> Detector::getClientZmqPort(Positions pos) const {
return pimpl->Parallel(&Module::getClientStreamingPort, pos);
return pimpl->Parallel1(&Receiver::getClientZmqPort, pos, {});
}
void Detector::setClientZmqPort(int port, int module_id) {
if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) {
pimpl->Parallel(&Module::setClientStreamingPort, {idet},
port_list[idet]);
pimpl->Parallel1(&Receiver::setClientZmqPort, {idet},
{}, port++);
}
} else {
pimpl->Parallel(&Module::setClientStreamingPort, {module_id},
port);
pimpl->Parallel1(&Receiver::setClientZmqPort, {module_id},
{}, port);// FIXME: Needs a clientzmqport2
}
}
Result<IpAddr> Detector::getClientZmqIp(Positions pos) const {
return pimpl->Parallel(&Module::getClientStreamingIP, pos);
return pimpl->Parallel3(&Receiver::getClientZmqIP);
}
void Detector::setClientZmqIp(const IpAddr ip, Positions pos) {
int previouslyClientStreaming = pimpl->enableDataStreamingToClient(-1);
pimpl->Parallel(&Module::setClientStreamingIP, pos, ip);
pimpl->Parallel3(&Receiver::setClientZmqIP, ip);
if (previouslyClientStreaming != 0) {
pimpl->enableDataStreamingToClient(0);
pimpl->enableDataStreamingToClient(1);
@ -923,11 +1014,33 @@ void Detector::setClientZmqIp(const IpAddr ip, Positions pos) {
// Eiger Specific
Result<int> Detector::getDynamicRange(Positions pos) const {
return pimpl->Parallel(&Module::setDynamicRange, pos, -1);
return pimpl->Parallel(&Module::getDynamicRange, pos);
}
void Detector::setDynamicRange(int value) {
bool change = false;
int prevVal = value;
if (getDetectorType().squash() == defs::EIGER) {
prevVal = getDynamicRange().squash();
if (prevVal != value) {
change = true;
}
}
pimpl->Parallel(&Module::setDynamicRange, {}, value);
pimpl->Parallel3(&Receiver::setDynamicRange, value);
if (change) {
// update speed for usability
if (value == 32) {
LOG(logINFO) << "Setting Clock to Quarter Speed to cope with "
"Dynamic Range of 32";
setSpeed(defs::QUARTER_SPEED);
} else if (prevVal == 32) {
LOG(logINFO) << "Setting Clock to Full Speed for Dynamic Range "
"of " << value;
setSpeed(defs::FULL_SPEED);
}
pimpl->Parallel(&Module::updateRateCorrection, {});
}
}
Result<ns> Detector::getSubExptime(Positions pos) const {
@ -935,7 +1048,18 @@ Result<ns> Detector::getSubExptime(Positions pos) const {
}
void Detector::setSubExptime(ns t, Positions pos) {
bool change = false;
if (getDetectorType().squash() == defs::EIGER) {
ns prevVal = getSubExptime(pos).squash();
if (prevVal != t) {
change = true;
}
}
pimpl->Parallel(&Module::setSubExptime, pos, t.count());
pimpl->Parallel3(&Receiver::setSubExptime, t.count());
if (change) {
pimpl->Parallel(&Module::updateRateCorrection, pos);
}
}
Result<ns> Detector::getSubDeadTime(Positions pos) const {
@ -944,15 +1068,34 @@ Result<ns> Detector::getSubDeadTime(Positions pos) const {
void Detector::setSubDeadTime(ns value, Positions pos) {
pimpl->Parallel(&Module::setSubDeadTime, pos, value.count());
pimpl->Parallel3(&Receiver::setSubDeadTime, value.count());
}
Result<int> Detector::getThresholdEnergy(Positions pos) const {
if (getDetectorType().squash() == defs::MOENCH) {
auto res = getAdditionalJsonParameter("threshold", pos);
Result<int> intResult(res.size());
try {
for (unsigned int i = 0; i < res.size(); ++i) {
intResult[i] = stoi(res[i]);
}
} catch (...) {
throw RuntimeError(
"Cannot find or convert threshold string to integer");
}
return intResult;
}
return pimpl->Parallel(&Module::getThresholdEnergy, pos);
}
void Detector::setThresholdEnergy(int threshold_ev,
defs::detectorSettings settings,
bool trimbits, Positions pos) {
if (getDetectorType().squash() == defs::MOENCH) {
setAdditionalJsonParameter("threshold",
std::to_string(threshold_ev), pos);
}
pimpl->Parallel(&Module::setThresholdEnergy, pos, threshold_ev,
settings, static_cast<int>(trimbits));
}
@ -994,11 +1137,11 @@ void Detector::setStoreInRamMode(bool value, Positions pos) {
}
Result<bool> Detector::getBottom(Positions pos) const {
return pimpl->Parallel(&Module::getFlippedDataX, pos);
return pimpl->Parallel3(&Receiver::getFlippedDataX);
}
void Detector::setBottom(bool value, Positions pos) {
pimpl->Parallel(&Module::setFlippedDataX, pos, value);
pimpl->Parallel3(&Receiver::setFlippedDataX, value);
}
Result<int> Detector::getAllTrimbits(Positions pos) const {
@ -1035,6 +1178,7 @@ Result<int> Detector::getPartialReadout(Positions pos) const {
void Detector::setPartialReadout(const int lines, Positions pos) {
pimpl->Parallel(&Module::setReadNLines, pos, lines);
pimpl->Parallel3(&Receiver::setReadNLines, lines);
}
Result<bool> Detector::getInterruptSubframe(Positions pos) const {
@ -1054,19 +1198,20 @@ Result<ns> Detector::getMeasuredSubFramePeriod(Positions pos) const {
}
Result<bool> Detector::getActive(Positions pos) const {
return pimpl->Parallel(&Module::activate, pos, -1);
return pimpl->Parallel(&Module::getActivate, pos);
}
void Detector::setActive(bool active, Positions pos) {
pimpl->Parallel(&Module::activate, pos, static_cast<int>(active));
pimpl->Parallel(&Module::setActivate, pos, active);
pimpl->Parallel3(&Receiver::setActivate, active);
}
Result<bool> Detector::getRxPadDeactivatedMode(Positions pos) const {
return pimpl->Parallel(&Module::getDeactivatedRxrPaddingMode, pos);
return pimpl->Parallel3(&Receiver::getDeactivatedPaddingMode);
}
void Detector::setRxPadDeactivatedMode(bool pad, Positions pos) {
pimpl->Parallel(&Module::setDeactivatedRxrPaddingMode, pos, pad);
pimpl->Parallel3(&Receiver::setDeactivatedPaddingMode, pad);
}
Result<bool> Detector::getPartialReset(Positions pos) const {
@ -1104,6 +1249,7 @@ void Detector::setQuad(const bool enable) {
"Eiger Quad Half module.");
}
pimpl->Parallel(&Module::setQuad, {}, enable);
pimpl->Parallel3(&Receiver::setQuad, enable); //FIXME
}
// Jungfrau Specific
@ -1181,11 +1327,16 @@ void Detector::setROI(defs::ROI value, int module_id) {
if (module_id < 0 && size() > 1) {
throw RuntimeError("Cannot set ROI for all modules simultaneously");
}
if (value.xmin < 0 || value.xmax >= getModuleSize({module_id})[0].x) {
throw RuntimeError("roi arguments out of range");
}
pimpl->Parallel(&Module::setROI, {module_id}, value);
pimpl->Parallel3(&Receiver::setROI, value);
}
void Detector::clearROI(Positions pos) {
pimpl->Parallel(&Module::clearROI, pos);
pimpl->Parallel3(&Receiver::clearROI);
}
Result<ns> Detector::getExptimeLeft(Positions pos) const {
@ -1211,6 +1362,7 @@ Result<int64_t> Detector::getNumberOfBursts(Positions pos) const {
void Detector::setNumberOfBursts(int64_t value) {
pimpl->Parallel(&Module::setNumberOfBursts, {}, value);
pimpl->Parallel3(&Receiver::setNumberOfBursts, value);
}
Result<ns> Detector::getBurstPeriod(Positions pos) const {
@ -1247,6 +1399,7 @@ Result<defs::burstMode> Detector::getBurstMode(Positions pos) {
void Detector::setBurstMode(defs::burstMode value, Positions pos) {
pimpl->Parallel(&Module::setBurstMode, pos, value);
pimpl->Parallel3(&Receiver::setBurstMode, value);
}
Result<bool> Detector::getCurrentSource(Positions pos) const {
@ -1273,6 +1426,7 @@ Result<uint32_t> Detector::getCounterMask(Positions pos) const {
void Detector::setCounterMask(uint32_t countermask, Positions pos) {
pimpl->Parallel(&Module::setCounterMask, pos, countermask);
pimpl->Parallel3(&Receiver::setCounterMask, countermask);
}
// CTB/ Moench Specific
@ -1283,6 +1437,7 @@ Result<int> Detector::getNumberOfAnalogSamples(Positions pos) const {
void Detector::setNumberOfAnalogSamples(int value, Positions pos) {
pimpl->Parallel(&Module::setNumberOfAnalogSamples, pos, value);
pimpl->Parallel3(&Receiver::setNumberOfAnalogSamples, value);
}
@ -1360,7 +1515,11 @@ Result<uint32_t> Detector::getADCEnableMask(Positions pos) const {
}
void Detector::setADCEnableMask(uint32_t mask, Positions pos) {
if (getDetectorType().squash() == defs::MOENCH) {
setAdditionalJsonParameter("adcmask_1g", std::to_string(mask), pos);
}
pimpl->Parallel(&Module::setADCEnableMask, pos, mask);
pimpl->Parallel3(&Receiver::setADCEnableMask, mask);
}
Result<uint32_t> Detector::getTenGigaADCEnableMask(Positions pos) const {
@ -1368,7 +1527,11 @@ Result<uint32_t> Detector::getTenGigaADCEnableMask(Positions pos) const {
}
void Detector::setTenGigaADCEnableMask(uint32_t mask, Positions pos) {
if (getDetectorType().squash() == defs::MOENCH) {
setAdditionalJsonParameter("adcmask_10g", std::to_string(mask), pos);
}
pimpl->Parallel(&Module::setTenGigaADCEnableMask, pos, mask);
pimpl->Parallel3(&Receiver::setTenGigaADCEnableMask, mask);
}
// CTB Specific
@ -1380,6 +1543,7 @@ Result<int> Detector::getNumberOfDigitalSamples(Positions pos) const {
void Detector::setNumberOfDigitalSamples(int value, Positions pos) {
pimpl->Parallel(&Module::setNumberOfDigitalSamples, pos, value);
pimpl->Parallel3(&Receiver::setNumberOfDigitalSamples, value);
}
Result<defs::readoutMode> Detector::getReadoutMode(Positions pos) const {
@ -1388,6 +1552,7 @@ Result<defs::readoutMode> Detector::getReadoutMode(Positions pos) const {
void Detector::setReadoutMode(defs::readoutMode value, Positions pos) {
pimpl->Parallel(&Module::setReadoutMode, pos, value);
pimpl->Parallel3(&Receiver::setReadoutMode, value);
}
Result<int> Detector::getDBITClock(Positions pos) const {
@ -1459,19 +1624,19 @@ void Detector::setExternalSampling(bool value, Positions pos) {
}
Result<std::vector<int>> Detector::getRxDbitList(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverDbitList, pos);
return pimpl->Parallel3(&Receiver::getDbitList);
}
void Detector::setRxDbitList(const std::vector<int>& list, Positions pos) {
pimpl->Parallel(&Module::setReceiverDbitList, pos, list);
pimpl->Parallel3(&Receiver::setDbitList, list);
}
Result<int> Detector::getRxDbitOffset(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverDbitOffset, pos);
return pimpl->Parallel3(&Receiver::getDbitOffset);
}
void Detector::setRxDbitOffset(int value, Positions pos) {
pimpl->Parallel(&Module::setReceiverDbitOffset, pos, value);
pimpl->Parallel3(&Receiver::setDbitOffset, value);
}
void Detector::setDigitalIODelay(uint64_t pinMask, int delay, Positions pos) {
@ -1613,28 +1778,27 @@ void Detector::setPatternBitMask(uint64_t mask, Positions pos) {
// Moench
Result<std::map<std::string, std::string>> Detector::getAdditionalJsonHeader(Positions pos) const {
return pimpl->Parallel(&Module::getAdditionalJsonHeader, pos);
return pimpl->Parallel3(&Receiver::getAdditionalJsonHeader);
}
void Detector::setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader,
Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonHeader, pos, jsonHeader);
pimpl->Parallel3(&Receiver::setAdditionalJsonHeader, jsonHeader);
}
Result<std::string> Detector::getAdditionalJsonParameter(const std::string &key,
Positions pos) const {
return pimpl->Parallel(&Module::getAdditionalJsonParameter, pos, key);
return pimpl->Parallel3(&Receiver::getAdditionalJsonParameter, key);
}
void Detector::setAdditionalJsonParameter(const std::string &key, const std::string &value,
Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos, key, value);
pimpl->Parallel3(&Receiver::setAdditionalJsonParameter, key, value);
}
Result<int> Detector::getDetectorMinMaxEnergyThreshold(const bool isEmax,
Positions pos) const {
auto res = pimpl->Parallel(&Module::getAdditionalJsonParameter, pos,
isEmax ? "emax" : "emin");
auto res = getAdditionalJsonParameter(isEmax ? "emax" : "emin", pos);
Result<int> intResult(res.size());
try {
for (unsigned int i = 0; i < res.size(); ++i) {
@ -1650,13 +1814,12 @@ Result<int> Detector::getDetectorMinMaxEnergyThreshold(const bool isEmax,
void Detector::setDetectorMinMaxEnergyThreshold(const bool isEmax,
const int value,
Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos,
isEmax ? "emax" : "emin", std::to_string(value));
setAdditionalJsonParameter(isEmax ? "emax" : "emin",
std::to_string(value), pos);
}
Result<defs::frameModeType> Detector::getFrameMode(Positions pos) const {
auto res = pimpl->Parallel(&Module::getAdditionalJsonParameter, pos,
"frameMode");
auto res = getAdditionalJsonParameter("frameMode", pos);
Result<defs::frameModeType> intResult(res.size());
try {
for (unsigned int i = 0; i < res.size(); ++i) {
@ -1671,13 +1834,11 @@ Result<defs::frameModeType> Detector::getFrameMode(Positions pos) const {
}
void Detector::setFrameMode(defs::frameModeType value, Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos, "frameMode",
sls::ToString(value));
setAdditionalJsonParameter("frameMode", sls::ToString(value), pos);
}
Result<defs::detectorModeType> Detector::getDetectorMode(Positions pos) const {
auto res = pimpl->Parallel(&Module::getAdditionalJsonParameter, pos,
"detectorMode");
auto res = getAdditionalJsonParameter("detectorMode", pos);
Result<defs::detectorModeType> intResult(res.size());
try {
for (unsigned int i = 0; i < res.size(); ++i) {
@ -1692,8 +1853,7 @@ Result<defs::detectorModeType> Detector::getDetectorMode(Positions pos) const {
}
void Detector::setDetectorMode(defs::detectorModeType value, Positions pos) {
pimpl->Parallel(&Module::setAdditionalJsonParameter, pos,
"detectorMode", sls::ToString(value));
setAdditionalJsonParameter("detectorMode", sls::ToString(value), pos);
}
// Advanced
@ -1819,29 +1979,7 @@ Result<ns> Detector::getMeasurementTime(Positions pos) const {
std::string Detector::getUserDetails() const { return pimpl->getUserDetails(); }
Result<uint64_t> Detector::getRxCurrentFrameIndex(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverCurrentFrameIndex, pos);
}
std::vector<int> Detector::getPortNumbers(int start_port) {
int num_sockets_per_detector = 1;
switch (getDetectorType().squash()) {
case defs::EIGER:
num_sockets_per_detector *= 2;
break;
case defs::JUNGFRAU:
if (getNumberofUDPInterfaces().squash() == 2) {
num_sockets_per_detector *= 2;
}
break;
default:
break;
}
std::vector<int> res;
res.reserve(size());
for (int idet = 0; idet < size(); ++idet) {
res.push_back(start_port + (idet * num_sockets_per_detector));
}
return res;
return pimpl->Parallel3(&Receiver::getCurrentFrameIndex);
}
} // namespace sls

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
#pragma once
#include "Container3.h"
#include "Result.h"
#include "SharedMemory.h"
#include "logger.h"
@ -15,22 +15,23 @@ class detectorData;
#include <thread>
#include <vector>
#define MULTI_SHMAPIVERSION 0x190809
#define MULTI_SHMVERSION 0x200319
#define DETECTOR_SHMAPIVERSION 0x190809
#define DETECTOR_SHMVERSION 0x200319
#define SHORT_STRING_LENGTH 50
#include <future>
#include <numeric>
namespace sls{
namespace sls {
class Module;
class Receiver;
/**
* @short structure allocated in shared memory to store detector settings
* for IPC and cache
*/
struct sharedMultiSlsDetector {
struct sharedDetector {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND
* ------*/
@ -47,7 +48,7 @@ struct sharedMultiSlsDetector {
/** last time stamp when accessing the shared memory */
char lastDate[SHORT_STRING_LENGTH];
int numberOfDetectors;
int numberOfModules;
slsDetectorDefs::detectorType multiDetectorType;
/** END OF FIXED PATTERN
@ -68,27 +69,29 @@ class DetectorImpl : public virtual slsDetectorDefs {
public:
/**
* Constructor
* @param id multi detector id
* @param detector_id multi detector id
* @param verify true to verify if shared memory version matches existing
* one
* @param update true to update last user pid, date etc
*/
explicit DetectorImpl(int multi_id = 0, bool verify = true,
bool update = true);
explicit DetectorImpl(int detector_id = 0, bool verify = true,
bool update = true);
/**
* Destructor
*/
virtual ~DetectorImpl();
template <class CT> struct NonDeduced { using type = CT; };
template <typename RT, typename... CT>
sls::Result<RT> Parallel(RT (sls::Module::*somefunc)(CT...),
std::vector<int> positions,
typename NonDeduced<CT>::type... Args) {
if (detectors.size() == 0)
throw sls::RuntimeError("No detectors added");
if (detectors.size() == 0)
throw sls::RuntimeError("No detectors added");
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(detectors.size());
@ -115,8 +118,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
std::vector<int> positions,
typename NonDeduced<CT>::type... Args) const {
if (detectors.size() == 0)
throw sls::RuntimeError("No detectors added");
if (detectors.size() == 0)
throw sls::RuntimeError("No detectors added");
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(detectors.size());
@ -143,8 +146,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
std::vector<int> positions,
typename NonDeduced<CT>::type... Args) {
if (detectors.size() == 0)
throw sls::RuntimeError("No detectors added");
if (detectors.size() == 0)
throw sls::RuntimeError("No detectors added");
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(detectors.size());
@ -168,8 +171,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
std::vector<int> positions,
typename NonDeduced<CT>::type... Args) const {
if (detectors.size() == 0)
throw sls::RuntimeError("No detectors added");
if (detectors.size() == 0)
throw sls::RuntimeError("No detectors added");
if (positions.empty() ||
(positions.size() == 1 && positions[0] == -1)) {
positions.resize(detectors.size());
@ -188,21 +191,101 @@ class DetectorImpl : public virtual slsDetectorDefs {
}
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel1(RT (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {
return {};
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel1(RT (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {
return {};
}
template <typename... CT>
void Parallel1(void (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions, std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {}
template <typename... CT>
void Parallel1(void (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions, std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {}
template <typename RT, typename... CT>
sls::Result<RT> Parallel2(RT (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {
return {};
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel2(RT (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {
return {};
}
template <typename... CT>
void Parallel2(void (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions, std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {}
template <typename... CT>
void Parallel2(void (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions, std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {}
// for all , but dont complain if receiver2 doesnt exist
template <typename RT, typename... CT>
sls::Result<RT> Parallel3(RT (sls::Receiver::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {
return {};
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel3(RT (sls::Receiver::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const {
return {};
}
template <typename... CT>
void Parallel3(void (sls::Receiver::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {}
template <typename... CT>
void Parallel3(void (sls::Receiver::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const {}
/** set acquiring flag in shared memory */
void setAcquiringFlag(bool flag);
void setAcquiringFlag(bool flag);
/** return multi detector shared memory ID */
int getMultiId() const;
/** return detector shared memory ID */
int getDetectorId() const;
/** Free specific shared memory from the command line without creating object */
static void freeSharedMemory(int multiId, int detPos = -1);
/** Free specific shared memory from the command line without creating
* object */
static void freeSharedMemory(int detectorId, int moduleId = -1);
/** Free all modules from current multi Id shared memory and delete members */
void freeSharedMemory();
/** Free all modules from current multi Id shared memory and delete members
*/
void freeSharedMemory();
/** Get user details of shared memory */
std::string getUserDetails();
std::string getUserDetails();
bool getInitialChecks() const;
@ -217,19 +300,32 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/
void setVirtualDetectorServers(const int numdet, const int port);
/** Sets the hostname of all sls detectors in shared memory and updates local cache */
void setHostname(const std::vector<std::string> &name);
void setHostname(const std::vector<std::string> &name);
void setHostname(const std::vector<std::string> &name,
const std::vector<int> &port);
Result<std::string> getRxHostname(Positions pos, int udpInterface);
Result<int> getRxPort(Positions pos, int udpInterface);
int getNumberofReceiversPerModule() const;
void initReceiver(const int udpInterface);
bool isReceiverInitialized(const int udpInterface);
void removeReceivers(const int udpInterface);
void configureReceiver(const int udpInterface, Positions pos,
const std::string &hostname);
void configureReceiver(const int udpInterface, int module_id,
const std::string &hostname, const int port);
/** Gets the total number of detectors */
int size() const;
slsDetectorDefs::xy getNumberOfDetectors() const;
slsDetectorDefs::xy getNumberOfDetectors() const;
slsDetectorDefs::xy getNumberOfChannels() const;
slsDetectorDefs::xy getNumberOfChannels() const;
/** Must be set before setting hostname
* Sets maximum number of channels of all sls detectors */
void setNumberOfChannels(const slsDetectorDefs::xy c);
void setNumberOfChannels(const slsDetectorDefs::xy c);
/** [Eiger][Jungfrau] */
bool getGapPixelsinCallback() const;
@ -272,7 +368,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
* index, loops for measurements, calls required call backs.
* @returns OK or FAIL depending on if it already started
*/
int acquire();
int acquire();
/**
* Combines data from all readouts and gives it to the gui
@ -284,7 +380,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
* Convert raw file
* [Jungfrau][Ctb] from pof file
* [Mythen3][Gotthard2] from rbf file
* @param fname name of pof/rbf file
* @param fname name of pof/rbf file
* @param fpgasrc pointer in memory to read programming file to
* @returns file size
*/
@ -298,7 +394,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
* one
* @param update true to update last user pid, date etc
*/
void setupMultiDetector(bool verify = true, bool update = true);
void setupDetector(bool verify = true, bool update = true);
/**
* Creates shm and initializes shm structure OR
@ -324,7 +420,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** Execute command in terminal and return result */
std::string exec(const char *cmd);
void addSlsDetector(const std::string &hostname);
void addModule(const std::string &hostname, const int port);
void updateDetectorSize();
@ -351,16 +447,10 @@ class DetectorImpl : public virtual slsDetectorDefs {
* @param nPixelsy number of pixels in Y axis (updated)
* @returns total data bytes for updated image
*/
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
int &nPixelsx, int &nPixelsy);
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
int &nPixelsx, int &nPixelsy);
double setTotalProgress();
double getCurrentProgress();
void incrementProgress();
void setCurrentProgress(int64_t i = 0);
void printProgress(double progress);
void startProcessingThread();
@ -383,14 +473,23 @@ class DetectorImpl : public virtual slsDetectorDefs {
int kbhit();
/** Multi detector Id */
const int multiId{0};
const int detectorId{0};
/** Shared Memory object */
sls::SharedMemory<sharedMultiSlsDetector> multi_shm{0, -1};
sls::SharedMemory<sharedDetector> detector_shm{0, -1};
/** pointers to the Module structures */
std::vector<std::unique_ptr<sls::Module>> detectors;
/** pointers to the Receiver structures, each row for a module */
// std::vector<std::vector<std::unique_ptr<sls::Receiver>>> receivers;
/** for the second udp port [Eiger][Jungfrau] */
std::vector<std::vector<std::unique_ptr<sls::Receiver>>> receivers2;
sls::Container3<std::unique_ptr<sls::Receiver>> receivers;
// sls::Container3<Receiver> receivers;
/** data streaming (down stream) enabled in client (zmq sckets created) */
bool client_downstream{false};
@ -405,12 +504,6 @@ class DetectorImpl : public virtual slsDetectorDefs {
* from ext. process) */
sem_t sem_endRTAcquisition;
/** Total number of frames/images for next acquisition */
double totalProgress{0};
/** Current progress or frames/images processed in current acquisition */
double progressIndex{0};
/** mutex to synchronize main and data processing threads */
mutable std::mutex mp;
@ -430,4 +523,4 @@ class DetectorImpl : public virtual slsDetectorDefs {
void *pCallbackArg{nullptr};
};
}//namespace sls
} // namespace sls

View File

@ -0,0 +1,59 @@
#pragma once
#include "Container3.h"
#include <initializer_list>
#include <vector>
namespace sls{
class MaskGenerator {
enum class OperationMode { ALL, ROW, SINGLE };
OperationMode mode_{OperationMode::ALL};
std::vector<int> idx0; // hack
size_t x_{0};
size_t y_{0};
size_t z_{0};
public:
MaskGenerator(){};
explicit MaskGenerator(size_t i) : mode_(OperationMode::SINGLE), x_(i) {}
MaskGenerator(size_t i, size_t j)
: mode_(OperationMode::SINGLE), x_(i), y_(j) {}
MaskGenerator(size_t i, size_t j, size_t k)
: mode_(OperationMode::SINGLE), x_(i), y_(j), z_(k) {}
explicit MaskGenerator(const std::vector<int> vec)
: mode_(OperationMode::ROW), idx0(vec) {}
explicit MaskGenerator(const std::vector<int> vec, size_t y)
: mode_(OperationMode::ROW), idx0(vec), y_(y) {}
template <typename T> Container3<bool> mask(const Container3<T>& cont) {
return mask(cont.shape());
}
Container3<bool> mask(std::array<size_t, 3> shape) {
Container3<bool> m(shape);
if (idx0.size()== 1 && idx0[0] == -1){
idx0.resize(m.size(0));
std::iota(begin(idx0), end(idx0), 0);
}
switch (mode_) {
case OperationMode::ALL:
for (auto &item : m)
item = true;
break;
case OperationMode::ROW:
for (auto i : idx0) {
m(i, 0, 0) = true;
}
break;
case OperationMode::SINGLE:
m(x_, y_, z_) = true;
break;
}
return m;
}
Container3<bool> mask() { return {}; }
};
} // namespace sls

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,9 @@
class ServerInterface;
#define SLS_SHMAPIVERSION 0x190726
#define SLS_SHMVERSION 0x200324
#define MODULE_SHMRXVERSION 0x200415
#define MODULE_SHMAPIVERSION 0x190726
#define MODULE_SHMVERSION 0x200423
namespace sls{
@ -22,7 +23,7 @@ namespace sls{
* @short structure allocated in shared memory to store detector settings for
* IPC and cache
*/
struct sharedSlsDetector {
struct sharedModule {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
@ -36,10 +37,13 @@ struct sharedSlsDetector {
/** detector type \ see :: detectorType*/
slsDetectorDefs::detectorType myDetectorType;
int numberOfReceivers;
int numberOfReceivers2;
/** END OF FIXED PATTERN -----------------------------------------------*/
/** Number of detectors in multi list in x dir and y dir */
slsDetectorDefs::xy multiSize;
slsDetectorDefs::xy detectorSize;
/** is the port used for control functions */
int controlPort;
@ -62,54 +66,8 @@ struct sharedSlsDetector {
/** number of dacs per module*/
int nDacs;
/** dynamic range of the detector data */
int dynamicRange;
/** detector settings (standard, fast, etc.) */
slsDetectorDefs::detectorSettings currentSettings;
/** number of frames */
int64_t nFrames;
/** number of triggers */
int64_t nTriggers;
/** number of bursts */
int64_t nBursts;
/** number of additional storage cells */
int nAddStorageCells;
/** timing mode */
slsDetectorDefs::timingMode timingMode;
/** burst mode */
slsDetectorDefs::burstMode burstMode;
/** rate correction in ns (needed for default -1) */
int64_t deadTime;
/** ip address/hostname of the receiver for client control via TCP */
char rxHostname[MAX_STR_LENGTH];
/** is the TCP port used to communicate between client and the receiver */
int rxTCPPort;
/** is set if the receiver hostname given and is connected,
* unset if socket connection is not possible */
bool useReceiverFlag;
/** tcp port from gui/different process to receiver (only data) */
int zmqport;
/** zmq tcp src ip address in client (only data) **/
sls::IpAddr zmqip;
/** num udp interfaces */
int numUDPInterfaces;
/** stopped flag to inform rxr */
bool stoppedFlag;
};
class Module : public virtual slsDetectorDefs {
@ -117,22 +75,22 @@ class Module : public virtual slsDetectorDefs {
/**
* Constructor called when creating new shared memory
* @param type detector type
* @param multi_id multi detector shared memory id
* @param id sls detector id (position in detectors list)
* @param detector_id multi detector shared memory id
* @param module_id module id (position in detectors list)
* @param verify true to verify if shared memory version matches existing
* one
*/
explicit Module(detectorType type, int multi_id = 0, int det_id = 0,
explicit Module(detectorType type, int detector_id = 0, int module_id = 0,
bool verify = true);
/**
* Constructor called when opening existing shared memory
* @param multi_id multi detector shared memory id
* @param id sls detector id (position in detectors list)
* @param detector_id multi detector shared memory id
* @param module_id module id (position in detectors list)
* @param verify true to verify if shared memory version matches existing
* one
*/
explicit Module(int multi_id = 0, int det_id = 0, bool verify = true);
explicit Module(int detector_id = 0, int module_id = 0, bool verify = true);
/**
* Destructor
@ -145,11 +103,13 @@ class Module : public virtual slsDetectorDefs {
*/
bool isFixedPatternSharedMemoryCompatible();
/**
* Check version compatibility with receiver software
*/
void checkReceiverVersionCompatibility();
static bool hasSharedMemoryReceiverList(int version);
int getNumberOfReceivers() const;
void setNumberOfReceivers(const int num);
int getNumberOfReceivers2() const;
void setNumberOfReceivers2(const int num);
/**
* Check version compatibility with detector software
*/
@ -161,14 +121,9 @@ class Module : public virtual slsDetectorDefs {
int64_t getSerialNumber();
/**
* Get Receiver Software version
*/
int64_t getReceiverSoftwareVersion() const;
/**
* Free shared memory and delete shared memory structure
* occupied by the sharedSlsDetector structure
* occupied by the sharedModule structure
* Is only safe to call if one deletes the Module object afterward
* and frees multi shared memory/updates
* thisMultiDetector->numberOfDetectors
@ -203,13 +158,6 @@ class Module : public virtual slsDetectorDefs {
*/
detectorType getDetectorType() const;
/**
* Gets detector type from detector and set it in receiver
* @param type the detector type
* @returns detector type in receiver
*/
int setDetectorType(detectorType type = GET_DETECTOR_TYPE);
/**
* Update total number of channels (chiptestboard or moench)
* from the detector server
@ -247,12 +195,12 @@ class Module : public virtual slsDetectorDefs {
* Set Detector offset in shared memory in dimension d
* @param det detector size
*/
void updateMultiSize(slsDetectorDefs::xy det);
void updateDetectorSize(slsDetectorDefs::xy det);
int setControlPort(int port_number);
/**
* Returns the detector TCP control port \sa sharedSlsDetector
* Returns the detector TCP control port
* @returns the detector TCP control port
*/
int getControlPort() const;
@ -260,19 +208,11 @@ class Module : public virtual slsDetectorDefs {
int setStopPort(int port_number);
/**
* Returns the detector TCP stop port \sa sharedSlsDetector
* Returns the detector TCP stop port
* @returns the detector TCP stop port
*/
int getStopPort() const;
int setReceiverPort(int port_number);
/**
* Returns the receiver TCP port \sa sharedSlsDetector
* @returns the receiver TCP port
*/
int getReceiverPort() const;
/**
* Lock server for this client IP
* @param p 0 to unlock, 1 to lock (-1 gets)
@ -298,21 +238,12 @@ class Module : public virtual slsDetectorDefs {
*/
void execCommand(const std::string &cmd);
/**
* Updates some of the shared memory receiving the data from the detector
*/
void updateCachedDetectorVariables();
/**
* Get detector specific commands to write into config file
* @returns vector of strings with commands
*/
std::vector<std::string> getConfigFileCommands();
/**
* Get detector settings
* @returns current settings
*/
detectorSettings getSettings();
/** [Jungfrau] Options:DYNAMICGAIN, DYNAMICHG0, FIXGAIN1, FIXGAIN2, FORCESWITCHG1, FORCESWITCHG2
@ -320,18 +251,8 @@ class Module : public virtual slsDetectorDefs {
* [Gotthard2] Options: DYNAMICGAIN, FIXGAIN1, FIXGAIN2
* [Moench] Options: G1_HIGHGAIN, G1_LOWGAIN, G2_HIGHCAP_HIGHGAIN, G2_HIGHCAP_LOWGAIN,
* G2_LOWCAP_HIGHGAIN, G2_LOWCAP_LOWGAIN, G4_HIGHGAIN, G4_LOWGAIN
* [Eiger] Only stores them locally in shm Options: STANDARD, HIGHGAIN, LOWGAIN, VERYHIGHGAIN, VERYLOWGAIN
*/
detectorSettings setSettings(detectorSettings isettings);
/**
* Send detector settings only (set only for Jungfrau, Gotthard, Moench, get
* for all) Only the settings enum is sent to the detector, where it will
* initialize al the dacs already hard coded in the detector server
* @param isettings settings
* @returns current settings
*/
detectorSettings sendSettingsOnly(detectorSettings isettings);
void setSettings(detectorSettings isettings);
/**
* Get threshold energy (Mythen and Eiger)
@ -359,13 +280,13 @@ class Module : public virtual slsDetectorDefs {
int tb = 1);
/**
* Returns the detector trimbit/settings directory \sa sharedSlsDetector
* Returns the detector trimbit/settings directory
* @returns the trimbit/settings directory
*/
std::string getSettingsDir();
/**
* Sets the detector trimbit/settings directory \sa sharedSlsDetector
* Sets the detector trimbit/settings directory
* @param s trimbits/settings directory
* @returns the trimbit/settings directory
*/
@ -445,10 +366,6 @@ class Module : public virtual slsDetectorDefs {
*/
uint64_t getStartingFrameNumber();
int64_t getTotalNumFramesToReceive();
void sendTotalNumFramestoReceiver();
int64_t getNumberOfFrames();
void setNumberOfFrames(int64_t value);
@ -556,22 +473,17 @@ class Module : public virtual slsDetectorDefs {
* [Gotthard2] only in continuous mode */
int64_t getMeasurementTime() const;
/**
* Set/get timing mode
* @param value timing mode (-1 gets)
* @returns current timing mode
*/
timingMode setTimingMode(timingMode value = GET_TIMING_MODE);
timingMode getTimingMode();
void setTimingMode(timingMode value);
int getDynamicRange();
/**
* Set/get dynamic range
* (Eiger: If i is 32, also sets clkdivider to 2, if 16, sets clkdivider to
* 1)
* @param i dynamic range (-1 get)
* @returns current dynamic range
* \sa sharedSlsDetector
*/
int setDynamicRange(int n = -1);
void setDynamicRange(int n);
/**
* Set/get dacs value
@ -696,22 +608,9 @@ class Module : public virtual slsDetectorDefs {
*/
uint32_t clearBit(uint32_t addr, int n);
/**
* Validates and sets the receiver.
* Also updates the receiver with all the shared memory parameters
* significant for the receiver Also configures the detector to the receiver
* as UDP destination
* @param receiver receiver hostname or IP address
* @returns the receiver IP address from shared memory
*/
std::string setReceiverHostname(const std::string &receiver);
/**
* Returns the receiver IP address\sa sharedSlsDetector
* @returns the receiver IP address
*/
std::string getReceiverHostname() const;
/** gets receiver parameters from detector and shared memory */
rxParameters getReceiverParameters();
/**
* Validates the format of the detector MAC address and sets it
* @param mac detector MAC address
@ -776,13 +675,6 @@ class Module : public virtual slsDetectorDefs {
*/
sls::IpAddr getDestinationUDPIP();
/**
* Gets destination udp ip from detector,
* if 0, it converts rx_hostname to ip and
* updates both detector and receiver
*/
void updateRxDestinationUDPIP();
/**
* Validates the format of the receiver UDP IP address (bottom half) and
* sets it(Jungfrau only)
@ -798,13 +690,6 @@ class Module : public virtual slsDetectorDefs {
*/
sls::IpAddr getDestinationUDPIP2();
/**
* Gets destination udp ip2 from detector,
* if 0, it converts rx_hostname to ip and
* updates both detector and receiver
*/
void updateRxDestinationUDPIP2();
/**
* Validates the format of the receiver UDP MAC address and sets it
* @param mac receiver UDP MAC address
@ -831,26 +716,26 @@ class Module : public virtual slsDetectorDefs {
sls::MacAddr getDestinationUDPMAC2();
/**
* Sets the receiver UDP port\sa sharedSlsDetector
* Sets the receiver UDP port
* @param udpport receiver UDP port
*/
void setDestinationUDPPort(int udpport);
/**
* Returns the receiver UDP port\sa sharedSlsDetector
* Returns the receiver UDP port
* @returns the receiver UDP port
*/
int getDestinationUDPPort();
/**
* Sets the receiver UDP port 2\sa sharedSlsDetector (Eiger and Jungfrau
* Sets the receiver UDP port 2 (Eiger and Jungfrau
* only)
* @param udpport receiver UDP port 2
*/
void setDestinationUDPPort2(int udpport);
/**
* Returns the receiver UDP port 2 of same interface\sa sharedSlsDetector
* Returns the receiver UDP port 2 of same interface
* (Eiger and Jungfrau only)
* @returns the receiver UDP port 2 of same interface
*/
@ -889,53 +774,7 @@ class Module : public virtual slsDetectorDefs {
*/
int getSelectedUDPInterface();
/**
* Sets the client zmq port\sa sharedSlsDetector
* @param port client zmq port
*/
void setClientStreamingPort(int port);
/**
* Returns the client zmq port \sa sharedSlsDetector
* @returns the client zmq port
*/
int getClientStreamingPort();
/**
* Sets the receiver zmq port\sa sharedSlsDetector
* @param port receiver zmq port
*/
void setReceiverStreamingPort(int port);
/**
* Returns the receiver zmq port \sa sharedSlsDetector
* @returns the receiver zmq port
*/
int getReceiverStreamingPort();
/**
* Sets the client zmq ip\sa sharedSlsDetector
* @param ip client zmq ip
*/
void setClientStreamingIP(const sls::IpAddr ip);
/**
* Returns the client zmq ip \sa sharedSlsDetector
* @returns the client zmq ip
*/
sls::IpAddr getClientStreamingIP();
/**
* Sets the receiver zmq ip\sa sharedSlsDetector
* @param ip receiver zmq ip
*/
void setReceiverStreamingIP(const sls::IpAddr ip);
/**
* Returns the receiver zmq ip \sa sharedSlsDetector
* @returns the receiver zmq ip
*/
sls::IpAddr getReceiverStreamingIP();
std::string printUDPConfiguration();
/** update receiver stremaing ip from shm to receiver
* if empty, use rx_hostname ip
@ -979,35 +818,6 @@ class Module : public virtual slsDetectorDefs {
*/
void setTransmissionDelayRight(int value);
/** empty vector deletes entire additional json header */
void setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader);
std::map<std::string, std::string> getAdditionalJsonHeader();
/**
* Sets the value for the additional json header parameter key if found, else
* append it. If value empty, then deletes parameter */
void setAdditionalJsonParameter(const std::string &key, const std::string &value);
std::string getAdditionalJsonParameter(const std::string &key);
/**
* Sets the receiver UDP socket buffer size
* @param udpsockbufsize additional json header
* @returns receiver udp socket buffer size
*/
int64_t setReceiverUDPSocketBufferSize(int64_t udpsockbufsize = -1);
/**
* Returns the receiver UDP socket buffer size\sa sharedSlsDetector
* @returns the receiver UDP socket buffer size
*/
int64_t getReceiverUDPSocketBufferSize();
/**
* Returns the receiver real UDP socket buffer size\sa sharedSlsDetector
* @returns the receiver real UDP socket buffer size
*/
int64_t getReceiverRealUDPSocketBufferSize() const;
/** [Gotthard][Jungfrau][CTB][Moench] */
void executeFirmwareTest();
@ -1085,28 +895,10 @@ class Module : public virtual slsDetectorDefs {
*/
slsDetectorDefs::ROI getROI();
/**
* Set ADC Enable Mask (CTB, Moench)
* @param mask ADC Enable mask
*/
void setADCEnableMask(uint32_t mask);
/**
* Get ADC Enable Mask (CTB, Moench)
* @returns ADC Enable mask
*/
uint32_t getADCEnableMask();
/**
* Set 10Gb ADC Enable Mask (CTB, Moench)
* @param mask ADC Enable mask
*/
void setTenGigaADCEnableMask(uint32_t mask);
/**
* Get 10Gb ADC Enable Mask (CTB, Moench)
* @returns ADC Enable mask
*/
uint32_t getTenGigaADCEnableMask();
/**
@ -1153,14 +945,6 @@ class Module : public virtual slsDetectorDefs {
*/
int getExternalSampling();
/** digital data bits enable (CTB only) */
void setReceiverDbitList(const std::vector<int>& list);
std::vector<int> getReceiverDbitList() const;
/** Set digital data offset in bytes (CTB only) */
void setReceiverDbitOffset(int value);
int getReceiverDbitOffset();
/**
* Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert
* users
@ -1169,32 +953,10 @@ class Module : public virtual slsDetectorDefs {
*/
void writeAdcRegister(uint32_t addr, uint32_t val);
/**
* Activates/Deactivates the detector (Eiger only)
* @param enable active (1) or inactive (0), -1 gets
* @returns 0 (inactive) or 1 (active)for activate mode
*/
int activate(int const enable = -1);
bool getDeactivatedRxrPaddingMode();
/**
* Set deactivated Receiver padding mode (Eiger only)
*/
void setDeactivatedRxrPaddingMode(bool padding);
/**
* Returns the enable if data will be flipped across x axis (Eiger)
* @returns if flipped across x axis
*/
bool getFlippedDataX();
/**
* Sets the enable which determines if
* data will be flipped across x axis (Eiger)
* @param value 0 or 1 to reset/set
*/
void setFlippedDataX(bool value);
/** [Eiger] */
bool getActivate();
/** [Eiger] */
void setActivate(const bool enable);
/**
* Sets all the trimbits to a particular value (Eiger)
@ -1205,7 +967,6 @@ class Module : public virtual slsDetectorDefs {
/**
* Sets the number of trim energies and their value (Eiger)
* \sa sharedSlsDetector
* @param nen number of energies
* @param vector os trimmed energies
* @returns number of trim energies
@ -1214,7 +975,6 @@ class Module : public virtual slsDetectorDefs {
/**
* Returns a vector with the trimmed energies (Eiger)
* \sa sharedSlsDetector
* @returns vector with the trimmed energies
*/
std::vector<int> getTrimEn();
@ -1363,168 +1123,8 @@ class Module : public virtual slsDetectorDefs {
*/
void updateRateCorrection();
/**
* Prints receiver configuration
* @returns receiver configuration
*/
std::string printReceiverConfiguration();
/**
* Gets the use receiver flag from shared memory
*/
bool getUseReceiverFlag() const;
/**
* Locks/Unlocks the connection to the receiver
* @param lock sets (1), usets (0), gets (-1) the lock
* @returns lock status of the receiver
*/
int lockReceiver(int lock = -1);
/**
* Returns the IP of the last client connecting to the receiver
* @returns the IP of the last client connecting to the receiver
*/
sls::IpAddr getReceiverLastClientIP() const;
/**
* Exits the receiver TCP server
*/
void exitReceiver();
/**
* Executes a system command on the receiver server
* e.g. mount an nfs disk, reboot and returns answer etc.
* @param cmd command to be executed
*/
void execReceiverCommand(const std::string &cmd);
/**
* Send the multi detector size to the detector
* @param detx number of detectors in x dir
* @param dety number of detectors in y dir
*/
void sendMultiDetectorSize();
/**
* Send the detector pos id to the receiver
* for various file naming conventions for multi detectors in receiver
*/
void setDetectorId();
/**
* Send the detector host name to the receiver
* for various handshaking required with the detector
*/
void setDetectorHostname();
std::string getFilePath();
void setFilePath(const std::string &path);
std::string getFileName();
void setFileName(const std::string &fname);
int64_t getFileIndex();
void setFileIndex(int64_t file_index);
void incrementFileIndex();
fileFormat getFileFormat() ;
void setFileFormat(fileFormat f);
int getFramesPerFile();
/** 0 will set frames per file to unlimited */
void setFramesPerFile(int n_frames);
frameDiscardPolicy getReceiverFramesDiscardPolicy();
void setReceiverFramesDiscardPolicy(frameDiscardPolicy f);
bool getPartialFramesPadding();
void setPartialFramesPadding(bool padding);
/**
* Receiver starts listening to packets
*/
void startReceiver();
/**
* Stops the listening mode of receiver
*/
void stopReceiver();
/**
* Gets the status of the listening mode of receiver
* @returns status
*/
runStatus getReceiverStatus() const;
/**
* Gets the number of frames caught by receiver
* @returns number of frames caught by receiver
*/
int64_t getFramesCaughtByReceiver() const;
/** Gets number of missing packets */
std::vector<uint64_t> getNumMissingPackets() const;
/**
* Gets the current frame index of receiver
* @returns current frame index of receiver
*/
uint64_t getReceiverCurrentFrameIndex() const;
void setFileWrite(bool value);
bool getFileWrite();
void setMasterFileWrite(bool value);
bool getMasterFileWrite();
void setFileOverWrite(bool value);
bool getFileOverWrite();
int getReceiverStreamingFrequency();
/**
* (previously setReadReceiverFrequency)
* Sets the receiver streaming frequency
* @param freq nth frame streamed out, if 0, streamed out at a timer of 200
* ms
* @param detPos -1 for all detectors in list or specific detector position
*/
void setReceiverStreamingFrequency(int freq);
/**
* (previously setReceiverReadTimer)
* Sets the receiver streaming timer
* If receiver streaming frequency is 0, then this timer between each
* data stream is set. Default is 200 ms.
* @param time_in_ms timer between frames
* @returns receiver streaming timer in ms
*/
int setReceiverStreamingTimer(int time_in_ms = 200);
bool getReceiverStreaming();
void setReceiverStreaming(bool enable);
/**
* Enable/disable or 10Gbe
* @param i is -1 to get, 0 to disable and 1 to enable
* @returns if 10Gbe is enabled
*/
bool enableTenGigabitEthernet(int value = -1);
/**
* Set/get receiver fifo depth
* @param i is -1 to get, any other value to set the fifo deph
* @returns the receiver fifo depth
*/
int setReceiverFifoDepth(int n_frames = -1);
bool getReceiverSilentMode();
void setReceiverSilentMode(bool enable);
/**
* If data streaming in receiver is enabled,
* restream the stop dummy packet from receiver
* Used usually for Moench,
* in case it is lost in network due to high data rate
*/
void restreamStopFromReceiver();
bool getTenGiga();
void setTenGiga(bool value);
/**
* Opens pattern file and sends pattern to CTB
@ -1660,9 +1260,6 @@ class Module : public virtual slsDetectorDefs {
/** [Mythen3] */
void setCounterMask(uint32_t countermask);
/** [Mythen3] */
void sendNumberofCounterstoReceiver(uint32_t countermask);
/** [Mythen3] */
uint32_t getCounterMask();
@ -1728,67 +1325,23 @@ class Module : public virtual slsDetectorDefs {
void sendToDetectorStop(int fnum) const;
/**
* Send function parameters to receiver
* @param fnum function enum
* @param args argument pointer
* @param args_size size of argument
* @param retval return pointers
* @param retval_size size of return value
*/
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const;
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval);
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval) const;
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t);
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t) const;
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval);
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const;
template <typename Ret>
Ret sendToReceiver(int fnum);
template <typename Ret>
Ret sendToReceiver(int fnum) const;
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args);
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args) const;
/**
* Get Detector Type from Shared Memory (opening shm without verifying size)
* @param multi_id multi detector Id
* @param detector_id multi detector Id
* @param verify true to verify if shm size matches existing one
* @returns detector type
*/
detectorType getDetectorTypeFromShm(int multi_id, bool verify = true);
detectorType getDetectorTypeFromShm(int detector_id, bool verify = true);
/**
* Initialize shared memory
* @param created true if shared memory must be created, else false to open
* @param type type of detector
* @param multi_id multi detector Id
* @param detector_id multi detector Id
* @param verify true to verify if shm size matches existing one
* @returns true if the shared memory was created now
*/
void initSharedMemory(detectorType type, int multi_id, bool verify = true);
void initSharedMemory(detectorType type, int detector_id, bool verify = true);
/**
* Initialize detector structure to defaults
@ -1871,10 +1424,10 @@ class Module : public virtual slsDetectorDefs {
std::vector<std::string> getSettingsFileDacNames();
/** Module Id or position in the detectors list */
const int detId;
const int moduleId;
/** Shared Memory object */
mutable sls::SharedMemory<sharedSlsDetector> shm{0, 0};
mutable sls::SharedMemory<sharedModule> shm{0, 0};
};
}// sls

View File

@ -0,0 +1,85 @@
#pragma once
#include "Container3.h"
#include "Result.h"
#include <future>
#include <vector>
/*
Can't use std::forward<CT>(Args)...) in parallel call since it would
end up moving temporary objects into the first called function
leaving the other ones with moved from args.
*/
namespace experimental {
using sls::Container3;
template <class CT> struct NonDeduced { using type = CT; };
template <typename RT, typename Class, typename... CT>
sls::Result<RT> Parallel(RT (Class::*func)(CT...) const,
const Container3<std::unique_ptr<Class>> &objects,
const Container3<bool> &mask,
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<RT>> futures;
for (size_t i = 0; i < objects.size(); ++i) {
if (mask[i])
futures.push_back(
std::async(std::launch::async, func, objects[i].get(), Args...));
}
sls::Result<RT> result;
for (auto &f : futures) {
result.push_back(f.get());
}
return result;
}
template <typename RT, typename Class, typename... CT>
sls::Result<RT> Parallel(RT (Class::*func)(CT...),
const Container3<std::unique_ptr<Class>> &objects,
const Container3<bool> &mask,
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<RT>> futures;
for (size_t i = 0; i < objects.size(); ++i) {
if (mask[i])
futures.push_back(
std::async(std::launch::async, func, &objects[i], Args...));
}
sls::Result<RT> result;
for (auto &f : futures) {
result.push_back(f.get());
}
return result;
}
template <typename Class, typename... CT>
void Parallel(void (Class::*func)(CT...) const,
const Container3<std::unique_ptr<Class>> &objects,
const Container3<bool> &mask,
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<void>> futures;
for (size_t i = 0; i < objects.size(); ++i) {
if (mask[i])
futures.push_back(
std::async(std::launch::async, func, &objects[i], Args...));
}
for (auto &f : futures) {
f.get();
}
}
template <typename Class, typename... CT>
void Parallel(void (Class::*func)(CT...),
const Container3<std::unique_ptr<Class>> &objects,
const Container3<bool> &mask,
typename NonDeduced<CT>::type... Args) {
std::vector<std::future<void>> futures;
for (size_t i = 0; i < objects.size(); ++i) {
if (mask[i])
futures.push_back(
std::async(std::launch::async, func, &objects[i], Args...));
}
for (auto &f : futures)
f.get();
}
} // namespace experimental

View File

@ -0,0 +1,883 @@
#include "Receiver.h"
#include "ClientSocket.h"
#include "FixedCapacityContainer.h"
#include "string_utils.h"
#include "versionAPI.h"
#include "ToString.h"
namespace sls {
// create shm
Receiver::Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, int tcp_port, std::string hostname,
int zmq_port) :
receiverId(receiver_id), interfaceId(interface_id), moduleId(module_id),
shm(detector_id, module_id, interface_id, receiver_id) {
createIndexString();
// ensure shared memory was not created before
if (shm.IsExisting()) {
LOG(logWARNING) << "This shared memory should have been deleted "
"before! " << shm.GetName() << ". Freeing it again";
shm.RemoveSharedMemory();
}
shm = SharedMemory<sharedReceiver>(detector_id, module_id, interface_id,
receiver_id);
shm.CreateSharedMemory();
// initalize receiver structure
shm()->shmversion = RECEIVER_SHMVERSION;
memset(shm()->hostname, 0, MAX_STR_LENGTH);
shm()->tcpPort = DEFAULT_RX_PORTNO + receiver_id;
shm()-> stoppedFlag = false;
shm()->zmqPort = DEFAULT_ZMQ_RX_PORTNO + receiver_id;
shm()->zmqIp = IpAddr{};
// copy port, hostname if given
if (tcp_port != 0) {
setTCPPort(tcp_port);
}
if (zmq_port != 0) {
shm()->zmqPort = zmq_port;
}
if (!hostname.empty()) {
setHostname(hostname);
}
}
// open shm
Receiver::Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, bool verify) :
receiverId(receiver_id), interfaceId(interface_id), moduleId(module_id),
shm(detector_id, module_id, interface_id, receiver_id) {
createIndexString();
shm.OpenSharedMemory();
if (verify && shm()->shmversion != RECEIVER_SHMVERSION) {
std::ostringstream ss;
ss << "Receiver shared memory (" << detector_id << "-" << indexString
<< ":" << receiverId << ") version mismatch (expected 0x" << std::hex
<< RECEIVER_SHMVERSION << " but got 0x" << shm()->shmversion << ")"
<< std::dec << ". Clear Shared memory to continue.";
throw SharedMemoryError(ss.str());
}
}
Receiver::~Receiver() = default;
void Receiver::createIndexString() {
std::ostringstream oss;
oss << '(' << moduleId << (char)(interfaceId + 97) << "." << receiverId << ')';
indexString = oss.str();
}
/** Configuration */
void Receiver::freeSharedMemory() {
if (shm.IsExisting()) {
shm.RemoveSharedMemory();
}
}
std::string Receiver::getHostname() const {
return shm()->hostname;
}
void Receiver::setHostname(const std::string &hostname) {
if (hostname.empty()) {
throw RuntimeError("Invalid receiver hostname. Cannot be empty.");
}
sls::strcpy_safe(shm()->hostname, hostname.c_str());
checkVersionCompatibility();
}
int Receiver::getTCPPort() const {
return shm()->tcpPort;
}
void Receiver::setTCPPort(const int port) {
LOG(logDEBUG1) << "Setting reciever port to " << port;
if (port >= 0 && port != shm()->tcpPort) {
if (strlen(shm()->hostname) != 0) {
int retval = -1;
sendToReceiver(F_SET_RECEIVER_PORT, port, retval);
shm()->tcpPort = retval;
LOG(logDEBUG1) << "Receiver port: " << retval;
} else {
shm()->tcpPort = port;
}
}
}
void Receiver::checkVersionCompatibility() {
int64_t arg = APIRECEIVER;
LOG(logDEBUG1)
<< "Checking version compatibility with receiver with value "
<< std::hex << arg << std::dec;
sendToReceiver(F_RECEIVER_CHECK_VERSION, arg, nullptr);
}
sls::MacAddr Receiver::configure(slsDetectorDefs::rxParameters arg) {
// hostname
memset(arg.hostname, 0, sizeof(arg.hostname));
strcpy_safe(arg.hostname, shm()->hostname);
// interface id
arg.interfaceId = interfaceId;
// zmqip
{
sls::IpAddr ip;
// Hostname could be ip try to decode otherwise look up the hostname
ip = sls::IpAddr{shm()->hostname};
if (ip == 0) {
ip = HostnameToIp(shm()->hostname);
}
LOG(logINFO) << "Setting default receiver " << indexString
<< " streaming zmq ip to " << ip;
// if client zmqip is empty, update it
if (shm()->zmqIp == 0) {
shm()->zmqIp = ip;
}
memcpy(&arg.zmq_ip, &ip, sizeof(ip));
}
if (arg.detType == EIGER) {
arg.udpInterfaces = 2;
}
LOG(logDEBUG1)
<< "detType:" << arg.detType << std::endl
<< "detectorSize.x:" << arg.detectorSize.x << std::endl
<< "detectorSize.y:" << arg.detectorSize.y << std::endl
<< "moduleId:" << arg.moduleId << std::endl
<< "hostname:" << arg.hostname << std::endl
<< "interfaceId: " << arg.interfaceId << std::endl
<< "zmq ip:" << arg.zmq_ip << std::endl
<< "udpInterfaces:" << arg.udpInterfaces << std::endl
<< "udp_dstport:" << arg.udp_dstport << std::endl
<< "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl
<< "udp_dstmac:" << sls::MacAddr(arg.udp_dstmac) << std::endl
<< "udp_dstport2:" << arg.udp_dstport2 << std::endl
<< "udp_dstip2:" << sls::IpAddr(arg.udp_dstip2) << std::endl
<< "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2) << std::endl
<< "frames:" << arg.frames << std::endl
<< "triggers:" << arg.triggers << std::endl
<< "bursts:" << arg.bursts << std::endl
<< "analogSamples:" << arg.analogSamples << std::endl
<< "digitalSamples:" << arg.digitalSamples << std::endl
<< "expTimeNs:" << arg.expTimeNs << std::endl
<< "periodNs:" << arg.periodNs << std::endl
<< "subExpTimeNs:" << arg.subExpTimeNs << std::endl
<< "subDeadTimeNs:" << arg.subDeadTimeNs << std::endl
<< "activate:" << arg.activate << std::endl
<< "quad:" << arg.quad << std::endl
<< "dynamicRange:" << arg.dynamicRange << std::endl
<< "timMode:" << arg.timMode << std::endl
<< "tenGiga:" << arg.tenGiga << std::endl
<< "roMode:" << arg.roMode << std::endl
<< "adcMask:" << arg.adcMask << std::endl
<< "adc10gMask:" << arg.adc10gMask << std::endl
<< "roi.xmin:" << arg.roi.xmin << std::endl
<< "roi.xmax:" << arg.roi.xmax << std::endl
<< "countermask:" << arg.countermask << std::endl
<< "burstType:" << arg.burstType << std::endl;
sls::MacAddr mac;
{
sls::MacAddr retval;
sendToReceiver(F_SETUP_RECEIVER, arg, retval);
// detector does not have customized udp mac
if (arg.udp_dstmac == 0) {
mac = retval;
}
}
if (arg.detType == MOENCH) {
setAdditionalJsonParameter("adcmask_1g", std::to_string(arg.adcMask));
setAdditionalJsonParameter("adcmask_10g", std::to_string(arg.adc10gMask));
}
LOG(logINFOBLUE) << "reciever " << indexString << " configured!";
return mac;
}
std::string Receiver::printConfiguration() {
std::ostringstream oss;
oss << std::endl << std::endl
<< "Receiver " << indexString << std::endl
<< "Hostname : " << shm()->hostname << std::endl
<< "Tcp port : " << shm()->tcpPort << std::endl;
/*
os << "\nReceiver UDP IP:\t"
<< getDestinationUDPIP() << "\nReceiver UDP MAC:\t" << getDestinationUDPMAC();
if (shm()->myDetectorType == JUNGFRAU) {
os << "\nDetector UDP IP2:\t" << getSourceUDPIP2()
<< "\nDetector UDP MAC2:\t" << getSourceUDPMAC2()
<< "\nReceiver UDP IP2:\t" << getDestinationUDPIP2()
<< "\nReceiver UDP MAC2:\t" << getDestinationUDPMAC2();
}
os << "\nReceiver UDP Port:\t" << getDestinationUDPPort();
if (shm()->myDetectorType == JUNGFRAU || shm()->myDetectorType == EIGER) {
os << "\nReceiver UDP Port2:\t" << getDestinationUDPPort2();
}
*/
oss << "\n";
return oss.str();
}
int64_t Receiver::getSoftwareVersion() const {
LOG(logDEBUG1) << "Getting receiver software version";
return sendToReceiver<int64_t>(F_GET_RECEIVER_VERSION);
}
/** Acquisition */
void Receiver::start() {
LOG(logDEBUG1) << "Starting Receiver";
shm()->stoppedFlag = false;
sendToReceiver(F_START_RECEIVER, nullptr, nullptr);
}
void Receiver::stop() {
LOG(logDEBUG1) << "Stopping Receiver";
int arg = static_cast<int>(shm()->stoppedFlag);
sendToReceiver(F_STOP_RECEIVER, arg, nullptr);
}
slsDetectorDefs::runStatus Receiver::getStatus() const {
runStatus retval = ERROR;
LOG(logDEBUG1) << "Getting Receiver Status";
sendToReceiver(F_GET_RECEIVER_STATUS, nullptr, retval);
LOG(logDEBUG1) << "Receiver Status: " << ToString(retval);
return retval;
}
int Receiver::getProgress() const {
int retval = -1;
sendToReceiver(F_GET_RECEIVER_PROGRESS, nullptr, retval);
LOG(logDEBUG1) << "Current Progress of Receiver: " << retval;
return retval;
}
void Receiver::setStoppedFlag() {
shm()->stoppedFlag = true;
}
void Receiver::restreamStop() {
LOG(logDEBUG1) << "Restream stop dummy from Receiver via zmq";
sendToReceiver(F_RESTREAM_STOP_FROM_RECEIVER, nullptr, nullptr);
}
uint64_t Receiver::getFramesCaught() const {
return sendToReceiver<uint64_t>(F_GET_RECEIVER_FRAMES_CAUGHT);
}
uint64_t Receiver::getNumMissingPackets() const {
return sendToReceiver<uint64_t>(F_GET_NUM_MISSING_PACKETS);
}
uint64_t Receiver::getCurrentFrameIndex() const {
return sendToReceiver<uint64_t>(F_GET_RECEIVER_FRAME_INDEX);
}
/** Network Configuration (Detector<->Receiver) */
sls::MacAddr Receiver::setUDPIP(const IpAddr ip) {
LOG(logDEBUG1) << "Setting udp ip to receier: " << ip;
if (ip == 0) {
throw RuntimeError("Invalid destination udp ip address");
}
sls::MacAddr retval(0LU);
sendToReceiver(F_SET_RECEIVER_UDP_IP, ip, retval);
return retval;
}
void Receiver::setUDPPort(const int port) {
LOG(logDEBUG1) << "Setting udp port to receiver: " << port;
sendToReceiver(F_SET_RECEIVER_UDP_PORT, port, nullptr);
}
int64_t Receiver::getUDPSocketBufferSize() const {
return sendToReceiver<int64_t>(F_GET_RECEIVER_UDP_SOCK_BUF_SIZE);
}
void Receiver::setUDPSocketBufferSize(int64_t value) {
LOG(logDEBUG1) << "Sending UDP Socket Buffer size to receiver: "
<< value;
sendToReceiver(F_SET_RECEIVER_UDP_SOCK_BUF_SIZE, value, nullptr);
}
int64_t Receiver::getRealUDPSocketBufferSize() const {
return sendToReceiver<int64_t>(F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE);
}
/** ZMQ Streaming Parameters (Receiver<->Client) */
bool Receiver::getZmq() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING);
}
void Receiver::setZmq(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_SET_RECEIVER_STREAMING, arg, nullptr);
}
int Receiver::getZmqFrequency() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_FREQUENCY);
}
void Receiver::setZmqFrequency(const int freq) {
if (freq < 0) {
throw RuntimeError("Invalid streaming frequency " + std::to_string(freq));
}
sendToReceiver(F_SET_RECEIVER_STREAMING_FREQUENCY, freq, nullptr);
}
int Receiver::getZmqTimer() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_TIMER);
}
void Receiver::setZmqTimer(const int time_in_ms) {
sendToReceiver(F_SET_RECEIVER_STREAMING_TIMER, time_in_ms, nullptr);
}
int Receiver::getZmqPort() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_PORT);
}
void Receiver::setZmqPort(int port) {
sendToReceiver(F_SET_RECEIVER_STREAMING_PORT, port, nullptr);
}
sls::IpAddr Receiver::getZmqIP() const {
return sendToReceiver<sls::IpAddr>(F_GET_RECEIVER_STREAMING_SRC_IP);
}
void Receiver::setZmqIP(const sls::IpAddr ip) {
if (ip == 0) {
throw RuntimeError("Invalid receiver zmq ip address");
}
// if client zmqip is empty, update it
if (shm()->zmqIp == 0) {
shm()->zmqIp = ip;
}
sendToReceiver(F_SET_RECEIVER_STREAMING_SRC_IP, ip, nullptr);
}
int Receiver::getClientZmqPort() const {
return shm()->zmqPort;
}
void Receiver::setClientZmqPort(const int port) {
shm()->zmqPort = port;
}
sls::IpAddr Receiver::getClientZmqIP() const {
return shm()->zmqIp;
}
void Receiver::setClientZmqIP(const sls::IpAddr ip) {
LOG(logDEBUG1) << "Setting client zmq ip to " << ip;
if (ip == 0) {
throw RuntimeError("Invalid client zmq ip address");
}
shm()->zmqIp = ip;
}
/** Receiver Parameters */
bool Receiver::getLock() const {
return sendToReceiver<int>(F_GET_LOCK_RECEIVER);
}
void Receiver::setLock(const bool lock) {
LOG(logDEBUG1) << "Setting receiver server lock to " << lock;
sendToReceiver(F_SET_LOCK_RECEIVER, lock, nullptr);
}
sls::IpAddr Receiver::getLastClientIP() const {
return sendToReceiver<sls::IpAddr>(F_GET_LAST_RECEIVER_CLIENT_IP);
}
void Receiver::exitServer() {
LOG(logDEBUG1) << "Sending exit command to receiver server";
sendToReceiver(F_EXIT_RECEIVER, nullptr, nullptr);
}
bool Receiver::getDeactivatedPaddingMode() const {
return sendToReceiver<int>(F_GET_RECEIVER_DEACTIVATED_PADDING);
}
void Receiver::setDeactivatedPaddingMode(const bool padding) {
int arg = static_cast<int>(padding);
sendToReceiver(F_SET_RECEIVER_DEACTIVATED_PADDING, arg, nullptr);
}
bool Receiver::getFlippedDataX() const {
int arg = -1;
return sendToReceiver<int>(F_GET_FLIPPED_DATA_RECEIVER, arg);
}
void Receiver::setFlippedDataX(const bool value) {
int arg = static_cast<int>(value);
LOG(logDEBUG1) << "Setting flipped data across x axis with value: "
<< value;
sendToReceiver(F_SET_FLIPPED_DATA_RECEIVER, arg, nullptr);
}
slsDetectorDefs::frameDiscardPolicy Receiver::getFramesDiscardPolicy() const {
return static_cast<frameDiscardPolicy>(
sendToReceiver<int>(F_GET_RECEIVER_DISCARD_POLICY));
}
void Receiver::setFramesDiscardPolicy(const frameDiscardPolicy f) {
int arg = static_cast<int>(f);
sendToReceiver(F_SET_RECEIVER_DISCARD_POLICY, arg, nullptr);
}
bool Receiver::getPartialFramesPadding() const {
return sendToReceiver<int>(F_GET_RECEIVER_PADDING);
}
void Receiver::setPartialFramesPadding(const bool padding) {
int arg = static_cast<int>(padding);
sendToReceiver(F_SET_RECEIVER_PADDING, arg, nullptr);
}
int Receiver::getFifoDepth() const {
return sendToReceiver<int>(F_GET_RECEIVER_FIFO_DEPTH);
}
void Receiver::setFifoDepth(const int value) {
sendToReceiver(F_SET_RECEIVER_FIFO_DEPTH, value, nullptr);
}
bool Receiver::getSilentMode() const {
return sendToReceiver<int>(F_GET_RECEIVER_SILENT_MODE);
}
void Receiver::setSilentMode(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_SET_RECEIVER_SILENT_MODE, arg, nullptr);
}
/** File */
std::string Receiver::getFilePath() const {
char retvals[MAX_STR_LENGTH]{};
sendToReceiver(F_GET_RECEIVER_FILE_PATH, nullptr, retvals);
return std::string(retvals);
}
void Receiver::setFilePath(const std::string &path) {
if (path.empty()) {
throw RuntimeError("Cannot set empty file path");
}
char args[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, path.c_str());
sendToReceiver(F_SET_RECEIVER_FILE_PATH, args, nullptr);
}
std::string Receiver::getFileName() const {
char retvals[MAX_STR_LENGTH]{};
sendToReceiver(F_GET_RECEIVER_FILE_NAME, nullptr, retvals);
return std::string(retvals);
}
void Receiver::setFileName(const std::string &fname) {
if (fname.empty()) {
throw RuntimeError("Cannot set empty file name prefix");
}
char args[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, fname.c_str());
sendToReceiver(F_SET_RECEIVER_FILE_NAME, args, nullptr);
}
int64_t Receiver::getFileIndex() const {
return sendToReceiver<int64_t>(F_GET_RECEIVER_FILE_INDEX);
}
void Receiver::setFileIndex(const int64_t file_index) {
sendToReceiver(F_SET_RECEIVER_FILE_INDEX, file_index, nullptr);
}
void Receiver::incrementFileIndex() {
sendToReceiver(F_INCREMENT_FILE_INDEX, nullptr, nullptr);
}
slsDetectorDefs::fileFormat Receiver::getFileFormat() const {
return static_cast<fileFormat>(
sendToReceiver<int>(F_GET_RECEIVER_FILE_FORMAT));
}
void Receiver::setFileFormat(const fileFormat f) {
int arg = static_cast<int>(f);
sendToReceiver(F_SET_RECEIVER_FILE_FORMAT, arg, nullptr);
}
int Receiver::getFramesPerFile() const {
return sendToReceiver<int>(F_GET_RECEIVER_FRAMES_PER_FILE);
}
void Receiver::setFramesPerFile(const int n_frames) {
sendToReceiver(F_SET_RECEIVER_FRAMES_PER_FILE, n_frames, nullptr);
}
bool Receiver::getFileWrite() const {
return sendToReceiver<int>(F_GET_RECEIVER_FILE_WRITE);
}
void Receiver::setFileWrite(const bool value) {
int arg = static_cast<int>(value);
sendToReceiver(F_SET_RECEIVER_FILE_WRITE, arg, nullptr);
}
bool Receiver::getMasterFileWrite() const {
return sendToReceiver<int>(F_GET_RECEIVER_MASTER_FILE_WRITE);
}
void Receiver::setMasterFileWrite(const bool value) {
int arg = static_cast<int>(value);
sendToReceiver(F_SET_RECEIVER_MASTER_FILE_WRITE, arg, nullptr);
}
bool Receiver::getFileOverWrite() const {
return sendToReceiver<int>(F_GET_RECEIVER_OVERWRITE);
}
void Receiver::setFileOverWrite(const bool value) {
int arg = static_cast<int>(value);
sendToReceiver(F_SET_RECEIVER_OVERWRITE, arg, nullptr);
}
/** Detector Parameters */
void Receiver::setNumberOfFrames(const int64_t value) {
LOG(logDEBUG1) << "Sending number of frames to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, value, nullptr);
}
void Receiver::setNumberOfTriggers(const int64_t value) {
LOG(logDEBUG1) << "Sending number of triggers to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_NUM_TRIGGERS, value, nullptr);
}
void Receiver::setNumberOfBursts(const int64_t value) {
LOG(logDEBUG1) << "Sending number of bursts to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_NUM_BURSTS, value, nullptr);
}
void Receiver::setNumberOfAnalogSamples(const int value) {
LOG(logDEBUG1) << "Sending number of analog samples to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_ANALOG_SAMPLES, value, nullptr);
}
void Receiver::setNumberOfDigitalSamples(const int value) {
LOG(logDEBUG1) << "Sending number of digital samples to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, value, nullptr);
}
void Receiver::setExptime(const int64_t value) {
LOG(logDEBUG1) << "Sending exptime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_EXPTIME, value, nullptr);
}
void Receiver::setPeriod(const int64_t value) {
LOG(logDEBUG1) << "Sending period to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_PERIOD, value, nullptr);
}
void Receiver::setSubExptime(const int64_t value) {
LOG(logDEBUG1) << "Sending sub exptime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_SUB_EXPTIME, value, nullptr);
}
void Receiver::setSubDeadTime(const int64_t value) {
LOG(logDEBUG1) << "Sending sub deadtime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_SUB_DEADTIME, value, nullptr);
}
void Receiver::setTimingMode(const timingMode value) {
LOG(logDEBUG1) << "Sending timing mode to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_TIMING_MODE, value, nullptr);
}
void Receiver::setDynamicRange(const int n) {
int retval = -1;
LOG(logDEBUG1) << "Sending dynamic range to receiver: " << n;
sendToReceiver(F_SET_RECEIVER_DYNAMIC_RANGE, n, retval);
}
void Receiver::setReadoutMode(const slsDetectorDefs::readoutMode mode) {
sendToReceiver(F_RECEIVER_SET_READOUT_MODE, mode, nullptr);
}
void Receiver::setQuad(const bool enable) {
int value = enable ? 1 : 0;
LOG(logDEBUG1) << "Setting Quad type to " << value << " in Receiver";
sendToReceiver(F_SET_RECEIVER_QUAD, value, nullptr);
}
void Receiver::setReadNLines(const int value) {
LOG(logDEBUG1) << "Setting read n lines to " << value
<< " in Receiver";
sendToReceiver(F_SET_RECEIVER_READ_N_LINES, value, nullptr);
}
void Receiver::setADCEnableMask(const uint32_t mask) {
sendToReceiver(F_RECEIVER_SET_ADC_MASK, mask, nullptr);
}
void Receiver::setTenGigaADCEnableMask(const uint32_t mask) {
sendToReceiver(F_RECEIVER_SET_ADC_MASK_10G, mask, nullptr);
}
void Receiver::setBurstMode(const slsDetectorDefs::burstMode value) {
LOG(logDEBUG1) << "Sending burst mode to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_BURST_MODE, value, nullptr);
}
void Receiver::setROI(const slsDetectorDefs::ROI arg) {
std::array<int, 2> args{arg.xmin, arg.xmax};
LOG(logDEBUG1) << "Sending ROI to receiver";
sendToReceiver(F_RECEIVER_SET_ROI, args, nullptr);
}
void Receiver::clearROI() {
LOG(logDEBUG1) << "Clearing ROI";
slsDetectorDefs::ROI arg;
arg.xmin = -1;
arg.xmax = -1;
setROI(arg);
}
std::vector<int> Receiver::getDbitList() const {
sls::FixedCapacityContainer<int, MAX_RX_DBIT> retval;
sendToReceiver(F_GET_RECEIVER_DBIT_LIST, nullptr, retval);
return retval;
}
void Receiver::setDbitList(const std::vector<int>& list) {
LOG(logDEBUG1) << "Setting Receiver Dbit List";
if (list.size() > 64) {
throw sls::RuntimeError("Dbit list size cannot be greater than 64\n");
}
for (auto &it : list) {
if (it < 0 || it > 63) {
throw sls::RuntimeError(
"Dbit list value must be between 0 and 63\n");
}
}
sls::FixedCapacityContainer<int, MAX_RX_DBIT> arg = list;
sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr);
}
int Receiver::getDbitOffset() const {
return sendToReceiver<int>(F_GET_RECEIVER_DBIT_OFFSET);
}
void Receiver::setDbitOffset(const int value) {
sendToReceiver(F_SET_RECEIVER_DBIT_OFFSET, value, nullptr);
}
void Receiver::setActivate(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_RECEIVER_ACTIVATE, arg, nullptr);
}
void Receiver::setTenGiga(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_ENABLE_RECEIVER_TEN_GIGA, arg, nullptr);
}
void Receiver::setCounterMask(const uint32_t mask) {
int ncounters = __builtin_popcount(mask);
LOG(logDEBUG1) << "Sending Reciver #counters: " << ncounters;
sendToReceiver(F_RECEIVER_SET_NUM_COUNTERS, ncounters, nullptr);
}
/** Json */
std::map<std::string, std::string> Receiver::getAdditionalJsonHeader() const {
int fnum = F_GET_ADDITIONAL_JSON_HEADER;
int ret = FAIL;
int size = 0;
auto client = ReceiverSocket(shm()->hostname, shm()->tcpPort);
client.Send(&fnum, sizeof(fnum));
client.Receive(&ret, sizeof(ret));
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + std::string(mess));
} else {
client.Receive(&size, sizeof(size));
std::map<std::string, std::string> retval;
if (size > 0) {
char retvals[size * 2][SHORT_STR_LENGTH];
memset(retvals, 0, sizeof(retvals));
client.Receive(retvals, sizeof(retvals));
for (int i = 0; i < size; ++i) {
retval[retvals[2 * i]] = retvals[2 * i + 1];
}
}
LOG(logDEBUG) << "Getting additional json header " << ToString(retval);
return retval;
}
}
void Receiver::setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader) {
for (auto &it : jsonHeader) {
if (it.first.empty() || it.first.length() > SHORT_STR_LENGTH ||
it.second.length() > SHORT_STR_LENGTH ) {
throw RuntimeError(it.first + " or " + it.second + " pair has invalid size. "
"Key cannot be empty. Both can have max 20 characters");
}
}
const int size = jsonHeader.size();
int fnum = F_SET_ADDITIONAL_JSON_HEADER;
int ret = FAIL;
LOG(logDEBUG) << "Sending to receiver additional json header " << ToString(jsonHeader);
auto client = ReceiverSocket(shm()->hostname, shm()->tcpPort);
client.Send(&fnum, sizeof(fnum));
client.Send(&size, sizeof(size));
if (size > 0) {
char args[size * 2][SHORT_STR_LENGTH];
memset(args, 0, sizeof(args));
int iarg = 0;
for (auto &it : jsonHeader) {
sls::strcpy_safe(args[iarg], it.first.c_str());
sls::strcpy_safe(args[iarg + 1], it.second.c_str());
iarg += 2;
}
client.Send(args, sizeof(args));
}
client.Receive(&ret, sizeof(ret));
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + std::string(mess));
}
}
std::string Receiver::getAdditionalJsonParameter(const std::string &key) const {
char arg[SHORT_STR_LENGTH]{};
sls::strcpy_safe(arg, key.c_str());
char retval[SHORT_STR_LENGTH]{};
sendToReceiver(F_GET_ADDITIONAL_JSON_PARAMETER, arg, retval);
return retval;
}
void Receiver::setAdditionalJsonParameter(const std::string &key, const std::string &value) {
if (key.empty() || key.length() > SHORT_STR_LENGTH ||
value.length() > SHORT_STR_LENGTH ) {
throw RuntimeError(key + " or " + value + " pair has invalid size. "
"Key cannot be empty. Both can have max 2 characters");
}
char args[2][SHORT_STR_LENGTH]{};
sls::strcpy_safe(args[0], key.c_str());
sls::strcpy_safe(args[1], value.c_str());
sendToReceiver(F_SET_ADDITIONAL_JSON_PARAMETER, args, nullptr);
}
void Receiver::sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) {
static_cast<const Receiver &>(*this).sendToReceiver(
fnum, args, args_size, retval, retval_size);
}
void Receiver::sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const {
if (strlen(shm()->hostname) == 0) {
throw RuntimeError("Reciver not added");
}
auto receiver = ReceiverSocket(shm()->hostname, shm()->tcpPort);
receiver.sendCommandThenRead(fnum, args, args_size, retval, retval_size);
receiver.close();
}
template <typename Arg, typename Ret>
void Receiver::sendToReceiver(int fnum, const Arg &args, Ret &retval) {
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
}
template <typename Arg, typename Ret>
void Receiver::sendToReceiver(int fnum, const Arg &args, Ret &retval) const {
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
}
template <typename Arg>
void Receiver::sendToReceiver(int fnum, const Arg &args, std::nullptr_t) {
sendToReceiver(fnum, &args, sizeof(args), nullptr, 0);
}
template <typename Arg>
void Receiver::sendToReceiver(int fnum, const Arg &args,
std::nullptr_t) const {
sendToReceiver(fnum, &args, sizeof(args), nullptr, 0);
}
template <typename Ret>
void Receiver::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) {
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
}
template <typename Ret>
void Receiver::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const {
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
}
template <typename Ret>
Ret Receiver::sendToReceiver(int fnum){
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", nullptr, 0, " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
template <typename Ret>
Ret Receiver::sendToReceiver(int fnum) const{
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", nullptr, 0, " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
template <typename Ret, typename Arg>
Ret Receiver::sendToReceiver(int fnum, const Arg &args){
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", " << args << ", " << sizeof(args) << ", " << typeid(Ret).name()
<< ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
template <typename Ret, typename Arg>
Ret Receiver::sendToReceiver(int fnum, const Arg &args) const{
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", " << args << ", " << sizeof(args) << ", " << typeid(Ret).name()
<< ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
} // namespace sls

View File

@ -0,0 +1,251 @@
#pragma once
#include "SharedMemory.h"
#include "logger.h"
#include "network_utils.h"
#include "sls_detector_defs.h"
#include <map>
#define RECEIVER_SHMVERSION 0x200421
namespace sls {
struct sharedReceiver {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
int shmversion;
char hostname[MAX_STR_LENGTH];
int tcpPort;
/** END OF FIXED PATTERN -----------------------------------------------*/
int stoppedFlag;
int zmqPort;
sls::IpAddr zmqIp;
};
class Receiver : public virtual slsDetectorDefs {
const int receiverId{0};
const int interfaceId{0};
const int moduleId{0};
std::string indexString;
mutable sls::SharedMemory<sharedReceiver> shm{0, 0, 0, 0};
public:
static size_t getNumReceivers();
// create shm
explicit Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, int tcp_port = 0,
std::string hostname = "", int zmq_port = 0);
// open shm
explicit Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, bool verify);
virtual ~Receiver();
void createIndexString();
/**************************************************
* *
* Configuration *
* *
* ************************************************/
/**
* Free shared memory and delete shared memory structure
* occupied by the sharedReceiver structure
* Is only safe to call if one deletes the Receiver object afterward
* and frees multi shared memory/updates
* thisMultiDetector->numberOfReceivers
*/
void freeSharedMemory();
std::string getHostname() const;
void setHostname(const std::string &hostname);
sls::MacAddr configure(slsDetectorDefs::rxParameters arg);
int getTCPPort() const;
void setTCPPort(const int port);
std::string printConfiguration();
int64_t getSoftwareVersion() const;
/**************************************************
* *
* Acquisition *
* *
* ************************************************/
void start();
void stop();
slsDetectorDefs::runStatus getStatus() const;
int getProgress() const;
void setStoppedFlag();
void restreamStop();
uint64_t getFramesCaught() const;
uint64_t getNumMissingPackets() const;
uint64_t getCurrentFrameIndex() const;
/**************************************************
* *
* Network Configuration (Detector<->Receiver) *
* *
* ************************************************/
sls::MacAddr setUDPIP(const sls::IpAddr ip);
void setUDPPort(const int udpport);
int64_t getUDPSocketBufferSize() const;
void setUDPSocketBufferSize(int64_t value);
int64_t getRealUDPSocketBufferSize() const;
/**************************************************
* *
* ZMQ Streaming Parameters (Receiver<->Client)*
* *
* ************************************************/
bool getZmq() const;
void setZmq(const bool enable);
int getZmqFrequency() const;
/** Freq = 0 for a timer, else frequency */
void setZmqFrequency(const int freq);
int getZmqTimer() const;
void setZmqTimer(const int time_in_ms = 200);
int getZmqPort() const;
void setZmqPort(int port);
sls::IpAddr getZmqIP() const;
void setZmqIP(const sls::IpAddr ip);
int getClientZmqPort() const;
void setClientZmqPort(const int port);
sls::IpAddr getClientZmqIP() const;
void setClientZmqIP(const sls::IpAddr ip);
/**************************************************
* *
* Receiver Parameters *
* *
* ************************************************/
bool getLock() const;
void setLock(const bool lock);
sls::IpAddr getLastClientIP() const;
void exitServer();
bool getDeactivatedPaddingMode() const;
void setDeactivatedPaddingMode(const bool padding);
bool getFlippedDataX() const;
void setFlippedDataX(const bool value);
frameDiscardPolicy getFramesDiscardPolicy() const;
void setFramesDiscardPolicy(const frameDiscardPolicy f);
bool getPartialFramesPadding() const;
void setPartialFramesPadding(const bool padding);
int getFifoDepth() const;
void setFifoDepth(const int value);
bool getSilentMode() const;
void setSilentMode(const bool value);
/**************************************************
* *
* File *
* *
* ************************************************/
std::string getFilePath() const;
void setFilePath(const std::string &path);
std::string getFileName() const;
void setFileName(const std::string &fname);
int64_t getFileIndex() const;
void setFileIndex(const int64_t file_index);
void incrementFileIndex();
fileFormat getFileFormat() const;
void setFileFormat(const fileFormat f);
int getFramesPerFile() const;
/** 0 will set frames per file to unlimited */
void setFramesPerFile(const int n_frames);
bool getFileWrite() const;
void setFileWrite(const bool value);
bool getMasterFileWrite() const;
void setMasterFileWrite(const bool value);
bool getFileOverWrite() const;
void setFileOverWrite(const bool value);
/**************************************************
* *
* Detector Parameters *
* *
* ************************************************/
void setNumberOfFrames(const int64_t value);
void setNumberOfTriggers(const int64_t value);
void setNumberOfBursts(const int64_t value);
void setNumberOfAnalogSamples(const int value);
void setNumberOfDigitalSamples(const int value);
void setExptime(const int64_t value);
void setPeriod(const int64_t value);
void setSubExptime(const int64_t value);
void setSubDeadTime(const int64_t value);
void setTimingMode(const timingMode value);
void setDynamicRange(const int n);
void setReadoutMode(const readoutMode mode);
void setQuad(const bool enable);
void setReadNLines(const int value);
void setADCEnableMask(const uint32_t mask);
void setTenGigaADCEnableMask(const uint32_t mask);
void setBurstMode(const burstMode value);
void setROI(const slsDetectorDefs::ROI arg);
void clearROI();
std::vector<int> getDbitList() const;
/** digital data bits enable (CTB only) */
void setDbitList(const std::vector<int> &list);
int getDbitOffset() const;
/** Set digital data offset in bytes (CTB only) */
void setDbitOffset(const int value);
void setActivate(const bool enable);
void setTenGiga(const bool enable);
void setCounterMask(const uint32_t mask);
/**************************************************
* *
* Json *
* *
* ************************************************/
std::map<std::string, std::string> getAdditionalJsonHeader() const;
/** empty vector deletes entire additional json header */
void setAdditionalJsonHeader(
const std::map<std::string, std::string> &jsonHeader);
std::string getAdditionalJsonParameter(const std::string &key) const;
/** Sets the value for the additional json header parameter key if found,
else append it. If value empty, then deletes parameter */
void setAdditionalJsonParameter(const std::string &key,
const std::string &value);
private:
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const;
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval);
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval) const;
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t);
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t) const;
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval);
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const;
template <typename Ret> Ret sendToReceiver(int fnum);
template <typename Ret> Ret sendToReceiver(int fnum) const;
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args);
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args) const;
void checkVersionCompatibility();
};
} // namespace sls

View File

@ -23,7 +23,8 @@
#include <unistd.h>
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
#define SHM_SLS_PREFIX "_sls_"
#define SHM_MODULE_PREFIX "_module_"
#define SHM_RECEIVER_PREFIX "_receiver_"
#define SHM_ENV_NAME "SLSDETNAME"
#include <iostream>
@ -39,10 +40,12 @@ class SharedMemory {
* Constructor
* creates the single/multi detector shared memory name
* @param multiId multi detector id
* @param slsId sls detector id, -1 if a multi detector shared memory
* @param moduleId module detectr id, -1 if a multi detector shared memory
* @param interfaceId 0 for primary interface, 1 for secondary
* @param receiverId receiver id, -1 if not a rxr shm, else round robin entry
*/
SharedMemory(int multiId, int slsId) {
name = ConstructSharedMemoryName(multiId, slsId);
SharedMemory(int multiId, int moduleId, int interfaceId = 0, int receiverId = -1) {
name = ConstructSharedMemoryName(multiId, moduleId, interfaceId, receiverId);
}
/**
@ -184,7 +187,8 @@ class SharedMemory {
// silent exit if shm did not exist anyway
if (errno == ENOENT)
return;
std::string msg = "Free Shared Memory " + name + " Failed: " + strerror(errno);
std::string msg = "Free Shared Memory " + name + " Failed: " +
strerror(errno);
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
}
@ -215,10 +219,13 @@ class SharedMemory {
* Create Shared memory name
* throws exception if name created is longer than required 255(manpages)
* @param multiId multi detector id
* @param slsId sls detector id, -1 if a multi detector shared memory
* @param moduleId module detector id, -1 if a multi detector shared memory
* @param interfaceId 0 for primary interface, 1 for secondary
* @param receiverId receiver id, -1 if not a rxr shm, else round robin entry
* @returns shared memory name
*/
std::string ConstructSharedMemoryName(int multiId, int slsId) {
std::string ConstructSharedMemoryName(int multiId, int moduleId,
int interfaceId = 0, int receiverId = -1) {
// using environment path
std::string sEnvPath = "";
@ -229,14 +236,22 @@ class SharedMemory {
}
std::stringstream ss;
if (slsId < 0)
if (moduleId < 0 && receiverId < 0)
ss << SHM_MULTI_PREFIX << multiId << sEnvPath;
else if (receiverId < 0)
ss << SHM_MULTI_PREFIX << multiId <<
SHM_MODULE_PREFIX << moduleId << sEnvPath;
else
ss << SHM_MULTI_PREFIX << multiId << SHM_SLS_PREFIX << slsId << sEnvPath;
ss << SHM_MULTI_PREFIX << multiId <<
SHM_MODULE_PREFIX << moduleId <<
SHM_RECEIVER_PREFIX << (char)(interfaceId + 97) << '_' << receiverId << sEnvPath;
std::string temp = ss.str();
if (temp.length() > NAME_MAX_LENGTH) {
std::string msg = "Shared memory initialization failed. " + temp + " has " + std::to_string(temp.length()) + " characters. \n" + "Maximum is " + std::to_string(NAME_MAX_LENGTH) + ". Change the environment variable " + SHM_ENV_NAME;
std::string msg = "Shared memory initialization failed. " +
temp + " has " + std::to_string(temp.length()) + " characters. \n" +
"Maximum is " + std::to_string(NAME_MAX_LENGTH) +
". Change the environment variable " + SHM_ENV_NAME;
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
}
@ -250,9 +265,11 @@ class SharedMemory {
*/
T *MapSharedMemory() {
void *addr = mmap(nullptr, sizeof(T), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
void *addr = mmap(nullptr, sizeof(T), PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
std::string msg = "Mapping shared memory " + name + " failed: " + strerror(errno);
std::string msg = "Mapping shared memory " + name + " failed: " +
strerror(errno);
LOG(logERROR) << msg;
close(fd);
throw SharedMemoryError(msg);
@ -271,7 +288,8 @@ class SharedMemory {
struct stat sb;
// could not fstat
if (fstat(fd, &sb) < 0) {
std::string msg = "Could not verify existing shared memory " + name + " size match " + "(could not fstat): " + strerror(errno);
std::string msg = "Could not verify existing shared memory " +
name + " size match " + "(could not fstat): " + strerror(errno);
LOG(logERROR) << msg;
close(fd);
throw SharedMemoryError(msg);
@ -280,7 +298,9 @@ class SharedMemory {
//size does not match
auto sz = static_cast<size_t>(sb.st_size);
if (sz != expectedSize) {
std::string msg = "Existing shared memory " + name + " size does not match" + "Expected " + std::to_string(expectedSize) + ", found " + std::to_string(sz);
std::string msg = "Existing shared memory " + name +
" size does not match" + "Expected " +
std::to_string(expectedSize) + ", found " + std::to_string(sz);
LOG(logERROR) << msg;
throw SharedMemoryError(msg);
return 1;

View File

@ -13,6 +13,9 @@ target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdProxy-global.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-Result.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-CmdParser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-Container3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-MaskGenerator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-Receiver.cpp
)
target_include_directories(tests PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../src>")

View File

@ -15,7 +15,9 @@ using sls::Detector;
using test::GET;
using test::PUT;
TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs]") {
/* dacs */
TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs][.new]") {
// dac 0 to dac 17
Detector det;
@ -23,12 +25,12 @@ TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs]") {
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD) {
for (int i = 0; i < 18; ++i) {
SECTION("dac " + std::to_string(i)) { test_dac(static_cast<defs::dacIndex>(i), "dac " + std::to_string(i), 0); }
SECTION("dac " + std::to_string(i)) { test_dac(static_cast<defs::dacIndex>(i), "dac", 0); }
}
// eiger
REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET));
@ -51,30 +53,30 @@ TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs]") {
REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
// gotthard
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
//REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));

View File

@ -13,6 +13,245 @@ using sls::CmdProxy;
using sls::Detector;
using test::GET;
using test::PUT;
/** temperature */
TEST_CASE("temp_fpgaext", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_fpgaext", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_fpgaext", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_fpgaext "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_fpgaext", {}, -1, GET));
}
}
TEST_CASE("temp_10ge", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_10ge", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_10ge", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_10ge "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_10ge", {}, -1, GET));
}
}
TEST_CASE("temp_dcdc", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_dcdc", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_dcdc", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_dcdc "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_dcdc", {}, -1, GET));
}
}
TEST_CASE("temp_sodl", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_sodl", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_sodl", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_sodl "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_sodl", {}, -1, GET));
}
}
TEST_CASE("temp_sodr", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_sodr", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_sodr", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_sodr "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_sodr", {}, -1, GET));
}
}
TEST_CASE("temp_fpgafl", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_fpgafl", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_fpgafl", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_fpgafl "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_fpgafl", {}, -1, GET));
}
}
TEST_CASE("temp_fpgafr", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_fpgafr", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_fpgafr", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_fpgafr "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_fpgafr", {}, -1, GET));
}
}
/* dacs */
TEST_CASE("Setting and reading back EIGER dacs", "[.cmd][.dacs][.new]") {
// vsvp, vtr, vrf, vrs, vsvn, vtgstv, vcmp_ll, vcmp_lr, vcal, vcmp_rl,
// rxb_rb, rxb_lb, vcmp_rr, vcp, vcn, vis, vthreshold
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
SECTION("vsvp") { test_dac(defs::SVP, "vsvp", 5); }
SECTION("vtr") { test_dac(defs::VRF, "vtr", 1200); }
SECTION("vrf") { test_dac(defs::VRF, "vrf", 1500); }
SECTION("vrs") { test_dac(defs::VRF, "vrs", 1510); }
SECTION("vsvn") { test_dac(defs::SVN, "vsvn", 3800); }
SECTION("vtgstv") { test_dac(defs::VTGSTV, "vtgstv", 2550); }
SECTION("vcmp_ll") { test_dac(defs::VCMP_LL, "vcmp_ll", 1400); }
SECTION("vcmp_lr") { test_dac(defs::VCMP_LR, "vcmp_lr", 1400); }
SECTION("vcal") { test_dac(defs::CAL, "vcal", 1400); }
SECTION("vcmp_rl") { test_dac(defs::VCMP_RL, "vcmp_rl", 1400); }
SECTION("rxb_rb") { test_dac(defs::RXB_RB, "rxb_rb", 1400); }
SECTION("rxb_lb") { test_dac(defs::RXB_LB, "rxb_lb", 1400); }
SECTION("vcmp_rr") { test_dac(defs::VCMP_RR, "vcmp_rr", 1400); }
SECTION("vcp") { test_dac(defs::VCP, "vcp", 1400); }
SECTION("vcn") { test_dac(defs::VCN, "vcn", 1400); }
SECTION("vis") { test_dac(defs::VIS, "vis", 1400); }
SECTION("iodelay") { test_dac(defs::IO_DELAY, "iodelay", 1400); }
SECTION("vthreshold") {
// Read out individual vcmp to be able to reset after
// the test is done
auto vcmp_ll = det.getDAC(defs::VCMP_LL, false);
auto vcmp_lr = det.getDAC(defs::VCMP_LR, false);
auto vcmp_rl = det.getDAC(defs::VCMP_RL, false);
auto vcmp_rr = det.getDAC(defs::VCMP_RR, false);
auto vcp = det.getDAC(defs::VCP, false);
{
std::ostringstream oss;
proxy.Call("vthreshold", {"1234"}, -1, PUT, oss);
REQUIRE(oss.str() == "vthreshold 1234\n");
}
{
std::ostringstream oss;
proxy.Call("vthreshold", {}, -1, GET, oss);
REQUIRE(oss.str() == "vthreshold 1234\n");
}
// Reset dacs after test
for (int i = 0; i != det.size(); ++i) {
det.setDAC(defs::VCMP_LL, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_LR, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_RL, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_RR, vcmp_ll[i], false, {i});
det.setDAC(defs::VCP, vcp[i], false, {i});
}
}
// gotthard
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET));
// gotthard2
REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET));
// jungfrau
REQUIRE_THROWS(proxy.Call("vb_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdd_prot", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_com", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
}
}
TEST_CASE("Eiger transmission delay", "[.cmd]") {
Detector det;
@ -280,110 +519,7 @@ TEST_CASE("quad", "[.cmd]") {
}
}
TEST_CASE("Setting and reading back EIGER dacs", "[.cmd][.dacs]") {
// vsvp, vtr, vrf, vrs, vsvn, vtgstv, vcmp_ll, vcmp_lr, vcal, vcmp_rl,
// rxb_rb, rxb_lb, vcmp_rr, vcp, vcn, vis, vthreshold
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
SECTION("vsvp") { test_dac(defs::SVP, "vsvp", 5); }
SECTION("vtr") { test_dac(defs::VRF, "vtr", 1200); }
SECTION("vrf") { test_dac(defs::VRF, "vrf", 1500); }
SECTION("vrs") { test_dac(defs::VRF, "vrs", 1510); }
SECTION("vsvn") { test_dac(defs::SVN, "vsvn", 3800); }
SECTION("vtgstv") { test_dac(defs::VTGSTV, "vtgstv", 2550); }
SECTION("vcmp_ll") { test_dac(defs::VCMP_LL, "vcmp_ll", 1400); }
SECTION("vcmp_lr") { test_dac(defs::VCMP_LR, "vcmp_lr", 1400); }
SECTION("vcal") { test_dac(defs::CAL, "vcal", 1400); }
SECTION("vcmp_rl") { test_dac(defs::VCMP_RL, "vcmp_rl", 1400); }
SECTION("rxb_rb") { test_dac(defs::RXB_RB, "rxb_rb", 1400); }
SECTION("rxb_lb") { test_dac(defs::RXB_LB, "rxb_lb", 1400); }
SECTION("vcmp_rr") { test_dac(defs::VCMP_RR, "vcmp_rr", 1400); }
SECTION("vcp") { test_dac(defs::VCP, "vcp", 1400); }
SECTION("vcn") { test_dac(defs::VCN, "vcn", 1400); }
SECTION("vis") { test_dac(defs::VIS, "vis", 1400); }
SECTION("iodelay") { test_dac(defs::IO_DELAY, "iodelay", 1400); }
SECTION("vthreshold") {
// Read out individual vcmp to be able to reset after
// the test is done
auto vcmp_ll = det.getDAC(defs::VCMP_LL, false);
auto vcmp_lr = det.getDAC(defs::VCMP_LR, false);
auto vcmp_rl = det.getDAC(defs::VCMP_RL, false);
auto vcmp_rr = det.getDAC(defs::VCMP_RR, false);
auto vcp = det.getDAC(defs::VCP, false);
{
std::ostringstream oss;
proxy.Call("vthreshold", {"1234"}, -1, PUT, oss);
REQUIRE(oss.str() == "vthreshold 1234\n");
}
{
std::ostringstream oss;
proxy.Call("vthreshold", {}, -1, GET, oss);
REQUIRE(oss.str() == "vthreshold 1234\n");
}
// Reset dacs after test
for (int i = 0; i != det.size(); ++i) {
det.setDAC(defs::VCMP_LL, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_LR, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_RL, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_RR, vcmp_ll[i], false, {i});
det.setDAC(defs::VCP, vcp[i], false, {i});
}
}
// gotthard
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET));
// gotthard2
REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET));
// jungfrau
REQUIRE_THROWS(proxy.Call("vb_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdd_prot", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_com", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
}
}
// TEST_CASE("trigger", "[.cmd]") {
// Detector det;

View File

@ -16,12 +16,46 @@ void test_dac(defs::dacIndex index, const std::string &dacname, int dacvalue) {
std::ostringstream oss_set, oss_get;
auto dacstr = std::to_string(dacvalue);
auto previous = det.getDAC(index, false);
proxy.Call(dacname, {dacstr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == dacname + " " + dacstr + "\n");
proxy.Call(dacname, {}, -1, GET, oss_get);
REQUIRE(oss_get.str() == dacname + " " + dacstr + "\n");
// chip test board
if (dacname == "dac") {
auto dacIndexstr = std::to_string(static_cast<int>(index));
proxy.Call(dacname, {dacIndexstr, dacstr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == dacname + " " + dacIndexstr + " " + dacstr + "\n");
proxy.Call(dacname, {dacIndexstr}, -1, GET, oss_get);
REQUIRE(oss_get.str() == dacname + " " + dacIndexstr + " " + dacstr + "\n");
}
// other detectors
else {
proxy.Call(dacname, {dacstr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == dacname + " " + dacstr + "\n");
proxy.Call(dacname, {}, -1, GET, oss_get);
REQUIRE(oss_get.str() == dacname + " " + dacstr + "\n");
}
// Reset all dacs to previous value
for (int i = 0; i != det.size(); ++i) {
det.setDAC(index, previous[i], false, {i});
}
}
void test_onchip_dac(defs::dacIndex index, const std::string &dacname, int dacvalue) {
Detector det;
CmdProxy proxy(&det);
REQUIRE_THROWS(proxy.Call(dacname, {}, -1, GET));
REQUIRE_THROWS(proxy.Call(dacname, {"10", "0x0"}, -1, PUT)); // chip index (-1 to 9)
REQUIRE_THROWS(proxy.Call(dacname, {"-1", "0x400"}, -1, PUT)); // max val is 0x3ff
int chipIndex = -1; // for now, it is -1 only
auto prev_val = det.getOnChipDAC(index, chipIndex);
auto dacValueStr = sls::ToStringHex(dacvalue);
auto chipIndexStr = std::to_string(chipIndex);
std::ostringstream oss_set, oss_get;
proxy.Call(dacname, {chipIndexStr, dacValueStr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == dacname + " " + chipIndexStr + " " + dacValueStr + "\n");
proxy.Call(dacname, {chipIndexStr}, -1, GET, oss_get);
REQUIRE(oss_get.str() == dacname + " " + chipIndexStr + " " + dacValueStr + "\n");
// Reset all dacs to previous value
for (int i = 0; i != det.size(); ++i) {
det.setOnChipDAC(index, chipIndex, prev_val[i], {i});
}
}

View File

@ -1,4 +1,5 @@
#pragma once
#include "sls_detector_defs.h"
void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue);
void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue);
void test_onchip_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue);

View File

@ -15,7 +15,9 @@ using sls::Detector;
using test::GET;
using test::PUT;
TEST_CASE("Setting and reading back GOTTHARD dacs", "[.cmd][.dacs]") {
/* dacs */
TEST_CASE("Setting and reading back GOTTHARD dacs", "[.cmd][.dacs][.new]") {
// vref_ds, vcascn_pb, vcascp_pb, vout_cm, vcasc_out, vin_cm, vref_comp, ib_test_c
Detector det;

View File

@ -88,17 +88,9 @@ TEST_CASE("bursts", "[.cmd][.new]") {
}
}
/* dacs */
TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs]") {
TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs][.new]") {
// vref_h_adc, vb_comp_fe, vb_comp_adc, vcom_cds,
// vref_restore, vb_opa_1st, vref_comp_fe, vcom_adc1,
// vref_prech, vref_l_adc, vref_cds, vb_cs,
@ -179,45 +171,89 @@ TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs]") {
}
}
TEST_CASE("vchip", "[.cmd][.onchipdacs]") {
/* on chip dacs */
TEST_CASE("vchip_comp_fe", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
std::vector<std::string> on_chip_dac_names = {"vchip_comp_fe", "vchip_opa_1st", "vchip_opa_fd", "vchip_comp_adc", "vchip_ref_comp_fe", "vchip_cs"};
std::vector<defs::dacIndex> on_chip_dac_indices = {defs::VB_COMP_FE, defs::VB_OPA_1ST, defs::VB_OPA_FD, defs::VB_COMP_ADC, defs::VREF_COMP_FE, defs::VB_CS};
std::vector<int> values = {0x137, 0x000, 0x134, 0x3FF, 0x100, 0x0D0};
for (size_t i = 0; i < on_chip_dac_names.size(); ++i) {
REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {}, -1, GET));
REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {"10", "0x0"}, -1, GET)); // chip index (-1 to 9)
REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {"-1", "0x400"}, -1, GET)); // max val is 0x3ff
auto previous = det.getOnChipDAC(on_chip_dac_indices[i], -1);
auto dacstr = sls::ToStringHex(values[i]);
int chip_index = -1;
auto chip_index_str = std::to_string(chip_index);
std::ostringstream oss_set, oss_get;
proxy.Call(on_chip_dac_names[i], {chip_index_str, dacstr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == on_chip_dac_names[i] + " " + chip_index_str + " " + dacstr + "\n");
proxy.Call(on_chip_dac_names[i], {chip_index_str}, -1, GET, oss_get);
REQUIRE(oss_get.str() == on_chip_dac_names[i] + " " + chip_index_str + " " + dacstr + "\n");
// Reset all dacs to previous value
for (int i = 0; i != det.size(); ++i) {
det.setOnChipDAC(on_chip_dac_indices[i], chip_index, previous[i], {i});
}
}
SECTION("vchip_comp_fe") { test_onchip_dac(defs::VB_COMP_FE, "vchip_comp_fe", 0x137); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vchip_opa_1st", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vchip_opa_fd", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vchip_comp_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vchip_ref_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vchip_cs", {}, -1, GET));
}
}
TEST_CASE("vchip_opa_1st", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_opa_1st") { test_onchip_dac(defs::VB_OPA_1ST, "vchip_opa_1st", 0x000); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_opa_1st", {}, -1, GET));
}
}
TEST_CASE("vchip_opa_fd", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_opa_fd") { test_onchip_dac(defs::VB_OPA_FD, "vchip_opa_fd", 0x134); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_opa_fd", {}, -1, GET));
}
}
TEST_CASE("vchip_comp_adc", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_comp_adc") { test_onchip_dac(defs::VB_COMP_ADC, "vchip_comp_adc", 0x3FF); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_comp_adc", {}, -1, GET));
}
}
TEST_CASE("vchip_ref_comp_fe", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_ref_comp_fe") { test_onchip_dac(defs::VREF_COMP_FE, "vchip_ref_comp_fe", 0x100); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_ref_comp_fe", {}, -1, GET));
}
}
TEST_CASE("vchip_cs", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_cs") { test_onchip_dac(defs::VB_CS, "vchip_cs", 0x0D0); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_cs", {}, -1, GET));
}
}
TEST_CASE("burstmode", "[.cmd]") {
Detector det;

View File

@ -13,38 +13,116 @@ using sls::Detector;
using test::GET;
using test::PUT;
TEST_CASE("powerchip", "[.cmd][!mayfail]") {
// TODO! this test currently fails with the
// virtual detecto server
/* dacs */
TEST_CASE("Setting and reading back Jungfrau dacs", "[.cmd][.dacs][.new]") {
// vb_comp, vdd_prot, vin_com, vref_prech, vb_pixbuf, vb_ds, vref_ds, vref_comp
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU) {
auto pc = det.getPowerChip();
{
std::ostringstream oss;
proxy.Call("powerchip", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "powerchip 1\n");
}
{
std::ostringstream oss;
proxy.Call("powerchip", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "powerchip 0\n");
}
{
std::ostringstream oss;
proxy.Call("powerchip", {}, -1, GET, oss);
REQUIRE(oss.str() == "powerchip 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setPowerChip(pc[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("powerchip", {}, -1, GET));
SECTION("vb_comp") { test_dac(defs::VB_COMP, "vb_comp", 1220); }
SECTION("vdd_prot") { test_dac(defs::VDD_PROT, "vdd_prot", 3000); }
SECTION("vin_com") { test_dac(defs::VIN_COM, "vin_com", 1053); }
SECTION("vref_prech") { test_dac(defs::VREF_PRECH, "vref_prech", 1450); }
SECTION("vb_pixbuf") { test_dac(defs::VB_PIXBUF, "vb_pixbuf", 750); }
SECTION("vb_ds") { test_dac(defs::VB_DS, "vb_ds", 1000); }
SECTION("vref_ds") { test_dac(defs::VREF_DS, "vref_ds", 480); }
SECTION("vref_comp") { test_dac(defs::VREF_COMP, "vref_comp", 420); }
// eiger
REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtgstv", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_ll", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_lr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcal", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_rl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_rr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("rxb_rb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("rxb_lb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcn", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vis", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("iodelay", {}, -1, GET));
// gotthard
// REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET));
// gotthard2
REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET));
}
}
TEST_CASE("nframes", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
@ -158,78 +236,3 @@ TEST_CASE("resetfpga", "[.cmd]") {
}
TEST_CASE("Setting and reading back Jungfrau dacs", "[.cmd]") {
// vb_comp, vdd_prot, vin_com, vref_prech, vb_pixbuf, vb_ds, vref_ds, vref_comp
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU) {
SECTION("vb_comp") { test_dac(defs::VB_COMP, "vb_comp", 1220); }
SECTION("vdd_prot") { test_dac(defs::VDD_PROT, "vdd_prot", 3000); }
SECTION("vin_com") { test_dac(defs::VIN_COM, "vin_com", 1053); }
SECTION("vref_prech") { test_dac(defs::VREF_PRECH, "vref_prech", 1450); }
SECTION("vb_pixbuf") { test_dac(defs::VB_PIXBUF, "vb_pixbuf", 750); }
SECTION("vb_ds") { test_dac(defs::VB_DS, "vb_ds", 1000); }
SECTION("vref_ds") { test_dac(defs::VREF_DS, "vref_ds", 480); }
SECTION("vref_comp") { test_dac(defs::VREF_COMP, "vref_comp", 420); }
// eiger
REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtgstv", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_ll", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_lr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcal", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_rl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_rr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("rxb_rb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("rxb_lb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcn", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vis", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("iodelay", {}, -1, GET));
// gotthard
// REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET));
// gotthard2
REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET));
}
}

View File

@ -15,7 +15,9 @@ using sls::Detector;
using test::GET;
using test::PUT;
TEST_CASE("Setting and reading back MOENCH dacs", "[.cmd][.dacs]") {
/* dacs */
TEST_CASE("Setting and reading back MOENCH dacs", "[.cmd][.dacs][.new]") {
// vbp_colbuf, vipre, vin_cm", vb_sda, vcasc_sfp, vout_cm, vipre_cds, ibias_sfp
Detector det;

View File

@ -15,7 +15,9 @@ using sls::Detector;
using test::GET;
using test::PUT;
TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs]") {
/* dacs */
TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs][.new]") {
// vcassh, vth2, vshaper, vshaperneg, vipre_out, vth3, vth1,
// vicin, vcas, vpreamp, vpl, vipre, viinsh, vph, vtrim, vdcsh,
@ -87,88 +89,21 @@ TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs]") {
}
}
TEST_CASE("clkfreq", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) {
REQUIRE_THROWS(proxy.Call("clkfreq", {"0", "2"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("clkfreq", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkfreq", {"7"}, -1, GET));
auto value = det.getClockFrequency(0).squash(-1);
std::ostringstream oss_set, oss_get;
proxy.Call("clkfreq", {"0"}, -1, GET, oss_get);
REQUIRE(oss_get.str() == "clkfreq " + std::to_string(value) + "\n");
} else {
REQUIRE_THROWS(proxy.Call("clkfreq", {"0"}, -1, GET));
}
}
TEST_CASE("clkphase", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) {
REQUIRE_THROWS(proxy.Call("clkphase", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkphase", {"7"}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkphase", {"4"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("clkphase", {"7", "4"}, -1, PUT));
auto previous = det.getClockFrequency(0).squash(-1);
auto previous_string = std::to_string(previous);
std::ostringstream oss_set, oss_get, oss_get2;
proxy.Call("clkfreq", {"0", previous_string}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == "clkfreq" + previous_string + "\n");
proxy.Call("clkfreq", {"0"}, -1, GET, oss_get);
REQUIRE(oss_get.str() == "clkfreq " + previous_string + "\n");
REQUIRE_NOTHROW(proxy.Call("clkphase", {"0", "deg"}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("clkphase", {"0"}, -1, GET));
}
}
TEST_CASE("clkdiv", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) {
REQUIRE_THROWS(proxy.Call("clkdiv", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkdiv", {"7"}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkdiv", {"7", "4"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("clkdiv", {"7", "4"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("clkdiv", {"0", "1"}, -1, PUT));
auto previous = det.getClockDivider(0).squash(-1);
auto previous_string = std::to_string(previous);
std::ostringstream oss_set, oss_get;
proxy.Call("clkdiv", {"0", previous_string}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == "clkdiv" + previous_string + "\n");
proxy.Call("clkdiv", {"0"}, -1, GET, oss_get);
REQUIRE(oss_get.str() == "clkdiv " + previous_string + "\n");
} else {
REQUIRE_THROWS(proxy.Call("clkdiv", {"0"}, -1, GET));
}
}
TEST_CASE("maxclkphaseshift", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) {
REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"0", "2"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"7"}, -1, GET));
auto value = det.getMaxClockPhaseShift(0).squash(-1);
std::ostringstream oss_set, oss_get;
proxy.Call("maxclkphaseshift", {"0"}, -1, GET, oss_get);
REQUIRE(oss_get.str() ==
"maxclkphaseshift " + std::to_string(value) + "\n");
} else {
REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"0"}, -1, GET));
}
}
TEST_CASE("counters", "[.cmd]") {
Detector det;

View File

@ -144,10 +144,10 @@ TEST_CASE("rx_printconfig", "[.cmd][.rx][.new]") {
/* Receiver Config */
TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") {
Detector det;
CmdProxy proxy(&det);
auto prev_val = det.getRxHostname();
// TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") {
// Detector det;
// CmdProxy proxy(&det);
// auto prev_val = det.getRxHostname();
// Cannot set rx_hostname (will reset parameters in rxr and no shm variables to update)
// {
@ -168,37 +168,37 @@ TEST_CASE("rx_hostname", "[.cmd][.rx][.new]") {
// for (int i = 0; i != det.size(); ++i) {
// det.setRxHostname(prev_val[i], {i});
// }
{
std::ostringstream oss;
proxy.Call("rx_hostname", {}, 0, GET, oss);
REQUIRE(oss.str() == "rx_hostname " + prev_val[0] + "\n");
}
}
// {
// std::ostringstream oss;
// proxy.Call("rx_hostname", {}, 0, GET, oss);
// REQUIRE(oss.str() == "rx_hostname " + prev_val[0] + "\n");
// }
// }
TEST_CASE("rx_tcpport", "[.cmd][.rx][.new]") {
Detector det;
CmdProxy proxy(&det);
auto prev_val = det.getRxPort();
// TEST_CASE("rx_tcpport", "[.cmd][.rx][.new]") {
// Detector det;
// CmdProxy proxy(&det);
// auto prev_val = det.getRxPort();
int port = 3500;
proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
for (int i = 0; i != det.size(); ++i) {
std::ostringstream oss;
proxy.Call("rx_tcpport", {}, i, GET, oss);
REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
}
REQUIRE_THROWS(proxy.Call("rx_tcpport", {"15"}, -1, PUT));
port = 5754;
proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
for (int i = 0; i != det.size(); ++i) {
std::ostringstream oss;
proxy.Call("rx_tcpport", {}, i, GET, oss);
REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
}
for (int i = 0; i != det.size(); ++i) {
det.setRxPort(prev_val[i], i);
}
}
// int port = 3500;
// proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
// for (int i = 0; i != det.size(); ++i) {
// std::ostringstream oss;
// proxy.Call("rx_tcpport", {}, i, GET, oss);
// REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
// }
// REQUIRE_THROWS(proxy.Call("rx_tcpport", {"15"}, -1, PUT));
// port = 5754;
// proxy.Call("rx_tcpport", {std::to_string(port)}, -1, PUT);
// for (int i = 0; i != det.size(); ++i) {
// std::ostringstream oss;
// proxy.Call("rx_tcpport", {}, i, GET, oss);
// REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
// }
// for (int i = 0; i != det.size(); ++i) {
// det.setRxPort(prev_val[i], i);
// }
// }
TEST_CASE("rx_fifodepth", "[.cmd][.rx][.new]") {
Detector det;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,330 @@
#include "catch.hpp"
#include "Container3.h"
using sls::Container3;
TEST_CASE("Default construction gives container of size 0") {
Container3<int> c;
CHECK(c.size() == 0);
CHECK(c.size(0) == 0);
CHECK(c.size(1) == 0);
CHECK(c.size(2) == 0);
}
TEST_CASE("Construct container with size") {
Container3<int> c(3, 4, 5);
CHECK(c.size() == 3 * 4 * 5);
CHECK(c.size(0) == 3);
CHECK(c.size(1) == 4);
CHECK(c.size(2) == 5);
}
TEST_CASE("Constructor with default value") {
constexpr int val = 7;
Container3<int> c({1, 1, 5}, val);
for (size_t i = 0; i < c.size(); ++i) {
CHECK(c[i] == val);
}
}
TEST_CASE("Container3 can be iterated with range for") {
constexpr int val = 7;
Container3<int> c({1, 1, 5}, val);
for (const auto& item : c) {
CHECK(item == val);
}
}
TEST_CASE(
"() gives access to an element for both const and non const objects") {
Container3<int> c{1, 1, 1};
CHECK(c(0, 0, 0) == 0);
const Container3<int> c2{1, 1, 1};
CHECK(c2(0, 0, 0) == 0);
}
TEST_CASE("() can be used to modify object") {
Container3<int> c{1, 1, 1};
c(0, 0, 0) = 7;
CHECK(c(0, 0, 0) == 7);
}
TEST_CASE("at() can be used to modify object") {
Container3<int> c{1, 1, 1};
c.at(0, 0, 0) = 7;
CHECK(c(0, 0, 0) == 7);
}
TEST_CASE("at throws outsize range for both const and non const objects") {
Container3<int> c{1, 1, 1};
const Container3<double> c2{1, 1, 1};
CHECK_THROWS(c.at(5, 5, 5));
CHECK_THROWS(c2.at(5, 5, 5));
}
TEST_CASE("Set values") {
Container3<int> c(2, 3, 4);
size_t count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
}
TEST_CASE("Check if index is valid") {
Container3<int> c(2, 3, 4);
CHECK(c.is_valid_index(1,1,1));
CHECK(c.is_valid_index(1,2,3));
CHECK(c.is_valid_index(1,2,3));
CHECK_FALSE(c.is_valid_index(1,7,1));
CHECK_FALSE(c.is_valid_index(1,1,4));
CHECK_FALSE(c.is_valid_index(3,1,1));
}
TEST_CASE("Copy data from one container to another") {
Container3<int> c(2, 1, 2);
for (size_t i = 0; i < c.size(); ++i) {
c[i] = i;
}
Container3<int> c2(3, 3, 3);
c2.copy_data(c);
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
CHECK(c2(i, j, k) == c(i, j, k));
}
}
}
}
TEST_CASE("Copy assignment copies values") {
Container3<int> c(2, 3, 4);
size_t count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
Container3<int> c2;
c2 = c;
count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c2(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
}
TEST_CASE("Copy constructor copies values") {
Container3<int> c(18, 23, 4);
size_t count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
Container3<int> c2 = c;
count = 0;
for (size_t i = 0; i < c.size(0); ++i) {
for (size_t j = 0; j < c.size(1); ++j) {
for (size_t k = 0; k < c.size(2); ++k) {
c2(i, j, k) = count;
CHECK(c(i, j, k) == count);
CHECK(c[count] == count);
++count;
}
}
}
}
TEST_CASE("Copy assignment create disjoint objects") {
Container3<int> c(2, 3, 4);
Container3<int> c2;
c2 = c;
c2(1, 1, 1) = 72;
CHECK(c2(1, 1, 1) == 72);
CHECK(c(1, 1, 1) != 72);
}
TEST_CASE("Move constructor") {
Container3<int> c(2, 3, 4);
// explicit move only for testing
Container3<int> c2(std::move(c));
// Moved from object is in an ok state
CHECK(c.data() == nullptr);
for (size_t i = 0; i < 3; ++i) {
CHECK(c.size(i) == 0);
}
// new object has the correct size and owns some data
CHECK(c2.data() != nullptr);
CHECK(c2.size(0) == 2);
CHECK(c2.size(1) == 3);
CHECK(c2.size(2) == 4);
}
TEST_CASE("Move assignment ") {
Container3<int> c(2, 3, 4);
Container3<int> c2(5, 5, 5);
c2 = std::move(c);
// Moved from object is in an ok state
CHECK(c.data() == nullptr);
for (size_t i = 0; i < 3; ++i) {
CHECK(c.size(i) == 0);
}
// new object has the correct size and owns some data
CHECK(c2.data() != nullptr);
CHECK(c2.size(0) == 2);
CHECK(c2.size(1) == 3);
CHECK(c2.size(2) == 4);
}
TEST_CASE("Resize to a larger size") {
Container3<int> c(2, 3, 4);
// Assign values
auto shape = c.shape();
CHECK(shape == std::array<size_t, 3>{2,3,4});
size_t count = 0;
for (size_t i = 0; i < shape[0]; ++i) {
for (size_t j = 0; j < shape[1]; ++j) {
for (size_t k = 0; k < shape[2]; ++k) {
c(i, j, k) = count;
CHECK(c(i, j, k) == count);
++count;
}
}
}
c.resize(3, 4, 5);
CHECK(c.shape() == std::array<size_t, 3>{3,4,5});
// Values should remain the same in the old region
count = 0;
for (size_t i = 0; i < shape[0]; ++i) {
for (size_t j = 0; j < shape[1]; ++j) {
for (size_t k = 0; k < shape[2]; ++k) {
CHECK(c(i, j, k) == count);
++count;
}
}
}
// Default constructed values outsize
CHECK(c(2, 2, 2) == 0);
CHECK(c(2, 3, 2) == 0);
}
TEST_CASE("Inserting values outside range with a empty receiver") {
Container3<int> c;
c.at_can_grow(0, 0, 0) = 5;
CHECK(c(0, 0, 0) == 5);
CHECK(c.size() == 1);
CHECK(c.size(0) == 1);
CHECK(c.size(1) == 1);
CHECK(c.size(2) == 1);
c.at_can_grow(0, 0, 1) = 6;
CHECK(c.size() == 2);
CHECK(c.size(0) == 1);
CHECK(c.size(1) == 1);
CHECK(c.size(2) == 2);
}
TEST_CASE("Inserting a value outside of the current size") {
Container3<int> c{1, 2, 3};
for (size_t i = 0; i < c.size(); ++i) {
c[i] = i;
}
Container3<int> copy;
copy = c;
c.at_can_grow(2, 2, 2) = 7;
CHECK(c.size(0) == 3);
CHECK(c.size(1) == 3);
CHECK(c.size(2) == 3);
for (size_t i = 0; i < copy.size(0); ++i) {
for (size_t j = 0; j < copy.size(0); ++j) {
for (size_t k = 0; k < copy.size(0); ++k) {
CHECK(copy(i, j, k) == c(i, j, k));
}
}
}
}
TEST_CASE("Clear sets size to zero and clears memory"){
Container3<int> c(5,5,5);
CHECK(c.shape() == std::array<size_t, 3>{5,5,5});
c.clear();
CHECK(c.shape() == std::array<size_t, 3>{0,0,0});
CHECK(c.size() == 0);
}
TEST_CASE("Put unique pointer in Container3"){
Container3<std::unique_ptr<int>> c(3,1,1);
c(0,0,0) = std::unique_ptr<int>(new int);
CHECK(c(0,0,0) != nullptr);
CHECK(c(1,0,0) == nullptr);
CHECK(c(2,0,0) == nullptr);
*c(0,0,0) = 5;
CHECK(*c(0,0,0) == 5);
}
TEST_CASE("Resize with unique ptr"){
Container3<std::unique_ptr<int>> c(2,1,1);
c(1,0,0) = std::unique_ptr<int>(new int);
*c(1,0,0) = 7;
c.resize(3,1,1);
CHECK(c.size() == 3);
CHECK(*c(1,0,0) == 7);
}

View File

@ -0,0 +1,99 @@
#include "catch.hpp"
#include "MaskGenerator.h"
using sls::MaskGenerator;
using sls::Container3;
TEST_CASE("Default construction gives an mask of size 0") {
auto m = MaskGenerator().mask();
CHECK(m.shape() == std::array<size_t, 3>{0, 0, 0});
CHECK(m.size() == 0);
}
TEST_CASE("Default behaviour with shape is all true and same shape") {
Container3<int> c{1, 2, 3};
auto m = MaskGenerator().mask(c.shape());
CHECK(m.shape() == std::array<size_t, 3>{1, 2, 3});
for (auto &i : m)
CHECK(i == true);
}
TEST_CASE("With std::vector we give back the first index and 0, 0") {
Container3<int> rec{14, 1, 3};
auto m = MaskGenerator(std::vector<int>{0, 3, 5}).mask(rec.shape());
CHECK(m.shape() == std::array<size_t, 3>{14, 1, 3});
CHECK(m(0, 0, 0) == true);
CHECK(m(3, 0, 0) == true);
CHECK(m(5, 0, 0) == true);
std::vector<int> positions(rec.size(0));
std::iota(begin(positions), end(positions), 0);
positions.erase(std::remove(positions.begin(), positions.end(), 0),
positions.end());
positions.erase(std::remove(positions.begin(), positions.end(), 3),
positions.end());
positions.erase(std::remove(positions.begin(), positions.end(), 5),
positions.end());
for (auto i : positions) {
for (size_t j = 0; j < rec.size(1); ++j) {
for (size_t k = 0; k < rec.size(2); ++k) {
REQUIRE(m(i, j, k) == false);
}
}
}
}
TEST_CASE("With single number we get that detector x,0,0") {
Container3<int> rec{2, 2, 1};
auto m = MaskGenerator(1).mask(rec);
CHECK(m(1, 0, 0) == true);
CHECK(m(1, 1, 0) == false);
CHECK(m(0, 1, 0) == false);
CHECK(m(0, 0, 0) == false);
}
TEST_CASE("With two numbers we get x,y,0") {
Container3<int> rec{2, 2, 1};
auto m = MaskGenerator(1, 1).mask(rec);
CHECK(m(1, 1, 0) == true);
CHECK(m(1, 0, 0) == false);
CHECK(m(0, 1, 0) == false);
CHECK(m(0, 0, 0) == false);
}
TEST_CASE("With three numbers we get x,y,z") {
Container3<int> rec{9, 7, 5};
auto m = MaskGenerator(3, 4, 1).mask(rec);
REQUIRE(m.shape() == rec.shape());
REQUIRE(m(3, 4, 1) == true);
for (size_t i = 0; i < rec.size(0); ++i) {
for (size_t j = 0; j < rec.size(1); ++j) {
for (size_t k = 0; k < rec.size(2); ++k) {
if (!(i == 3 && j == 4 && k == 1)) {
REQUIRE(m(i, j, k) == false);
}
}
}
}
}
TEST_CASE("Passing in -1 as the only element in the vector gives all rows"){
Container3<int> r{3,3,3};
std::vector<int> vec{-1};
auto m = MaskGenerator(vec, 0).mask(r);
REQUIRE(m.shape() == std::array<size_t, 3>{3,3,3});
CHECK(m(0,0,0) == true);
CHECK(m(1,0,0) == true);
CHECK(m(2,0,0) == true);
CHECK(m(0,1,0) == false);
CHECK(m(0,2,0) == false);
CHECK(m(0,0,1) == false);
}

View File

@ -0,0 +1,10 @@
#include "catch.hpp"
#include "Container3.h"
#include "Receiver.h"
using sls::Receiver;
// TEST_CASE("Receiver can be default constructed"){
// }

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,18 @@ class ServerInterface;
#include <future>
class ClientInterface : private virtual slsDetectorDefs {
private:
enum numberMode { DEC, HEX };
detectorType myDetectorType;
int portNumber{0};
sls::ServerSocket server;
std::unique_ptr<Implementation> receiver;
std::unique_ptr<std::thread> tcpThread;
int ret{OK};
int fnum{-1};
int lockedByClient{0};
std::atomic<bool> killTcpThread{false};
public:
virtual ~ClientInterface();
@ -49,17 +59,22 @@ class ClientInterface : private virtual slsDetectorDefs {
void verifyLock();
void verifyIdle(sls::ServerInterface &socket);
int exec_command(sls::ServerInterface &socket);
int exit_server(sls::ServerInterface &socket);
int lock_receiver(sls::ServerInterface &socket);
int set_lock_server(sls::ServerInterface &socket);
int get_lock_server(sls::ServerInterface &socket);
int get_last_client_ip(sls::ServerInterface &socket);
int set_port(sls::ServerInterface &socket);
int get_version(sls::ServerInterface &socket);
int set_detector_type(sls::ServerInterface &socket);
int set_detector_hostname(sls::ServerInterface &socket);
int setup_receiver(sls::ServerInterface &socket);
void setDetectorType(detectorType arg);
int set_roi(sls::ServerInterface &socket);
int set_num_frames(sls::ServerInterface &socket);
int set_num_triggers(sls::ServerInterface &socket);
int set_num_bursts(sls::ServerInterface &socket);
int set_num_add_storage_cells(sls::ServerInterface &socket);
int set_timing_mode(sls::ServerInterface &socket);
int set_burst_mode(sls::ServerInterface &socket);
int set_num_analog_samples(sls::ServerInterface &socket);
int set_num_digital_samples(sls::ServerInterface &socket);
int set_exptime(sls::ServerInterface &socket);
@ -90,15 +105,16 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_overwrite(sls::ServerInterface &socket);
int enable_tengiga(sls::ServerInterface &socket);
int set_fifo_depth(sls::ServerInterface &socket);
int get_fifo_depth(sls::ServerInterface &socket);
int set_activate(sls::ServerInterface &socket);
int set_streaming(sls::ServerInterface &socket);
int get_streaming(sls::ServerInterface &socket);
int set_streaming_timer(sls::ServerInterface &socket);
int get_streaming_timer(sls::ServerInterface &socket);
int set_flipped_data(sls::ServerInterface &socket);
int get_flipped_data(sls::ServerInterface &socket);
int set_file_format(sls::ServerInterface &socket);
int get_file_format(sls::ServerInterface &socket);
int set_detector_posid(sls::ServerInterface &socket);
int set_multi_detector_size(sls::ServerInterface &socket);
int set_streaming_port(sls::ServerInterface &socket);
int get_streaming_port(sls::ServerInterface &socket);
int set_streaming_source_ip(sls::ServerInterface &socket);
@ -109,6 +125,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_additional_json_header(sls::ServerInterface &socket);
int get_additional_json_header(sls::ServerInterface &socket);
int set_udp_socket_buffer_size(sls::ServerInterface &socket);
int get_udp_socket_buffer_size(sls::ServerInterface &socket);
int get_real_udp_socket_buffer_size(sls::ServerInterface &socket);
int set_frames_per_file(sls::ServerInterface &socket);
int get_frames_per_file(sls::ServerInterface &socket);
@ -127,17 +144,17 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_dbit_offset(sls::ServerInterface &socket);
int set_quad_type(sls::ServerInterface &socket);
int set_read_n_lines(sls::ServerInterface &socket);
sls::MacAddr setUdpIp(sls::IpAddr arg);
int set_udp_ip(sls::ServerInterface &socket);
int set_udp_ip2(sls::ServerInterface &socket);
int set_udp_port(sls::ServerInterface &socket);
int set_udp_port2(sls::ServerInterface &socket);
int set_num_interfaces(sls::ServerInterface &socket);
int set_adc_mask_10g(sls::ServerInterface &socket);
int set_num_counters(sls::ServerInterface &socket);
int increment_file_index(sls::ServerInterface &socket);
int set_additional_json_parameter(sls::ServerInterface &socket);
int get_additional_json_parameter(sls::ServerInterface &socket);
int get_progress(sls::ServerInterface &socket);
Implementation *impl() {
if (receiver != nullptr) {
return receiver.get();
@ -147,19 +164,9 @@ class ClientInterface : private virtual slsDetectorDefs {
}
}
detectorType myDetectorType;
std::unique_ptr<Implementation> receiver{nullptr};
int (ClientInterface::*flist[NUM_REC_FUNCTIONS])(
sls::ServerInterface &socket);
int ret{OK};
int fnum{-1};
int lockedByClient{0};
int portNumber{0};
std::atomic<bool> killTcpThread{false};
std::unique_ptr<std::thread> tcpThread;
//***callback parameters***
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t, uint32_t,
@ -172,6 +179,6 @@ class ClientInterface : private virtual slsDetectorDefs {
void *) = nullptr;
void *pRawDataReady{nullptr};
protected:
std::unique_ptr<sls::ServerSocket> server{nullptr};
};

View File

@ -29,13 +29,9 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
uint32_t* freq, uint32_t* timer,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
std::vector <int> * cdl, int* cdo, int* cad) :
ThreadObject(ind, TypeName),
runningFlag(false),
generalData(nullptr),
fifo(f),
myDetectorType(dtype),
file(nullptr),
dataStreamEnable(dsEnable),
fileFormatType(ftype),
fileWriteEnable(fwenable),
@ -43,7 +39,6 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
dynamicRange(dr),
streamingFrequency(freq),
streamingTimerInMs(timer),
currentFreqCount(0),
activated(act),
deactivatedPaddingEnable(depaden),
silentMode(sm),
@ -51,14 +46,7 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
framePadding(fp),
ctbDbitList(cdl),
ctbDbitOffset(cdo),
ctbAnalogDataBytes(cad),
startedFlag(false),
firstIndex(0),
numFramesCaught(0),
currentFrameIndex(0),
rawDataReadyCallBack(nullptr),
rawDataModifyReadyCallBack(nullptr),
pRawDataReady(nullptr)
ctbAnalogDataBytes(cad)
{
LOG(logDEBUG) << "DataProcessor " << ind << " created";
memset((void*)&timerBegin, 0, sizeof(timespec));
@ -71,10 +59,6 @@ DataProcessor::~DataProcessor() {
/** getters */
bool DataProcessor::IsRunning() {
return runningFlag;
}
bool DataProcessor::GetStartedFlag(){
return startedFlag;
}
@ -91,24 +75,12 @@ uint64_t DataProcessor::GetProcessedIndex() {
return currentFrameIndex - firstIndex;
}
/** setters */
void DataProcessor::StartRunning() {
runningFlag = true;
}
void DataProcessor::StopRunning() {
runningFlag = false;
}
void DataProcessor::SetFifo(Fifo* f) {
fifo = f;
}
void DataProcessor::ResetParametersforNewAcquisition(){
runningFlag = false;
StopRunning();
startedFlag = false;
numFramesCaught = 0;
firstIndex = 0;

View File

@ -59,11 +59,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
//*** getters ***
/**
* Returns if the thread is currently running
* @returns true if thread is running, else false
*/
bool IsRunning() override;
/**
* Get acquisition started flag
@ -89,17 +84,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
*/
uint64_t GetProcessedIndex();
//*** setters ***
/**
* Set bit in RunningMask to allow thread to run
*/
void StartRunning();
/**
* Reset bit in RunningMask to prevent thread from running
*/
void StopRunning();
/**
* Set Fifo pointer to the one given
* @param f address of Fifo pointer
@ -254,11 +238,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
/** type of thread */
static const std::string TypeName;
/** Object running status */
std::atomic<bool> runningFlag;
/** GeneralData (Detector Data) object */
const GeneralData* generalData;
const GeneralData* generalData{nullptr};
/** Fifo structure */
Fifo* fifo;
@ -269,7 +250,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
detectorType myDetectorType;
/** File writer implemented as binary or hdf5 File */
File* file;
File* file{nullptr};
/** Data Stream Enable */
bool* dataStreamEnable;
@ -293,7 +274,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
uint32_t* streamingTimerInMs;
/** Current frequency count */
uint32_t currentFreqCount;
uint32_t currentFreqCount{0};
/** timer beginning stamp for random streaming */
struct timespec timerBegin;
@ -324,21 +305,18 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
//acquisition start
/** Aquisition Started flag */
bool startedFlag;
std::atomic<bool> startedFlag{false};
/** Frame Number of First Frame */
uint64_t firstIndex;
std::atomic<uint64_t> firstIndex{0};
//for statistics
/** Number of complete frames caught */
uint64_t numFramesCaught;
uint64_t numFramesCaught{0};
/** Frame Number of latest processed frame number */
uint64_t currentFrameIndex;
std::atomic<uint64_t> currentFrameIndex{0};
//call back
/**
@ -349,7 +327,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* dataSize in bytes is the size of the data in bytes.
*/
void (*rawDataReadyCallBack)(char*,
char*, uint32_t, void*);
char*, uint32_t, void*) = nullptr;
/**
* Call back for raw data (modified)
@ -359,9 +337,9 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value).
*/
void (*rawDataModifyReadyCallBack)(char*,
char*, uint32_t &, void*);
char*, uint32_t &, void*) = nullptr;
void *pRawDataReady;
void *pRawDataReady{nullptr};

View File

@ -17,24 +17,18 @@ const std::string DataStreamer::TypeName = "DataStreamer";
DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
uint64_t* fi, int fd, int* nd, bool* qe) :
uint64_t* fi, int fd, int* nr, bool* qe, uint64_t* tot) :
ThreadObject(ind, TypeName),
runningFlag(0),
generalData(nullptr),
fifo(f),
zmqSocket(nullptr),
dynamicRange(dr),
roi(r),
adcConfigured(-1),
fileIndex(fi),
flippedDataX(fd),
startedFlag(false),
firstIndex(0),
completeBuffer(nullptr),
quadEnable(qe)
quadEnable(qe),
totalNumFrames(tot)
{
numDet[0] = nd[0];
numDet[1] = nd[1];
numRx[0] = nr[0];
numRx[1] = nr[1];
LOG(logDEBUG) << "DataStreamer " << ind << " created";
}
@ -45,29 +39,12 @@ DataStreamer::~DataStreamer() {
delete [] completeBuffer;
}
/** getters */
bool DataStreamer::IsRunning() {
return runningFlag;
}
/** setters */
void DataStreamer::StartRunning() {
runningFlag = true;
}
void DataStreamer::StopRunning() {
runningFlag = false;
}
void DataStreamer::SetFifo(Fifo* f) {
fifo = f;
}
void DataStreamer::ResetParametersforNewAcquisition(const std::string& fname){
runningFlag = false;
StopRunning();
startedFlag = false;
firstIndex = 0;
@ -97,9 +74,9 @@ void DataStreamer::SetGeneralData(GeneralData* g) {
generalData->Print();
}
void DataStreamer::SetNumberofDetectors(int* nd) {
numDet[0] = nd[0];
numDet[1] = nd[1];
void DataStreamer::SetReceiverShape(int* nr) {
numRx[0] = nr[0];
numRx[1] = nr[1];
}
void DataStreamer::SetFlippedDataX(int fd) {
@ -234,13 +211,14 @@ int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32
zHeader.dynamicRange = *dynamicRange;
zHeader.fileIndex = *fileIndex;
zHeader.ndetx = numDet[0];
zHeader.ndety = numDet[1];
zHeader.nSocketX = numRx[0];
zHeader.nSocketY = numRx[1];
zHeader.npixelsx = nx;
zHeader.npixelsy = ny;
zHeader.imageSize = size;
zHeader.acqIndex = acquisitionIndex;
zHeader.frameIndex = frameIndex;
zHeader.progress = 100 * ((double)(frameIndex + 1) / (double)(*totalNumFrames));
zHeader.fname = fileNametoStream;
zHeader.frameNumber = header.frameNumber;
zHeader.expLength = header.expLength;

View File

@ -29,11 +29,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param r roi
* @param fi pointer to file index
* @param fd flipped data enable for x dimension
* @param nd pointer to number of detectors in each dimension
* @param nd pointer to number of receivers in each dimension
* @param qe pointer to quad Enable
* @param tot pointer to total number of frames
*/
DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
uint64_t* fi, int fd, int* nd, bool* qe);
uint64_t* fi, int fd, int* nr, bool* qe, uint64_t* tot);
/**
* Destructor
@ -41,25 +42,6 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
*/
~DataStreamer();
//*** getters ***
/**
* Returns if the thread is currently running
* @returns true if thread is running, else false
*/
bool IsRunning();
//*** setters ***
/**
* Set bit in RunningMask to allow thread to run
*/
void StartRunning();
/**
* Reset bit in RunningMask to prevent thread from running
*/
void StopRunning();
/**
* Set Fifo pointer to the one given
* @param f address of Fifo pointer
@ -78,10 +60,10 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
void SetGeneralData(GeneralData* g);
/**
* Set number of detectors
* @param number of detectors in both dimensions
* Set receiver shape
* @param number of receivers in both dimensions
*/
void SetNumberofDetectors(int* nd);
void SetReceiverShape(int* nr);
/**
* Set Flipped data enable across x dimension
@ -157,19 +139,14 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
/** type of thread */
static const std::string TypeName;
/** Object running status */
bool runningFlag;
/** GeneralData (Detector Data) object */
const GeneralData* generalData;
const GeneralData* generalData{nullptr};
/** Fifo structure */
Fifo* fifo;
/** ZMQ Socket - Receiver to Client */
ZmqSocket* zmqSocket;
ZmqSocket* zmqSocket{nullptr};
/** Pointer to dynamic range */
uint32_t* dynamicRange;
@ -178,7 +155,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
ROI* roi;
/** adc Configured */
int adcConfigured;
int adcConfigured{-1};
/** Pointer to file index */
uint64_t* fileIndex;
@ -190,22 +167,25 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
std::map<std::string, std::string> additionJsonHeader;
/** Aquisition Started flag */
bool startedFlag;
bool startedFlag{nullptr};
/** Frame Number of First Frame */
uint64_t firstIndex;
uint64_t firstIndex{0};
/* File name to stream */
std::string fileNametoStream;
/** Complete buffer used for roi, eg. shortGotthard */
char* completeBuffer;
char* completeBuffer{nullptr};
/** Number of Detectors in X and Y dimension */
int numDet[2];
/** Number of Recievers in X and Y dimension */
int numRx[2];
/** Quad Enable */
bool* quadEnable;
/** Total number of frames */
uint64_t* totalNumFrames;
};

View File

@ -64,9 +64,6 @@ public:
/** Default Fifo depth */
uint32_t defaultFifoDepth;
/** Threads per receiver */
uint32_t threadsPerReceiver;
/** Size of a header packet */
uint32_t headerPacketSize;
@ -105,7 +102,6 @@ public:
maxFramesPerFile(0),
fifoBufferHeaderSize(0),
defaultFifoDepth(0),
threadsPerReceiver(1),
headerPacketSize(0),
nPixelsXComplete(0),
nPixelsYComplete(0),
@ -233,7 +229,6 @@ public:
LOG(level) << "Max Frames Per File: " << maxFramesPerFile;
LOG(level) << "Fifo Buffer Header Size: " << fifoBufferHeaderSize;
LOG(level) << "Default Fifo Depth: " << defaultFifoDepth;
LOG(level) << "Threads Per Receiver: " << threadsPerReceiver;
LOG(level) << "Header Packet Size: " << headerPacketSize;
LOG(level) << "Complete Pixels X: " << nPixelsXComplete;
LOG(level) << "Complete Pixels Y: " << nPixelsYComplete;
@ -414,8 +409,7 @@ class EigerData : public GeneralData {
imageSize = dataSize*packetsPerFrame;
maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 100;
threadsPerReceiver = 2;
defaultFifoDepth = 1000;
headerPacketSize = 40;
standardheader = true;
};
@ -428,6 +422,7 @@ class EigerData : public GeneralData {
void SetDynamicRange(int dr, bool tgEnable) {
packetsPerFrame = (tgEnable ? 4 : 16) * dr;
imageSize = dataSize*packetsPerFrame;
defaultFifoDepth = (dr == 32 ? 100 : 1000);
}
/**
@ -478,7 +473,6 @@ class JungfrauData : public GeneralData {
nPixelsY = 256;
packetsPerFrame = 64;
imageSize = dataSize * packetsPerFrame;
threadsPerReceiver = 2;
defaultUdpSocketBufferSize = (500 * 1024 * 1024);
}
@ -487,7 +481,6 @@ class JungfrauData : public GeneralData {
nPixelsY = 512;
packetsPerFrame = 128;
imageSize = dataSize * packetsPerFrame;
threadsPerReceiver = 1;
defaultUdpSocketBufferSize = (1000 * 1024 * 1024);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ class Implementation : private virtual slsDetectorDefs {
void setDetectorType(const detectorType d);
int *getMultiDetectorSize() const;
void setMultiDetectorSize(const int *size);
void setDetectorSize(const int *size);
int getDetectorPositionId() const;
void setDetectorPositionId(const int id);
std::string getDetectorHostname() const;
@ -75,12 +75,13 @@ class Implementation : private virtual slsDetectorDefs {
runStatus getStatus() const;
uint64_t getFramesCaught() const;
uint64_t getAcquisitionIndex() const;
std::vector<uint64_t> getNumMissingPackets() const;
int getProgress() const;
uint64_t getNumMissingPackets() const;
void startReceiver();
void setStoppedFlag(bool stopped);
void stopReceiver();
void startReadout();
void shutDownUDPSockets();
void shutDownUDPSocket();
void closeFiles();
void restreamStop();
@ -90,19 +91,15 @@ class Implementation : private virtual slsDetectorDefs {
* Network Configuration (UDP) *
* *
* ************************************************/
int getInterfaceId() const;
void setInterfaceId(const int value);
int getNumberofUDPInterfaces() const;
/* [Jungfrau] */
void setNumberofUDPInterfaces(const int n);
std::string getEthernetInterface() const;
void setEthernetInterface(const std::string &c);
std::string getEthernetInterface2() const;
/* [Jungfrau] */
void setEthernetInterface2(const std::string &c);
uint32_t getUDPPortNumber() const;
void setUDPPortNumber(const uint32_t i);
uint32_t getUDPPortNumber2() const;
/* [Eiger][Jungfrau] */
void setUDPPortNumber2(const uint32_t i);
int64_t getUDPSocketBufferSize() const;
void setUDPSocketBufferSize(const int64_t s);
int64_t getActualUDPSocketBufferSize() const;
@ -134,8 +131,19 @@ class Implementation : private virtual slsDetectorDefs {
* Detector Parameters *
* *
* ************************************************/
void updateTotalNumberOfFrames();
uint64_t getNumberOfFrames() const;
void setNumberOfFrames(const uint64_t i);
uint64_t getNumberOfTriggers() const;
void setNumberOfTriggers(const uint64_t i);
uint64_t getNumberOfBursts() const;
void setNumberOfBursts(const uint64_t i);
int getNumberOfAdditionalStorageCells() const;
void setNumberOfAdditionalStorageCells(const int i);
timingMode getTimingMode() const;
void setTimingMode(const timingMode i);
burstMode getBurstMode() const;
void setBurstMode(const burstMode i);
uint64_t getAcquisitionTime() const;
void setAcquisitionTime(const uint64_t i);
uint64_t getAcquisitionPeriod() const;
@ -214,7 +222,7 @@ class Implementation : private virtual slsDetectorDefs {
void SetupFifoStructure();
void ResetParametersforNewAcquisition();
void CreateUDPSockets();
void CreateUDPSocket();
void SetupWriter();
void StartRunning();
@ -226,9 +234,9 @@ class Implementation : private virtual slsDetectorDefs {
* ************************************************/
// config parameters
int numThreads;
detectorType myDetectorType;
int numDet[MAX_DIMENSIONS];
int numRx[MAX_DIMENSIONS];
int detID;
std::string detHostname;
bool silentMode;
@ -251,9 +259,10 @@ class Implementation : private virtual slsDetectorDefs {
bool stoppedFlag;
// network configuration (UDP)
int interfaceId;
int numUDPInterfaces;
std::vector <std::string> eth;
std::vector <uint32_t> udpPortNum;
std::string eth;
uint32_t udpPortNum;
int64_t udpSocketBufferSize;
int64_t actualUDPSocketBufferSize;
@ -266,7 +275,13 @@ class Implementation : private virtual slsDetectorDefs {
std::map<std::string, std::string> additionalJsonHeader;
// detector parameters
uint64_t numberOfTotalFrames;
uint64_t numberOfFrames;
uint64_t numberOfTriggers;
uint64_t numberOfBursts;
int numberOfAdditionalStorageCells;
timingMode timingMode;
burstMode burstMode;
uint64_t acquisitionPeriod;
uint64_t acquisitionTime;
uint64_t subExpTime;
@ -300,8 +315,8 @@ class Implementation : private virtual slsDetectorDefs {
// class objects
GeneralData *generalData;
std::vector<std::unique_ptr<Listener>> listener;
std::vector<std::unique_ptr<DataProcessor>> dataProcessor;
std::vector<std::unique_ptr<DataStreamer>> dataStreamer;
std::vector<std::unique_ptr<Fifo>> fifo;
std::unique_ptr<Listener> listener;
std::unique_ptr<DataProcessor> dataProcessor;
std::unique_ptr<DataStreamer> dataStreamer;
std::unique_ptr<Fifo> fifo;
};

View File

@ -12,6 +12,7 @@
#include "container_utils.h" // For sls::make_unique<>
#include "sls_detector_exceptions.h"
#include "UdpRxSocket.h"
#include "network_utils.h"
#include <cerrno>
#include <cstring>
@ -25,12 +26,9 @@ Listener::Listener(int ind, detectorType dtype, Fifo* f, std::atomic<runStatus>*
int64_t* us, int64_t* as, uint32_t* fpf,
frameDiscardPolicy* fdp, bool* act, bool* depaden, bool* sm) :
ThreadObject(ind, TypeName),
runningFlag(0),
generalData(nullptr),
fifo(f),
myDetectorType(dtype),
status(s),
udpSocket(nullptr),
udpPortNumber(portno),
eth(e),
numImages(nf),
@ -41,45 +39,22 @@ Listener::Listener(int ind, detectorType dtype, Fifo* f, std::atomic<runStatus>*
frameDiscardMode(fdp),
activated(act),
deactivatedPaddingEnable(depaden),
silentMode(sm),
row(0),
column(0),
startedFlag(false),
firstIndex(0),
numPacketsCaught(0),
lastCaughtFrameIndex(0),
currentFrameIndex(0),
carryOverFlag(0),
udpSocketAlive(0),
numPacketsStatistic(0),
numFramesStatistic(0),
oddStartingPacket(true)
silentMode(sm)
{
LOG(logDEBUG) << "Listener " << ind << " created";
}
Listener::~Listener() = default;
Listener::~Listener() {
if (udpSocket){
sem_post(&semaphore_socket);
sem_destroy(&semaphore_socket);
}
}
/** getters */
bool Listener::IsRunning() {
return runningFlag;
}
uint64_t Listener::GetPacketsCaught() {
uint64_t Listener::GetPacketsCaught() const {
return numPacketsCaught;
}
uint64_t Listener::GetLastFrameIndexCaught() {
uint64_t Listener::GetLastFrameIndexCaught() const {
return lastCaughtFrameIndex;
}
uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) {
uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const {
if (!stoppedFlag) {
return (numPackets - numPacketsCaught);
}
@ -89,24 +64,12 @@ uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) {
return (lastCaughtFrameIndex - firstIndex + 1) * generalData->packetsPerFrame - numPacketsCaught;
}
/** setters */
void Listener::StartRunning() {
runningFlag = true;
}
void Listener::StopRunning() {
runningFlag = false;
}
void Listener::SetFifo(Fifo* f) {
fifo = f;
}
void Listener::ResetParametersforNewAcquisition() {
runningFlag = false;
StopRunning();
startedFlag = false;
numPacketsCaught = 0;
firstIndex = 0;
@ -149,7 +112,7 @@ void Listener::SetGeneralData(GeneralData* g) {
}
void Listener::CreateUDPSockets() {
void Listener::CreateUDPSocket() {
if (!(*activated)) {
return;
}
@ -174,10 +137,9 @@ void Listener::CreateUDPSockets() {
}
udpSocketAlive = true;
sem_init(&semaphore_socket,1,0);
// doubled due to kernel bookkeeping (could also be less due to permissions)
*actualUDPSocketBufferSize = udpSocket->getActualUDPSocketBufferSize();
*actualUDPSocketBufferSize = udpSocket->getBufferSize();
}
@ -185,14 +147,8 @@ void Listener::CreateUDPSockets() {
void Listener::ShutDownUDPSocket() {
if(udpSocket){
udpSocketAlive = false;
udpSocket->ShutDownSocket();
udpSocket->Shutdown();
LOG(logINFO) << "Shut down of UDP port " << *udpPortNumber;
fflush(stdout);
// wait only if the threads have started as it is the threads that
//give a post to semaphore(at stopListening)
if (runningFlag)
sem_wait(&semaphore_socket);
sem_destroy(&semaphore_socket);
}
}
@ -220,7 +176,7 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int64_t s) {
*udpSocketBufferSize);
// doubled due to kernel bookkeeping (could also be less due to permissions)
*actualUDPSocketBufferSize = g.getActualUDPSocketBufferSize();
*actualUDPSocketBufferSize = g.getBufferSize();
if (*actualUDPSocketBufferSize == -1) {
*udpSocketBufferSize = temp;
} else {
@ -300,10 +256,8 @@ void Listener::StopListening(char* buf) {
(*((uint32_t*)buf)) = DUMMY_PACKET_VALUE;
fifo->PushAddress(buf);
StopRunning();
sem_post(&semaphore_socket);
LOG(logDEBUG1) << index << ": Listening Packets (" << *udpPortNumber << ") : " << numPacketsCaught;
LOG(logDEBUG1) << index << ": Listening Completed";
LOG(logDEBUG1) << index << ": Listening Packets (" << *udpPortNumber << ") : " << numPacketsCaught;
LOG(logDEBUG1) << index << ": Listening Completed";
}

View File

@ -12,13 +12,10 @@
#include <memory>
#include <atomic>
#include "ThreadObject.h"
#include "UdpRxSocket.h"
class GeneralData;
class Fifo;
namespace sls{
class UdpRxSocket;
}
class Listener : private virtual slsDetectorDefs, public ThreadObject {
@ -53,40 +50,20 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
*/
~Listener();
//*** getters ***
/**
* Returns if the thread is currently running
* @returns true if thread is running, else false
*/
bool IsRunning() override;
/**
* Get Packets caught
* @return Packets caught
*/
uint64_t GetPacketsCaught();
uint64_t GetPacketsCaught() const;
/**
* Get Last Frame index caught
* @return last frame index caught
*/
uint64_t GetLastFrameIndexCaught();
uint64_t GetLastFrameIndexCaught() const;
/** Get number of missing packets */
uint64_t GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets);
//*** setters ***
/**
* Set bit in RunningMask to allow thread to run
*/
void StartRunning();
/**
* Reset bit in RunningMask to prevent thread from running
*/
void StopRunning();
uint64_t GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const;
/**
* Set Fifo pointer to the one given
@ -106,9 +83,9 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
void SetGeneralData(GeneralData* g);
/**
* Creates UDP Sockets
* Creates UDP Socket
*/
void CreateUDPSockets();
void CreateUDPSocket();
/**
* Shuts down and deletes UDP Sockets
@ -140,7 +117,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
void RecordFirstIndex(uint64_t fnum);
/**
* Thread Exeution for Listener Class
* Thread Execution for Listener Class
* Pop free addresses, listen to udp socket,
* write to memory & push the address into fifo
*/
@ -168,16 +145,11 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
*/
void PrintFifoStatistics();
/** type of thread */
static const std::string TypeName;
/** Object running status */
std::atomic<bool> runningFlag;
/** GeneralData (Detector Data) object */
GeneralData* generalData;
GeneralData* generalData{nullptr};
/** Fifo structure */
Fifo* fifo;
@ -190,7 +162,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
std::atomic<runStatus>* status;
/** UDP Socket - Detector to Receiver */
std::unique_ptr<sls::UdpRxSocket> udpSocket;
std::unique_ptr<sls::UdpRxSocket> udpSocket{nullptr};
/** UDP Port Number */
uint32_t* udpPortNumber;
@ -228,36 +200,34 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
/** row hardcoded as 1D or 2d,
* if detector does not send them yet or
* missing packets/deactivated (eiger/jungfrau sends 2d pos) **/
uint16_t row;
uint16_t row{0};
/** column hardcoded as 2D,
* deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/
uint16_t column;
uint16_t column{0};
// acquisition start
/** Aquisition Started flag */
std::atomic<bool> startedFlag;
std::atomic<bool> startedFlag{false};
/** Frame Number of First Frame */
uint64_t firstIndex;
uint64_t firstIndex{0};
// for acquisition summary
/** Number of complete Packets caught */
std::atomic<uint64_t> numPacketsCaught;
std::atomic<uint64_t> numPacketsCaught{0};
/** Last Frame Index caught from udp network */
std::atomic<uint64_t> lastCaughtFrameIndex;
std::atomic<uint64_t> lastCaughtFrameIndex{0};
// parameters to acquire image
/** Current Frame Index, default value is 0
* ( always check startedFlag for validity first)
*/
uint64_t currentFrameIndex;
uint64_t currentFrameIndex{0};
/** True if there is a packet carry over from previous Image */
bool carryOverFlag;
bool carryOverFlag{false};
/** Carry over packet buffer */
std::unique_ptr<char []> carryOverPacket;
@ -266,22 +236,19 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
std::unique_ptr<char []> listeningPacket;
/** if the udp socket is connected */
std::atomic<bool> udpSocketAlive;
std::atomic<bool> udpSocketAlive{false};
/** Semaphore to synchonize deleting udp socket */
sem_t semaphore_socket;
// for print progress during acqusition
// for print progress during acquisition
/** number of packets for statistic */
uint32_t numPacketsStatistic;
uint32_t numPacketsStatistic{0};
/** number of images for statistic */
uint32_t numFramesStatistic;
uint32_t numFramesStatistic{0};
/**
* starting packet number is odd or evern, accordingly increment frame number
* starting packet number is odd or even, accordingly increment frame number
* to get first packet number as 0
* (pecific to gotthard, can vary between modules, hence defined here) */
bool oddStartingPacket;
bool oddStartingPacket{true};
};

View File

@ -42,17 +42,14 @@ int main(int argc, char *argv[]) {
LOG(logERROR) << "Could not set handler function for SIGPIPE";
}
std::unique_ptr<Receiver> receiver = nullptr;
try {
receiver = sls::make_unique<Receiver>(argc, argv);
Receiver r(argc, argv);
LOG(logINFO) << "[ Press \'Ctrl+c\' to exit ]";
sem_wait(&semaphore);
sem_destroy(&semaphore);
} catch (...) {
LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]";
throw;
//pass
}
LOG(logINFO) << "[ Press \'Ctrl+c\' to exit ]";
sem_wait(&semaphore);
sem_destroy(&semaphore);
LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]";
LOG(logINFO) << "Exiting Receiver";
return 0;

View File

@ -3,56 +3,51 @@
* @short creates/destroys a thread
***********************************************/
#include "ThreadObject.h"
#include "container_utils.h"
#include <iostream>
#include <sys/syscall.h>
#include <unistd.h>
ThreadObject::ThreadObject(int threadIndex, std::string threadType)
: index(threadIndex), type(threadType) {
LOG(logDEBUG) << type << " thread created: " << index;
sem_init(&semaphore,1,0);
try {
threadObject = sls::make_unique<std::thread>(&ThreadObject::RunningThread, this);
threadObject = std::thread(&ThreadObject::RunningThread, this);
} catch (...) {
throw sls::RuntimeError("Could not create " + type + " thread with index " + std::to_string(index));
}
}
ThreadObject::~ThreadObject() {
killThread = true;
sem_post(&semaphore);
threadObject->join();
threadObject.join();
sem_destroy(&semaphore);
}
bool ThreadObject::IsRunning() const{
return runningFlag;
}
void ThreadObject::StartRunning() {
runningFlag = true;
}
void ThreadObject::StopRunning() {
runningFlag = false;
}
void ThreadObject::RunningThread() {
LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]";
LOG(logDEBUG) << type << " thread " << index << " created successfully.";
while(true) {
while(!killThread) {
while(IsRunning()) {
ThreadExecution();
}
//wait till the next acquisition
sem_wait(&semaphore);
if(killThread) {
break;
}
}
LOG(logDEBUG) << type << " thread with index " << index << " destroyed successfully.";
LOG(logINFOBLUE) << "Exiting [ " << type << " Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]";
}
@ -61,11 +56,10 @@ void ThreadObject::Continue() {
sem_post(&semaphore);
}
void ThreadObject::SetThreadPriority(int priority) {
struct sched_param param;
param.sched_priority = priority;
if (pthread_setschedparam(threadObject->native_handle(), SCHED_FIFO, &param) == EPERM) {
if (pthread_setschedparam(threadObject.native_handle(), SCHED_FIFO, &param) == EPERM) {
if (index == 0) {
LOG(logWARNING) << "Could not prioritize " << type << " thread. "
"(No Root Privileges?)";

View File

@ -7,41 +7,40 @@
*@short creates/destroys a thread
*/
#include "sls_detector_defs.h"
#include "logger.h"
#include "sls_detector_defs.h"
#include <atomic>
#include <thread>
#include <semaphore.h>
#include <string>
#include <atomic>
#include <future>
class ThreadObject : private virtual slsDetectorDefs {
public:
ThreadObject(int threadIndex, std::string threadType);
virtual ~ThreadObject();
virtual bool IsRunning() = 0;
void Continue();
void SetThreadPriority(int priority);
protected:
const int index{0};
protected:
virtual void ThreadExecution() = 0;
private:
std::atomic<bool> killThread{false};
std::atomic<bool> runningFlag{false};
std::thread threadObject;
sem_t semaphore;
const std::string type;
private:
/**
* Thread called: An infinite while loop in which,
* semaphore starts executing its contents as long RunningMask is satisfied
* Then it exits the thread on its own if killThread is true
*/
void RunningThread();
public:
ThreadObject(int threadIndex, std::string threadType);
virtual ~ThreadObject();
bool IsRunning() const;
void StartRunning();
void StopRunning();
void Continue();
void SetThreadPriority(int priority);
protected:
int index{0};
std::string type;
std::atomic<bool> killThread{false};
std::unique_ptr<std::thread> threadObject;
sem_t semaphore;
private:
virtual void ThreadExecution() = 0;
/**
* Thread called: An infinite while loop in which,
* semaphore starts executing its contents as long RunningMask is satisfied
* Then it exits the thread on its own if killThread is true
*/
void RunningThread();
};

View File

@ -8,6 +8,7 @@ set(SOURCES
src/ToString.cpp
src/network_utils.cpp
src/ZmqSocket.cpp
src/UdpRxSocket.cpp
)
set(HEADERS

View File

@ -21,7 +21,7 @@ class DataSocket {
//No copy since the class manage the underlying socket
DataSocket(const DataSocket &) = delete;
DataSocket &operator=(DataSocket const &) = delete;
int getSocketId() const { return socketId_; }
int getSocketId() const { return sockfd_; }
int Send(const void *buffer, size_t size);
@ -51,9 +51,10 @@ class DataSocket {
int setReceiveTimeout(int us);
void close();
void shutDownSocket();
void shutdown();
private:
int socketId_ = -1;
int sockfd_ = -1;
};
}; // namespace sls

View File

@ -1,141 +1,30 @@
#pragma once
/*
UdpRxSocket provies socket control to receive
data on a udp socket.
It provides a drop in replacement for
genericSocket. But please be careful since
this might be deprecated in the future
UDP socket class to receive data. The intended use is in the
receiver listener loop. Should be used RAII style...
*/
#include "network_utils.h"
#include "sls_detector_exceptions.h"
#include <cstdint>
#include <errno.h>
#include <iostream>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <vector>
#include <sys/types.h> //ssize_t
namespace sls {
class UdpRxSocket {
const ssize_t packet_size;
char *buff;
int fd = -1;
const ssize_t packet_size_;
int sockfd_{-1};
public:
UdpRxSocket(int port, ssize_t packet_size, const char *hostname = nullptr,
ssize_t buffer_size = 0)
: packet_size(packet_size) {
/* hostname = nullptr -> wildcard */
size_t kernel_buffer_size = 0);
~UdpRxSocket();
bool ReceivePacket(char *dst) noexcept;
size_t getBufferSize() const;
void setBufferSize(ssize_t size);
ssize_t getPacketSize() const noexcept;
void Shutdown();
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
struct addrinfo *res = 0;
const std::string portname = std::to_string(port);
if (getaddrinfo(hostname, portname.c_str(), &hints, &res)) {
throw RuntimeError("Failed at getaddrinfo with " +
std::string(hostname));
}
fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (fd == -1) {
throw RuntimeError("Failed to create UDP RX socket");
}
if (bind(fd, res->ai_addr, res->ai_addrlen) == -1) {
throw RuntimeError("Failed to bind UDP RX socket");
}
freeaddrinfo(res);
// If we get a specified buffer size that is larger than the set one
// we set it. Otherwise we leave it there since it could have been
// set by the rx_udpsocksize command
if (buffer_size) {
auto current = getBufferSize() / 2;
if (current < buffer_size) {
setBufferSize(buffer_size);
if (getBufferSize() / 2 < buffer_size) {
LOG(logWARNING)
<< "Could not set buffer size. Got: "
<< getBufferSize() / 2 << " instead of " << buffer_size;
}
}
}
// Allocate at the end to avoid memory leak if we throw
buff = new char[packet_size];
}
~UdpRxSocket() {
delete[] buff;
Shutdown();
}
const char *LastPacket() const noexcept { return buff; }
ssize_t getPacketSize() const noexcept { return packet_size; }
bool ReceivePacket() noexcept { return ReceivePacket(buff); }
bool ReceivePacket(char *dst, int flags = 0) noexcept {
auto bytes_received =
recvfrom(fd, dst, packet_size, flags, nullptr, nullptr);
return bytes_received == packet_size;
}
bool PeekPacket() noexcept{
return ReceivePacket(buff, MSG_PEEK);
}
// Only for backwards compatibility this function will be removed during
// refactoring of the receiver
ssize_t ReceiveDataOnly(char *dst) {
auto r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr);
constexpr ssize_t eiger_header_packet =
40; // only detector that has this
if (r == eiger_header_packet) {
LOG(logWARNING) << "Got header pkg";
r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr);
}
return r;
}
ssize_t getBufferSize() const {
uint64_t ret_size = 0;
socklen_t optlen = sizeof(uint64_t);
if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen) == -1)
return -1;
else
return ret_size;
}
// Only for backwards compatibility will be removed
ssize_t getActualUDPSocketBufferSize() const { return getBufferSize(); }
// Only for backwards compatibility will be removed
void ShutDownSocket() { Shutdown(); }
void setBufferSize(ssize_t size) {
socklen_t optlen = sizeof(size);
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, optlen)) {
throw RuntimeError("Could not set socket buffer size");
}
}
void Shutdown() {
shutdown(fd, SHUT_RDWR);
if (fd >= 0) {
close(fd);
fd = -1;
}
}
// Only for backwards compatibility, this drops the EIGER small pkt, may be
// removed
ssize_t ReceiveDataOnly(char *dst) noexcept;
};
} // namespace sls

View File

@ -26,10 +26,10 @@ struct zmqHeader {
uint32_t jsonversion{0};
uint32_t dynamicRange{0};
uint64_t fileIndex{0};
/** number of detectors in x axis */
uint32_t ndetx{0};
/** number of detectors in y axis */
uint32_t ndety{0};
/** number of sockets in x axis */
uint32_t nSocketX{0};
/** number of sockets in y axis */
uint32_t nSocketY{0};
/** number of pixels/channels in x axis for this zmq socket */
uint32_t npixelsx{0};
/** number of pixels/channels in y axis for this zmq socket */
@ -40,6 +40,8 @@ struct zmqHeader {
uint64_t acqIndex{0};
/** frame index (starting at 0 for each acquisition) */
uint64_t frameIndex{0};
/** progress in percentage */
int progress{0};
/** file name prefix */
std::string fname{""};
/** header from detector */

View File

@ -32,6 +32,7 @@
/** default ports */
#define DEFAULT_PORTNO 1952
#define DEFAULT_RX_PORTNO 1954
#define DEFAULT_UDP_PORTNO 50001
#define DEFAULT_ZMQ_CL_PORTNO 30001
#define DEFAULT_ZMQ_RX_PORTNO 30001
@ -87,8 +88,7 @@ class slsDetectorDefs {
/** return values */
enum {
OK, /**< function succeeded */
FAIL, /**< function failed */
FORCE_UPDATE
FAIL /**< function failed */
};
/** staus mask */
@ -176,7 +176,7 @@ class slsDetectorDefs {
struct ROI {
int xmin{-1}; /**< is the roi xmin (in channel number) */
int xmax{-1}; /**< is the roi xmax (in channel number)*/
};
}__attribute__((packed));
#else
typedef struct {
int xmin; /**< is the roi xmin (in channel number) */
@ -204,7 +204,7 @@ class slsDetectorDefs {
int y{0};
xy() = default;
xy(int x, int y):x(x),y(y){};
};
}__attribute__((packed));
#endif
@ -245,7 +245,8 @@ class slsDetectorDefs {
AUTO_TIMING, /**< internal timing */
TRIGGER_EXPOSURE, /**< trigger mode i.e. exposure is triggered */
GATED, /**< gated */
BURST_TRIGGER /**< trigger a burst of frames */
BURST_TRIGGER, /**< trigger a burst of frames */
NUM_TIMING_MODES
};
/**
@ -448,7 +449,8 @@ class slsDetectorDefs {
enum burstMode {
BURST_OFF,
BURST_INTERNAL,
BURST_EXTERNAL
BURST_EXTERNAL,
NUM_BURST_MODES
};
/**
@ -459,6 +461,46 @@ class slsDetectorDefs {
TIMING_EXTERNAL
};
#ifdef __cplusplus
/**
* structure to udpate receiver
*/
struct rxParameters {
detectorType detType{GENERIC};
xy detectorSize;
int moduleId{0};
char hostname[MAX_STR_LENGTH];
int interfaceId{0};
uint32_t zmq_ip{0U};
int udpInterfaces{1};
int udp_dstport{0};
uint32_t udp_dstip{0U};
uint64_t udp_dstmac{0LU};
int udp_dstport2{0};
uint32_t udp_dstip2{0U};
uint64_t udp_dstmac2{0LU};
int64_t frames{0};
int64_t triggers{0};
int64_t bursts{0};
int analogSamples{0};
int digitalSamples{0};
int64_t expTimeNs{0};
int64_t periodNs{0};
int64_t subExpTimeNs{0};
int64_t subDeadTimeNs{0};
int activate{0};
int quad{0};
int dynamicRange{16};
timingMode timMode{AUTO_TIMING};
int tenGiga{0};
readoutMode roMode{ANALOG_ONLY};
uint32_t adcMask{0};
uint32_t adc10gMask{0};
ROI roi;
uint32_t countermask{0};
burstMode burstType{BURST_OFF};
}__attribute__((packed));
#endif
#ifdef __cplusplus
protected:
@ -480,7 +522,6 @@ struct detParameters {
int nChipX{0};
int nChipY{0};
int nDacs{0};
int dynamicRange{0};
detParameters() = default;
explicit detParameters(slsDetectorDefs::detectorType type) {
@ -491,7 +532,6 @@ struct detParameters {
nChipX = 10;
nChipY = 1;
nDacs = 8;
dynamicRange = 16;
break;
case slsDetectorDefs::detectorType::JUNGFRAU:
nChanX = 256;
@ -499,7 +539,6 @@ struct detParameters {
nChipX = 4;
nChipY = 2;
nDacs = 8;
dynamicRange = 16;
break;
case slsDetectorDefs::detectorType::CHIPTESTBOARD:
nChanX = 36;
@ -507,7 +546,6 @@ struct detParameters {
nChipX = 1;
nChipY = 1;
nDacs = 24;
dynamicRange = 16;
break;
case slsDetectorDefs::detectorType::MOENCH:
nChanX = 32;
@ -515,7 +553,6 @@ struct detParameters {
nChipX = 1;
nChipY = 1;
nDacs = 8;
dynamicRange = 16;
break;
case slsDetectorDefs::detectorType::EIGER:
nChanX = 256;
@ -523,7 +560,6 @@ struct detParameters {
nChipX = 4;
nChipY = 1;
nDacs = 16;
dynamicRange = 16;
break;
case slsDetectorDefs::detectorType::MYTHEN3:
nChanX = 128 * 3;
@ -531,7 +567,6 @@ struct detParameters {
nChipX = 10;
nChipY = 1;
nDacs = 16;
dynamicRange = 32;
break;
case slsDetectorDefs::detectorType::GOTTHARD2:
nChanX = 128;
@ -539,7 +574,6 @@ struct detParameters {
nChipX = 10;
nChipY = 1;
nDacs = 14;
dynamicRange = 16;
break;
default:
throw sls::RuntimeError("Unknown detector type! " + std::to_string(type));

View File

@ -74,7 +74,6 @@ enum detFuncs{
F_LOCK_SERVER,
F_GET_LAST_CLIENT_IP,
F_SET_PORT,
F_UPDATE_CLIENT,
F_ENABLE_TEN_GIGA,
F_SET_ALL_TRIMBITS,
F_SET_PATTERN_IO_CONTROL,
@ -197,20 +196,26 @@ enum detFuncs{
F_GET_TIMING_SOURCE,
F_SET_TIMING_SOURCE,
F_GET_NUM_CHANNELS,
F_UPDATE_RATE_CORRECTION,
F_GET_RECEIVER_PARAMETERS,
NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this (detector server should not compile anyway) */
F_EXEC_RECEIVER_COMMAND,
F_EXIT_RECEIVER,
F_LOCK_RECEIVER,
F_SET_LOCK_RECEIVER,
F_GET_LOCK_RECEIVER,
F_GET_LAST_RECEIVER_CLIENT_IP,
F_SET_RECEIVER_PORT,
F_GET_RECEIVER_VERSION,
F_GET_RECEIVER_TYPE,
F_SEND_RECEIVER_DETHOSTNAME,
F_RECEIVER_SET_ROI,
F_RECEIVER_SET_NUM_FRAMES,
F_SET_RECEIVER_NUM_TRIGGERS,
F_SET_RECEIVER_NUM_BURSTS,
F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS,
F_SET_RECEIVER_TIMING_MODE,
F_SET_RECEIVER_BURST_MODE,
F_RECEIVER_SET_NUM_ANALOG_SAMPLES,
F_RECEIVER_SET_NUM_DIGITAL_SAMPLES,
F_RECEIVER_SET_EXPTIME,
@ -240,15 +245,16 @@ enum detFuncs{
F_GET_RECEIVER_OVERWRITE,
F_ENABLE_RECEIVER_TEN_GIGA,
F_SET_RECEIVER_FIFO_DEPTH,
F_GET_RECEIVER_FIFO_DEPTH,
F_RECEIVER_ACTIVATE,
F_SET_RECEIVER_STREAMING,
F_GET_RECEIVER_STREAMING,
F_RECEIVER_STREAMING_TIMER,
F_SET_RECEIVER_STREAMING_TIMER,
F_GET_RECEIVER_STREAMING_TIMER,
F_SET_FLIPPED_DATA_RECEIVER,
F_GET_FLIPPED_DATA_RECEIVER,
F_SET_RECEIVER_FILE_FORMAT,
F_GET_RECEIVER_FILE_FORMAT,
F_SEND_RECEIVER_DETPOSID,
F_SEND_RECEIVER_MULTIDETSIZE,
F_SET_RECEIVER_STREAMING_PORT,
F_GET_RECEIVER_STREAMING_PORT,
F_SET_RECEIVER_STREAMING_SRC_IP,
@ -258,8 +264,9 @@ enum detFuncs{
F_RESTREAM_STOP_FROM_RECEIVER,
F_SET_ADDITIONAL_JSON_HEADER,
F_GET_ADDITIONAL_JSON_HEADER,
F_RECEIVER_UDP_SOCK_BUF_SIZE,
F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE,
F_SET_RECEIVER_UDP_SOCK_BUF_SIZE,
F_GET_RECEIVER_UDP_SOCK_BUF_SIZE,
F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE,
F_SET_RECEIVER_FRAMES_PER_FILE,
F_GET_RECEIVER_FRAMES_PER_FILE,
F_RECEIVER_CHECK_VERSION,
@ -278,15 +285,16 @@ enum detFuncs{
F_SET_RECEIVER_QUAD,
F_SET_RECEIVER_READ_N_LINES,
F_SET_RECEIVER_UDP_IP,
F_SET_RECEIVER_UDP_IP2,
F_SET_RECEIVER_UDP_PORT,
F_SET_RECEIVER_UDP_PORT2,
F_SET_RECEIVER_NUM_INTERFACES,
F_RECEIVER_SET_ADC_MASK_10G,
F_RECEIVER_SET_NUM_COUNTERS,
F_INCREMENT_FILE_INDEX,
F_SET_ADDITIONAL_JSON_PARAMETER,
F_GET_ADDITIONAL_JSON_PARAMETER,
F_GET_RECEIVER_PROGRESS,
F_SETUP_RECEIVER,
NUM_REC_FUNCTIONS
};
@ -357,7 +365,6 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_LOCK_SERVER: return "F_LOCK_SERVER";
case F_GET_LAST_CLIENT_IP: return "F_GET_LAST_CLIENT_IP";
case F_SET_PORT: return "F_SET_PORT";
case F_UPDATE_CLIENT: return "F_UPDATE_CLIENT";
case F_ENABLE_TEN_GIGA: return "F_ENABLE_TEN_GIGA";
case F_SET_ALL_TRIMBITS: return "F_SET_ALL_TRIMBITS";
case F_SET_PATTERN_IO_CONTROL: return "F_SET_PATTERN_IO_CONTROL";
@ -480,20 +487,27 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_GET_TIMING_SOURCE: return "F_GET_TIMING_SOURCE";
case F_SET_TIMING_SOURCE: return "F_SET_TIMING_SOURCE";
case F_GET_NUM_CHANNELS: return "F_GET_NUM_CHANNELS";
case F_UPDATE_RATE_CORRECTION: return "F_UPDATE_RATE_CORRECTION";
case F_GET_RECEIVER_PARAMETERS: return "F_GET_RECEIVER_PARAMETERS";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
case F_EXEC_RECEIVER_COMMAND: return "F_EXEC_RECEIVER_COMMAND";
case F_EXIT_RECEIVER: return "F_EXIT_RECEIVER";
case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER";
case F_SET_LOCK_RECEIVER: return "F_SET_LOCK_RECEIVER";
case F_GET_LOCK_RECEIVER: return "F_GET_LOCK_RECEIVER";
case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP";
case F_SET_RECEIVER_PORT: return "F_SET_RECEIVER_PORT";
case F_GET_RECEIVER_VERSION: return "F_GET_RECEIVER_VERSION";
case F_GET_RECEIVER_TYPE: return "F_GET_RECEIVER_TYPE";
case F_SEND_RECEIVER_DETHOSTNAME: return "F_SEND_RECEIVER_DETHOSTNAME";
case F_SETUP_RECEIVER: return "F_SETUP_RECEIVER";
case F_RECEIVER_SET_ROI: return "F_RECEIVER_SET_ROI";
case F_RECEIVER_SET_NUM_FRAMES: return "F_RECEIVER_SET_NUM_FRAMES";
case F_SET_RECEIVER_NUM_TRIGGERS: return "F_SET_RECEIVER_NUM_TRIGGERS";
case F_SET_RECEIVER_NUM_BURSTS: return "F_SET_RECEIVER_NUM_BURSTS";
case F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS: return "F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS";
case F_SET_RECEIVER_TIMING_MODE: return "F_SET_RECEIVER_TIMING_MODE";
case F_SET_RECEIVER_BURST_MODE: return "F_SET_RECEIVER_BURST_MODE";
case F_RECEIVER_SET_NUM_ANALOG_SAMPLES: return "F_RECEIVER_SET_NUM_ANALOG_SAMPLES";
case F_RECEIVER_SET_NUM_DIGITAL_SAMPLES:return "F_RECEIVER_SET_NUM_DIGITAL_SAMPLES";
case F_RECEIVER_SET_EXPTIME: return "F_RECEIVER_SET_EXPTIME";
@ -523,15 +537,16 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_GET_RECEIVER_OVERWRITE: return "F_GET_RECEIVER_OVERWRITE";
case F_ENABLE_RECEIVER_TEN_GIGA: return "F_ENABLE_RECEIVER_TEN_GIGA";
case F_SET_RECEIVER_FIFO_DEPTH: return "F_SET_RECEIVER_FIFO_DEPTH";
case F_GET_RECEIVER_FIFO_DEPTH: return "F_GET_RECEIVER_FIFO_DEPTH";
case F_RECEIVER_ACTIVATE: return "F_RECEIVER_ACTIVATE";
case F_SET_RECEIVER_STREAMING: return "F_SET_RECEIVER_STREAMING";
case F_GET_RECEIVER_STREAMING: return "F_GET_RECEIVER_STREAMING";
case F_RECEIVER_STREAMING_TIMER: return "F_RECEIVER_STREAMING_TIMER";
case F_SET_RECEIVER_STREAMING_TIMER: return "F_SET_RECEIVER_STREAMING_TIMER";
case F_GET_RECEIVER_STREAMING_TIMER: return "F_GET_RECEIVER_STREAMING_TIMER";
case F_SET_FLIPPED_DATA_RECEIVER: return "F_SET_FLIPPED_DATA_RECEIVER";
case F_GET_FLIPPED_DATA_RECEIVER: return "F_GET_FLIPPED_DATA_RECEIVER";
case F_SET_RECEIVER_FILE_FORMAT: return "F_SET_RECEIVER_FILE_FORMAT";
case F_GET_RECEIVER_FILE_FORMAT: return "F_GET_RECEIVER_FILE_FORMAT";
case F_SEND_RECEIVER_DETPOSID: return "F_SEND_RECEIVER_DETPOSID";
case F_SEND_RECEIVER_MULTIDETSIZE: return "F_SEND_RECEIVER_MULTIDETSIZE";
case F_SET_RECEIVER_STREAMING_PORT: return "F_SET_RECEIVER_STREAMING_PORT";
case F_GET_RECEIVER_STREAMING_PORT: return "F_GET_RECEIVER_STREAMING_PORT";
case F_SET_RECEIVER_STREAMING_SRC_IP: return "F_SET_RECEIVER_STREAMING_SRC_IP";
@ -541,8 +556,9 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_RESTREAM_STOP_FROM_RECEIVER: return "F_RESTREAM_STOP_FROM_RECEIVER";
case F_SET_ADDITIONAL_JSON_HEADER: return "F_SET_ADDITIONAL_JSON_HEADER";
case F_GET_ADDITIONAL_JSON_HEADER: return "F_GET_ADDITIONAL_JSON_HEADER";
case F_RECEIVER_UDP_SOCK_BUF_SIZE: return "F_RECEIVER_UDP_SOCK_BUF_SIZE";
case F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE: return "F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE";
case F_SET_RECEIVER_UDP_SOCK_BUF_SIZE: return "F_SET_RECEIVER_UDP_SOCK_BUF_SIZE";
case F_GET_RECEIVER_UDP_SOCK_BUF_SIZE: return "F_GET_RECEIVER_UDP_SOCK_BUF_SIZE";
case F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE: return "F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE";
case F_SET_RECEIVER_FRAMES_PER_FILE: return "F_SET_RECEIVER_FRAMES_PER_FILE";
case F_GET_RECEIVER_FRAMES_PER_FILE: return "F_GET_RECEIVER_FRAMES_PER_FILE";
case F_RECEIVER_CHECK_VERSION: return "F_RECEIVER_CHECK_VERSION";
@ -561,15 +577,14 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_RECEIVER_QUAD: return "F_SET_RECEIVER_QUAD";
case F_SET_RECEIVER_READ_N_LINES: return "F_SET_RECEIVER_READ_N_LINES";
case F_SET_RECEIVER_UDP_IP: return "F_SET_RECEIVER_UDP_IP";
case F_SET_RECEIVER_UDP_IP2: return "F_SET_RECEIVER_UDP_IP2";
case F_SET_RECEIVER_UDP_PORT: return "F_SET_RECEIVER_UDP_PORT";
case F_SET_RECEIVER_UDP_PORT2: return "F_SET_RECEIVER_UDP_PORT2";
case F_SET_RECEIVER_NUM_INTERFACES: return "F_SET_RECEIVER_NUM_INTERFACES";
case F_RECEIVER_SET_ADC_MASK_10G: return "F_RECEIVER_SET_ADC_MASK_10G";
case F_RECEIVER_SET_NUM_COUNTERS: return "F_RECEIVER_SET_NUM_COUNTERS";
case F_INCREMENT_FILE_INDEX: return "F_INCREMENT_FILE_INDEX";
case F_SET_ADDITIONAL_JSON_PARAMETER: return "F_SET_ADDITIONAL_JSON_PARAMETER";
case F_GET_ADDITIONAL_JSON_PARAMETER: return "F_GET_ADDITIONAL_JSON_PARAMETER";
case F_GET_RECEIVER_PROGRESS: return "F_GET_RECEIVER_PROGRESS";
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function";

View File

@ -1,12 +1,12 @@
/** API versions */
#define GITBRANCH "developer"
#define APILIB 0x200227
#define APIRECEIVER 0x200227
#define APIGUI 0x200227
#define APICTB 0x200311
#define APIGOTTHARD 0x200326
#define APIGOTTHARD2 0x200326
#define APIJUNGFRAU 0x200326
#define APIMYTHEN3 0x200311
#define APIMOENCH 0x200326
#define APIEIGER 0x200326
#define GITBRANCH "setrxhostname"
#define APILIB 0x200409
#define APIRECEIVER 0x200409
#define APIGUI 0x200409
#define APIEIGER 0x200409
#define APICTB 0x200409
#define APIGOTTHARD 0x200409
#define APIGOTTHARD2 0x200409
#define APIJUNGFRAU 0x200409
#define APIMYTHEN3 0x200409
#define APIMOENCH 0x200409

View File

@ -15,13 +15,13 @@
namespace sls {
DataSocket::DataSocket(int socketId) : socketId_(socketId) {
DataSocket::DataSocket(int socketId) : sockfd_(socketId) {
int value = 1;
setsockopt(socketId_, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
}
DataSocket::~DataSocket() {
if (socketId_ <= 0) {
if (sockfd_ <= 0) {
return;
} else {
try {
@ -32,7 +32,7 @@ DataSocket::~DataSocket() {
}
void DataSocket::swap(DataSocket &other) noexcept {
std::swap(socketId_, other.socketId_);
std::swap(sockfd_, other.sockfd_);
}
DataSocket::DataSocket(DataSocket &&move) noexcept { move.swap(*this); }
@ -121,19 +121,23 @@ int DataSocket::setTimeOut(int t_seconds) {
}
void DataSocket::close() {
if (socketId_ > 0) {
if (::close(socketId_)) {
if (sockfd_ > 0) {
if (::close(sockfd_)) {
throw SocketError("could not close socket");
}
socketId_ = -1;
sockfd_ = -1;
} else {
throw std::runtime_error("Socket ERROR: close called on bad socket\n");
}
}
void DataSocket::shutDownSocket() {
shutdown(getSocketId(), SHUT_RDWR);
::shutdown(getSocketId(), SHUT_RDWR);
close();
}
void DataSocket::shutdown(){
::shutdown(sockfd_, SHUT_RDWR);
}
} // namespace sls

View File

@ -11,7 +11,7 @@ std::string ToString(const defs::runStatus s) {
case defs::RUNNING:
return std::string("running");
case defs::TRANSMITTING:
return std::string("data");
return std::string("transmitting");
case defs::RUN_FINISHED:
return std::string("finished");
case defs::STOPPED:

View File

@ -0,0 +1,96 @@
#include "UdpRxSocket.h"
#include "network_utils.h"
#include "sls_detector_exceptions.h"
#include <cstdint>
#include <errno.h>
#include <iostream>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
namespace sls {
UdpRxSocket::UdpRxSocket(int port, ssize_t packet_size, const char *hostname,
size_t kernel_buffer_size)
: packet_size_(packet_size) {
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
struct addrinfo *res = 0;
const std::string portname = std::to_string(port);
if (getaddrinfo(hostname, portname.c_str(), &hints, &res)) {
throw RuntimeError("Failed at getaddrinfo with " +
std::string(hostname));
}
sockfd_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd_ == -1) {
throw RuntimeError("Failed to create UDP RX socket");
}
if (bind(sockfd_, res->ai_addr, res->ai_addrlen) == -1) {
throw RuntimeError("Failed to bind UDP RX socket");
}
freeaddrinfo(res);
// If we get a specified buffer size that is larger than the set one
// we set it. Otherwise we leave it there since it could have been
// set by the rx_udpsocksize command
if (kernel_buffer_size) {
auto current = getBufferSize() / 2;
if (current < kernel_buffer_size) {
setBufferSize(kernel_buffer_size);
if (getBufferSize() / 2 < kernel_buffer_size) {
LOG(logWARNING)
<< "Could not set buffer size. Got: " << getBufferSize() / 2
<< " instead of " << kernel_buffer_size;
}
}
}
}
UdpRxSocket::~UdpRxSocket() { Shutdown(); }
ssize_t UdpRxSocket::getPacketSize() const noexcept { return packet_size_; }
bool UdpRxSocket::ReceivePacket(char *dst) noexcept{
auto bytes_received =
recvfrom(sockfd_, dst, packet_size_, 0, nullptr, nullptr);
return bytes_received == packet_size_;
}
ssize_t UdpRxSocket::ReceiveDataOnly(char *dst) noexcept {
auto r = recvfrom(sockfd_, dst, packet_size_, 0, nullptr, nullptr);
constexpr ssize_t eiger_header_packet =
40; // only detector that has this
if (r == eiger_header_packet) {
LOG(logWARNING) << "Got header pkg";
r = recvfrom(sockfd_, dst, packet_size_, 0, nullptr, nullptr);
}
return r;
}
size_t UdpRxSocket::getBufferSize() const {
size_t ret = 0;
socklen_t optlen = sizeof(ret);
if (getsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &ret, &optlen) == -1)
throw RuntimeError("Could not get socket buffer size");
return ret;
}
void UdpRxSocket::setBufferSize(ssize_t size) {
if (setsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)))
throw RuntimeError("Could not set socket buffer size");
}
void UdpRxSocket::Shutdown() {
shutdown(sockfd_, SHUT_RDWR);
if (sockfd_ >= 0) {
close(sockfd_);
sockfd_ = -1;
}
}
} // namespace sls

View File

@ -158,6 +158,7 @@ int ZmqSocket::SendHeader(
"\"size\":%u, "
"\"acqIndex\":%lu, "
"\"frameIndex\":%lu, "
"\"progress\":%u, "
"\"fname\":\"%s\", "
"\"data\": %d, "
"\"completeImage\": %d, "
@ -186,13 +187,14 @@ int ZmqSocket::SendHeader(
header.jsonversion,
header.dynamicRange,
header.fileIndex,
header.ndetx,
header.ndety,
header.nSocketX,
header.nSocketY,
header.npixelsx,
header.npixelsy,
header.imageSize,
header.acqIndex,
header.frameIndex,
header.progress,
header.fname.c_str(),
header.data ? 1 : 0,
header.completeImage ? 1 : 0,
@ -317,13 +319,14 @@ int ZmqSocket::ParseHeader(const int index, int length, char *buff,
zHeader.data = ((document["data"].GetUint()) == 0) ? false : true;
zHeader.dynamicRange = document["bitmode"].GetUint();
zHeader.fileIndex = document["fileIndex"].GetUint64();
zHeader.ndetx = document["detshape"][0].GetUint();
zHeader.ndety = document["detshape"][1].GetUint();
zHeader.nSocketX = document["detshape"][0].GetUint();
zHeader.nSocketY = document["detshape"][1].GetUint();
zHeader.npixelsx = document["shape"][0].GetUint();
zHeader.npixelsy = document["shape"][1].GetUint();
zHeader.imageSize = document["size"].GetUint();
zHeader.acqIndex = document["acqIndex"].GetUint64();
zHeader.frameIndex = document["frameIndex"].GetUint64();
zHeader.progress = document["progress"].GetUint();
zHeader.fname = document["fname"].GetString();
zHeader.frameNumber = document["frameNumber"].GetUint64();

View File

@ -109,7 +109,7 @@ TEST_CASE("run status"){
using defs = slsDetectorDefs;
REQUIRE(ToString(defs::runStatus::ERROR) == "error");
REQUIRE(ToString(defs::runStatus::WAITING) == "waiting");
REQUIRE(ToString(defs::runStatus::TRANSMITTING) == "data"); //??
REQUIRE(ToString(defs::runStatus::TRANSMITTING) == "transmitting");
REQUIRE(ToString(defs::runStatus::RUN_FINISHED) == "finished");
REQUIRE(ToString(defs::runStatus::STOPPED) == "stopped");
REQUIRE(ToString(defs::runStatus::IDLE) == "idle");

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