format receiver

This commit is contained in:
Erik Frojdh 2020-05-05 10:04:52 +02:00
parent 3618f6e5d3
commit e599bb7c24
35 changed files with 4642 additions and 4530 deletions

View File

@ -4,3 +4,4 @@ IndentWidth: 4
UseTab: Never UseTab: Never
ColumnLimit: 80 ColumnLimit: 80
AlignConsecutiveAssignments: false AlignConsecutiveAssignments: false
AlignConsecutiveMacros: true

View File

@ -53,7 +53,6 @@ set(ClangFormat_EXCLUDE_PATTERNS "build/"
"slsDetectorServers/" "slsDetectorServers/"
"ctbGui/" "ctbGui/"
"slsSupportLib/" "slsSupportLib/"
"slsReceiverSoftware/"
"manual/" "manual/"
"slsDetectorGui/" "slsDetectorGui/"
"python/" "python/"

View File

@ -116,7 +116,8 @@ int slsDetectorUsers::size() const { return detector->size(); }
// int slsDetectorUsers::setThresholdEnergy(int e_ev, int tb, int isettings, int // int slsDetectorUsers::setThresholdEnergy(int e_ev, int tb, int isettings, int
// detPos) { return detector.setThresholdEnergy(e_ev, // detPos) { return detector.setThresholdEnergy(e_ev,
// (isettings == -1) ? slsDetectorDefs::GET_SETTINGS : // (isettings == -1) ? slsDetectorDefs::GET_SETTINGS :
// (slsDetectorDefs::detectorSettings)isettings, tb, detPos); // (slsDetectorDefs::detectorSettings)isettings,
// tb, detPos);
// } // }
// double slsDetectorUsers::setExposureTime(double t, bool inseconds, int // double slsDetectorUsers::setExposureTime(double t, bool inseconds, int

2
slsReceiverSoftware/include/CircularFifo.h Executable file → Normal file
View File

@ -30,7 +30,7 @@ template <typename Element> class CircularFifo {
} }
CircularFifo(const CircularFifo &) = delete; CircularFifo(const CircularFifo &) = delete;
CircularFifo(CircularFifo&&) = delete; CircularFifo(CircularFifo &&) = delete;
virtual ~CircularFifo() { virtual ~CircularFifo() {
sem_destroy(&data_mutex); sem_destroy(&data_mutex);

22
slsReceiverSoftware/include/Receiver.h Executable file → Normal file
View File

@ -46,14 +46,18 @@ class Receiver : private virtual slsDetectorDefs {
* we write depending on file write enable * we write depending on file write enable
* users get data to write depending on call backs registered * users get data to write depending on call backs registered
*/ */
void registerCallBackStartAcquisition(int (*func)(std::string, std::string, uint64_t, uint32_t, void*),void *arg); void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
uint64_t, uint32_t,
void *),
void *arg);
/** /**
* Call back for acquisition finished * Call back for acquisition finished
* callback argument is * callback argument is
* @param total frames caught * @param total frames caught
*/ */
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *),
void *arg);
/** /**
* Call back for raw data * Call back for raw data
@ -62,8 +66,9 @@ class Receiver : private virtual slsDetectorDefs {
* @param dataPointer is the pointer to the data * @param dataPointer is the pointer to the data
* @param dataSize in bytes is the size of the data in bytes. * @param dataSize in bytes is the size of the data in bytes.
*/ */
void registerCallBackRawDataReady(void (*func)(char* , void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
char*, uint32_t, void*),void *arg); void *),
void *arg);
/** /**
* Call back for raw data (modified) * Call back for raw data (modified)
@ -71,11 +76,12 @@ class Receiver : private virtual slsDetectorDefs {
* @param sls_receiver_header frame metadata * @param sls_receiver_header frame metadata
* @param dataPointer is the pointer to the data * @param dataPointer is the pointer to the data
* @param revDatasize is the reference of data size in bytes. * @param revDatasize is the reference of data size in bytes.
* Can be modified to the new size to be written/streamed. (only smaller value). * Can be modified to the new size to be written/streamed. (only smaller
* value).
*/ */
void registerCallBackRawDataModifyReady(void (*func)(char* , void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
char*, uint32_t &,void*),void *arg); uint32_t &, void *),
void *arg);
private: private:
std::unique_ptr<ClientInterface> tcpipInterface; std::unique_ptr<ClientInterface> tcpipInterface;

119
slsReceiverSoftware/src/BinaryFile.cpp Executable file → Normal file
View File

@ -8,30 +8,26 @@
#include "Fifo.h" #include "Fifo.h"
#include "receiver_defs.h" #include "receiver_defs.h"
#include <iostream>
#include <iomanip> #include <iomanip>
#include <iostream>
#include <string.h> #include <string.h>
FILE* BinaryFile::masterfd = nullptr; FILE *BinaryFile::masterfd = nullptr;
BinaryFile::BinaryFile(int ind, uint32_t* maxf, BinaryFile::BinaryFile(int ind, uint32_t *maxf, int *nd, std::string *fname,
int* nd, std::string* fname, std::string* fpath, uint64_t* findex, bool* owenable, std::string *fpath, uint64_t *findex, bool *owenable,
int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
bool* smode): uint32_t *portno, bool *smode)
File(ind, BINARY, maxf, nd, fname, fpath, findex, owenable, dindex, nunits, nf, dr, portno, smode), : File(ind, BINARY, maxf, nd, fname, fpath, findex, owenable, dindex,
filefd(nullptr), nunits, nf, dr, portno, smode),
numFramesInFile(0), filefd(nullptr), numFramesInFile(0), numActualPacketsInFile(0),
numActualPacketsInFile(0), maxMasterFileSize(2000) {
maxMasterFileSize(2000)
{
#ifdef VERBOSE #ifdef VERBOSE
PrintMembers(); PrintMembers();
#endif #endif
} }
BinaryFile::~BinaryFile() { BinaryFile::~BinaryFile() { CloseAllFiles(); }
CloseAllFiles();
}
void BinaryFile::PrintMembers(TLogLevel level) { void BinaryFile::PrintMembers(TLogLevel level) {
File::PrintMembers(level); File::PrintMembers(level);
@ -45,24 +41,28 @@ void BinaryFile::CreateFile() {
std::ostringstream os; std::ostringstream os;
os << *filePath << "/" << *fileNamePrefix << "_d" os << *filePath << "/" << *fileNamePrefix << "_d"
<< (*detIndex * (*numUnitsPerDetector) + index) << "_f" << subFileIndex << '_' << (*detIndex * (*numUnitsPerDetector) + index) << "_f" << subFileIndex
<< *fileIndex << ".raw"; << '_' << *fileIndex << ".raw";
currentFileName = os.str(); currentFileName = os.str();
if (!(*overWriteEnable)){ if (!(*overWriteEnable)) {
if (NULL == (filefd = fopen((const char *) currentFileName.c_str(), "wx"))){ if (NULL ==
(filefd = fopen((const char *)currentFileName.c_str(), "wx"))) {
filefd = 0; filefd = 0;
throw sls::RuntimeError("Could not create/overwrite file " + currentFileName); throw sls::RuntimeError("Could not create/overwrite file " +
currentFileName);
} }
} else if (NULL == (filefd = fopen((const char *) currentFileName.c_str(), "w"))){ } else if (NULL ==
(filefd = fopen((const char *)currentFileName.c_str(), "w"))) {
filefd = 0; filefd = 0;
throw sls::RuntimeError("Could not create file " + currentFileName); throw sls::RuntimeError("Could not create file " + currentFileName);
} }
//setting to no file buffering // setting to no file buffering
setvbuf(filefd, NULL, _IONBF, 0); setvbuf(filefd, NULL, _IONBF, 0);
if(!(*silentMode)) { if (!(*silentMode)) {
LOG(logINFO) << "[" << *udpPortNumber << "]: Binary File created: " << currentFileName; LOG(logINFO) << "[" << *udpPortNumber
<< "]: Binary File created: " << currentFileName;
} }
} }
@ -81,14 +81,14 @@ void BinaryFile::CloseAllFiles() {
} }
} }
int BinaryFile::WriteData(char* buf, int bsize) { int BinaryFile::WriteData(char *buf, int bsize) {
if (!filefd) if (!filefd)
return 0; return 0;
return fwrite(buf, 1, bsize, filefd); return fwrite(buf, 1, bsize, filefd);
} }
void BinaryFile::WriteToFile(char *buffer, int buffersize,
void BinaryFile::WriteToFile(char* buffer, int buffersize, uint64_t currentFrameNumber, uint64_t currentFrameNumber,
uint32_t numPacketsCaught) { uint32_t numPacketsCaught) {
// check if maxframesperfile = 0 for infinite // check if maxframesperfile = 0 for infinite
if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) { if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) {
@ -114,28 +114,29 @@ void BinaryFile::WriteToFile(char* buffer, int buffersize, uint64_t currentFrame
// get contiguous representation of bit mask // get contiguous representation of bit mask
bitset_storage storage; bitset_storage storage;
memset(storage, 0 , sizeof(bitset_storage)); memset(storage, 0, sizeof(bitset_storage));
sls_bitset bits = *(sls_bitset*)(buffer + sizeof(sls_detector_header)); sls_bitset bits = *(sls_bitset *)(buffer + sizeof(sls_detector_header));
for (int i = 0; i < MAX_NUM_PACKETS; ++i) for (int i = 0; i < MAX_NUM_PACKETS; ++i)
storage[i >> 3] |= (bits[i] << (i & 7)); storage[i >> 3] |= (bits[i] << (i & 7));
// write bitmask // write bitmask
ret += WriteData((char*)storage, sizeof(bitset_storage)); ret += WriteData((char *)storage, sizeof(bitset_storage));
// write data // write data
ret += WriteData(buffer + sizeof(sls_detector_header), ret += WriteData(buffer + sizeof(sls_detector_header),
buffersize - sizeof(sls_receiver_header)); buffersize - sizeof(sls_receiver_header));
} }
// if write error // if write error
if (ret != buffersize) { if (ret != buffersize) {
throw sls::RuntimeError(std::to_string(index) + " : Write to file failed for image number " + throw sls::RuntimeError(std::to_string(index) +
" : Write to file failed for image number " +
std::to_string(currentFrameNumber)); std::to_string(currentFrameNumber));
} }
} }
void BinaryFile::CreateMasterFile(bool masterFileWriteEnable,
void BinaryFile::CreateMasterFile(bool masterFileWriteEnable, masterAttributes& masterFileAttributes) { masterAttributes &masterFileAttributes) {
//beginning of every acquisition // beginning of every acquisition
numFramesInFile = 0; numFramesInFile = 0;
numActualPacketsInFile = 0; numActualPacketsInFile = 0;
@ -145,22 +146,26 @@ void BinaryFile::CreateMasterFile(bool masterFileWriteEnable, masterAttributes&
os << *filePath << "/" << *fileNamePrefix << "_master" os << *filePath << "/" << *fileNamePrefix << "_master"
<< "_" << *fileIndex << ".raw"; << "_" << *fileIndex << ".raw";
masterFileName = os.str(); masterFileName = os.str();
if(!(*silentMode)) { if (!(*silentMode)) {
LOG(logINFO) << "Master File: " << masterFileName; LOG(logINFO) << "Master File: " << masterFileName;
} }
masterFileAttributes.version = BINARY_WRITER_VERSION; masterFileAttributes.version = BINARY_WRITER_VERSION;
// create master file // create master file
if (!(*overWriteEnable)){ if (!(*overWriteEnable)) {
if (NULL == (masterfd = fopen((const char *) masterFileName.c_str(), "wx"))) { if (NULL == (masterfd = fopen((const char *)masterFileName.c_str(),
"wx"))) {
masterfd = 0; masterfd = 0;
throw sls::RuntimeError("Could not create binary master file " throw sls::RuntimeError("Could not create binary master file "
"(without overwrite enable) " + masterFileName); "(without overwrite enable) " +
masterFileName);
} }
}else if (NULL == (masterfd = fopen((const char *) masterFileName.c_str(), "w"))) { } else if (NULL == (masterfd = fopen(
(const char *)masterFileName.c_str(), "w"))) {
masterfd = 0; masterfd = 0;
throw sls::RuntimeError("Could not create binary master file " throw sls::RuntimeError("Could not create binary master file "
"(with overwrite enable) " + masterFileName); "(with overwrite enable) " +
masterFileName);
} }
// create master file data // create master file data
time_t t = time(0); time_t t = time(0);
@ -202,14 +207,10 @@ void BinaryFile::CreateMasterFile(bool masterFileWriteEnable, masterAttributes&
"Round Robin Number : 2 bytes\n" "Round Robin Number : 2 bytes\n"
"Detector Type : 1 byte\n" "Detector Type : 1 byte\n"
"Header Version : 1 byte\n" "Header Version : 1 byte\n"
"Packets Caught Mask : 64 bytes\n" "Packets Caught Mask : 64 bytes\n",
, masterFileAttributes.version, masterFileAttributes.detectorType,
masterFileAttributes.version, masterFileAttributes.dynamicRange, masterFileAttributes.tenGiga,
masterFileAttributes.detectorType, masterFileAttributes.imageSize, masterFileAttributes.nPixelsX,
masterFileAttributes.dynamicRange,
masterFileAttributes.tenGiga,
masterFileAttributes.imageSize,
masterFileAttributes.nPixelsX,
masterFileAttributes.nPixelsY, masterFileAttributes.nPixelsY,
masterFileAttributes.maxFramesPerFile, masterFileAttributes.maxFramesPerFile,
(long long int)masterFileAttributes.totalFrames, (long long int)masterFileAttributes.totalFrames,
@ -219,25 +220,25 @@ void BinaryFile::CreateMasterFile(bool masterFileWriteEnable, masterAttributes&
(long long int)masterFileAttributes.periodNs, (long long int)masterFileAttributes.periodNs,
masterFileAttributes.quadEnable, masterFileAttributes.quadEnable,
masterFileAttributes.analogFlag, masterFileAttributes.analogFlag,
masterFileAttributes.digitalFlag, masterFileAttributes.digitalFlag, masterFileAttributes.adcmask,
masterFileAttributes.adcmask,
masterFileAttributes.dbitoffset, masterFileAttributes.dbitoffset,
(long long int)masterFileAttributes.dbitlist, (long long int)masterFileAttributes.dbitlist,
masterFileAttributes.roiXmin, masterFileAttributes.roiXmin, masterFileAttributes.roiXmax,
masterFileAttributes.roiXmax,
ctime(&t)); ctime(&t));
if (strlen(message) > maxMasterFileSize) { if (strlen(message) > maxMasterFileSize) {
throw sls::RuntimeError("Master File Size " + std::to_string(strlen(message)) + throw sls::RuntimeError("Master File Size " +
" is greater than max str size " + std::to_string(maxMasterFileSize)); std::to_string(strlen(message)) +
" is greater than max str size " +
std::to_string(maxMasterFileSize));
} }
// write and close file // write and close file
if (fwrite((void*)message, 1, strlen(message), masterfd) != strlen(message)) { if (fwrite((void *)message, 1, strlen(message), masterfd) !=
throw sls::RuntimeError("Master binary file incorrect number of bytes written to file"); strlen(message)) {
throw sls::RuntimeError(
"Master binary file incorrect number of bytes written to file");
} }
if (masterfd) if (masterfd)
fclose(masterfd); fclose(masterfd);
masterfd = 0; masterfd = 0;
} }
} }

24
slsReceiverSoftware/src/BinaryFile.h Executable file → Normal file
View File

@ -5,14 +5,14 @@
* creates/closes the file and writes data to it * creates/closes the file and writes data to it
***********************************************/ ***********************************************/
/** /**
*@short sets/gets properties for the binary file, creates/closes the file and writes data to it *@short sets/gets properties for the binary file, creates/closes the file and
*writes data to it
*/ */
#include "File.h" #include "File.h"
#include <string> #include <string>
class BinaryFile : private virtual slsDetectorDefs, public File { class BinaryFile : private virtual slsDetectorDefs, public File {
public: public:
@ -33,29 +33,27 @@ class BinaryFile : private virtual slsDetectorDefs, public File {
* @param portno pointer to udp port number for logging * @param portno pointer to udp port number for logging
* @param smode pointer to silent mode * @param smode pointer to silent mode
*/ */
BinaryFile(int ind, uint32_t* maxf, BinaryFile(int ind, uint32_t *maxf, int *nd, std::string *fname,
int* nd, std::string* fname, std::string* fpath, uint64_t* findex, bool* owenable, std::string *fpath, uint64_t *findex, bool *owenable,
int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
bool* smode); uint32_t *portno, bool *smode);
~BinaryFile(); ~BinaryFile();
void PrintMembers(TLogLevel level = logDEBUG1) override; void PrintMembers(TLogLevel level = logDEBUG1) override;
void CreateFile() override; void CreateFile() override;
void CreateMasterFile(bool masterFileWriteEnable, void CreateMasterFile(bool masterFileWriteEnable,
masterAttributes& masterFileAttributes) override; masterAttributes &masterFileAttributes) override;
void CloseCurrentFile() override; void CloseCurrentFile() override;
void CloseAllFiles() override; void CloseAllFiles() override;
void WriteToFile(char* buffer, int buffersize, uint64_t currentFrameNumber, void WriteToFile(char *buffer, int buffersize, uint64_t currentFrameNumber,
uint32_t numPacketsCaught) override; uint32_t numPacketsCaught) override;
private: private:
int WriteData(char* buf, int bsize); int WriteData(char *buf, int bsize);
FILE* filefd; FILE *filefd;
static FILE* masterfd; static FILE *masterfd;
uint32_t numFramesInFile; uint32_t numFramesInFile;
uint64_t numActualPacketsInFile; uint64_t numActualPacketsInFile;
const size_t maxMasterFileSize; const size_t maxMasterFileSize;
}; };

247
slsReceiverSoftware/src/ClientInterface.cpp Executable file → Normal file
View File

@ -1,22 +1,22 @@
#include "ClientInterface.h" #include "ClientInterface.h"
#include "FixedCapacityContainer.h" #include "FixedCapacityContainer.h"
#include "ServerSocket.h" #include "ServerSocket.h"
#include "ToString.h"
#include "sls_detector_exceptions.h" #include "sls_detector_exceptions.h"
#include "string_utils.h" #include "string_utils.h"
#include "versionAPI.h" #include "versionAPI.h"
#include "ToString.h"
#include <array> #include <array>
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <map>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <unistd.h> #include <unistd.h>
#include <map> #include <vector>
using sls::RuntimeError; using sls::RuntimeError;
using sls::SocketError; using sls::SocketError;
@ -36,20 +36,23 @@ ClientInterface::ClientInterface(int portNumber)
server(portNumber) { server(portNumber) {
functionTable(); functionTable();
// start up tcp thread // start up tcp thread
tcpThread = sls::make_unique<std::thread>(&ClientInterface::startTCPServer, this); tcpThread =
sls::make_unique<std::thread>(&ClientInterface::startTCPServer, this);
} }
int64_t ClientInterface::getReceiverVersion() { return APIRECEIVER; } int64_t ClientInterface::getReceiverVersion() { return APIRECEIVER; }
/***callback functions***/ /***callback functions***/
void ClientInterface::registerCallBackStartAcquisition( void ClientInterface::registerCallBackStartAcquisition(
int (*func)(std::string, std::string, uint64_t, uint32_t, void *), void *arg) { int (*func)(std::string, std::string, uint64_t, uint32_t, void *),
void *arg) {
startAcquisitionCallBack = func; startAcquisitionCallBack = func;
pStartAcquisition = arg; pStartAcquisition = arg;
} }
void ClientInterface::registerCallBackAcquisitionFinished( void ClientInterface::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
void (*func)(uint64_t, void *), void *arg) { void *),
void *arg) {
acquisitionFinishedCallBack = func; acquisitionFinishedCallBack = func;
pAcquisitionFinished = arg; pAcquisitionFinished = arg;
} }
@ -67,9 +70,10 @@ void ClientInterface::registerCallBackRawDataModifyReady(
} }
void ClientInterface::startTCPServer() { void ClientInterface::startTCPServer() {
LOG(logINFOBLUE) << "Created [ TCP server Tid: " << syscall(SYS_gettid) << "]"; LOG(logINFOBLUE) << "Created [ TCP server Tid: " << syscall(SYS_gettid)
LOG(logINFO) << "SLS Receiver starting TCP Server on port " << "]";
<< portNumber << '\n'; LOG(logINFO) << "SLS Receiver starting TCP Server on port " << portNumber
<< '\n';
// server = sls::make_unique<sls::ServerSocket>(portNumber); // server = sls::make_unique<sls::ServerSocket>(portNumber);
while (!killTcpThread) { while (!killTcpThread) {
LOG(logDEBUG1) << "Start accept loop"; LOG(logDEBUG1) << "Start accept loop";
@ -97,7 +101,8 @@ void ClientInterface::startTCPServer() {
if (receiver) { if (receiver) {
receiver->shutDownUDPSockets(); receiver->shutDownUDPSockets();
} }
LOG(logINFOBLUE) << "Exiting [ TCP server Tid: " << syscall(SYS_gettid) << "]"; LOG(logINFOBLUE) << "Exiting [ TCP server Tid: " << syscall(SYS_gettid)
<< "]";
} }
// clang-format off // clang-format off
@ -208,11 +213,10 @@ int ClientInterface::decodeFunction(Interface &socket) {
std::to_string(fnum) + "\n"); std::to_string(fnum) + "\n");
} else { } else {
LOG(logDEBUG1) << "calling function fnum: " << fnum << " (" LOG(logDEBUG1) << "calling function fnum: " << fnum << " ("
<< getFunctionNameFromEnum((enum detFuncs)fnum) << getFunctionNameFromEnum((enum detFuncs)fnum) << ")";
<< ")";
ret = (this->*flist[fnum])(socket); ret = (this->*flist[fnum])(socket);
LOG(logDEBUG1) LOG(logDEBUG1) << "Function "
<< "Function " << getFunctionNameFromEnum((enum detFuncs)fnum) << getFunctionNameFromEnum((enum detFuncs)fnum)
<< " finished"; << " finished";
} }
return ret; return ret;
@ -233,7 +237,7 @@ void ClientInterface::modeNotImplemented(const std::string &modename,
} }
template <typename T> template <typename T>
void ClientInterface::validate(T arg, T retval, const std::string& modename, void ClientInterface::validate(T arg, T retval, const std::string &modename,
numberMode hex) { numberMode hex) {
if (ret == OK && arg != -1 && retval != arg) { if (ret == OK && arg != -1 && retval != arg) {
auto format = (hex == HEX) ? std::hex : std::dec; auto format = (hex == HEX) ? std::hex : std::dec;
@ -254,7 +258,8 @@ void ClientInterface::verifyLock() {
void ClientInterface::verifyIdle(Interface &socket) { void ClientInterface::verifyIdle(Interface &socket) {
if (impl()->getStatus() != IDLE) { if (impl()->getStatus() != IDLE) {
std::ostringstream oss; std::ostringstream oss;
oss << "Can not execute " << getFunctionNameFromEnum((enum detFuncs)fnum) oss << "Can not execute "
<< getFunctionNameFromEnum((enum detFuncs)fnum)
<< " when receiver is not idle"; << " when receiver is not idle";
throw sls::SocketError(oss.str()); throw sls::SocketError(oss.str());
} }
@ -292,7 +297,8 @@ int ClientInterface::lock_receiver(Interface &socket) {
auto lock = socket.Receive<int>(); auto lock = socket.Receive<int>();
LOG(logDEBUG1) << "Locking Server to " << lock; LOG(logDEBUG1) << "Locking Server to " << lock;
if (lock >= 0) { if (lock >= 0) {
if (!lockedByClient || (server.getLockedBy() == server.getThisClient())) { if (!lockedByClient ||
(server.getLockedBy() == server.getThisClient())) {
lockedByClient = lock; lockedByClient = lock;
lock ? server.setLockedBy(server.getThisClient()) lock ? server.setLockedBy(server.getThisClient())
: server.setLockedBy(sls::IpAddr{}); : server.setLockedBy(sls::IpAddr{});
@ -328,8 +334,7 @@ int ClientInterface::get_version(Interface &socket) {
int ClientInterface::setup_receiver(Interface &socket) { int ClientInterface::setup_receiver(Interface &socket) {
auto arg = socket.Receive<rxParameters>(); auto arg = socket.Receive<rxParameters>();
LOG(logDEBUG1) LOG(logDEBUG1) << "detType:" << arg.detType << std::endl
<< "detType:" << arg.detType << std::endl
<< "multiSize.x:" << arg.multiSize.x << std::endl << "multiSize.x:" << arg.multiSize.x << std::endl
<< "multiSize.y:" << arg.multiSize.y << std::endl << "multiSize.y:" << arg.multiSize.y << std::endl
<< "detId:" << arg.detId << std::endl << "detId:" << arg.detId << std::endl
@ -340,7 +345,8 @@ int ClientInterface::setup_receiver(Interface &socket) {
<< "udp_dstmac:" << sls::MacAddr(arg.udp_dstmac) << std::endl << "udp_dstmac:" << sls::MacAddr(arg.udp_dstmac) << std::endl
<< "udp_dstport2:" << arg.udp_dstport2 << std::endl << "udp_dstport2:" << arg.udp_dstport2 << std::endl
<< "udp_dstip2:" << sls::IpAddr(arg.udp_dstip2) << std::endl << "udp_dstip2:" << sls::IpAddr(arg.udp_dstip2) << std::endl
<< "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2) << std::endl << "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2)
<< std::endl
<< "frames:" << arg.frames << std::endl << "frames:" << arg.frames << std::endl
<< "triggers:" << arg.triggers << std::endl << "triggers:" << arg.triggers << std::endl
<< "bursts:" << arg.bursts << std::endl << "bursts:" << arg.bursts << std::endl
@ -363,7 +369,6 @@ int ClientInterface::setup_receiver(Interface &socket) {
<< "countermask:" << arg.countermask << std::endl << "countermask:" << arg.countermask << std::endl
<< "burstType:" << arg.burstType << std::endl; << "burstType:" << arg.burstType << std::endl;
// if object exists, verify unlocked and idle, else only verify lock // if object exists, verify unlocked and idle, else only verify lock
// (connecting first time) // (connecting first time)
if (receiver != nullptr) { if (receiver != nullptr) {
@ -392,7 +397,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == JUNGFRAU) { if (myDetectorType == JUNGFRAU) {
try { try {
impl()->setNumberofUDPInterfaces(arg.udpInterfaces); impl()->setNumberofUDPInterfaces(arg.udpInterfaces);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Failed to set number of interfaces to " + throw RuntimeError("Failed to set number of interfaces to " +
std::to_string(arg.udpInterfaces)); std::to_string(arg.udpInterfaces));
} }
@ -408,7 +413,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == MOENCH || myDetectorType == CHIPTESTBOARD) { if (myDetectorType == MOENCH || myDetectorType == CHIPTESTBOARD) {
try { try {
impl()->setNumberofAnalogSamples(arg.analogSamples); impl()->setNumberofAnalogSamples(arg.analogSamples);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set num analog samples to " + throw RuntimeError("Could not set num analog samples to " +
std::to_string(arg.analogSamples) + std::to_string(arg.analogSamples) +
" due to fifo structure memory allocation."); " due to fifo structure memory allocation.");
@ -417,9 +422,9 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == CHIPTESTBOARD) { if (myDetectorType == CHIPTESTBOARD) {
try { try {
impl()->setNumberofDigitalSamples(arg.digitalSamples); impl()->setNumberofDigitalSamples(arg.digitalSamples);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set num digital samples to " throw RuntimeError("Could not set num digital samples to " +
+ std::to_string(arg.analogSamples) + std::to_string(arg.analogSamples) +
" due to fifo structure memory allocation."); " due to fifo structure memory allocation.");
} }
} }
@ -431,7 +436,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
impl()->setActivate(static_cast<bool>(arg.activate)); impl()->setActivate(static_cast<bool>(arg.activate));
try { try {
impl()->setQuad(arg.quad == 0 ? false : true); impl()->setQuad(arg.quad == 0 ? false : true);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set quad to " + throw RuntimeError("Could not set quad to " +
std::to_string(arg.quad) + std::to_string(arg.quad) +
" due to fifo strucutre memory allocation"); " due to fifo strucutre memory allocation");
@ -440,8 +445,9 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) { if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
try { try {
impl()->setDynamicRange(arg.dynamicRange); impl()->setDynamicRange(arg.dynamicRange);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set dynamic range. Could not allocate " throw RuntimeError(
"Could not set dynamic range. Could not allocate "
"memory for fifo or could not start listening/writing threads"); "memory for fifo or could not start listening/writing threads");
} }
} }
@ -450,14 +456,14 @@ int ClientInterface::setup_receiver(Interface &socket) {
myDetectorType == CHIPTESTBOARD) { myDetectorType == CHIPTESTBOARD) {
try { try {
impl()->setTenGigaEnable(arg.tenGiga); impl()->setTenGigaEnable(arg.tenGiga);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10GbE."); throw RuntimeError("Could not set 10GbE.");
} }
} }
if (myDetectorType == CHIPTESTBOARD) { if (myDetectorType == CHIPTESTBOARD) {
try { try {
impl()->setReadoutMode(arg.roMode); impl()->setReadoutMode(arg.roMode);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set read out mode " throw RuntimeError("Could not set read out mode "
"due to fifo memory allocation."); "due to fifo memory allocation.");
} }
@ -465,13 +471,13 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == CHIPTESTBOARD || myDetectorType == MOENCH) { if (myDetectorType == CHIPTESTBOARD || myDetectorType == MOENCH) {
try { try {
impl()->setADCEnableMask(arg.adcMask); impl()->setADCEnableMask(arg.adcMask);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set adc enable mask " throw RuntimeError("Could not set adc enable mask "
"due to fifo memory allcoation"); "due to fifo memory allcoation");
} }
try { try {
impl()->setTenGigaADCEnableMask(arg.adc10gMask); impl()->setTenGigaADCEnableMask(arg.adc10gMask);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10Gb adc enable mask " throw RuntimeError("Could not set 10Gb adc enable mask "
"due to fifo memory allcoation"); "due to fifo memory allcoation");
} }
@ -479,7 +485,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == GOTTHARD) { if (myDetectorType == GOTTHARD) {
try { try {
impl()->setROI(arg.roi); impl()->setROI(arg.roi);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set ROI"); throw RuntimeError("Could not set ROI");
} }
} }
@ -522,14 +528,14 @@ void ClientInterface::setDetectorType(detectorType arg) {
impl()->registerCallBackStartAcquisition(startAcquisitionCallBack, impl()->registerCallBackStartAcquisition(startAcquisitionCallBack,
pStartAcquisition); pStartAcquisition);
if (acquisitionFinishedCallBack != nullptr) if (acquisitionFinishedCallBack != nullptr)
impl()->registerCallBackAcquisitionFinished( impl()->registerCallBackAcquisitionFinished(acquisitionFinishedCallBack,
acquisitionFinishedCallBack, pAcquisitionFinished); pAcquisitionFinished);
if (rawDataReadyCallBack != nullptr) if (rawDataReadyCallBack != nullptr)
impl()->registerCallBackRawDataReady(rawDataReadyCallBack, impl()->registerCallBackRawDataReady(rawDataReadyCallBack,
pRawDataReady); pRawDataReady);
if (rawDataModifyReadyCallBack != nullptr) if (rawDataModifyReadyCallBack != nullptr)
impl()->registerCallBackRawDataModifyReady( impl()->registerCallBackRawDataModifyReady(rawDataModifyReadyCallBack,
rawDataModifyReadyCallBack, pRawDataReady); pRawDataReady);
} }
int ClientInterface::set_roi(Interface &socket) { int ClientInterface::set_roi(Interface &socket) {
@ -544,7 +550,7 @@ int ClientInterface::set_roi(Interface &socket) {
verifyIdle(socket); verifyIdle(socket);
try { try {
impl()->setROI(arg); impl()->setROI(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set ROI"); throw RuntimeError("Could not set ROI");
} }
return socket.Send(OK); return socket.Send(OK);
@ -553,8 +559,7 @@ int ClientInterface::set_roi(Interface &socket) {
int ClientInterface::set_num_frames(Interface &socket) { int ClientInterface::set_num_frames(Interface &socket) {
auto value = socket.Receive<int64_t>(); auto value = socket.Receive<int64_t>();
if (value <= 0) { if (value <= 0) {
throw RuntimeError("Invalid number of frames " + throw RuntimeError("Invalid number of frames " + std::to_string(value));
std::to_string(value));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting num frames to " << value; LOG(logDEBUG1) << "Setting num frames to " << value;
@ -581,8 +586,7 @@ int ClientInterface::set_num_triggers(Interface &socket) {
int ClientInterface::set_num_bursts(Interface &socket) { int ClientInterface::set_num_bursts(Interface &socket) {
auto value = socket.Receive<int64_t>(); auto value = socket.Receive<int64_t>();
if (value <= 0) { if (value <= 0) {
throw RuntimeError("Invalid number of bursts " + throw RuntimeError("Invalid number of bursts " + std::to_string(value));
std::to_string(value));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting num bursts to " << value; LOG(logDEBUG1) << "Setting num bursts to " << value;
@ -609,8 +613,7 @@ int ClientInterface::set_num_add_storage_cells(Interface &socket) {
int ClientInterface::set_timing_mode(Interface &socket) { int ClientInterface::set_timing_mode(Interface &socket) {
auto value = socket.Receive<int>(); auto value = socket.Receive<int>();
if (value < 0 || value >= NUM_TIMING_MODES) { if (value < 0 || value >= NUM_TIMING_MODES) {
throw RuntimeError("Invalid timing mode " + throw RuntimeError("Invalid timing mode " + std::to_string(value));
std::to_string(value));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting timing mode to " << value; LOG(logDEBUG1) << "Setting timing mode to " << value;
@ -623,8 +626,7 @@ int ClientInterface::set_timing_mode(Interface &socket) {
int ClientInterface::set_burst_mode(Interface &socket) { int ClientInterface::set_burst_mode(Interface &socket) {
auto value = socket.Receive<int>(); auto value = socket.Receive<int>();
if (value < 0 || value >= NUM_BURST_MODES) { if (value < 0 || value >= NUM_BURST_MODES) {
throw RuntimeError("Invalid burst mode " + throw RuntimeError("Invalid burst mode " + std::to_string(value));
std::to_string(value));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting burst mode to " << value; LOG(logDEBUG1) << "Setting burst mode to " << value;
@ -642,8 +644,10 @@ int ClientInterface::set_num_analog_samples(Interface &socket) {
} }
try { try {
impl()->setNumberofAnalogSamples(value); impl()->setNumberofAnalogSamples(value);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set num analog samples to " + std::to_string(value) + " due to fifo structure memory allocation."); throw RuntimeError("Could not set num analog samples to " +
std::to_string(value) +
" due to fifo structure memory allocation.");
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -656,8 +660,10 @@ int ClientInterface::set_num_digital_samples(Interface &socket) {
} }
try { try {
impl()->setNumberofDigitalSamples(value); impl()->setNumberofDigitalSamples(value);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set num digital samples to " + std::to_string(value) + " due to fifo structure memory allocation."); throw RuntimeError("Could not set num digital samples to " +
std::to_string(value) +
" due to fifo structure memory allocation.");
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -689,7 +695,8 @@ int ClientInterface::set_subdeadtime(Interface &socket) {
auto value = socket.Receive<int64_t>(); auto value = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Setting sub deadtime to " << value << "ns"; LOG(logDEBUG1) << "Setting sub deadtime to " << value << "ns";
impl()->setSubPeriod(value + impl()->getSubExpTime()); impl()->setSubPeriod(value + impl()->getSubExpTime());
LOG(logDEBUG1) << "Setting sub period to " << impl()->getSubPeriod() << "ns"; LOG(logDEBUG1) << "Setting sub period to " << impl()->getSubPeriod()
<< "ns";
return socket.Send(OK); return socket.Send(OK);
} }
@ -699,7 +706,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting dynamic range: " << dr; LOG(logDEBUG1) << "Setting dynamic range: " << dr;
bool exists = false; bool exists = false;
switch(myDetectorType) { switch (myDetectorType) {
case EIGER: case EIGER:
if (dr == 4 || dr == 8 || dr == 16 || dr == 32) { if (dr == 4 || dr == 8 || dr == 16 || dr == 32) {
exists = true; exists = true;
@ -721,7 +728,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
} else { } else {
try { try {
impl()->setDynamicRange(dr); impl()->setDynamicRange(dr);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not allocate memory for fifo or " throw RuntimeError("Could not allocate memory for fifo or "
"could not start listening/writing threads"); "could not start listening/writing threads");
} }
@ -736,8 +743,8 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
int ClientInterface::set_streaming_frequency(Interface &socket) { int ClientInterface::set_streaming_frequency(Interface &socket) {
auto index = socket.Receive<int>(); auto index = socket.Receive<int>();
if (index < 0) { if (index < 0) {
throw RuntimeError("Invalid streaming frequency: " throw RuntimeError("Invalid streaming frequency: " +
+ std::to_string(index)); std::to_string(index));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting streaming frequency: " << index; LOG(logDEBUG1) << "Setting streaming frequency: " << index;
@ -791,7 +798,7 @@ int ClientInterface::set_file_dir(Interface &socket) {
if (strlen(fPath) == 0) { if (strlen(fPath) == 0) {
throw RuntimeError("Cannot set empty file path"); throw RuntimeError("Cannot set empty file path");
} }
if(fPath[0] != '/') if (fPath[0] != '/')
throw RuntimeError("Receiver path needs to be absolute path"); throw RuntimeError("Receiver path needs to be absolute path");
LOG(logDEBUG1) << "Setting file path: " << fPath; LOG(logDEBUG1) << "Setting file path: " << fPath;
impl()->setFilePath(fPath); impl()->setFilePath(fPath);
@ -841,8 +848,7 @@ int ClientInterface::get_file_name(Interface &socket) {
int ClientInterface::set_file_index(Interface &socket) { int ClientInterface::set_file_index(Interface &socket) {
auto index = socket.Receive<int64_t>(); auto index = socket.Receive<int64_t>();
if (index < 0) { if (index < 0) {
throw RuntimeError("Invalid file index: " throw RuntimeError("Invalid file index: " + std::to_string(index));
+ std::to_string(index));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting file index: " << index; LOG(logDEBUG1) << "Setting file index: " << index;
@ -887,7 +893,8 @@ int ClientInterface::get_frames_caught(Interface &socket) {
int ClientInterface::set_file_write(Interface &socket) { int ClientInterface::set_file_write(Interface &socket) {
auto enable = socket.Receive<int>(); auto enable = socket.Receive<int>();
if (enable < 0) { if (enable < 0) {
throw RuntimeError("Invalid file write enable: " + std::to_string(enable)); throw RuntimeError("Invalid file write enable: " +
std::to_string(enable));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting File write enable:" << enable; LOG(logDEBUG1) << "Setting File write enable:" << enable;
@ -908,8 +915,8 @@ int ClientInterface::get_file_write(Interface &socket) {
int ClientInterface::set_master_file_write(Interface &socket) { int ClientInterface::set_master_file_write(Interface &socket) {
auto enable = socket.Receive<int>(); auto enable = socket.Receive<int>();
if (enable < 0) { if (enable < 0) {
throw RuntimeError("Invalid master file write enable: " throw RuntimeError("Invalid master file write enable: " +
+ std::to_string(enable)); std::to_string(enable));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting Master File write enable:" << enable; LOG(logDEBUG1) << "Setting Master File write enable:" << enable;
@ -930,8 +937,8 @@ int ClientInterface::get_master_file_write(Interface &socket) {
int ClientInterface::set_overwrite(Interface &socket) { int ClientInterface::set_overwrite(Interface &socket) {
auto index = socket.Receive<int>(); auto index = socket.Receive<int>();
if (index < 0) { if (index < 0) {
throw RuntimeError("Invalid over write enable: " throw RuntimeError("Invalid over write enable: " +
+ std::to_string(index)); std::to_string(index));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting File overwrite enable:" << index; LOG(logDEBUG1) << "Setting File overwrite enable:" << index;
@ -960,8 +967,8 @@ int ClientInterface::enable_tengiga(Interface &socket) {
LOG(logDEBUG1) << "Setting 10GbE:" << val; LOG(logDEBUG1) << "Setting 10GbE:" << val;
try { try {
impl()->setTenGigaEnable(val); impl()->setTenGigaEnable(val);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10GbE." ); throw RuntimeError("Could not set 10GbE.");
} }
} }
int retval = impl()->getTenGigaEnable(); int retval = impl()->getTenGigaEnable();
@ -977,8 +984,9 @@ int ClientInterface::set_fifo_depth(Interface &socket) {
LOG(logDEBUG1) << "Setting fifo depth:" << value; LOG(logDEBUG1) << "Setting fifo depth:" << value;
try { try {
impl()->setFifoDepth(value); impl()->setFifoDepth(value);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set fifo depth due to fifo structure memory allocation."); throw RuntimeError("Could not set fifo depth due to fifo structure "
"memory allocation.");
} }
} }
int retval = impl()->getFifoDepth(); int retval = impl()->getFifoDepth();
@ -1006,15 +1014,16 @@ int ClientInterface::set_activate(Interface &socket) {
int ClientInterface::set_streaming(Interface &socket) { int ClientInterface::set_streaming(Interface &socket) {
auto index = socket.Receive<int>(); auto index = socket.Receive<int>();
if (index < 0) { if (index < 0) {
throw RuntimeError("Invalid streaming enable: " throw RuntimeError("Invalid streaming enable: " +
+ std::to_string(index)); std::to_string(index));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting data stream enable:" << index; LOG(logDEBUG1) << "Setting data stream enable:" << index;
try { try {
impl()->setDataStreamEnable(index); impl()->setDataStreamEnable(index);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set data stream enable to " + std::to_string(index)); throw RuntimeError("Could not set data stream enable to " +
std::to_string(index));
} }
auto retval = static_cast<int>(impl()->getDataStreamEnable()); auto retval = static_cast<int>(impl()->getDataStreamEnable());
@ -1063,8 +1072,7 @@ int ClientInterface::set_file_format(Interface &socket) {
fileFormat f = GET_FILE_FORMAT; fileFormat f = GET_FILE_FORMAT;
socket.Receive(f); socket.Receive(f);
if (f < 0 || f > NUM_FILE_FORMATS) { if (f < 0 || f > NUM_FILE_FORMATS) {
throw RuntimeError("Invalid file format: " throw RuntimeError("Invalid file format: " + std::to_string(f));
+ std::to_string(f));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting file format:" << f; LOG(logDEBUG1) << "Setting file format:" << f;
@ -1117,8 +1125,8 @@ int ClientInterface::set_streaming_source_ip(Interface &socket) {
LOG(logDEBUG1) << "streaming IP:" << retval; LOG(logDEBUG1) << "streaming IP:" << retval;
if (retval != arg && arg != 0) { if (retval != arg && arg != 0) {
std::ostringstream os; std::ostringstream os;
os << "Could not set streaming ip. Set " << arg os << "Could not set streaming ip. Set " << arg << ", but read "
<< ", but read " << retval << '\n'; << retval << '\n';
throw RuntimeError(os.str()); throw RuntimeError(os.str());
} }
return socket.Send(OK); return socket.Send(OK);
@ -1133,8 +1141,7 @@ int ClientInterface::get_streaming_source_ip(Interface &socket) {
int ClientInterface::set_silent_mode(Interface &socket) { int ClientInterface::set_silent_mode(Interface &socket) {
auto value = socket.Receive<int>(); auto value = socket.Receive<int>();
if (value < 0) { if (value < 0) {
throw RuntimeError("Invalid silent mode: " throw RuntimeError("Invalid silent mode: " + std::to_string(value));
+ std::to_string(value));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting silent mode:" << value; LOG(logDEBUG1) << "Setting silent mode:" << value;
@ -1190,7 +1197,7 @@ int ClientInterface::get_additional_json_header(Interface &socket) {
char retvals[size * 2][SHORT_STR_LENGTH]; char retvals[size * 2][SHORT_STR_LENGTH];
memset(retvals, 0, sizeof(retvals)); memset(retvals, 0, sizeof(retvals));
int iarg = 0; int iarg = 0;
for (auto & it : json) { for (auto &it : json) {
sls::strcpy_safe(retvals[iarg], it.first.c_str()); sls::strcpy_safe(retvals[iarg], it.first.c_str());
sls::strcpy_safe(retvals[iarg + 1], it.second.c_str()); sls::strcpy_safe(retvals[iarg + 1], it.second.c_str());
iarg += 2; iarg += 2;
@ -1216,8 +1223,7 @@ int ClientInterface::set_udp_socket_buffer_size(Interface &socket) {
return socket.sendResult(retval); return socket.sendResult(retval);
} }
int ClientInterface::get_real_udp_socket_buffer_size( int ClientInterface::get_real_udp_socket_buffer_size(Interface &socket) {
Interface &socket) {
auto size = impl()->getActualUDPSocketBufferSize(); auto size = impl()->getActualUDPSocketBufferSize();
LOG(logDEBUG1) << "Actual UDP socket size :" << size; LOG(logDEBUG1) << "Actual UDP socket size :" << size;
return socket.sendResult(size); return socket.sendResult(size);
@ -1226,8 +1232,7 @@ int ClientInterface::get_real_udp_socket_buffer_size(
int ClientInterface::set_frames_per_file(Interface &socket) { int ClientInterface::set_frames_per_file(Interface &socket) {
auto index = socket.Receive<int>(); auto index = socket.Receive<int>();
if (index < 0) { if (index < 0) {
throw RuntimeError("Invalid frames per file: " throw RuntimeError("Invalid frames per file: " + std::to_string(index));
+ std::to_string(index));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting frames per file: " << index; LOG(logDEBUG1) << "Setting frames per file: " << index;
@ -1247,8 +1252,7 @@ int ClientInterface::get_frames_per_file(Interface &socket) {
int ClientInterface::check_version_compatibility(Interface &socket) { int ClientInterface::check_version_compatibility(Interface &socket) {
auto arg = socket.Receive<int64_t>(); auto arg = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Checking versioning compatibility with value " LOG(logDEBUG1) << "Checking versioning compatibility with value " << arg;
<< arg;
int64_t client_requiredVersion = arg; int64_t client_requiredVersion = arg;
int64_t rx_apiVersion = APIRECEIVER; int64_t rx_apiVersion = APIRECEIVER;
int64_t rx_version = getReceiverVersion(); int64_t rx_version = getReceiverVersion();
@ -1314,15 +1318,14 @@ int ClientInterface::get_padding_enable(Interface &socket) {
return socket.sendResult(retval); return socket.sendResult(retval);
} }
int ClientInterface::set_deactivated_padding_enable( int ClientInterface::set_deactivated_padding_enable(Interface &socket) {
Interface &socket) {
auto enable = socket.Receive<int>(); auto enable = socket.Receive<int>();
if (myDetectorType != EIGER) { if (myDetectorType != EIGER) {
functionNotImplemented(); functionNotImplemented();
} }
if (enable < 0) { if (enable < 0) {
throw RuntimeError("Invalid Deactivated padding: " throw RuntimeError("Invalid Deactivated padding: " +
+ std::to_string(enable)); std::to_string(enable));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting deactivated padding enable: " << enable; LOG(logDEBUG1) << "Setting deactivated padding enable: " << enable;
@ -1334,8 +1337,7 @@ int ClientInterface::set_deactivated_padding_enable(
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::get_deactivated_padding_enable( int ClientInterface::get_deactivated_padding_enable(Interface &socket) {
Interface &socket) {
if (myDetectorType != EIGER) if (myDetectorType != EIGER)
functionNotImplemented(); functionNotImplemented();
auto retval = static_cast<int>(impl()->getDeactivatedPadding()); auto retval = static_cast<int>(impl()->getDeactivatedPadding());
@ -1354,8 +1356,9 @@ int ClientInterface::set_readout_mode(Interface &socket) {
LOG(logDEBUG1) << "Setting readout mode: " << arg; LOG(logDEBUG1) << "Setting readout mode: " << arg;
try { try {
impl()->setReadoutMode(arg); impl()->setReadoutMode(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set read out mode due to fifo memory allocation."); throw RuntimeError(
"Could not set read out mode due to fifo memory allocation.");
} }
} }
auto retval = impl()->getReadoutMode(); auto retval = impl()->getReadoutMode();
@ -1371,8 +1374,9 @@ int ClientInterface::set_adc_mask(Interface &socket) {
LOG(logDEBUG1) << "Setting 1Gb ADC enable mask: " << arg; LOG(logDEBUG1) << "Setting 1Gb ADC enable mask: " << arg;
try { try {
impl()->setADCEnableMask(arg); impl()->setADCEnableMask(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set adc enable mask due to fifo memory allcoation"); throw RuntimeError(
"Could not set adc enable mask due to fifo memory allcoation");
} }
auto retval = impl()->getADCEnableMask(); auto retval = impl()->getADCEnableMask();
if (retval != arg) { if (retval != arg) {
@ -1414,8 +1418,7 @@ int ClientInterface::set_dbit_offset(Interface &socket) {
if (myDetectorType != CHIPTESTBOARD) if (myDetectorType != CHIPTESTBOARD)
functionNotImplemented(); functionNotImplemented();
if (arg < 0) { if (arg < 0) {
throw RuntimeError("Invalid dbit offset: " throw RuntimeError("Invalid dbit offset: " + std::to_string(arg));
+ std::to_string(arg));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting Dbit offset: " << arg; LOG(logDEBUG1) << "Setting Dbit offset: " << arg;
@ -1442,8 +1445,10 @@ int ClientInterface::set_quad_type(Interface &socket) {
LOG(logDEBUG1) << "Setting quad:" << quadEnable; LOG(logDEBUG1) << "Setting quad:" << quadEnable;
try { try {
impl()->setQuad(quadEnable == 0 ? false : true); impl()->setQuad(quadEnable == 0 ? false : true);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set quad to " + std::to_string(quadEnable) + " due to fifo strucutre memory allocation"); throw RuntimeError("Could not set quad to " +
std::to_string(quadEnable) +
" due to fifo strucutre memory allocation");
} }
} }
int retval = impl()->getQuad() ? 1 : 0; int retval = impl()->getQuad() ? 1 : 0;
@ -1469,11 +1474,13 @@ sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
// getting eth // getting eth
std::string eth = sls::IpToInterfaceName(arg.str()); std::string eth = sls::IpToInterfaceName(arg.str());
if (eth == "none") { if (eth == "none") {
throw RuntimeError("Failed to get udp ethernet interface from IP " + arg.str()); throw RuntimeError("Failed to get udp ethernet interface from IP " +
arg.str());
} }
if (eth.find('.') != std::string::npos) { if (eth.find('.') != std::string::npos) {
eth = ""; eth = "";
LOG(logERROR) << "Failed to get udp ethernet interface from IP " << arg << ". Got " << eth; LOG(logERROR) << "Failed to get udp ethernet interface from IP " << arg
<< ". Got " << eth;
} }
impl()->setEthernetInterface(eth); impl()->setEthernetInterface(eth);
if (myDetectorType == EIGER) { if (myDetectorType == EIGER) {
@ -1482,7 +1489,8 @@ sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
// get mac address // get mac address
auto retval = sls::InterfaceNameToMac(eth); auto retval = sls::InterfaceNameToMac(eth);
if (retval == 0) { if (retval == 0) {
throw RuntimeError("Failed to get udp mac adddress to listen to (eth:" + eth + ", ip:" + arg.str() + ")\n"); throw RuntimeError("Failed to get udp mac adddress to listen to (eth:" +
eth + ", ip:" + arg.str() + ")\n");
} }
return retval; return retval;
} }
@ -1500,18 +1508,22 @@ sls::MacAddr ClientInterface::setUdpIp2(sls::IpAddr arg) {
// getting eth // getting eth
std::string eth = sls::IpToInterfaceName(arg.str()); std::string eth = sls::IpToInterfaceName(arg.str());
if (eth == "none") { if (eth == "none") {
throw RuntimeError("Failed to get udp ethernet interface2 from IP " + arg.str()); throw RuntimeError("Failed to get udp ethernet interface2 from IP " +
arg.str());
} }
if (eth.find('.') != std::string::npos) { if (eth.find('.') != std::string::npos) {
eth = ""; eth = "";
LOG(logERROR) << "Failed to get udp ethernet interface2 from IP " << arg << ". Got " << eth; LOG(logERROR) << "Failed to get udp ethernet interface2 from IP " << arg
<< ". Got " << eth;
} }
impl()->setEthernetInterface2(eth); impl()->setEthernetInterface2(eth);
// get mac address // get mac address
auto retval = sls::InterfaceNameToMac(eth); auto retval = sls::InterfaceNameToMac(eth);
if (retval == 0) { if (retval == 0) {
throw RuntimeError("Failed to get udp mac adddress2 to listen to (eth:" + eth + ", ip:" + arg.str() + ")\n"); throw RuntimeError(
"Failed to get udp mac adddress2 to listen to (eth:" + eth +
", ip:" + arg.str() + ")\n");
} }
return retval; return retval;
} }
@ -1520,7 +1532,8 @@ int ClientInterface::set_udp_ip2(Interface &socket) {
auto arg = socket.Receive<sls::IpAddr>(); auto arg = socket.Receive<sls::IpAddr>();
verifyIdle(socket); verifyIdle(socket);
if (myDetectorType != JUNGFRAU) { if (myDetectorType != JUNGFRAU) {
throw RuntimeError("UDP Destination IP2 not implemented for this detector"); throw RuntimeError(
"UDP Destination IP2 not implemented for this detector");
} }
LOG(logINFO) << "Received UDP IP2: " << arg; LOG(logINFO) << "Received UDP IP2: " << arg;
auto retval = setUdpIp2(arg); auto retval = setUdpIp2(arg);
@ -1540,7 +1553,8 @@ int ClientInterface::set_udp_port2(Interface &socket) {
auto arg = socket.Receive<int>(); auto arg = socket.Receive<int>();
verifyIdle(socket); verifyIdle(socket);
if (myDetectorType != JUNGFRAU && myDetectorType != EIGER) { if (myDetectorType != JUNGFRAU && myDetectorType != EIGER) {
throw RuntimeError("UDP Destination Port2 not implemented for this detector"); throw RuntimeError(
"UDP Destination Port2 not implemented for this detector");
} }
LOG(logDEBUG1) << "Setting UDP Port:" << arg; LOG(logDEBUG1) << "Setting UDP Port:" << arg;
impl()->setUDPPortNumber2(arg); impl()->setUDPPortNumber2(arg);
@ -1552,13 +1566,15 @@ int ClientInterface::set_num_interfaces(Interface &socket) {
arg = (arg > 1 ? 2 : 1); arg = (arg > 1 ? 2 : 1);
verifyIdle(socket); verifyIdle(socket);
if (myDetectorType != JUNGFRAU) { if (myDetectorType != JUNGFRAU) {
throw RuntimeError("Number of interfaces not implemented for this detector"); throw RuntimeError(
"Number of interfaces not implemented for this detector");
} }
LOG(logDEBUG1) << "Setting Number of UDP Interfaces:" << arg; LOG(logDEBUG1) << "Setting Number of UDP Interfaces:" << arg;
try { try {
impl()->setNumberofUDPInterfaces(arg); impl()->setNumberofUDPInterfaces(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Failed to set number of interfaces to " + std::to_string(arg)); throw RuntimeError("Failed to set number of interfaces to " +
std::to_string(arg));
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -1569,8 +1585,9 @@ int ClientInterface::set_adc_mask_10g(Interface &socket) {
LOG(logDEBUG1) << "Setting 10Gb ADC enable mask: " << arg; LOG(logDEBUG1) << "Setting 10Gb ADC enable mask: " << arg;
try { try {
impl()->setTenGigaADCEnableMask(arg); impl()->setTenGigaADCEnableMask(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10Gb adc enable mask due to fifo memory allcoation"); throw RuntimeError(
"Could not set 10Gb adc enable mask due to fifo memory allcoation");
} }
auto retval = impl()->getTenGigaADCEnableMask(); auto retval = impl()->getTenGigaADCEnableMask();
if (retval != arg) { if (retval != arg) {
@ -1600,12 +1617,12 @@ int ClientInterface::increment_file_index(Interface &socket) {
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::set_additional_json_parameter(Interface &socket) { int ClientInterface::set_additional_json_parameter(Interface &socket) {
char args[2][SHORT_STR_LENGTH]{}; char args[2][SHORT_STR_LENGTH]{};
socket.Receive(args); socket.Receive(args);
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting additional json parameter (" << args[0] << "): " << args[1]; LOG(logDEBUG1) << "Setting additional json parameter (" << args[0]
<< "): " << args[1];
impl()->setAdditionalJsonParameter(args[0], args[1]); impl()->setAdditionalJsonParameter(args[0], args[1]);
return socket.Send(OK); return socket.Send(OK);
} }

25
slsReceiverSoftware/src/ClientInterface.h Executable file → Normal file
View File

@ -1,9 +1,8 @@
#pragma once #pragma once
#include "receiver_defs.h"
#include "sls_detector_defs.h"
#include "Implementation.h" #include "Implementation.h"
#include "ServerSocket.h" #include "ServerSocket.h"
class MySocketTCP; #include "receiver_defs.h"
#include "sls_detector_defs.h"
class ServerInterface; class ServerInterface;
#include <atomic> #include <atomic>
@ -22,7 +21,6 @@ class ClientInterface : private virtual slsDetectorDefs {
std::atomic<bool> killTcpThread{false}; std::atomic<bool> killTcpThread{false};
public: public:
virtual ~ClientInterface(); virtual ~ClientInterface();
ClientInterface(int portNumber = -1); ClientInterface(int portNumber = -1);
@ -30,8 +28,9 @@ class ClientInterface : private virtual slsDetectorDefs {
//***callback functions*** //***callback functions***
/** params: filepath, filename, fileindex, datasize */ /** params: filepath, filename, fileindex, datasize */
void registerCallBackStartAcquisition(int (*func)(std::string, std::string, uint64_t, void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
uint32_t, void *), uint64_t, uint32_t,
void *),
void *arg); void *arg);
/** params: total frames caught */ /** params: total frames caught */
@ -43,7 +42,8 @@ class ClientInterface : private virtual slsDetectorDefs {
void *), void *),
void *arg); void *arg);
/** params: sls_receiver_header frame metadata, dataPointer, modified size */ /** params: sls_receiver_header frame metadata, dataPointer, modified size
*/
void registerCallBackRawDataModifyReady(void (*func)(char *, char *, void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
uint32_t &, void *), uint32_t &, void *),
void *arg); void *arg);
@ -53,9 +53,9 @@ class ClientInterface : private virtual slsDetectorDefs {
int functionTable(); int functionTable();
int decodeFunction(sls::ServerInterface &socket); int decodeFunction(sls::ServerInterface &socket);
void functionNotImplemented(); void functionNotImplemented();
void modeNotImplemented(const std::string& modename, int mode); void modeNotImplemented(const std::string &modename, int mode);
template <typename T> template <typename T>
void validate(T arg, T retval, const std::string& modename, numberMode hex); void validate(T arg, T retval, const std::string &modename, numberMode hex);
void verifyLock(); void verifyLock();
void verifyIdle(sls::ServerInterface &socket); void verifyIdle(sls::ServerInterface &socket);
@ -167,8 +167,8 @@ class ClientInterface : private virtual slsDetectorDefs {
//***callback parameters*** //***callback parameters***
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t, uint32_t, int (*startAcquisitionCallBack)(std::string, std::string, uint64_t,
void *) = nullptr; uint32_t, void *) = nullptr;
void *pStartAcquisition{nullptr}; void *pStartAcquisition{nullptr};
void (*acquisitionFinishedCallBack)(uint64_t, void *) = nullptr; void (*acquisitionFinishedCallBack)(uint64_t, void *) = nullptr;
void *pAcquisitionFinished{nullptr}; void *pAcquisitionFinished{nullptr};
@ -176,7 +176,4 @@ class ClientInterface : private virtual slsDetectorDefs {
void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &, void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &,
void *) = nullptr; void *) = nullptr;
void *pRawDataReady{nullptr}; void *pRawDataReady{nullptr};
}; };

293
slsReceiverSoftware/src/DataProcessor.cpp Executable file → Normal file
View File

@ -5,7 +5,6 @@
* and processes data stored in them & writes them to file * and processes data stored in them & writes them to file
***********************************************/ ***********************************************/
#include "DataProcessor.h" #include "DataProcessor.h"
#include "BinaryFile.h" #include "BinaryFile.h"
#include "Fifo.h" #include "Fifo.h"
@ -22,64 +21,40 @@
const std::string DataProcessor::TypeName = "DataProcessor"; const std::string DataProcessor::TypeName = "DataProcessor";
DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo *f,
DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat *ftype, bool fwenable, bool *mfwenable,
fileFormat* ftype, bool fwenable, bool* mfwenable, bool *dsEnable, uint32_t *dr, uint32_t *freq,
bool* dsEnable, uint32_t* dr, uint32_t *timer, bool *fp, bool *act,
uint32_t* freq, uint32_t* timer, bool *depaden, bool *sm, bool *qe,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, std::vector<int> *cdl, int *cdo, int *cad)
std::vector <int> * cdl, int* cdo, int* cad) : : ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype),
ThreadObject(ind, TypeName), dataStreamEnable(dsEnable), fileFormatType(ftype),
fifo(f), fileWriteEnable(fwenable), masterFileWriteEnable(mfwenable),
myDetectorType(dtype), dynamicRange(dr), streamingFrequency(freq), streamingTimerInMs(timer),
dataStreamEnable(dsEnable), activated(act), deactivatedPaddingEnable(depaden), silentMode(sm),
fileFormatType(ftype), quadEnable(qe), framePadding(fp), ctbDbitList(cdl), ctbDbitOffset(cdo),
fileWriteEnable(fwenable), ctbAnalogDataBytes(cad) {
masterFileWriteEnable(mfwenable),
dynamicRange(dr),
streamingFrequency(freq),
streamingTimerInMs(timer),
activated(act),
deactivatedPaddingEnable(depaden),
silentMode(sm),
quadEnable(qe),
framePadding(fp),
ctbDbitList(cdl),
ctbDbitOffset(cdo),
ctbAnalogDataBytes(cad)
{
LOG(logDEBUG) << "DataProcessor " << ind << " created"; LOG(logDEBUG) << "DataProcessor " << ind << " created";
memset((void*)&timerBegin, 0, sizeof(timespec)); memset((void *)&timerBegin, 0, sizeof(timespec));
} }
DataProcessor::~DataProcessor() { delete file; }
DataProcessor::~DataProcessor() {
delete file;
}
/** getters */ /** getters */
bool DataProcessor::GetStartedFlag(){ bool DataProcessor::GetStartedFlag() { return startedFlag; }
return startedFlag;
}
uint64_t DataProcessor::GetNumFramesCaught() { uint64_t DataProcessor::GetNumFramesCaught() { return numFramesCaught; }
return numFramesCaught;
}
uint64_t DataProcessor::GetCurrentFrameIndex() { uint64_t DataProcessor::GetCurrentFrameIndex() { return currentFrameIndex; }
return currentFrameIndex;
}
uint64_t DataProcessor::GetProcessedIndex() { uint64_t DataProcessor::GetProcessedIndex() {
return currentFrameIndex - firstIndex; return currentFrameIndex - firstIndex;
} }
void DataProcessor::SetFifo(Fifo* f) { void DataProcessor::SetFifo(Fifo *f) { fifo = f; }
fifo = f;
}
void DataProcessor::ResetParametersforNewAcquisition(){ void DataProcessor::ResetParametersforNewAcquisition() {
StopRunning(); StopRunning();
startedFlag = false; startedFlag = false;
numFramesCaught = 0; numFramesCaught = 0;
@ -87,9 +62,8 @@ void DataProcessor::ResetParametersforNewAcquisition(){
currentFrameIndex = 0; currentFrameIndex = 0;
} }
void DataProcessor::RecordFirstIndex(uint64_t fnum) { void DataProcessor::RecordFirstIndex(uint64_t fnum) {
//listen to this fnum, later +1 // listen to this fnum, later +1
currentFrameIndex = fnum; currentFrameIndex = fnum;
startedFlag = true; startedFlag = true;
@ -98,65 +72,69 @@ void DataProcessor::RecordFirstIndex(uint64_t fnum) {
LOG(logDEBUG1) << index << " First Index:" << firstIndex; LOG(logDEBUG1) << index << " First Index:" << firstIndex;
} }
void DataProcessor::SetGeneralData(GeneralData *g) {
void DataProcessor::SetGeneralData(GeneralData* g) {
generalData = g; generalData = g;
generalData->Print(); generalData->Print();
if (file != nullptr) { if (file != nullptr) {
if (file->GetFileType() == HDF5) { if (file->GetFileType() == HDF5) {
file->SetNumberofPixels(generalData->nPixelsX, generalData->nPixelsY); file->SetNumberofPixels(generalData->nPixelsX,
generalData->nPixelsY);
} }
} }
} }
void DataProcessor::SetFileFormat(const fileFormat f) { void DataProcessor::SetFileFormat(const fileFormat f) {
if ((file != nullptr) && file->GetFileType() != f) { if ((file != nullptr) && file->GetFileType() != f) {
//remember the pointer values before they are destroyed // remember the pointer values before they are destroyed
int nd[MAX_DIMENSIONS];nd[0] = 0; nd[1] = 0; int nd[MAX_DIMENSIONS];
uint32_t* maxf = nullptr; nd[0] = 0;
std::string* fname=nullptr; std::string* fpath=nullptr; nd[1] = 0;
uint64_t* findex=nullptr; bool* owenable=nullptr; int* dindex=nullptr; uint32_t *maxf = nullptr;
int* nunits=nullptr; uint64_t* nf = nullptr; std::string *fname = nullptr;
uint32_t* dr = nullptr; uint32_t* port = nullptr; std::string *fpath = nullptr;
file->GetMemberPointerValues(nd, maxf, fname, fpath, findex, uint64_t *findex = nullptr;
owenable, dindex, nunits, nf, dr, port); bool *owenable = nullptr;
//create file writer with same pointers int *dindex = nullptr;
int *nunits = nullptr;
uint64_t *nf = nullptr;
uint32_t *dr = nullptr;
uint32_t *port = nullptr;
file->GetMemberPointerValues(nd, maxf, fname, fpath, findex, owenable,
dindex, nunits, nf, dr, port);
// create file writer with same pointers
SetupFileWriter(fileWriteEnable, nd, maxf, fname, fpath, findex, SetupFileWriter(fileWriteEnable, nd, maxf, fname, fpath, findex,
owenable, dindex, nunits, nf, dr, port); owenable, dindex, nunits, nf, dr, port);
} }
} }
void DataProcessor::SetupFileWriter(bool fwe, int *nd, uint32_t *maxf,
void DataProcessor::SetupFileWriter(bool fwe, int* nd, uint32_t* maxf, std::string *fname, std::string *fpath,
std::string* fname, std::string* fpath, uint64_t* findex, uint64_t *findex, bool *owenable,
bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, int *dindex, int *nunits, uint64_t *nf,
uint32_t* portno, uint32_t *dr, uint32_t *portno,
GeneralData* g) GeneralData *g) {
{
fileWriteEnable = fwe; fileWriteEnable = fwe;
if (g != nullptr) if (g != nullptr)
generalData = g; generalData = g;
if (file != nullptr) { if (file != nullptr) {
delete file; delete file;
file = nullptr; file = nullptr;
} }
if (fileWriteEnable) { if (fileWriteEnable) {
switch(*fileFormatType){ switch (*fileFormatType) {
#ifdef HDF5C #ifdef HDF5C
case HDF5: case HDF5:
file = new HDF5File(index, maxf, file = new HDF5File(index, maxf, nd, fname, fpath, findex, owenable,
nd, fname, fpath, findex, owenable,
dindex, nunits, nf, dr, portno, dindex, nunits, nf, dr, portno,
generalData->nPixelsX, generalData->nPixelsY, silentMode); generalData->nPixelsX, generalData->nPixelsY,
silentMode);
break; break;
#endif #endif
default: default:
file = new BinaryFile(index, maxf, file =
nd, fname, fpath, findex, owenable, new BinaryFile(index, maxf, nd, fname, fpath, findex, owenable,
dindex, nunits, nf, dr, portno, silentMode); dindex, nunits, nf, dr, portno, silentMode);
break; break;
} }
@ -164,7 +142,7 @@ void DataProcessor::SetupFileWriter(bool fwe, int* nd, uint32_t* maxf,
} }
// only the first file // only the first file
void DataProcessor::CreateNewFile(masterAttributes& attr) { void DataProcessor::CreateNewFile(masterAttributes &attr) {
if (file == nullptr) { if (file == nullptr) {
throw sls::RuntimeError("file object not contstructed"); throw sls::RuntimeError("file object not contstructed");
} }
@ -174,7 +152,6 @@ void DataProcessor::CreateNewFile(masterAttributes& attr) {
file->CreateFile(); file->CreateFile();
} }
void DataProcessor::CloseFiles() { void DataProcessor::CloseFiles() {
if (file != nullptr) if (file != nullptr)
file->CloseAllFiles(); file->CloseAllFiles();
@ -185,20 +162,21 @@ void DataProcessor::EndofAcquisition(bool anyPacketsCaught, uint64_t numf) {
try { try {
file->EndofAcquisition(anyPacketsCaught, numf); file->EndofAcquisition(anyPacketsCaught, numf);
} catch (const sls::RuntimeError &e) { } catch (const sls::RuntimeError &e) {
;// ignore for now //TODO: send error to client via stop receiver ; // ignore for now //TODO: send error to client via stop receiver
} }
} }
} }
void DataProcessor::ThreadExecution() { void DataProcessor::ThreadExecution() {
char* buffer=nullptr; char *buffer = nullptr;
fifo->PopAddress(buffer); fifo->PopAddress(buffer);
LOG(logDEBUG5) << "DataProcessor " << index << ", " LOG(logDEBUG5) << "DataProcessor " << index
"pop 0x" << std::hex << (void*)(buffer) << std::dec << ":" << buffer; << ", "
"pop 0x"
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
//check dummy // check dummy
auto numBytes = (uint32_t)(*((uint32_t*)buffer)); auto numBytes = (uint32_t)(*((uint32_t *)buffer));
LOG(logDEBUG1) << "DataProcessor " << index << ", Numbytes:" << numBytes; LOG(logDEBUG1) << "DataProcessor " << index << ", Numbytes:" << numBytes;
if (numBytes == DUMMY_PACKET_VALUE) { if (numBytes == DUMMY_PACKET_VALUE) {
StopProcessing(buffer); StopProcessing(buffer);
@ -207,18 +185,17 @@ void DataProcessor::ThreadExecution() {
ProcessAnImage(buffer); ProcessAnImage(buffer);
//stream (if time/freq to stream) or free // stream (if time/freq to stream) or free
if (*dataStreamEnable && SendToStreamer()) if (*dataStreamEnable && SendToStreamer())
fifo->PushAddressToStream(buffer); fifo->PushAddressToStream(buffer);
else else
fifo->FreeAddress(buffer); fifo->FreeAddress(buffer);
} }
void DataProcessor::StopProcessing(char *buf) {
void DataProcessor::StopProcessing(char* buf) {
LOG(logDEBUG1) << "DataProcessing " << index << ": Dummy"; LOG(logDEBUG1) << "DataProcessing " << index << ": Dummy";
//stream or free // stream or free
if (*dataStreamEnable) if (*dataStreamEnable)
fifo->PushAddressToStream(buf); fifo->PushAddressToStream(buf);
else else
@ -230,10 +207,9 @@ void DataProcessor::StopProcessing(char* buf) {
LOG(logDEBUG1) << index << ": Processing Completed"; LOG(logDEBUG1) << index << ": Processing Completed";
} }
void DataProcessor::ProcessAnImage(char *buf) {
void DataProcessor::ProcessAnImage(char* buf) { auto *rheader = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
auto* rheader = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES);
sls_detector_header header = rheader->detHeader; sls_detector_header header = rheader->detHeader;
uint64_t fnum = header.frameNumber; uint64_t fnum = header.frameNumber;
currentFrameIndex = fnum; currentFrameIndex = fnum;
@ -248,12 +224,12 @@ void DataProcessor::ProcessAnImage(char* buf) {
RecordFirstIndex(fnum); RecordFirstIndex(fnum);
if (*dataStreamEnable) { if (*dataStreamEnable) {
//restart timer // restart timer
clock_gettime(CLOCK_REALTIME, &timerBegin); clock_gettime(CLOCK_REALTIME, &timerBegin);
timerBegin.tv_sec -= (*streamingTimerInMs) / 1000; timerBegin.tv_sec -= (*streamingTimerInMs) / 1000;
timerBegin.tv_nsec -= ((*streamingTimerInMs) % 1000) * 1000000; timerBegin.tv_nsec -= ((*streamingTimerInMs) % 1000) * 1000000;
//to send first image // to send first image
currentFreqCount = *streamingFrequency; currentFreqCount = *streamingFrequency;
} }
} }
@ -273,42 +249,40 @@ void DataProcessor::ProcessAnImage(char* buf) {
// normal call back // normal call back
if (rawDataReadyCallBack != nullptr) { if (rawDataReadyCallBack != nullptr) {
rawDataReadyCallBack( rawDataReadyCallBack((char *)rheader,
(char*)rheader, buf + FIFO_HEADER_NUMBYTES +
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), sizeof(sls_receiver_header),
(uint32_t)(*((uint32_t*)buf)), (uint32_t)(*((uint32_t *)buf)), pRawDataReady);
pRawDataReady);
} }
// call back with modified size // call back with modified size
else if (rawDataModifyReadyCallBack != nullptr) { else if (rawDataModifyReadyCallBack != nullptr) {
auto revsize = (uint32_t)(*((uint32_t*)buf)); auto revsize = (uint32_t)(*((uint32_t *)buf));
rawDataModifyReadyCallBack( rawDataModifyReadyCallBack((char *)rheader,
(char*)rheader, buf + FIFO_HEADER_NUMBYTES +
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), sizeof(sls_receiver_header),
revsize, revsize, pRawDataReady);
pRawDataReady); (*((uint32_t *)buf)) = revsize;
(*((uint32_t*)buf)) = revsize;
} }
// write to file // write to file
if (file != nullptr) { if (file != nullptr) {
try { try {
file->WriteToFile(buf + FIFO_HEADER_NUMBYTES, file->WriteToFile(
sizeof(sls_receiver_header) + (uint32_t)(*((uint32_t*)buf)), //+ size of data (resizable from previous call back buf + FIFO_HEADER_NUMBYTES,
fnum-firstIndex, nump); sizeof(sls_receiver_header) +
} catch(const sls::RuntimeError &e) { (uint32_t)(*((uint32_t *)buf)), //+ size of data (resizable
; //ignore write exception for now (TODO: send error message via stopReceiver tcp) //from previous call back
fnum - firstIndex, nump);
} catch (const sls::RuntimeError &e) {
; // ignore write exception for now (TODO: send error message via
// stopReceiver tcp)
} }
} }
} }
bool DataProcessor::SendToStreamer() { bool DataProcessor::SendToStreamer() {
//skip // skip
if ((*streamingFrequency) == 0u) { if ((*streamingFrequency) == 0u) {
if (!CheckTimer()) if (!CheckTimer())
return false; return false;
@ -319,27 +293,27 @@ bool DataProcessor::SendToStreamer() {
return true; return true;
} }
bool DataProcessor::CheckTimer() { bool DataProcessor::CheckTimer() {
struct timespec end; struct timespec end;
clock_gettime(CLOCK_REALTIME, &end); clock_gettime(CLOCK_REALTIME, &end);
LOG(logDEBUG1) << index << " Timer elapsed time:" << LOG(logDEBUG1) << index << " Timer elapsed time:"
(( end.tv_sec - timerBegin.tv_sec ) + ( end.tv_nsec - timerBegin.tv_nsec ) / 1000000000.0) << ((end.tv_sec - timerBegin.tv_sec) +
(end.tv_nsec - timerBegin.tv_nsec) / 1000000000.0)
<< " seconds"; << " seconds";
//still less than streaming timer, keep waiting // still less than streaming timer, keep waiting
if((( end.tv_sec - timerBegin.tv_sec ) + ( end.tv_nsec - timerBegin.tv_nsec ) if (((end.tv_sec - timerBegin.tv_sec) +
/ 1000000000.0) < ((double)*streamingTimerInMs/1000.00)) (end.tv_nsec - timerBegin.tv_nsec) / 1000000000.0) <
((double)*streamingTimerInMs / 1000.00))
return false; return false;
//restart timer // restart timer
clock_gettime(CLOCK_REALTIME, &timerBegin); clock_gettime(CLOCK_REALTIME, &timerBegin);
return true; return true;
} }
bool DataProcessor::CheckCount() { bool DataProcessor::CheckCount() {
if (currentFreqCount == *streamingFrequency ) { if (currentFreqCount == *streamingFrequency) {
currentFreqCount = 1; currentFreqCount = 1;
return true; return true;
} }
@ -347,38 +321,40 @@ bool DataProcessor::CheckCount() {
return false; return false;
} }
void DataProcessor::SetPixelDimension() { void DataProcessor::SetPixelDimension() {
if (file != nullptr) { if (file != nullptr) {
if (file->GetFileType() == HDF5) { if (file->GetFileType() == HDF5) {
file->SetNumberofPixels(generalData->nPixelsX, generalData->nPixelsY); file->SetNumberofPixels(generalData->nPixelsX,
generalData->nPixelsY);
} }
} }
} }
void DataProcessor::registerCallBackRawDataReady(void (*func)(char* , void DataProcessor::registerCallBackRawDataReady(void (*func)(char *, char *,
char*, uint32_t, void*),void *arg) { uint32_t, void *),
rawDataReadyCallBack=func; void *arg) {
pRawDataReady=arg; rawDataReadyCallBack = func;
pRawDataReady = arg;
} }
void DataProcessor::registerCallBackRawDataModifyReady(void (*func)(char* , void DataProcessor::registerCallBackRawDataModifyReady(
char*, uint32_t&, void*),void *arg) { void (*func)(char *, char *, uint32_t &, void *), void *arg) {
rawDataModifyReadyCallBack=func; rawDataModifyReadyCallBack = func;
pRawDataReady=arg; pRawDataReady = arg;
} }
void DataProcessor::PadMissingPackets(char* buf) { void DataProcessor::PadMissingPackets(char *buf) {
LOG(logDEBUG) << index << ": Padding Missing Packets"; LOG(logDEBUG) << index << ": Padding Missing Packets";
uint32_t pperFrame = generalData->packetsPerFrame; uint32_t pperFrame = generalData->packetsPerFrame;
auto* header = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES); auto *header = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
uint32_t nmissing = pperFrame - header->detHeader.packetNumber; uint32_t nmissing = pperFrame - header->detHeader.packetNumber;
sls_bitset pmask = header->packetsMask; sls_bitset pmask = header->packetsMask;
uint32_t dsize = generalData->dataSize; uint32_t dsize = generalData->dataSize;
uint32_t fifohsize = generalData->fifoBufferHeaderSize; uint32_t fifohsize = generalData->fifoBufferHeaderSize;
uint32_t corrected_dsize = dsize - ((pperFrame * dsize) - generalData->imageSize); uint32_t corrected_dsize =
dsize - ((pperFrame * dsize) - generalData->imageSize);
LOG(logDEBUG1) << "bitmask: " << pmask.to_string(); LOG(logDEBUG1) << "bitmask: " << pmask.to_string();
for (unsigned int pnum = 0; pnum < pperFrame; ++pnum) { for (unsigned int pnum = 0; pnum < pperFrame; ++pnum) {
@ -391,21 +367,24 @@ void DataProcessor::PadMissingPackets(char* buf) {
if (nmissing == 0u) if (nmissing == 0u)
break; break;
LOG(logDEBUG) << "padding for " << index << " for pnum: " << pnum << std::endl; LOG(logDEBUG) << "padding for " << index << " for pnum: " << pnum
<< std::endl;
// missing packet // missing packet
switch(myDetectorType) { switch (myDetectorType) {
//for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes data // for gotthard, 1st packet: 4 bytes fnum, CACA +
// 2nd packet: 4 bytes fnum, previous 1*2 bytes data + 640*2 bytes data !! // CACA, 639*2 bytes data
// 2nd packet: 4 bytes fnum, previous 1*2 bytes data +
// 640*2 bytes data !!
case GOTTHARD: case GOTTHARD:
if(pnum == 0u) if (pnum == 0u)
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize-2); memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize - 2);
else else
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize+2); memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize + 2);
break; break;
case CHIPTESTBOARD: case CHIPTESTBOARD:
case MOENCH: case MOENCH:
if (pnum == (pperFrame-1)) if (pnum == (pperFrame - 1))
memset(buf + fifohsize + (pnum * dsize), 0xFF, corrected_dsize); memset(buf + fifohsize + (pnum * dsize), 0xFF, corrected_dsize);
else else
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize); memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize);
@ -419,26 +398,30 @@ void DataProcessor::PadMissingPackets(char* buf) {
} }
/** ctb specific */ /** ctb specific */
void DataProcessor::RearrangeDbitData(char* buf) { void DataProcessor::RearrangeDbitData(char *buf) {
int totalSize = (int)(*((uint32_t*)buf)); int totalSize = (int)(*((uint32_t *)buf));
int ctbDigitalDataBytes = totalSize - (*ctbAnalogDataBytes) - (*ctbDbitOffset); int ctbDigitalDataBytes =
totalSize - (*ctbAnalogDataBytes) - (*ctbDbitOffset);
// no digital data // no digital data
if (ctbDigitalDataBytes == 0) { if (ctbDigitalDataBytes == 0) {
LOG(logWARNING) << "No digital data for call back, yet dbitlist is not empty."; LOG(logWARNING)
<< "No digital data for call back, yet dbitlist is not empty.";
return; return;
} }
const int numSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); const int numSamples = (ctbDigitalDataBytes / sizeof(uint64_t));
const int digOffset = FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header) + (*ctbAnalogDataBytes); const int digOffset = FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header) +
(*ctbAnalogDataBytes);
// ceil as numResult8Bits could be decimal // ceil as numResult8Bits could be decimal
const int numResult8Bits = ceil((double)(numSamples * (*ctbDbitList).size()) / 8.00); const int numResult8Bits =
ceil((double)(numSamples * (*ctbDbitList).size()) / 8.00);
uint8_t result[numResult8Bits]; uint8_t result[numResult8Bits];
memset(result, 0, numResult8Bits * sizeof(uint8_t)); memset(result, 0, numResult8Bits * sizeof(uint8_t));
uint8_t* dest = result; uint8_t *dest = result;
auto* source = (uint64_t*)(buf + digOffset + (*ctbDbitOffset)); auto *source = (uint64_t *)(buf + digOffset + (*ctbDbitOffset));
// loop through digital bit enable vector // loop through digital bit enable vector
int bitoffset = 0; int bitoffset = 0;
@ -463,9 +446,7 @@ void DataProcessor::RearrangeDbitData(char* buf) {
} }
} }
// copy back to buf and update size // copy back to buf and update size
memcpy(buf + digOffset, result, numResult8Bits * sizeof(uint8_t)); memcpy(buf + digOffset, result, numResult8Bits * sizeof(uint8_t));
(*((uint32_t*)buf)) = numResult8Bits * sizeof(uint8_t); (*((uint32_t *)buf)) = numResult8Bits * sizeof(uint8_t);
} }

123
slsReceiverSoftware/src/DataProcessor.h Executable file → Normal file
View File

@ -17,15 +17,16 @@ class Fifo;
class File; class File;
class DataStreamer; class DataStreamer;
#include <vector>
#include <atomic> #include <atomic>
#include <vector>
class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
public: public:
/** /**
* Constructor * Constructor
* Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofDataProcessors * Calls Base Class CreateThread(), sets ErrorMask if error and increments
* NumberofDataProcessors
* @param ind self index * @param ind self index
* @param dtype detector type * @param dtype detector type
* @param f address of Fifo pointer * @param f address of Fifo pointer
@ -45,11 +46,11 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* @param cdo pointer to digital bits offset * @param cdo pointer to digital bits offset
* @param cad pointer to ctb analog databytes * @param cad pointer to ctb analog databytes
*/ */
DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat* ftype, DataProcessor(int ind, detectorType dtype, Fifo *f, fileFormat *ftype,
bool fwenable, bool* mfwenable, bool* dsEnable, uint32_t* dr, bool fwenable, bool *mfwenable, bool *dsEnable, uint32_t *dr,
uint32_t* freq, uint32_t* timer, uint32_t *freq, uint32_t *timer, bool *fp, bool *act,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, bool *depaden, bool *sm, bool *qe, std::vector<int> *cdl,
std::vector <int> * cdl, int* cdo, int* cad); int *cdo, int *cad);
/** /**
* Destructor * Destructor
@ -57,7 +58,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
*/ */
~DataProcessor() override; ~DataProcessor() override;
//*** getters *** //*** getters ***
/** /**
@ -73,7 +73,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
uint64_t GetNumFramesCaught(); uint64_t GetNumFramesCaught();
/** /**
* Gets Actual Current Frame Index (that has not been subtracted from firstIndex) thats been processed * Gets Actual Current Frame Index (that has not been subtracted from
* firstIndex) thats been processed
* @return -1 if no frames have been caught, else current frame index * @return -1 if no frames have been caught, else current frame index
*/ */
uint64_t GetCurrentFrameIndex(); uint64_t GetCurrentFrameIndex();
@ -88,7 +89,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* Set Fifo pointer to the one given * Set Fifo pointer to the one given
* @param f address of Fifo pointer * @param f address of Fifo pointer
*/ */
void SetFifo(Fifo* f); void SetFifo(Fifo *f);
/** /**
* Reset parameters for new acquisition * Reset parameters for new acquisition
@ -99,7 +100,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* Set GeneralData pointer to the one given * Set GeneralData pointer to the one given
* @param g address of GeneralData (Detector Data) pointer * @param g address of GeneralData (Detector Data) pointer
*/ */
void SetGeneralData(GeneralData* g); void SetGeneralData(GeneralData *g);
/** /**
* Set File Format * Set File Format
@ -123,16 +124,16 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* @param portno pointer to udp port number * @param portno pointer to udp port number
* @param g address of GeneralData (Detector Data) pointer * @param g address of GeneralData (Detector Data) pointer
*/ */
void SetupFileWriter(bool fwe, int* nd, uint32_t* maxf, std::string* fname, void SetupFileWriter(bool fwe, int *nd, uint32_t *maxf, std::string *fname,
std::string* fpath, uint64_t* findex, std::string *fpath, uint64_t *findex, bool *owenable,
bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
uint32_t* portno, GeneralData* g = nullptr); uint32_t *portno, GeneralData *g = nullptr);
/** /**
* Create New File * Create New File
* @param attr master file attributes * @param attr master file attributes
*/ */
void CreateNewFile(masterAttributes& attr); void CreateNewFile(masterAttributes &attr);
/** /**
* Closes files * Closes files
@ -158,8 +159,9 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* dataPointer is the pointer to the data * dataPointer is the pointer to the data
* dataSize in bytes is the size of the data in bytes. * dataSize in bytes is the size of the data in bytes.
*/ */
void registerCallBackRawDataReady(void (*func)(char* , void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
char*, uint32_t, void*),void *arg); void *),
void *arg);
/** /**
* Call back for raw data (modified) * Call back for raw data (modified)
@ -167,15 +169,14 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* sls_receiver_header frame metadata * sls_receiver_header frame metadata
* dataPointer is the pointer to the data * dataPointer is the pointer to the data
* revDatasize is the reference of data size in bytes. * revDatasize is the reference of data size in bytes.
* Can be modified to the new size to be written/streamed. (only smaller value). * Can be modified to the new size to be written/streamed. (only smaller
* value).
*/ */
void registerCallBackRawDataModifyReady(void (*func)(char* , void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
char*, uint32_t &, void*),void *arg); uint32_t &, void *),
void *arg);
private: private:
/** /**
* Record First Index * Record First Index
* @param fnum frame index to record * @param fnum frame index to record
@ -194,14 +195,14 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* reset running mask by calling StopRunning() * reset running mask by calling StopRunning()
* @param buf address of pointer * @param buf address of pointer
*/ */
void StopProcessing(char* buf); void StopProcessing(char *buf);
/** /**
* Process an image popped from fifo, * Process an image popped from fifo,
* write to file if fw enabled & update parameters * write to file if fw enabled & update parameters
* @param buffer * @param buffer
*/ */
void ProcessAnImage(char* buf); void ProcessAnImage(char *buf);
/** /**
* Calls CheckTimer and CheckCount for streaming frequency and timer * Calls CheckTimer and CheckCount for streaming frequency and timer
@ -228,50 +229,51 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* Pad Missing Packets from the bit mask * Pad Missing Packets from the bit mask
* @param buf buffer * @param buf buffer
*/ */
void PadMissingPackets(char* buf); void PadMissingPackets(char *buf);
/** /**
* Align corresponding digital bits together (CTB only if ctbDbitlist is not empty) * Align corresponding digital bits together (CTB only if ctbDbitlist is not
* empty)
*/ */
void RearrangeDbitData(char* buf); void RearrangeDbitData(char *buf);
/** type of thread */ /** type of thread */
static const std::string TypeName; static const std::string TypeName;
/** GeneralData (Detector Data) object */ /** GeneralData (Detector Data) object */
const GeneralData* generalData{nullptr}; const GeneralData *generalData{nullptr};
/** Fifo structure */ /** Fifo structure */
Fifo* fifo; Fifo *fifo;
// individual members
//individual members
/** Detector Type */ /** Detector Type */
detectorType myDetectorType; detectorType myDetectorType;
/** File writer implemented as binary or hdf5 File */ /** File writer implemented as binary or hdf5 File */
File* file{nullptr}; File *file{nullptr};
/** Data Stream Enable */ /** Data Stream Enable */
bool* dataStreamEnable; bool *dataStreamEnable;
/** File Format Type */ /** File Format Type */
fileFormat* fileFormatType; fileFormat *fileFormatType;
/** File Write Enable */ /** File Write Enable */
bool fileWriteEnable; bool fileWriteEnable;
/** Master File Write Enable */ /** Master File Write Enable */
bool* masterFileWriteEnable; bool *masterFileWriteEnable;
/** Dynamic Range */ /** Dynamic Range */
uint32_t* dynamicRange; uint32_t *dynamicRange;
/** Pointer to Streaming frequency, if 0, sending random images with a timer */ /** Pointer to Streaming frequency, if 0, sending random images with a timer
uint32_t* streamingFrequency; */
uint32_t *streamingFrequency;
/** Pointer to the timer if Streaming frequency is random */ /** Pointer to the timer if Streaming frequency is random */
uint32_t* streamingTimerInMs; uint32_t *streamingTimerInMs;
/** Current frequency count */ /** Current frequency count */
uint32_t currentFreqCount{0}; uint32_t currentFreqCount{0};
@ -280,45 +282,44 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
struct timespec timerBegin; struct timespec timerBegin;
/** Activated/Deactivated */ /** Activated/Deactivated */
bool* activated; bool *activated;
/** Deactivated padding enable */ /** Deactivated padding enable */
bool* deactivatedPaddingEnable; bool *deactivatedPaddingEnable;
/** Silent Mode */ /** Silent Mode */
bool* silentMode; bool *silentMode;
/** quad enable */ /** quad enable */
bool* quadEnable; bool *quadEnable;
/** frame padding */ /** frame padding */
bool* framePadding; bool *framePadding;
/** ctb digital bits enable list */ /** ctb digital bits enable list */
std::vector <int> *ctbDbitList; std::vector<int> *ctbDbitList;
/** ctb digital bits offset */ /** ctb digital bits offset */
int* ctbDbitOffset; int *ctbDbitOffset;
/** ctb analog databytes */ /** ctb analog databytes */
int* ctbAnalogDataBytes; int *ctbAnalogDataBytes;
//acquisition start // acquisition start
/** Aquisition Started flag */ /** Aquisition Started flag */
std::atomic<bool> startedFlag{false}; std::atomic<bool> startedFlag{false};
/** Frame Number of First Frame */ /** Frame Number of First Frame */
std::atomic<uint64_t> firstIndex{0}; std::atomic<uint64_t> firstIndex{0};
// for statistics
//for statistics
/** Number of complete frames caught */ /** Number of complete frames caught */
uint64_t numFramesCaught{0}; uint64_t numFramesCaught{0};
/** Frame Number of latest processed frame number */ /** Frame Number of latest processed frame number */
std::atomic<uint64_t> currentFrameIndex{0}; std::atomic<uint64_t> currentFrameIndex{0};
//call back // call back
/** /**
* Call back for raw data * Call back for raw data
* args to raw data ready callback are * args to raw data ready callback are
@ -326,24 +327,18 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* dataPointer is the pointer to the data * dataPointer is the pointer to the data
* dataSize in bytes is the size of the data in bytes. * dataSize in bytes is the size of the data in bytes.
*/ */
void (*rawDataReadyCallBack)(char*, void (*rawDataReadyCallBack)(char *, char *, uint32_t, void *) = nullptr;
char*, uint32_t, void*) = nullptr;
/** /**
* Call back for raw data (modified) * Call back for raw data (modified)
* args to raw data ready callback are * args to raw data ready callback are
* sls_receiver_header frame metadata * sls_receiver_header frame metadata
* dataPointer is the pointer to the data * dataPointer is the pointer to the data
* revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value). * 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*, void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &,
char*, uint32_t &, void*) = nullptr; void *) = nullptr;
void *pRawDataReady{nullptr}; void *pRawDataReady{nullptr};
}; };

147
slsReceiverSoftware/src/DataStreamer.cpp Executable file → Normal file
View File

@ -3,7 +3,6 @@
* @short streams data from receiver via ZMQ * @short streams data from receiver via ZMQ
***********************************************/ ***********************************************/
#include "DataStreamer.h" #include "DataStreamer.h"
#include "Fifo.h" #include "Fifo.h"
#include "GeneralData.h" #include "GeneralData.h"
@ -15,35 +14,24 @@
const std::string DataStreamer::TypeName = "DataStreamer"; const std::string DataStreamer::TypeName = "DataStreamer";
DataStreamer::DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi,
DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r, int fd, int *nd, bool *qe, uint64_t *tot)
uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot) : : ThreadObject(ind, TypeName), fifo(f), dynamicRange(dr), roi(r),
ThreadObject(ind, TypeName), fileIndex(fi), flippedDataX(fd), quadEnable(qe), totalNumFrames(tot) {
fifo(f),
dynamicRange(dr),
roi(r),
fileIndex(fi),
flippedDataX(fd),
quadEnable(qe),
totalNumFrames(tot)
{
numDet[0] = nd[0]; numDet[0] = nd[0];
numDet[1] = nd[1]; numDet[1] = nd[1];
LOG(logDEBUG) << "DataStreamer " << ind << " created"; LOG(logDEBUG) << "DataStreamer " << ind << " created";
} }
DataStreamer::~DataStreamer() { DataStreamer::~DataStreamer() {
CloseZmqSocket(); CloseZmqSocket();
delete [] completeBuffer; delete[] completeBuffer;
} }
void DataStreamer::SetFifo(Fifo* f) { void DataStreamer::SetFifo(Fifo *f) { fifo = f; }
fifo = f;
}
void DataStreamer::ResetParametersforNewAcquisition(const std::string& fname){ void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
StopRunning(); StopRunning();
startedFlag = false; startedFlag = false;
firstIndex = 0; firstIndex = 0;
@ -69,37 +57,38 @@ void DataStreamer::RecordFirstIndex(uint64_t fnum) {
LOG(logDEBUG1) << index << " First Index: " << firstIndex; LOG(logDEBUG1) << index << " First Index: " << firstIndex;
} }
void DataStreamer::SetGeneralData(GeneralData* g) { void DataStreamer::SetGeneralData(GeneralData *g) {
generalData = g; generalData = g;
generalData->Print(); generalData->Print();
} }
void DataStreamer::SetNumberofDetectors(int* nd) { void DataStreamer::SetNumberofDetectors(int *nd) {
numDet[0] = nd[0]; numDet[0] = nd[0];
numDet[1] = nd[1]; numDet[1] = nd[1];
} }
void DataStreamer::SetFlippedDataX(int fd) { void DataStreamer::SetFlippedDataX(int fd) { flippedDataX = fd; }
flippedDataX = fd;
}
void DataStreamer::SetAdditionalJsonHeader(const std::map<std::string, std::string> &json) { void DataStreamer::SetAdditionalJsonHeader(
const std::map<std::string, std::string> &json) {
additionJsonHeader = json; additionJsonHeader = json;
} }
void DataStreamer::CreateZmqSockets(int* nunits, uint32_t port, const sls::IpAddr ip) { void DataStreamer::CreateZmqSockets(int *nunits, uint32_t port,
const sls::IpAddr ip) {
uint32_t portnum = port + index; uint32_t portnum = port + index;
std::string sip = ip.str(); std::string sip = ip.str();
try { try {
zmqSocket = new ZmqSocket(portnum, (ip != 0? sip.c_str(): nullptr)); zmqSocket = new ZmqSocket(portnum, (ip != 0 ? sip.c_str() : nullptr));
} catch (...) { } catch (...) {
LOG(logERROR) << "Could not create Zmq socket on port " << portnum << " for Streamer " << index; LOG(logERROR) << "Could not create Zmq socket on port " << portnum
<< " for Streamer " << index;
throw; throw;
} }
LOG(logINFO) << index << " Streamer: Zmq Server started at " << zmqSocket->GetZmqServerAddress(); LOG(logINFO) << index << " Streamer: Zmq Server started at "
<< zmqSocket->GetZmqServerAddress();
} }
void DataStreamer::CloseZmqSocket() { void DataStreamer::CloseZmqSocket() {
if (zmqSocket) { if (zmqSocket) {
delete zmqSocket; delete zmqSocket;
@ -107,16 +96,16 @@ void DataStreamer::CloseZmqSocket() {
} }
} }
void DataStreamer::ThreadExecution() { void DataStreamer::ThreadExecution() {
char* buffer=nullptr; char *buffer = nullptr;
fifo->PopAddressToStream(buffer); fifo->PopAddressToStream(buffer);
LOG(logDEBUG5) << "DataStreamer " << index << ", " LOG(logDEBUG5) << "DataStreamer " << index
"pop 0x" << std::hex << (void*)(buffer) << std::dec << ":" << buffer; << ", "
"pop 0x"
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
// check dummy
//check dummy uint32_t numBytes = (uint32_t)(*((uint32_t *)buffer));
uint32_t numBytes = (uint32_t)(*((uint32_t*)buffer));
LOG(logDEBUG1) << "DataStreamer " << index << ", Numbytes:" << numBytes; LOG(logDEBUG1) << "DataStreamer " << index << ", Numbytes:" << numBytes;
if (numBytes == DUMMY_PACKET_VALUE) { if (numBytes == DUMMY_PACKET_VALUE) {
StopProcessing(buffer); StopProcessing(buffer);
@ -125,20 +114,18 @@ void DataStreamer::ThreadExecution() {
ProcessAnImage(buffer); ProcessAnImage(buffer);
//free // free
fifo->FreeAddress(buffer); fifo->FreeAddress(buffer);
} }
void DataStreamer::StopProcessing(char *buf) {
void DataStreamer::StopProcessing(char* buf) {
LOG(logDEBUG1) << "DataStreamer " << index << ": Dummy"; LOG(logDEBUG1) << "DataStreamer " << index << ": Dummy";
sls_receiver_header* header = (sls_receiver_header*) (buf); sls_receiver_header *header = (sls_receiver_header *)(buf);
//send dummy header and data // send dummy header and data
if (!SendHeader(header, 0, 0, 0, true)) { if (!SendHeader(header, 0, 0, 0, true)) {
LOG(logERROR) << "Could not send zmq dummy header for streamer " << index; LOG(logERROR) << "Could not send zmq dummy header for streamer "
<< index;
} }
fifo->FreeAddress(buf); fifo->FreeAddress(buf);
@ -147,9 +134,10 @@ void DataStreamer::StopProcessing(char* buf) {
} }
/** buf includes only the standard header */ /** buf includes only the standard header */
void DataStreamer::ProcessAnImage(char* buf) { void DataStreamer::ProcessAnImage(char *buf) {
sls_receiver_header* header = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES); sls_receiver_header *header =
(sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
uint64_t fnum = header->detHeader.frameNumber; uint64_t fnum = header->detHeader.frameNumber;
LOG(logDEBUG1) << "DataStreamer " << index << ": fnum:" << fnum; LOG(logDEBUG1) << "DataStreamer " << index << ": fnum:" << fnum;
@ -157,44 +145,53 @@ void DataStreamer::ProcessAnImage(char* buf) {
RecordFirstIndex(fnum); RecordFirstIndex(fnum);
} }
//shortframe gotthard // shortframe gotthard
if (completeBuffer) { if (completeBuffer) {
//disregarding the size modified from callback (always using imageSizeComplete // disregarding the size modified from callback (always using
// instead of buf (32 bit) because gui needs imagesizecomplete and listener // imageSizeComplete
//write imagesize // instead of buf (32 bit) because gui needs imagesizecomplete and
// listener
// write imagesize
if (!SendHeader(header, generalData->imageSizeComplete, if (!SendHeader(header, generalData->imageSizeComplete,
generalData->nPixelsXComplete, generalData->nPixelsYComplete, false)) { generalData->nPixelsXComplete,
LOG(logERROR) << "Could not send zmq header for fnum " << fnum << " and streamer " << index; generalData->nPixelsYComplete, false)) {
LOG(logERROR) << "Could not send zmq header for fnum " << fnum
<< " and streamer " << index;
} }
memcpy(completeBuffer + ((generalData->imageSize) * adcConfigured), memcpy(completeBuffer + ((generalData->imageSize) * adcConfigured),
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
(uint32_t)(*((uint32_t*)buf)) ); (uint32_t)(*((uint32_t *)buf)));
if (!zmqSocket->SendData(completeBuffer, generalData->imageSizeComplete)) { if (!zmqSocket->SendData(completeBuffer,
LOG(logERROR) << "Could not send zmq data for fnum " << fnum << " and streamer " << index; generalData->imageSizeComplete)) {
LOG(logERROR) << "Could not send zmq data for fnum " << fnum
<< " and streamer " << index;
} }
} }
// normal
//normal
else { else {
if (!SendHeader(header, (uint32_t)(*((uint32_t*)buf)), if (!SendHeader(header, (uint32_t)(*((uint32_t *)buf)),
generalData->nPixelsX, generalData->nPixelsY, false)) {// new size possibly from callback generalData->nPixelsX, generalData->nPixelsY,
LOG(logERROR) << "Could not send zmq header for fnum " << fnum << " and streamer " << index; false)) { // new size possibly from callback
LOG(logERROR) << "Could not send zmq header for fnum " << fnum
<< " and streamer " << index;
} }
if (!zmqSocket->SendData(buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), if (!zmqSocket->SendData(
(uint32_t)(*((uint32_t*)buf)) )) {// new size possibly from callback buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
LOG(logERROR) << "Could not send zmq data for fnum " << fnum << " and streamer " << index; (uint32_t)(
*((uint32_t *)buf)))) { // new size possibly from callback
LOG(logERROR) << "Could not send zmq data for fnum " << fnum
<< " and streamer " << index;
} }
} }
} }
int DataStreamer::SendHeader(sls_receiver_header *rheader, uint32_t size,
uint32_t nx, uint32_t ny, bool dummy) {
int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32_t nx, uint32_t ny, bool dummy) {
zmqHeader zHeader; zmqHeader zHeader;
zHeader.data = !dummy; zHeader.data = !dummy;
@ -218,7 +215,8 @@ int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32
zHeader.imageSize = size; zHeader.imageSize = size;
zHeader.acqIndex = acquisitionIndex; zHeader.acqIndex = acquisitionIndex;
zHeader.frameIndex = frameIndex; zHeader.frameIndex = frameIndex;
zHeader.progress = 100 * ((double)(frameIndex + 1) / (double)(*totalNumFrames)); zHeader.progress =
100 * ((double)(frameIndex + 1) / (double)(*totalNumFrames));
zHeader.fname = fileNametoStream; zHeader.fname = fileNametoStream;
zHeader.frameNumber = header.frameNumber; zHeader.frameNumber = header.frameNumber;
zHeader.expLength = header.expLength; zHeader.expLength = header.expLength;
@ -235,23 +233,22 @@ int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32
zHeader.version = header.version; zHeader.version = header.version;
zHeader.flippedDataX = flippedDataX; zHeader.flippedDataX = flippedDataX;
zHeader.quad = *quadEnable; zHeader.quad = *quadEnable;
zHeader.completeImage = (header.packetNumber < generalData->packetsPerFrame ? false : true); zHeader.completeImage =
(header.packetNumber < generalData->packetsPerFrame ? false : true);
zHeader.addJsonHeader = additionJsonHeader; zHeader.addJsonHeader = additionJsonHeader;
return zmqSocket->SendHeader(index, zHeader); return zmqSocket->SendHeader(index, zHeader);
} }
void DataStreamer::RestreamStop() { void DataStreamer::RestreamStop() {
//send dummy header // send dummy header
zmqHeader zHeader; zmqHeader zHeader;
zHeader.data = false; zHeader.data = false;
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION; zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
int ret = zmqSocket->SendHeader(index, zHeader); int ret = zmqSocket->SendHeader(index, zHeader);
if (!ret) { if (!ret) {
throw sls::RuntimeError("Could not restream Dummy Header via ZMQ for port " + std::to_string(zmqSocket->GetPortNumber())); throw sls::RuntimeError(
"Could not restream Dummy Header via ZMQ for port " +
std::to_string(zmqSocket->GetPortNumber()));
} }
} }

49
slsReceiverSoftware/src/DataStreamer.h Executable file → Normal file
View File

@ -22,7 +22,8 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
public: public:
/** /**
* Constructor * Constructor
* Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofDataStreamers * Calls Base Class CreateThread(), sets ErrorMask if error and increments
* NumberofDataStreamers
* @param ind self index * @param ind self index
* @param f address of Fifo pointer * @param f address of Fifo pointer
* @param dr pointer to dynamic range * @param dr pointer to dynamic range
@ -33,8 +34,8 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param qe pointer to quad Enable * @param qe pointer to quad Enable
* @param tot pointer to total number of frames * @param tot pointer to total number of frames
*/ */
DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r, DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi, int fd,
uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot); int *nd, bool *qe, uint64_t *tot);
/** /**
* Destructor * Destructor
@ -46,24 +47,24 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* Set Fifo pointer to the one given * Set Fifo pointer to the one given
* @param f address of Fifo pointer * @param f address of Fifo pointer
*/ */
void SetFifo(Fifo* f); void SetFifo(Fifo *f);
/** /**
* Reset parameters for new acquisition * Reset parameters for new acquisition
*/ */
void ResetParametersforNewAcquisition(const std::string& fname); void ResetParametersforNewAcquisition(const std::string &fname);
/** /**
* Set GeneralData pointer to the one given * Set GeneralData pointer to the one given
* @param g address of GeneralData (Detector Data) pointer * @param g address of GeneralData (Detector Data) pointer
*/ */
void SetGeneralData(GeneralData* g); void SetGeneralData(GeneralData *g);
/** /**
* Set number of detectors * Set number of detectors
* @param number of detectors in both dimensions * @param number of detectors in both dimensions
*/ */
void SetNumberofDetectors(int* nd); void SetNumberofDetectors(int *nd);
/** /**
* Set Flipped data enable across x dimension * Set Flipped data enable across x dimension
@ -75,7 +76,8 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* Set additional json header * Set additional json header
* @param json additional json header * @param json additional json header
*/ */
void SetAdditionalJsonHeader(const std::map<std::string, std::string> &json); void
SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
/** /**
* Creates Zmq Sockets * Creates Zmq Sockets
@ -84,7 +86,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param port streaming port start index * @param port streaming port start index
* @param ip streaming source ip * @param ip streaming source ip
*/ */
void CreateZmqSockets(int* nunits, uint32_t port, const sls::IpAddr ip); void CreateZmqSockets(int *nunits, uint32_t port, const sls::IpAddr ip);
/** /**
* Shuts down and deletes Zmq Sockets * Shuts down and deletes Zmq Sockets
@ -96,9 +98,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
*/ */
void RestreamStop(); void RestreamStop();
private: private:
/** /**
* Record First Index * Record First Index
* @param fnum frame index to record * @param fnum frame index to record
@ -116,14 +116,14 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* reset running mask by calling StopRunning() * reset running mask by calling StopRunning()
* @param buf address of pointer * @param buf address of pointer
*/ */
void StopProcessing(char* buf); void StopProcessing(char *buf);
/** /**
* Process an image popped from fifo, * Process an image popped from fifo,
* write to file if fw enabled & update parameters * write to file if fw enabled & update parameters
* @param buffer * @param buffer
*/ */
void ProcessAnImage(char* buf); void ProcessAnImage(char *buf);
/** /**
* Create and send Json Header * Create and send Json Header
@ -134,31 +134,32 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param dummy true if its a dummy header * @param dummy true if its a dummy header
* @returns 0 if error, else 1 * @returns 0 if error, else 1
*/ */
int SendHeader(sls_receiver_header* rheader, uint32_t size = 0, uint32_t nx = 0, uint32_t ny = 0, bool dummy = true); int SendHeader(sls_receiver_header *rheader, uint32_t size = 0,
uint32_t nx = 0, uint32_t ny = 0, bool dummy = true);
/** type of thread */ /** type of thread */
static const std::string TypeName; static const std::string TypeName;
/** GeneralData (Detector Data) object */ /** GeneralData (Detector Data) object */
const GeneralData* generalData{nullptr}; const GeneralData *generalData{nullptr};
/** Fifo structure */ /** Fifo structure */
Fifo* fifo; Fifo *fifo;
/** ZMQ Socket - Receiver to Client */ /** ZMQ Socket - Receiver to Client */
ZmqSocket* zmqSocket{nullptr}; ZmqSocket *zmqSocket{nullptr};
/** Pointer to dynamic range */ /** Pointer to dynamic range */
uint32_t* dynamicRange; uint32_t *dynamicRange;
/** ROI */ /** ROI */
ROI* roi; ROI *roi;
/** adc Configured */ /** adc Configured */
int adcConfigured{-1}; int adcConfigured{-1};
/** Pointer to file index */ /** Pointer to file index */
uint64_t* fileIndex; uint64_t *fileIndex;
/** flipped data across x axis */ /** flipped data across x axis */
int flippedDataX; int flippedDataX;
@ -176,16 +177,14 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
std::string fileNametoStream; std::string fileNametoStream;
/** Complete buffer used for roi, eg. shortGotthard */ /** Complete buffer used for roi, eg. shortGotthard */
char* completeBuffer{nullptr}; char *completeBuffer{nullptr};
/** Number of Detectors in X and Y dimension */ /** Number of Detectors in X and Y dimension */
int numDet[2]; int numDet[2];
/** Quad Enable */ /** Quad Enable */
bool* quadEnable; bool *quadEnable;
/** Total number of frames */ /** Total number of frames */
uint64_t* totalNumFrames; uint64_t *totalNumFrames;
}; };

68
slsReceiverSoftware/src/Fifo.cpp Executable file → Normal file
View File

@ -13,41 +13,33 @@
#include <iostream> #include <iostream>
#include <unistd.h> #include <unistd.h>
Fifo::Fifo(int ind, uint32_t fifoItemSize, uint32_t depth): Fifo::Fifo(int ind, uint32_t fifoItemSize, uint32_t depth)
index(ind), : index(ind), memory(nullptr), fifoBound(nullptr), fifoFree(nullptr),
memory(nullptr), fifoStream(nullptr), fifoDepth(depth), status_fifoBound(0),
fifoBound(nullptr), status_fifoFree(depth) {
fifoFree(nullptr),
fifoStream(nullptr),
fifoDepth(depth),
status_fifoBound(0),
status_fifoFree(depth){
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
CreateFifos(fifoItemSize); CreateFifos(fifoItemSize);
} }
Fifo::~Fifo() { Fifo::~Fifo() {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
DestroyFifos(); DestroyFifos();
} }
void Fifo::CreateFifos(uint32_t fifoItemSize) { void Fifo::CreateFifos(uint32_t fifoItemSize) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
//destroy if not already // destroy if not already
DestroyFifos(); DestroyFifos();
//create fifos // create fifos
fifoBound = new CircularFifo<char>(fifoDepth); fifoBound = new CircularFifo<char>(fifoDepth);
fifoFree = new CircularFifo<char>(fifoDepth); fifoFree = new CircularFifo<char>(fifoDepth);
fifoStream = new CircularFifo<char>(fifoDepth); fifoStream = new CircularFifo<char>(fifoDepth);
//allocate memory // allocate memory
size_t mem_len = (size_t)fifoItemSize * (size_t)fifoDepth * sizeof(char); size_t mem_len = (size_t)fifoItemSize * (size_t)fifoDepth * sizeof(char);
memory = (char*) malloc (mem_len); memory = (char *)malloc(mem_len);
if (memory == nullptr){ if (memory == nullptr) {
throw sls::RuntimeError("Could not allocate memory for fifos"); throw sls::RuntimeError("Could not allocate memory for fifos");
} }
memset(memory, 0, mem_len); memset(memory, 0, mem_len);
@ -55,24 +47,25 @@ void Fifo::CreateFifos(uint32_t fifoItemSize) {
for (size_t i = 0; i < mem_len; i += pagesize) { for (size_t i = 0; i < mem_len; i += pagesize) {
strcpy(memory + i, "memory"); strcpy(memory + i, "memory");
} }
LOG(logDEBUG) << "Memory Allocated " << index << ": " << (double)mem_len/(double)(1024 * 1024) << " MB"; LOG(logDEBUG) << "Memory Allocated " << index << ": "
<< (double)mem_len / (double)(1024 * 1024) << " MB";
{ //push free addresses into fifoFree fifo { // push free addresses into fifoFree fifo
char* buffer = memory; char *buffer = memory;
for (int i = 0; i < fifoDepth; ++i) { for (int i = 0; i < fifoDepth; ++i) {
//sprintf(buffer,"memory"); // sprintf(buffer,"memory");
FreeAddress(buffer); FreeAddress(buffer);
buffer += fifoItemSize; buffer += fifoItemSize;
} }
} }
LOG(logINFO) << "Fifo " << index << " reconstructed Depth (rx_fifodepth): " << fifoFree->getDataValue(); LOG(logINFO) << "Fifo " << index << " reconstructed Depth (rx_fifodepth): "
<< fifoFree->getDataValue();
} }
void Fifo::DestroyFifos() {
void Fifo::DestroyFifos(){
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
if(memory) { if (memory) {
free(memory); free(memory);
memory = nullptr; memory = nullptr;
} }
@ -84,39 +77,31 @@ void Fifo::DestroyFifos(){
fifoStream = nullptr; fifoStream = nullptr;
} }
void Fifo::FreeAddress(char *&address) { fifoFree->push(address); }
void Fifo::FreeAddress(char*& address) { void Fifo::GetNewAddress(char *&address) {
fifoFree->push(address);
}
void Fifo::GetNewAddress(char*& address) {
int temp = fifoFree->getDataValue(); int temp = fifoFree->getDataValue();
if (temp < status_fifoFree) if (temp < status_fifoFree)
status_fifoFree = temp; status_fifoFree = temp;
fifoFree->pop(address); fifoFree->pop(address);
} }
void Fifo::PushAddress(char*& address) { void Fifo::PushAddress(char *&address) {
int temp = fifoBound->getDataValue(); int temp = fifoBound->getDataValue();
if (temp > status_fifoBound) if (temp > status_fifoBound)
status_fifoBound = temp; status_fifoBound = temp;
while(!fifoBound->push(address)); while (!fifoBound->push(address))
;
/*temp = fifoBound->getDataValue(); /*temp = fifoBound->getDataValue();
if (temp > status_fifoBound) if (temp > status_fifoBound)
status_fifoBound = temp;*/ status_fifoBound = temp;*/
} }
void Fifo::PopAddress(char*& address) { void Fifo::PopAddress(char *&address) { fifoBound->pop(address); }
fifoBound->pop(address);
}
void Fifo::PushAddressToStream(char*& address) { void Fifo::PushAddressToStream(char *&address) { fifoStream->push(address); }
fifoStream->push(address);
}
void Fifo::PopAddressToStream(char*& address) { void Fifo::PopAddressToStream(char *&address) { fifoStream->pop(address); }
fifoStream->pop(address);
}
int Fifo::GetMaxLevelForFifoBound() { int Fifo::GetMaxLevelForFifoBound() {
int temp = status_fifoBound; int temp = status_fifoBound;
@ -129,4 +114,3 @@ int Fifo::GetMinLevelForFifoFree() {
status_fifoFree = fifoDepth; status_fifoFree = fifoDepth;
return temp; return temp;
} }

24
slsReceiverSoftware/src/Fifo.h Executable file → Normal file
View File

@ -9,8 +9,8 @@
*@short constructs the fifo structure *@short constructs the fifo structure
*/ */
#include "sls_detector_defs.h"
#include "logger.h" #include "logger.h"
#include "sls_detector_defs.h"
#include "CircularFifo.h" #include "CircularFifo.h"
@ -34,32 +34,32 @@ class Fifo : private virtual slsDetectorDefs {
/** /**
* Frees the bound address by pushing into fifoFree * Frees the bound address by pushing into fifoFree
*/ */
void FreeAddress(char*& address); void FreeAddress(char *&address);
/** /**
* Pops free address from fifoFree * Pops free address from fifoFree
*/ */
void GetNewAddress(char*& address); void GetNewAddress(char *&address);
/** /**
* Pushes bound address into fifoBound * Pushes bound address into fifoBound
*/ */
void PushAddress(char*& address); void PushAddress(char *&address);
/** /**
* Pops bound address from fifoBound to process data * Pops bound address from fifoBound to process data
*/ */
void PopAddress(char*& address); void PopAddress(char *&address);
/** /**
* Pushes bound address into fifoStream * Pushes bound address into fifoStream
*/ */
void PushAddressToStream(char*& address); void PushAddressToStream(char *&address);
/** /**
* Pops bound address from fifoStream to stream data * Pops bound address from fifoStream to stream data
*/ */
void PopAddressToStream(char*& address); void PopAddressToStream(char *&address);
/** /**
* Get Maximum Level filled in Fifo Bound * Get Maximum Level filled in Fifo Bound
@ -74,7 +74,6 @@ class Fifo : private virtual slsDetectorDefs {
int GetMinLevelForFifoFree(); int GetMinLevelForFifoFree();
private: private:
/** /**
* Create Fifos, allocate memory & push addresses into fifo * Create Fifos, allocate memory & push addresses into fifo
* @param fifoItemSize size of each fifo item * @param fifoItemSize size of each fifo item
@ -86,21 +85,20 @@ class Fifo : private virtual slsDetectorDefs {
*/ */
void DestroyFifos(); void DestroyFifos();
/** Self Index */ /** Self Index */
int index; int index;
/** Memory allocated, whose addresses are pushed into the fifos */ /** Memory allocated, whose addresses are pushed into the fifos */
char* memory; char *memory;
/** Circular Fifo pointing to addresses of bound data in memory */ /** Circular Fifo pointing to addresses of bound data in memory */
CircularFifo<char>* fifoBound; CircularFifo<char> *fifoBound;
/** Circular Fifo pointing to addresses of freed data in memory */ /** Circular Fifo pointing to addresses of freed data in memory */
CircularFifo<char>* fifoFree; CircularFifo<char> *fifoFree;
/** Circular Fifo pointing to addresses of to be streamed data in memory */ /** Circular Fifo pointing to addresses of to be streamed data in memory */
CircularFifo<char>* fifoStream; CircularFifo<char> *fifoStream;
/** Fifo depth set */ /** Fifo depth set */
int fifoDepth; int fifoDepth;

54
slsReceiverSoftware/src/File.cpp Executable file → Normal file
View File

@ -8,26 +8,14 @@
#include <iostream> #include <iostream>
File::File(int ind, slsDetectorDefs::fileFormat type, uint32_t *maxf, int *nd,
File::File(int ind, slsDetectorDefs::fileFormat type, uint32_t* maxf, std::string *fname, std::string *fpath, uint64_t *findex,
int* nd, std::string* fname, std::string* fpath, uint64_t* findex, bool *owenable, int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t *portno, bool *smode)
uint32_t* portno, bool* smode): : index(ind), formatType(type), maxFramesPerFile(maxf), numDetX(nd[0]),
index(ind), numDetY(nd[1]), fileNamePrefix(fname), filePath(fpath), fileIndex(findex),
formatType(type), overWriteEnable(owenable), detIndex(dindex), numUnitsPerDetector(nunits),
maxFramesPerFile(maxf), numImages(nf), dynamicRange(dr), udpPortNumber(portno), silentMode(smode)
numDetX(nd[0]),
numDetY(nd[1]),
fileNamePrefix(fname),
filePath(fpath),
fileIndex(findex),
overWriteEnable(owenable),
detIndex(dindex),
numUnitsPerDetector(nunits),
numImages(nf),
dynamicRange(dr),
udpPortNumber(portno),
silentMode(smode)
{ {
master = ((index == 0) && (*detIndex == 0)) ? true : false; master = ((index == 0) && (*detIndex == 0)) ? true : false;
@ -35,17 +23,11 @@ File::File(int ind, slsDetectorDefs::fileFormat type, uint32_t* maxf,
File::~File() {} File::~File() {}
slsDetectorDefs::fileFormat File::GetFileType() { slsDetectorDefs::fileFormat File::GetFileType() { return formatType; }
return formatType;
}
std::string File::GetCurrentFileName() { std::string File::GetCurrentFileName() { return currentFileName; }
return currentFileName;
}
void File::resetSubFileIndex(){ void File::resetSubFileIndex() { subFileIndex = 0u; }
subFileIndex = 0u;
}
void File::PrintMembers(TLogLevel level) { void File::PrintMembers(TLogLevel level) {
LOG(level) << "\nGeneral Writer Variables:" << std::endl LOG(level) << "\nGeneral Writer Variables:" << std::endl
@ -59,7 +41,8 @@ void File::PrintMembers(TLogLevel level) {
<< "Over Write Enable: " << *overWriteEnable << std::endl << "Over Write Enable: " << *overWriteEnable << std::endl
<< "Detector Index: " << *detIndex << std::endl << "Detector Index: " << *detIndex << std::endl
<< "Number of Units Per Detector: " << *numUnitsPerDetector << std::endl << "Number of Units Per Detector: " << *numUnitsPerDetector
<< std::endl
<< "Number of Images in Acquisition: " << *numImages << std::endl << "Number of Images in Acquisition: " << *numImages << std::endl
<< "Dynamic Range: " << *dynamicRange << std::endl << "Dynamic Range: " << *dynamicRange << std::endl
<< "UDP Port number: " << *udpPortNumber << std::endl << "UDP Port number: " << *udpPortNumber << std::endl
@ -68,10 +51,11 @@ void File::PrintMembers(TLogLevel level) {
<< "Silent Mode: " << *silentMode; << "Silent Mode: " << *silentMode;
} }
void File::GetMemberPointerValues(int *nd, uint32_t *&maxf, std::string *&fname,
void File::GetMemberPointerValues(int* nd, uint32_t*& maxf, std::string*& fname, std::string*& fpath, uint64_t*& findex, bool*& owenable, std::string *&fpath, uint64_t *&findex,
int*& dindex, int*& nunits, uint64_t*& nf, uint32_t*& dr, uint32_t*& portno) bool *&owenable, int *&dindex, int *&nunits,
{ uint64_t *&nf, uint32_t *&dr,
uint32_t *&portno) {
nd[0] = numDetX; nd[0] = numDetX;
nd[1] = numDetY; nd[1] = numDetY;
maxf = maxFramesPerFile; maxf = maxFramesPerFile;
@ -85,5 +69,3 @@ void File::GetMemberPointerValues(int* nd, uint32_t*& maxf, std::string*& fname,
dr = dynamicRange; dr = dynamicRange;
portno = udpPortNumber; portno = udpPortNumber;
} }

50
slsReceiverSoftware/src/File.h Executable file → Normal file
View File

@ -5,16 +5,16 @@
* creates/closes the file and writes data to it * creates/closes the file and writes data to it
***********************************************/ ***********************************************/
/** /**
*@short sets/gets properties for the file, creates/closes the file and writes data to it *@short sets/gets properties for the file, creates/closes the file and writes
*data to it
*/ */
#include "sls_detector_defs.h"
#include "logger.h" #include "logger.h"
#include "receiver_defs.h" #include "receiver_defs.h"
#include "sls_detector_defs.h"
#include <string> #include <string>
class File : private virtual slsDetectorDefs { class File : private virtual slsDetectorDefs {
public: public:
@ -36,10 +36,10 @@ class File : private virtual slsDetectorDefs {
* @param portno pointer to udp port number for logging * @param portno pointer to udp port number for logging
* @param smode pointer to silent mode * @param smode pointer to silent mode
*/ */
File(int ind, slsDetectorDefs::fileFormat type, uint32_t* maxf, File(int ind, slsDetectorDefs::fileFormat type, uint32_t *maxf, int *nd,
int* nd, std::string* fname, std::string* fpath, uint64_t* findex, std::string *fname, std::string *fpath, uint64_t *findex,
bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, bool *owenable, int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
uint32_t* portno, bool* smode); uint32_t *portno, bool *smode);
virtual ~File(); virtual ~File();
fileFormat GetFileType(); fileFormat GetFileType();
@ -61,9 +61,11 @@ class File : private virtual slsDetectorDefs {
* @param dr pointer to dynamic range * @param dr pointer to dynamic range
* @param portno pointer to dynamic range * @param portno pointer to dynamic range
*/ */
void GetMemberPointerValues(int* nd, uint32_t*& maxf, std::string*& fname, void GetMemberPointerValues(int *nd, uint32_t *&maxf, std::string *&fname,
std::string*& fpath, uint64_t*& findex, bool*& owenable, int*& dindex, std::string *&fpath, uint64_t *&findex,
int*& nunits, uint64_t*& nf, uint32_t*& dr, uint32_t*& portno); bool *&owenable, int *&dindex, int *&nunits,
uint64_t *&nf, uint32_t *&dr,
uint32_t *&portno);
virtual void CreateFile() = 0; virtual void CreateFile() = 0;
virtual void CloseCurrentFile() = 0; virtual void CloseCurrentFile() = 0;
@ -75,14 +77,15 @@ class File : private virtual slsDetectorDefs {
* @param fnum current image number * @param fnum current image number
* @param nump number of packets caught * @param nump number of packets caught
*/ */
virtual void WriteToFile(char* buffer, int buffersize, uint64_t fnum, uint32_t nump) = 0; virtual void WriteToFile(char *buffer, int buffersize, uint64_t fnum,
uint32_t nump) = 0;
/** /**
* Create master file * Create master file
* @param mfwenable master file write enable * @param mfwenable master file write enable
* @param attr master file attributes * @param attr master file attributes
*/ */
virtual void CreateMasterFile(bool mfwenable, masterAttributes& attr) = 0; virtual void CreateMasterFile(bool mfwenable, masterAttributes &attr) = 0;
// HDf5 specific // HDf5 specific
/** /**
@ -109,21 +112,20 @@ class File : private virtual slsDetectorDefs {
bool master; bool master;
int index; int index;
slsDetectorDefs::fileFormat formatType; slsDetectorDefs::fileFormat formatType;
uint32_t* maxFramesPerFile; uint32_t *maxFramesPerFile;
std::string masterFileName; std::string masterFileName;
std::string currentFileName; std::string currentFileName;
int numDetX; int numDetX;
int numDetY; int numDetY;
std::string* fileNamePrefix; std::string *fileNamePrefix;
std::string* filePath; std::string *filePath;
uint64_t* fileIndex; uint64_t *fileIndex;
uint64_t subFileIndex{0}; uint64_t subFileIndex{0};
bool* overWriteEnable; bool *overWriteEnable;
int* detIndex; int *detIndex;
int* numUnitsPerDetector; int *numUnitsPerDetector;
uint64_t* numImages; uint64_t *numImages;
uint32_t* dynamicRange; uint32_t *dynamicRange;
uint32_t* udpPortNumber; uint32_t *udpPortNumber;
bool* silentMode; bool *silentMode;
}; };

248
slsReceiverSoftware/src/GeneralData.h Executable file → Normal file
View File

@ -7,18 +7,16 @@
*@short abstract for setting/getting properties of detector data *@short abstract for setting/getting properties of detector data
*/ */
#include "sls_detector_defs.h" #include "ToString.h"
#include "receiver_defs.h"
#include "logger.h" #include "logger.h"
#include "receiver_defs.h"
#include "sls_detector_defs.h"
#include <cmath> //ceil #include <cmath> //ceil
#include <vector> #include <vector>
#include "ToString.h"
class GeneralData { class GeneralData {
public: public:
/** DetectorType */ /** DetectorType */
slsDetectorDefs::detectorType myDetectorType; slsDetectorDefs::detectorType myDetectorType;
@ -70,10 +68,12 @@ public:
/** Size of a header packet */ /** Size of a header packet */
uint32_t headerPacketSize; uint32_t headerPacketSize;
/** Streaming (for ROI - mainly short Gotthard) - Number of Pixels in x axis */ /** Streaming (for ROI - mainly short Gotthard) - Number of Pixels in x axis
*/
uint32_t nPixelsXComplete; uint32_t nPixelsXComplete;
/** Streaming (for ROI - mainly short Gotthard) - Number of Pixels in y axis */ /** Streaming (for ROI - mainly short Gotthard) - Number of Pixels in y axis
*/
uint32_t nPixelsYComplete; uint32_t nPixelsYComplete;
/** Streaming (for ROI - mainly short Gotthard) - Image size (in bytes) */ /** Streaming (for ROI - mainly short Gotthard) - Image size (in bytes) */
@ -85,34 +85,16 @@ public:
/** default udp socket buffer size */ /** default udp socket buffer size */
uint32_t defaultUdpSocketBufferSize; uint32_t defaultUdpSocketBufferSize;
/** Cosntructor */ /** Cosntructor */
GeneralData(): GeneralData()
myDetectorType(slsDetectorDefs::GENERIC), : myDetectorType(slsDetectorDefs::GENERIC), nPixelsX(0), nPixelsY(0),
nPixelsX(0), headerSizeinPacket(0), dataSize(0), packetSize(0), packetsPerFrame(0),
nPixelsY(0), imageSize(0), frameIndexMask(0), frameIndexOffset(0),
headerSizeinPacket(0), packetIndexMask(0), packetIndexOffset(0), maxFramesPerFile(0),
dataSize(0), fifoBufferHeaderSize(0), defaultFifoDepth(0), threadsPerReceiver(1),
packetSize(0), headerPacketSize(0), nPixelsXComplete(0), nPixelsYComplete(0),
packetsPerFrame(0), imageSizeComplete(0), standardheader(false),
imageSize(0), defaultUdpSocketBufferSize(RECEIVE_SOCKET_BUFFER_SIZE){};
frameIndexMask(0),
frameIndexOffset(0),
packetIndexMask(0),
packetIndexOffset(0),
maxFramesPerFile(0),
fifoBufferHeaderSize(0),
defaultFifoDepth(0),
threadsPerReceiver(1),
headerPacketSize(0),
nPixelsXComplete(0),
nPixelsYComplete(0),
imageSizeComplete(0),
standardheader(false),
defaultUdpSocketBufferSize(RECEIVE_SOCKET_BUFFER_SIZE)
{};
/** Destructor */ /** Destructor */
virtual ~GeneralData(){}; virtual ~GeneralData(){};
@ -125,12 +107,12 @@ public:
* @param frameNumber frame number * @param frameNumber frame number
* @param packetNumber packet number * @param packetNumber packet number
*/ */
virtual void GetHeaderInfo(int index, char* packetData, bool oddStartingPacket, virtual void GetHeaderInfo(int index, char *packetData,
uint64_t& frameNumber, uint32_t& packetNumber) const bool oddStartingPacket, uint64_t &frameNumber,
{ uint32_t &packetNumber) const {
frameNumber = ((uint32_t)(*((uint32_t*)(packetData)))); frameNumber = ((uint32_t)(*((uint32_t *)(packetData))));
frameNumber++; frameNumber++;
packetNumber = frameNumber&packetIndexMask; packetNumber = frameNumber & packetIndexMask;
frameNumber = (frameNumber & frameIndexMask) >> frameIndexOffset; frameNumber = (frameNumber & frameIndexMask) >> frameIndexOffset;
} }
@ -139,7 +121,8 @@ public:
* @param i ROI * @param i ROI
*/ */
virtual void SetROI(slsDetectorDefs::ROI i) { virtual void SetROI(slsDetectorDefs::ROI i) {
LOG(logERROR) << "SetROI is a generic function that should be overloaded by a derived class"; LOG(logERROR) << "SetROI is a generic function that should be "
"overloaded by a derived class";
}; };
/** /**
@ -148,8 +131,9 @@ public:
* @param ROI * @param ROI
* @returns adc configured * @returns adc configured
*/ */
virtual int GetAdcConfigured(int index, slsDetectorDefs::ROI i) const{ virtual int GetAdcConfigured(int index, slsDetectorDefs::ROI i) const {
LOG(logERROR) << "GetAdcConfigured is a generic function that should be overloaded by a derived class"; LOG(logERROR) << "GetAdcConfigured is a generic function that should "
"be overloaded by a derived class";
return 0; return 0;
}; };
@ -159,7 +143,8 @@ public:
* @param tgEnable true if 10GbE is enabled, else false * @param tgEnable true if 10GbE is enabled, else false
*/ */
virtual void SetDynamicRange(int dr, bool tgEnable) { virtual void SetDynamicRange(int dr, bool tgEnable) {
LOG(logERROR) << "SetDynamicRange is a generic function that should be overloaded by a derived class"; LOG(logERROR) << "SetDynamicRange is a generic function that should be "
"overloaded by a derived class";
}; };
/** /**
@ -168,7 +153,8 @@ public:
* @param dr dynamic range * @param dr dynamic range
*/ */
virtual void SetTenGigaEnable(bool tgEnable, int dr) { virtual void SetTenGigaEnable(bool tgEnable, int dr) {
LOG(logERROR) << "SetTenGigaEnable is a generic function that should be overloaded by a derived class"; LOG(logERROR) << "SetTenGigaEnable is a generic function that should "
"be overloaded by a derived class";
}; };
/** /**
@ -177,8 +163,9 @@ public:
* @param packetData pointer to data * @param packetData pointer to data
* @returns true or false for odd starting packet number * @returns true or false for odd starting packet number
*/ */
virtual bool SetOddStartingPacket(int index, char* packetData) { virtual bool SetOddStartingPacket(int index, char *packetData) {
LOG(logERROR) << "SetOddStartingPacket is a generic function that should be overloaded by a derived class"; LOG(logERROR) << "SetOddStartingPacket is a generic function that "
"should be overloaded by a derived class";
return false; return false;
}; };
@ -191,8 +178,10 @@ public:
* @param f readout flags * @param f readout flags
* @returns analog data bytes * @returns analog data bytes
*/ */
virtual int setImageSize(uint32_t a, uint32_t as, uint32_t ds, bool t, slsDetectorDefs::readoutMode) { virtual int setImageSize(uint32_t a, uint32_t as, uint32_t ds, bool t,
LOG(logERROR) << "setImageSize is a generic function that should be overloaded by a derived class"; slsDetectorDefs::readoutMode) {
LOG(logERROR) << "setImageSize is a generic function that should be "
"overloaded by a derived class";
return 0; return 0;
}; };
@ -201,7 +190,8 @@ public:
* @param n number of interfaces * @param n number of interfaces
*/ */
virtual void SetNumberofInterfaces(const int n) { virtual void SetNumberofInterfaces(const int n) {
LOG(logERROR) << "SetNumberofInterfaces is a generic function that should be overloaded by a derived class"; LOG(logERROR) << "SetNumberofInterfaces is a generic function that "
"should be overloaded by a derived class";
} }
/** /**
@ -210,7 +200,8 @@ public:
* @param dr dynamic range * @param dr dynamic range
*/ */
virtual void SetNumberofCounters(const int n, const int dr) { virtual void SetNumberofCounters(const int n, const int dr) {
LOG(logERROR) << "SetNumberofCounters is a generic function that should be overloaded by a derived class"; LOG(logERROR) << "SetNumberofCounters is a generic function that "
"should be overloaded by a derived class";
} }
/** /**
@ -243,17 +234,16 @@ public:
}; };
}; };
class GotthardData : public GeneralData { class GotthardData : public GeneralData {
private: private:
const int nChip = 10; const int nChip = 10;
const int nChan = 128; const int nChan = 128;
const int nChipsPerAdc = 2; const int nChipsPerAdc = 2;
public:
public:
/** Constructor */ /** Constructor */
GotthardData(){ GotthardData() {
myDetectorType = slsDetectorDefs::GOTTHARD; myDetectorType = slsDetectorDefs::GOTTHARD;
nPixelsX = 1280; nPixelsX = 1280;
nPixelsY = 1; nPixelsY = 1;
@ -261,16 +251,16 @@ private:
dataSize = 1280; dataSize = 1280;
packetSize = GOTTHARD_PACKET_SIZE; packetSize = GOTTHARD_PACKET_SIZE;
packetsPerFrame = 2; packetsPerFrame = 2;
imageSize = dataSize*packetsPerFrame; imageSize = dataSize * packetsPerFrame;
frameIndexMask = 0xFFFFFFFE; frameIndexMask = 0xFFFFFFFE;
frameIndexOffset = 1; frameIndexOffset = 1;
packetIndexMask = 1; packetIndexMask = 1;
maxFramesPerFile = MAX_FRAMES_PER_FILE; maxFramesPerFile = MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize =
FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 50000; defaultFifoDepth = 50000;
}; };
/** /**
* Get Header Infomation (frame number, packet number) * Get Header Infomation (frame number, packet number)
* @param index thread index for debugging purposes * @param index thread index for debugging purposes
@ -279,14 +269,13 @@ private:
* @param frameNumber frame number * @param frameNumber frame number
* @param packetNumber packet number * @param packetNumber packet number
*/ */
void GetHeaderInfo(int index, char* packetData, bool oddStartingPacket, void GetHeaderInfo(int index, char *packetData, bool oddStartingPacket,
uint64_t& frameNumber, uint32_t& packetNumber) const uint64_t &frameNumber, uint32_t &packetNumber) const {
{
if (nPixelsX == 1280) { if (nPixelsX == 1280) {
frameNumber = *reinterpret_cast<uint32_t*>(packetData); frameNumber = *reinterpret_cast<uint32_t *>(packetData);
if (oddStartingPacket) if (oddStartingPacket)
frameNumber++; frameNumber++;
packetNumber = frameNumber&packetIndexMask; packetNumber = frameNumber & packetIndexMask;
frameNumber = (frameNumber & frameIndexMask) >> frameIndexOffset; frameNumber = (frameNumber & frameIndexMask) >> frameIndexOffset;
} else { } else {
frameNumber = *reinterpret_cast<uint32_t *>(packetData); frameNumber = *reinterpret_cast<uint32_t *>(packetData);
@ -294,24 +283,24 @@ private:
} }
} }
/** /**
* Set ROI * Set ROI
* @param i ROI * @param i ROI
*/ */
void SetROI(slsDetectorDefs::ROI i) { void SetROI(slsDetectorDefs::ROI i) {
// all adcs // all adcs
if(i.xmin == -1) { if (i.xmin == -1) {
nPixelsX = 1280; nPixelsX = 1280;
dataSize = 1280; dataSize = 1280;
packetSize = GOTTHARD_PACKET_SIZE; packetSize = GOTTHARD_PACKET_SIZE;
packetsPerFrame = 2; packetsPerFrame = 2;
imageSize = dataSize*packetsPerFrame; imageSize = dataSize * packetsPerFrame;
frameIndexMask = 0xFFFFFFFE; frameIndexMask = 0xFFFFFFFE;
frameIndexOffset = 1; frameIndexOffset = 1;
packetIndexMask = 1; packetIndexMask = 1;
maxFramesPerFile = MAX_FRAMES_PER_FILE; maxFramesPerFile = MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES +
sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 50000; defaultFifoDepth = 50000;
nPixelsXComplete = 0; nPixelsXComplete = 0;
nPixelsYComplete = 0; nPixelsYComplete = 0;
@ -324,12 +313,13 @@ private:
dataSize = 512; dataSize = 512;
packetSize = 518; packetSize = 518;
packetsPerFrame = 1; packetsPerFrame = 1;
imageSize = dataSize*packetsPerFrame; imageSize = dataSize * packetsPerFrame;
frameIndexMask = 0xFFFFFFFF; frameIndexMask = 0xFFFFFFFF;
frameIndexOffset = 0; frameIndexOffset = 0;
packetIndexMask = 0; packetIndexMask = 0;
maxFramesPerFile = SHORT_MAX_FRAMES_PER_FILE; maxFramesPerFile = SHORT_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES +
sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 75000; defaultFifoDepth = 75000;
nPixelsXComplete = 1280; nPixelsXComplete = 1280;
nPixelsYComplete = 1; nPixelsYComplete = 1;
@ -343,16 +333,16 @@ private:
* @param i ROI * @param i ROI
* @returns adc configured * @returns adc configured
*/ */
int GetAdcConfigured(int index, slsDetectorDefs::ROI i) const{ int GetAdcConfigured(int index, slsDetectorDefs::ROI i) const {
int adc = -1; int adc = -1;
// single adc // single adc
if(i.xmin != -1) { if (i.xmin != -1) {
// gotthard can have only one adc per detector enabled (or all) // gotthard can have only one adc per detector enabled (or all)
//adc = mid value/numchans also for only 1 roi // adc = mid value/numchans also for only 1 roi
adc = ((((i.xmax) + (i.xmin))/2)/ adc = ((((i.xmax) + (i.xmin)) / 2) / (nChan * nChipsPerAdc));
(nChan * nChipsPerAdc)); if ((adc < 0) || (adc > 4)) {
if((adc < 0) || (adc > 4)) { LOG(logWARNING) << index
LOG(logWARNING) << index << ": Deleting ROI. " << ": Deleting ROI. "
"Adc value should be between 0 and 4"; "Adc value should be between 0 and 4";
adc = -1; adc = -1;
} }
@ -367,12 +357,12 @@ private:
* @param packetData pointer to data * @param packetData pointer to data
* @returns true or false for odd starting packet number * @returns true or false for odd starting packet number
*/ */
bool SetOddStartingPacket(int index, char* packetData) { bool SetOddStartingPacket(int index, char *packetData) {
bool oddStartingPacket = true; bool oddStartingPacket = true;
// care only if no roi // care only if no roi
if (nPixelsX == 1280) { if (nPixelsX == 1280) {
uint32_t fnum = ((uint32_t)(*((uint32_t*)(packetData)))); uint32_t fnum = ((uint32_t)(*((uint32_t *)(packetData))));
uint32_t firstData = ((uint32_t)(*((uint32_t*)(packetData + 4)))); uint32_t firstData = ((uint32_t)(*((uint32_t *)(packetData + 4))));
// first packet // first packet
if (firstData == 0xCACACACA) { if (firstData == 0xCACACACA) {
// packet number should be 0, but is 1 => so odd starting packet // packet number should be 0, but is 1 => so odd starting packet
@ -394,26 +384,24 @@ private:
} }
return oddStartingPacket; return oddStartingPacket;
}; };
}; };
class EigerData : public GeneralData { class EigerData : public GeneralData {
public: public:
/** Constructor */ /** Constructor */
EigerData(){ EigerData() {
myDetectorType = slsDetectorDefs::EIGER; myDetectorType = slsDetectorDefs::EIGER;
nPixelsX = (256*2); nPixelsX = (256 * 2);
nPixelsY = 256; nPixelsY = 256;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
dataSize = 1024; dataSize = 1024;
packetSize = headerSizeinPacket + dataSize; packetSize = headerSizeinPacket + dataSize;
packetsPerFrame = 256; packetsPerFrame = 256;
imageSize = dataSize*packetsPerFrame; imageSize = dataSize * packetsPerFrame;
maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE; maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize =
FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 1000; defaultFifoDepth = 1000;
threadsPerReceiver = 2; threadsPerReceiver = 2;
headerPacketSize = 40; headerPacketSize = 40;
@ -427,7 +415,7 @@ class EigerData : public GeneralData {
*/ */
void SetDynamicRange(int dr, bool tgEnable) { void SetDynamicRange(int dr, bool tgEnable) {
packetsPerFrame = (tgEnable ? 4 : 16) * dr; packetsPerFrame = (tgEnable ? 4 : 16) * dr;
imageSize = dataSize*packetsPerFrame; imageSize = dataSize * packetsPerFrame;
defaultFifoDepth = (dr == 32 ? 100 : 1000); defaultFifoDepth = (dr == 32 ? 100 : 1000);
} }
@ -440,21 +428,17 @@ class EigerData : public GeneralData {
dataSize = (tgEnable ? 4096 : 1024); dataSize = (tgEnable ? 4096 : 1024);
packetSize = headerSizeinPacket + dataSize; packetSize = headerSizeinPacket + dataSize;
packetsPerFrame = (tgEnable ? 4 : 16) * dr; packetsPerFrame = (tgEnable ? 4 : 16) * dr;
imageSize = dataSize*packetsPerFrame; imageSize = dataSize * packetsPerFrame;
}; };
}; };
class JungfrauData : public GeneralData { class JungfrauData : public GeneralData {
public: public:
/** Constructor */ /** Constructor */
JungfrauData(){ JungfrauData() {
myDetectorType = slsDetectorDefs::JUNGFRAU; myDetectorType = slsDetectorDefs::JUNGFRAU;
nPixelsX = (256*4); nPixelsX = (256 * 4);
nPixelsY = 512; nPixelsY = 512;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
dataSize = 8192; dataSize = 8192;
@ -462,13 +446,13 @@ class JungfrauData : public GeneralData {
packetsPerFrame = 128; packetsPerFrame = 128;
imageSize = dataSize * packetsPerFrame; imageSize = dataSize * packetsPerFrame;
maxFramesPerFile = JFRAU_MAX_FRAMES_PER_FILE; maxFramesPerFile = JFRAU_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize =
FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 2500; defaultFifoDepth = 2500;
standardheader = true; standardheader = true;
defaultUdpSocketBufferSize = (1000 * 1024 * 1024); defaultUdpSocketBufferSize = (1000 * 1024 * 1024);
}; };
/** /**
* set number of interfaces (jungfrau) * set number of interfaces (jungfrau)
* @param number of interfaces * @param number of interfaces
@ -495,13 +479,13 @@ class JungfrauData : public GeneralData {
}; };
class Mythen3Data : public GeneralData { class Mythen3Data : public GeneralData {
private: private:
int ncounters; int ncounters;
const int NCHAN = 1280; const int NCHAN = 1280;
public:
public:
/** Constructor */ /** Constructor */
Mythen3Data(){ Mythen3Data() {
myDetectorType = slsDetectorDefs::MYTHEN3; myDetectorType = slsDetectorDefs::MYTHEN3;
ncounters = 3; ncounters = 3;
nPixelsX = (NCHAN * ncounters); // max 1280 channels x 3 counters nPixelsX = (NCHAN * ncounters); // max 1280 channels x 3 counters
@ -512,7 +496,8 @@ public:
packetsPerFrame = 2; packetsPerFrame = 2;
imageSize = dataSize * packetsPerFrame; imageSize = dataSize * packetsPerFrame;
maxFramesPerFile = MYTHEN3_MAX_FRAMES_PER_FILE; maxFramesPerFile = MYTHEN3_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize =
FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 50000; defaultFifoDepth = 50000;
standardheader = true; standardheader = true;
defaultUdpSocketBufferSize = (1000 * 1024 * 1024); defaultUdpSocketBufferSize = (1000 * 1024 * 1024);
@ -525,12 +510,14 @@ public:
*/ */
virtual void SetNumberofCounters(const int n, const int dr) { virtual void SetNumberofCounters(const int n, const int dr) {
if (n < 1 || n > 3) { if (n < 1 || n > 3) {
throw sls::RuntimeError("Invalid number of counters " + std::to_string(n)); throw sls::RuntimeError("Invalid number of counters " +
std::to_string(n));
} }
ncounters = n; ncounters = n;
nPixelsX = NCHAN * ncounters; nPixelsX = NCHAN * ncounters;
LOG(logINFO) << "nPixelsX: " << nPixelsX; LOG(logINFO) << "nPixelsX: " << nPixelsX;
imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit imageSize = nPixelsX * nPixelsY *
((dr > 16) ? 4 : // 32 bit
((dr > 8) ? 2 : // 16 bit ((dr > 8) ? 2 : // 16 bit
((dr > 4) ? 0.5 : // 4 bit ((dr > 4) ? 0.5 : // 4 bit
0.125))); // 1 bit 0.125))); // 1 bit
@ -545,7 +532,8 @@ public:
* @param tgEnable (discarded, of no value to mythen3) * @param tgEnable (discarded, of no value to mythen3)
*/ */
void SetDynamicRange(int dr, bool tgEnable) { void SetDynamicRange(int dr, bool tgEnable) {
imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit imageSize = nPixelsX * nPixelsY *
((dr > 16) ? 4 : // 32 bit
((dr > 8) ? 2 : // 16 bit ((dr > 8) ? 2 : // 16 bit
((dr > 4) ? 0.5 : // 4 bit ((dr > 4) ? 0.5 : // 4 bit
0.125))); // 1 bit 0.125))); // 1 bit
@ -555,12 +543,10 @@ public:
} }
}; };
class Gotthard2Data : public GeneralData { class Gotthard2Data : public GeneralData {
public: public:
/** Constructor */ /** Constructor */
Gotthard2Data(){ Gotthard2Data() {
myDetectorType = slsDetectorDefs::GOTTHARD2; myDetectorType = slsDetectorDefs::GOTTHARD2;
nPixelsX = 128 * 10; nPixelsX = 128 * 10;
nPixelsY = 1; nPixelsY = 1;
@ -570,16 +556,16 @@ public:
packetsPerFrame = 1; packetsPerFrame = 1;
imageSize = dataSize * packetsPerFrame; imageSize = dataSize * packetsPerFrame;
maxFramesPerFile = GOTTHARD2_MAX_FRAMES_PER_FILE; maxFramesPerFile = GOTTHARD2_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize =
FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 50000; defaultFifoDepth = 50000;
standardheader = true; standardheader = true;
defaultUdpSocketBufferSize = (1000 * 1024 * 1024); defaultUdpSocketBufferSize = (1000 * 1024 * 1024);
}; };
}; };
class ChipTestBoardData : public GeneralData { class ChipTestBoardData : public GeneralData {
private: private:
/** Number of analog channels */ /** Number of analog channels */
const int NCHAN_ANALOG = 32; const int NCHAN_ANALOG = 32;
/** Number of digital channels */ /** Number of digital channels */
@ -587,25 +573,25 @@ private:
/** Number of bytes per analog channel */ /** Number of bytes per analog channel */
const int NUM_BYTES_PER_ANALOG_CHANNEL = 2; const int NUM_BYTES_PER_ANALOG_CHANNEL = 2;
public: public:
/** Constructor */ /** Constructor */
ChipTestBoardData(){ ChipTestBoardData() {
myDetectorType = slsDetectorDefs::CHIPTESTBOARD; myDetectorType = slsDetectorDefs::CHIPTESTBOARD;
nPixelsX = 36; // total number of channels nPixelsX = 36; // total number of channels
nPixelsY = 1; // number of samples nPixelsY = 1; // number of samples
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
dataSize = UDP_PACKET_DATA_BYTES; dataSize = UDP_PACKET_DATA_BYTES;
packetSize = headerSizeinPacket + dataSize; packetSize = headerSizeinPacket + dataSize;
//packetsPerFrame = 1; // packetsPerFrame = 1;
imageSize = nPixelsX * nPixelsY * 2; imageSize = nPixelsX * nPixelsY * 2;
frameIndexMask = 0xFFFFFF; // 10g frameIndexMask = 0xFFFFFF; // 10g
frameIndexOffset = 8; // 10g frameIndexOffset = 8; // 10g
packetIndexMask = 0xFF; //10g packetIndexMask = 0xFF; // 10g
packetsPerFrame = ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES); packetsPerFrame =
ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES);
maxFramesPerFile = CTB_MAX_FRAMES_PER_FILE; maxFramesPerFile = CTB_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize =
FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 2500; defaultFifoDepth = 2500;
standardheader = true; standardheader = true;
}; };
@ -619,7 +605,8 @@ public:
* @param f readout flags * @param f readout flags
* @returns analog data bytes * @returns analog data bytes
*/ */
int setImageSize(uint32_t a, uint32_t as, uint32_t ds, bool t, slsDetectorDefs::readoutMode f) { int setImageSize(uint32_t a, uint32_t as, uint32_t ds, bool t,
slsDetectorDefs::readoutMode f) {
int nachans = 0, ndchans = 0; int nachans = 0, ndchans = 0;
int adatabytes = 0, ddatabytes = 0; int adatabytes = 0, ddatabytes = 0;
@ -667,18 +654,15 @@ public:
return adatabytes; return adatabytes;
} }
}; };
class MoenchData : public GeneralData { class MoenchData : public GeneralData {
private:
private:
/** Number of bytes per analog channel */ /** Number of bytes per analog channel */
const int NUM_BYTES_PER_ANALOG_CHANNEL = 2; const int NUM_BYTES_PER_ANALOG_CHANNEL = 2;
public: public:
/** Constructor */ /** Constructor */
MoenchData() { MoenchData() {
myDetectorType = slsDetectorDefs::MOENCH; myDetectorType = slsDetectorDefs::MOENCH;
@ -689,10 +673,12 @@ public:
packetSize = headerSizeinPacket + dataSize; packetSize = headerSizeinPacket + dataSize;
// packetsPerFrame = 1; // packetsPerFrame = 1;
imageSize = nPixelsX * nPixelsY * 2; imageSize = nPixelsX * nPixelsY * 2;
packetsPerFrame = ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES); packetsPerFrame =
ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES);
frameIndexMask = 0xFFFFFF; frameIndexMask = 0xFFFFFF;
maxFramesPerFile = MOENCH_MAX_FRAMES_PER_FILE; maxFramesPerFile = MOENCH_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize =
FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 2500; defaultFifoDepth = 2500;
standardheader = true; standardheader = true;
}; };
@ -706,7 +692,8 @@ public:
* @param f readout flags * @param f readout flags
* @returns analog data bytes * @returns analog data bytes
*/ */
int setImageSize(uint32_t a, uint32_t as, uint32_t ds, bool t, slsDetectorDefs::readoutMode) { int setImageSize(uint32_t a, uint32_t as, uint32_t ds, bool t,
slsDetectorDefs::readoutMode) {
// count number of channels in x, each adc has 25 channels each // count number of channels in x, each adc has 25 channels each
int nchanTop = __builtin_popcount(a & 0xF0F0F0F0) * 25; int nchanTop = __builtin_popcount(a & 0xF0F0F0F0) * 25;
@ -719,8 +706,8 @@ public:
nrows = 2; nrows = 2;
} }
nPixelsY = as / 25 * nrows; nPixelsY = as / 25 * nrows;
LOG(logINFO) << "Number of Pixels: [" << nPixelsX << ", " << nPixelsY << "]"; LOG(logINFO) << "Number of Pixels: [" << nPixelsX << ", " << nPixelsY
<< "]";
// 10G // 10G
if (t) { if (t) {
@ -740,6 +727,3 @@ public:
return imageSize; return imageSize;
} }
}; };

833
slsReceiverSoftware/src/HDF5File.cpp Executable file → Normal file

File diff suppressed because it is too large Load Diff

49
slsReceiverSoftware/src/HDF5File.h Executable file → Normal file
View File

@ -6,19 +6,18 @@
* creates/closes the file and writes data to it * creates/closes the file and writes data to it
***********************************************/ ***********************************************/
/** /**
*@short sets/gets properties for the HDF5 file, creates/closes the file and writes data to it *@short sets/gets properties for the HDF5 file, creates/closes the file and
*writes data to it
*/ */
#include "File.h" #include "File.h"
#include "H5Cpp.h" #include "H5Cpp.h"
#ifndef H5_NO_NAMESPACE #ifndef H5_NO_NAMESPACE
using namespace H5; using namespace H5;
#endif #endif
#include <mutex> #include <mutex>
class HDF5File : private virtual slsDetectorDefs, public File { class HDF5File : private virtual slsDetectorDefs, public File {
public: public:
@ -41,41 +40,42 @@ class HDF5File : private virtual slsDetectorDefs, public File {
* @param ny number of pixels in y direction * @param ny number of pixels in y direction
* @param smode pointer to silent mode * @param smode pointer to silent mode
*/ */
HDF5File(int ind, uint32_t* maxf, HDF5File(int ind, uint32_t *maxf, int *nd, std::string *fname,
int* nd, std::string* fname, std::string* fpath, uint64_t* findex, bool* owenable, std::string *fpath, uint64_t *findex, bool *owenable, int *dindex,
int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, int *nunits, uint64_t *nf, uint32_t *dr, uint32_t *portno,
uint32_t nx, uint32_t ny, uint32_t nx, uint32_t ny, bool *smode);
bool* smode);
~HDF5File(); ~HDF5File();
void SetNumberofPixels(uint32_t nx, uint32_t ny); void SetNumberofPixels(uint32_t nx, uint32_t ny);
void CreateFile(); void CreateFile();
void CloseCurrentFile(); void CloseCurrentFile();
void CloseAllFiles(); void CloseAllFiles();
void WriteToFile(char* buffer, int bufferSize, uint64_t currentFrameNumber, uint32_t numPacketsCaught); void WriteToFile(char *buffer, int bufferSize, uint64_t currentFrameNumber,
void CreateMasterFile(bool masterFileWriteEnable, masterAttributes& masterFileAttributes); uint32_t numPacketsCaught);
void CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes);
void EndofAcquisition(bool anyPacketsCaught, uint64_t numImagesCaught); void EndofAcquisition(bool anyPacketsCaught, uint64_t numImagesCaught);
private: private:
void CloseFile(H5File *&fd, bool masterFile);
void CloseFile(H5File*& fd, bool masterFile); void WriteDataFile(uint64_t currentFrameNumber, char *buffer);
void WriteDataFile(uint64_t currentFrameNumber, char* buffer); void WriteParameterDatasets(uint64_t currentFrameNumber,
void WriteParameterDatasets(uint64_t currentFrameNumber, sls_receiver_header* rheader); sls_receiver_header *rheader);
void ExtendDataset(); void ExtendDataset();
void CreateDataFile(); void CreateDataFile();
void CreateMasterDataFile(masterAttributes& masterFileAttributes); void CreateMasterDataFile(masterAttributes &masterFileAttributes);
void CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf); void CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf);
void LinkVirtualInMaster(std::string fname, std::string dsetname); void LinkVirtualInMaster(std::string fname, std::string dsetname);
hid_t GetDataTypeinC(DataType dtype); hid_t GetDataTypeinC(DataType dtype);
static std::mutex hdf5Lib; static std::mutex hdf5Lib;
H5File* masterfd; H5File *masterfd;
/** Virtual File handle ( only file name because /** Virtual File handle ( only file name because
code in C as H5Pset_virtual doesnt exist yet in C++) */ code in C as H5Pset_virtual doesnt exist yet in C++) */
hid_t virtualfd; hid_t virtualfd;
H5File* filefd; H5File *filefd;
DataSpace* dataspace; DataSpace *dataspace;
DataSet* dataset; DataSet *dataset;
DataType datatype; DataType datatype;
uint32_t nPixelsX; uint32_t nPixelsX;
@ -84,12 +84,11 @@ class HDF5File : private virtual slsDetectorDefs, public File {
uint64_t numActualPacketsInFile; uint64_t numActualPacketsInFile;
int numFilesinAcquisition; int numFilesinAcquisition;
std::vector <const char*> parameterNames; std::vector<const char *> parameterNames;
std::vector <DataType> parameterDataTypes; std::vector<DataType> parameterDataTypes;
DataSpace* dataspace_para; DataSpace *dataspace_para;
std::vector <DataSet*> dataset_para; std::vector<DataSet *> dataset_para;
uint64_t extNumImages; uint64_t extNumImages;
}; };
#endif #endif

261
slsReceiverSoftware/src/Implementation.cpp Executable file → Normal file
View File

@ -4,9 +4,9 @@
#include "Fifo.h" #include "Fifo.h"
#include "GeneralData.h" #include "GeneralData.h"
#include "Listener.h" #include "Listener.h"
#include "ToString.h"
#include "ZmqSocket.h" //just for the zmq port define #include "ZmqSocket.h" //just for the zmq port define
#include "file_utils.h" #include "file_utils.h"
#include "ToString.h"
#include <cerrno> //eperm #include <cerrno> //eperm
#include <cstdlib> //system #include <cstdlib> //system
@ -188,7 +188,8 @@ void Implementation::SetupFifoStructure() {
} catch (...) { } catch (...) {
fifo.clear(); fifo.clear();
fifoDepth = 0; fifoDepth = 0;
throw sls::RuntimeError("Could not allocate memory for fifo structure " + throw sls::RuntimeError(
"Could not allocate memory for fifo structure " +
std::to_string(i) + ". FifoDepth is now 0."); std::to_string(i) + ". FifoDepth is now 0.");
} }
// set the listener & dataprocessor threads to point to the right fifo // set the listener & dataprocessor threads to point to the right fifo
@ -203,13 +204,12 @@ void Implementation::SetupFifoStructure() {
LOG(logINFO) << "Memory Allocated Per Fifo: " LOG(logINFO) << "Memory Allocated Per Fifo: "
<< (double)(((size_t)(generalData->imageSize) + << (double)(((size_t)(generalData->imageSize) +
(size_t)(generalData->fifoBufferHeaderSize)) * (size_t)(generalData->fifoBufferHeaderSize)) *
(size_t)fifoDepth) / (double)(1024 * 1024) (size_t)fifoDepth) /
(double)(1024 * 1024)
<< " MB"; << " MB";
LOG(logINFO) << numThreads << " Fifo structure(s) reconstructed"; LOG(logINFO) << numThreads << " Fifo structure(s) reconstructed";
} }
/************************************************** /**************************************************
* * * *
* Configuration Parameters * * Configuration Parameters *
@ -227,11 +227,11 @@ void Implementation::setDetectorType(const detectorType d) {
case MOENCH: case MOENCH:
case MYTHEN3: case MYTHEN3:
case GOTTHARD2: case GOTTHARD2:
LOG(logINFO) << " ***** " << sls::ToString(d) LOG(logINFO) << " ***** " << sls::ToString(d) << " Receiver *****";
<< " Receiver *****";
break; break;
default: default:
throw sls::RuntimeError("This is an unknown receiver type " + std::to_string(static_cast<int>(d))); throw sls::RuntimeError("This is an unknown receiver type " +
std::to_string(static_cast<int>(d)));
} }
// set detector specific variables // set detector specific variables
@ -280,15 +280,16 @@ void Implementation::setDetectorType(const detectorType d) {
&activated, &deactivatedPaddingEnable, &silentMode)); &activated, &deactivatedPaddingEnable, &silentMode));
dataProcessor.push_back(sls::make_unique<DataProcessor>( dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable, i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable,
&masterFileWriteEnable, &dataStreamEnable, &masterFileWriteEnable, &dataStreamEnable, &dynamicRange,
&dynamicRange, &streamingFrequency, &streamingTimerInMs, &streamingFrequency, &streamingTimerInMs, &framePadding,
&framePadding, &activated, &deactivatedPaddingEnable, &activated, &deactivatedPaddingEnable, &silentMode, &quadEnable,
&silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset, &ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes));
&ctbAnalogDataBytes));
} catch (...) { } catch (...) {
listener.clear(); listener.clear();
dataProcessor.clear(); dataProcessor.clear();
throw sls::RuntimeError("Could not create listener/dataprocessor threads (index:" + std::to_string(i) + ")"); throw sls::RuntimeError(
"Could not create listener/dataprocessor threads (index:" +
std::to_string(i) + ")");
} }
} }
@ -349,14 +350,14 @@ void Implementation::setDetectorPositionId(const int id) {
LOG(logINFO) << "Detector Position Id:" << detID; LOG(logINFO) << "Detector Position Id:" << detID;
// update zmq port // update zmq port
streamingPort = DEFAULT_ZMQ_RX_PORTNO + streamingPort =
(detID * (myDetectorType == EIGER ? 2 : 1)); DEFAULT_ZMQ_RX_PORTNO + (detID * (myDetectorType == EIGER ? 2 : 1));
for (unsigned int i = 0; i < dataProcessor.size(); ++i) { for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->SetupFileWriter( dataProcessor[i]->SetupFileWriter(
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, &filePath, fileWriteEnable, (int *)numDet, &framesPerFile, &fileName,
&fileIndex, &overwriteEnable, &detID, &numThreads, &numberOfTotalFrames, &filePath, &fileIndex, &overwriteEnable, &detID, &numThreads,
&dynamicRange, &udpPortNum[i], generalData); &numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData);
} }
assert(numDet[1] != 0); assert(numDet[1] != 0);
for (unsigned int i = 0; i < listener.size(); ++i) { for (unsigned int i = 0; i < listener.size(); ++i) {
@ -373,7 +374,7 @@ std::string Implementation::getDetectorHostname() const {
return detHostname; return detHostname;
} }
void Implementation::setDetectorHostname(const std::string& c) { void Implementation::setDetectorHostname(const std::string &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
if (!c.empty()) if (!c.empty())
@ -412,15 +413,13 @@ Implementation::getFrameDiscardPolicy() const {
return frameDiscardMode; return frameDiscardMode;
} }
void Implementation::setFrameDiscardPolicy( void Implementation::setFrameDiscardPolicy(const frameDiscardPolicy i) {
const frameDiscardPolicy i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
if (i >= 0 && i < NUM_DISCARD_POLICIES) if (i >= 0 && i < NUM_DISCARD_POLICIES)
frameDiscardMode = i; frameDiscardMode = i;
LOG(logINFO) << "Frame Discard Policy: " LOG(logINFO) << "Frame Discard Policy: " << sls::ToString(frameDiscardMode);
<< sls::ToString(frameDiscardMode);
} }
bool Implementation::getFramePaddingEnable() const { bool Implementation::getFramePaddingEnable() const {
@ -435,7 +434,6 @@ void Implementation::setFramePaddingEnable(const bool i) {
LOG(logINFO) << "Frame Padding: " << framePadding; LOG(logINFO) << "Frame Padding: " << framePadding;
} }
/************************************************** /**************************************************
* * * *
* File Parameters * * File Parameters *
@ -469,11 +467,11 @@ std::string Implementation::getFilePath() const {
return filePath; return filePath;
} }
void Implementation::setFilePath(const std::string& c) { void Implementation::setFilePath(const std::string &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
if (!c.empty()) { if (!c.empty()) {
mkdir_p(c); //throws if it can't create mkdir_p(c); // throws if it can't create
filePath = c; filePath = c;
} }
LOG(logINFO) << "File path: " << filePath; LOG(logINFO) << "File path: " << filePath;
@ -484,7 +482,7 @@ std::string Implementation::getFileName() const {
return fileName; return fileName;
} }
void Implementation::setFileName(const std::string& c) { void Implementation::setFileName(const std::string &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
if (!c.empty()) if (!c.empty())
@ -516,11 +514,13 @@ void Implementation::setFileWriteEnable(const bool b) {
dataProcessor[i]->SetupFileWriter( dataProcessor[i]->SetupFileWriter(
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, fileWriteEnable, (int *)numDet, &framesPerFile, &fileName,
&filePath, &fileIndex, &overwriteEnable, &detID, &numThreads, &filePath, &fileIndex, &overwriteEnable, &detID, &numThreads,
&numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData); &numberOfTotalFrames, &dynamicRange, &udpPortNum[i],
generalData);
} }
} }
LOG(logINFO) << "File Write Enable: " << (fileWriteEnable ? "enabled" : "disabled"); LOG(logINFO) << "File Write Enable: "
<< (fileWriteEnable ? "enabled" : "disabled");
} }
bool Implementation::getMasterFileWriteEnable() const { bool Implementation::getMasterFileWriteEnable() const {
@ -544,7 +544,8 @@ void Implementation::setOverwriteEnable(const bool b) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
overwriteEnable = b; overwriteEnable = b;
LOG(logINFO) << "Overwrite Enable: " << (overwriteEnable ? "enabled" : "disabled"); LOG(logINFO) << "Overwrite Enable: "
<< (overwriteEnable ? "enabled" : "disabled");
} }
uint32_t Implementation::getFramesPerFile() const { uint32_t Implementation::getFramesPerFile() const {
@ -559,7 +560,6 @@ void Implementation::setFramesPerFile(const uint32_t i) {
LOG(logINFO) << "Frames per file: " << framesPerFile; LOG(logINFO) << "Frames per file: " << framesPerFile;
} }
/************************************************** /**************************************************
* * * *
* Acquisition * * Acquisition *
@ -617,7 +617,8 @@ int Implementation::getProgress() const {
currentFrameIndex = -1; currentFrameIndex = -1;
} }
return (100.00 * ((double)(currentFrameIndex + 1) / (double)numberOfTotalFrames)); return (100.00 *
((double)(currentFrameIndex + 1) / (double)numberOfTotalFrames));
} }
std::vector<uint64_t> Implementation::getNumMissingPackets() const { std::vector<uint64_t> Implementation::getNumMissingPackets() const {
@ -673,9 +674,7 @@ void Implementation::startReceiver() {
LOG(logINFO) << "Status: " << sls::ToString(status); LOG(logINFO) << "Status: " << sls::ToString(status);
} }
void Implementation::setStoppedFlag(bool stopped) { void Implementation::setStoppedFlag(bool stopped) { stoppedFlag = stopped; }
stoppedFlag = stopped;
}
void Implementation::stopReceiver() { void Implementation::stopReceiver() {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
@ -703,8 +702,7 @@ void Implementation::stopReceiver() {
uint64_t maxIndexCaught = 0; uint64_t maxIndexCaught = 0;
bool anycaught = false; bool anycaught = false;
for (const auto &it : dataProcessor) { for (const auto &it : dataProcessor) {
maxIndexCaught = maxIndexCaught = std::max(maxIndexCaught, it->GetProcessedIndex());
std::max(maxIndexCaught, it->GetProcessedIndex());
if (it->GetStartedFlag()) if (it->GetStartedFlag())
anycaught = true; anycaught = true;
} }
@ -733,8 +731,7 @@ void Implementation::stopReceiver() {
int nf = dataProcessor[i]->GetNumFramesCaught(); int nf = dataProcessor[i]->GetNumFramesCaught();
tot += nf; tot += nf;
TLogLevel lev = TLogLevel lev = (((int64_t)mp[i]) > 0) ? logINFORED : logINFOGREEN;
(((int64_t)mp[i]) > 0) ? logINFORED : logINFOGREEN;
LOG(lev) << LOG(lev) <<
// udp port number could be the second if selected interface is // udp port number could be the second if selected interface is
// 2 for jungfrau // 2 for jungfrau
@ -770,8 +767,9 @@ void Implementation::startReadout() {
totalPacketsReceived += it->GetPacketsCaught(); totalPacketsReceived += it->GetPacketsCaught();
// wait for all packets // wait for all packets
const int numPacketsToReceive = const int numPacketsToReceive = numberOfTotalFrames *
numberOfTotalFrames * generalData->packetsPerFrame * listener.size(); generalData->packetsPerFrame *
listener.size();
if (totalPacketsReceived != numPacketsToReceive) { if (totalPacketsReceived != numPacketsToReceive) {
while (totalPacketsReceived != previousValue) { while (totalPacketsReceived != previousValue) {
LOG(logDEBUG3) LOG(logDEBUG3)
@ -808,8 +806,7 @@ void Implementation::closeFiles() {
bool anycaught = false; bool anycaught = false;
for (const auto &it : dataProcessor) { for (const auto &it : dataProcessor) {
it->CloseFiles(); it->CloseFiles();
maxIndexCaught = maxIndexCaught = std::max(maxIndexCaught, it->GetProcessedIndex());
std::max(maxIndexCaught, it->GetProcessedIndex());
if (it->GetStartedFlag()) if (it->GetStartedFlag())
anycaught = true; anycaught = true;
} }
@ -846,11 +843,11 @@ void Implementation::ResetParametersforNewAcquisition() {
void Implementation::CreateUDPSockets() { void Implementation::CreateUDPSockets() {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
try{ try {
for (unsigned int i = 0; i < listener.size(); ++i) { for (unsigned int i = 0; i < listener.size(); ++i) {
listener[i]->CreateUDPSockets(); listener[i]->CreateUDPSockets();
} }
} catch(const sls::RuntimeError &e) { } catch (const sls::RuntimeError &e) {
shutDownUDPSockets(); shutDownUDPSockets();
throw sls::RuntimeError("Could not create UDP Socket(s)."); throw sls::RuntimeError("Could not create UDP Socket(s).");
} }
@ -874,8 +871,12 @@ void Implementation::SetupWriter() {
attr.subPeriodNs = subPeriod; attr.subPeriodNs = subPeriod;
attr.periodNs = acquisitionPeriod; attr.periodNs = acquisitionPeriod;
attr.quadEnable = quadEnable; attr.quadEnable = quadEnable;
attr.analogFlag = (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0; attr.analogFlag =
attr.digitalFlag = (readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0; (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
: 0;
attr.digitalFlag =
(readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
: 0;
attr.adcmask = tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga; attr.adcmask = tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
attr.dbitoffset = ctbDbitOffset; attr.dbitoffset = ctbDbitOffset;
attr.dbitlist = 0; attr.dbitlist = 0;
@ -889,7 +890,7 @@ void Implementation::SetupWriter() {
for (unsigned int i = 0; i < dataProcessor.size(); ++i) { for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->CreateNewFile(attr); dataProcessor[i]->CreateNewFile(attr);
} }
} catch(const sls::RuntimeError &e) { } catch (const sls::RuntimeError &e) {
shutDownUDPSockets(); shutDownUDPSockets();
closeFiles(); closeFiles();
throw sls::RuntimeError("Could not create file."); throw sls::RuntimeError("Could not create file.");
@ -914,7 +915,6 @@ void Implementation::StartRunning() {
} }
} }
/************************************************** /**************************************************
* * * *
* Network Configuration (UDP) * * Network Configuration (UDP) *
@ -967,15 +967,17 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
dataProcessor.push_back(sls::make_unique<DataProcessor>( dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, myDetectorType, fifo_ptr, &fileFormatType, i, myDetectorType, fifo_ptr, &fileFormatType,
fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable, fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable,
&dynamicRange, &streamingFrequency, &dynamicRange, &streamingFrequency, &streamingTimerInMs,
&streamingTimerInMs, &framePadding, &activated, &framePadding, &activated, &deactivatedPaddingEnable,
&deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList, &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset,
&ctbDbitOffset, &ctbAnalogDataBytes)); &ctbAnalogDataBytes));
dataProcessor[i]->SetGeneralData(generalData); dataProcessor[i]->SetGeneralData(generalData);
} catch (...) { } catch (...) {
listener.clear(); listener.clear();
dataProcessor.clear(); dataProcessor.clear();
throw sls::RuntimeError("Could not create listener/dataprocessor threads (index:" + std::to_string(i) + ")"); throw sls::RuntimeError(
"Could not create listener/dataprocessor threads (index:" +
std::to_string(i) + ")");
} }
// streamer threads // streamer threads
if (dataStreamEnable) { if (dataStreamEnable) {
@ -988,19 +990,22 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
nd[1] = 2; nd[1] = 2;
} }
dataStreamer.push_back(sls::make_unique<DataStreamer>( dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, fd,
fd, (int*)nd, &quadEnable, &numberOfTotalFrames)); (int *)nd, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets( dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP); &numThreads, streamingPort, streamingSrcIP);
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader); dataStreamer[i]->SetAdditionalJsonHeader(
additionalJsonHeader);
} catch (...) { } catch (...) {
if (dataStreamEnable) { if (dataStreamEnable) {
dataStreamer.clear(); dataStreamer.clear();
dataStreamEnable = false; dataStreamEnable = false;
} }
throw sls::RuntimeError("Could not create datastreamer threads (index:" + std::to_string(i) + ")"); throw sls::RuntimeError(
"Could not create datastreamer threads (index:" +
std::to_string(i) + ")");
} }
} }
} }
@ -1089,7 +1094,9 @@ void Implementation::setUDPSocketBufferSize(const int64_t s) {
size_t listSize = listener.size(); size_t listSize = listener.size();
if (myDetectorType == JUNGFRAU && (int)listSize != numUDPInterfaces) { if (myDetectorType == JUNGFRAU && (int)listSize != numUDPInterfaces) {
throw sls::RuntimeError("Number of Interfaces " + std::to_string(numUDPInterfaces) + " do not match listener size " + std::to_string(listSize)); throw sls::RuntimeError(
"Number of Interfaces " + std::to_string(numUDPInterfaces) +
" do not match listener size " + std::to_string(listSize));
} }
for (unsigned int i = 0; i < listSize; ++i) { for (unsigned int i = 0; i < listSize; ++i) {
@ -1102,7 +1109,6 @@ int64_t Implementation::getActualUDPSocketBufferSize() const {
return actualUDPSocketBufferSize; return actualUDPSocketBufferSize;
} }
/************************************************** /**************************************************
* * * *
* ZMQ Streaming Parameters (ZMQ) * * ZMQ Streaming Parameters (ZMQ) *
@ -1132,16 +1138,18 @@ void Implementation::setDataStreamEnable(const bool enable) {
nd[1] = 2; nd[1] = 2;
} }
dataStreamer.push_back(sls::make_unique<DataStreamer>( dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, fd,
fd, (int*)nd, &quadEnable, &numberOfTotalFrames)); (int *)nd, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets( dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP); &numThreads, streamingPort, streamingSrcIP);
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader); dataStreamer[i]->SetAdditionalJsonHeader(
additionalJsonHeader);
} catch (...) { } catch (...) {
dataStreamer.clear(); dataStreamer.clear();
dataStreamEnable = false; dataStreamEnable = false;
throw sls::RuntimeError("Could not set data stream enable."); throw sls::RuntimeError(
"Could not set data stream enable.");
} }
} }
SetThreadPriorities(); SetThreadPriorities();
@ -1196,54 +1204,65 @@ void Implementation::setStreamingSourceIP(const sls::IpAddr ip) {
LOG(logINFO) << "Streaming Source IP: " << streamingSrcIP; LOG(logINFO) << "Streaming Source IP: " << streamingSrcIP;
} }
std::map<std::string, std::string> Implementation::getAdditionalJsonHeader() const { std::map<std::string, std::string>
Implementation::getAdditionalJsonHeader() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
return additionalJsonHeader; return additionalJsonHeader;
} }
void Implementation::setAdditionalJsonHeader(const std::map<std::string, std::string> &c) { void Implementation::setAdditionalJsonHeader(
const std::map<std::string, std::string> &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
additionalJsonHeader = c; additionalJsonHeader = c;
for (const auto &it : dataStreamer) { for (const auto &it : dataStreamer) {
it->SetAdditionalJsonHeader(c); it->SetAdditionalJsonHeader(c);
} }
LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader); LOG(logINFO) << "Additional JSON Header: "
<< sls::ToString(additionalJsonHeader);
} }
std::string Implementation::getAdditionalJsonParameter(const std::string &key) const { std::string
Implementation::getAdditionalJsonParameter(const std::string &key) const {
if (additionalJsonHeader.find(key) != additionalJsonHeader.end()) { if (additionalJsonHeader.find(key) != additionalJsonHeader.end()) {
return additionalJsonHeader.at(key); return additionalJsonHeader.at(key);
} }
throw sls::RuntimeError("No key " + key + " found in additional json header"); throw sls::RuntimeError("No key " + key +
" found in additional json header");
} }
void Implementation::setAdditionalJsonParameter(const std::string &key, const std::string &value) { void Implementation::setAdditionalJsonParameter(const std::string &key,
const std::string &value) {
auto pos = additionalJsonHeader.find(key); auto pos = additionalJsonHeader.find(key);
// if value is empty, delete // if value is empty, delete
if (value.empty()) { if (value.empty()) {
// doesnt exist // doesnt exist
if (pos == additionalJsonHeader.end()) { if (pos == additionalJsonHeader.end()) {
LOG(logINFO) << "Additional json parameter (" << key << ") does not exist anyway"; LOG(logINFO) << "Additional json parameter (" << key
<< ") does not exist anyway";
} else { } else {
LOG(logINFO) << "Deleting additional json parameter (" << key << ")"; LOG(logINFO) << "Deleting additional json parameter (" << key
<< ")";
additionalJsonHeader.erase(pos); additionalJsonHeader.erase(pos);
} }
} }
// if found, set it // if found, set it
else if (pos != additionalJsonHeader.end()) { else if (pos != additionalJsonHeader.end()) {
additionalJsonHeader[key] = value; additionalJsonHeader[key] = value;
LOG(logINFO) << "Setting additional json parameter (" << key << ") to " << value; LOG(logINFO) << "Setting additional json parameter (" << key << ") to "
<< value;
} }
// append if not found // append if not found
else { else {
additionalJsonHeader[key] = value; additionalJsonHeader[key] = value;
LOG(logINFO) << "Adding additional json parameter (" << key << ") to " << value; LOG(logINFO) << "Adding additional json parameter (" << key << ") to "
<< value;
} }
for (const auto &it : dataStreamer) { for (const auto &it : dataStreamer) {
it->SetAdditionalJsonHeader(additionalJsonHeader); it->SetAdditionalJsonHeader(additionalJsonHeader);
} }
LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader); LOG(logINFO) << "Additional JSON Header: "
<< sls::ToString(additionalJsonHeader);
} }
/************************************************** /**************************************************
@ -1256,7 +1275,7 @@ void Implementation::updateTotalNumberOfFrames() {
// gotthard2: auto mode // gotthard2: auto mode
// burst mode: (bursts instead of triggers) // burst mode: (bursts instead of triggers)
// non burst mode: no bursts or triggers // non burst mode: no bursts or triggers
if (myDetectorType == GOTTHARD2 &&timingMode == AUTO_TIMING) { if (myDetectorType == GOTTHARD2 && timingMode == AUTO_TIMING) {
if (burstMode == BURST_OFF) { if (burstMode == BURST_OFF) {
repeats = numberOfBursts; repeats = numberOfBursts;
} else { } else {
@ -1315,7 +1334,8 @@ int Implementation::getNumberOfAdditionalStorageCells() const {
void Implementation::setNumberOfAdditionalStorageCells(const int i) { void Implementation::setNumberOfAdditionalStorageCells(const int i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
numberOfAdditionalStorageCells = i; numberOfAdditionalStorageCells = i;
LOG(logINFO) << "Number of Additional Storage Cells: " << numberOfAdditionalStorageCells; LOG(logINFO) << "Number of Additional Storage Cells: "
<< numberOfAdditionalStorageCells;
updateTotalNumberOfFrames(); updateTotalNumberOfFrames();
} }
@ -1352,8 +1372,8 @@ void Implementation::setAcquisitionPeriod(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
acquisitionPeriod = i; acquisitionPeriod = i;
LOG(logINFO) << "Acquisition Period: " LOG(logINFO) << "Acquisition Period: " << (double)acquisitionPeriod / (1E9)
<< (double)acquisitionPeriod / (1E9) << "s"; << "s";
} }
uint64_t Implementation::getAcquisitionTime() const { uint64_t Implementation::getAcquisitionTime() const {
@ -1378,8 +1398,7 @@ void Implementation::setSubExpTime(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
subExpTime = i; subExpTime = i;
LOG(logINFO) << "Sub Exposure Time: " << (double)subExpTime / (1E9) LOG(logINFO) << "Sub Exposure Time: " << (double)subExpTime / (1E9) << "s";
<< "s";
} }
uint64_t Implementation::getSubPeriod() const { uint64_t Implementation::getSubPeriod() const {
@ -1391,8 +1410,7 @@ void Implementation::setSubPeriod(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
subPeriod = i; subPeriod = i;
LOG(logINFO) << "Sub Period: " << (double)subPeriod / (1E9) LOG(logINFO) << "Sub Period: " << (double)subPeriod / (1E9) << "s";
<< "s";
} }
uint32_t Implementation::getNumberofAnalogSamples() const { uint32_t Implementation::getNumberofAnalogSamples() const {
@ -1406,16 +1424,15 @@ void Implementation::setNumberofAnalogSamples(const uint32_t i) {
ctbAnalogDataBytes = generalData->setImageSize( ctbAnalogDataBytes = generalData->setImageSize(
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
numberOfAnalogSamples, numberOfDigitalSamples, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
tengigaEnable, readoutType); readoutType);
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetPixelDimension(); it->SetPixelDimension();
SetupFifoStructure(); SetupFifoStructure();
} }
LOG(logINFO) << "Number of Analog Samples: " << numberOfAnalogSamples; LOG(logINFO) << "Number of Analog Samples: " << numberOfAnalogSamples;
LOG(logINFO) << "Packets per Frame: " LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
<< (generalData->packetsPerFrame);
} }
uint32_t Implementation::getNumberofDigitalSamples() const { uint32_t Implementation::getNumberofDigitalSamples() const {
@ -1429,17 +1446,15 @@ void Implementation::setNumberofDigitalSamples(const uint32_t i) {
ctbAnalogDataBytes = generalData->setImageSize( ctbAnalogDataBytes = generalData->setImageSize(
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
numberOfAnalogSamples, numberOfDigitalSamples, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
tengigaEnable, readoutType); readoutType);
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetPixelDimension(); it->SetPixelDimension();
SetupFifoStructure(); SetupFifoStructure();
} }
LOG(logINFO) << "Number of Digital Samples: " LOG(logINFO) << "Number of Digital Samples: " << numberOfDigitalSamples;
<< numberOfDigitalSamples; LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
LOG(logINFO) << "Packets per Frame: "
<< (generalData->packetsPerFrame);
} }
int Implementation::getNumberofCounters() const { int Implementation::getNumberofCounters() const {
@ -1502,9 +1517,9 @@ void Implementation::setROI(slsDetectorDefs::ROI arg) {
SetupFifoStructure(); SetupFifoStructure();
} }
LOG(logINFO) << "ROI: [" << roi.xmin << ", " << roi.xmax << "]";; LOG(logINFO) << "ROI: [" << roi.xmin << ", " << roi.xmax << "]";
LOG(logINFO) << "Packets per Frame: " ;
<< (generalData->packetsPerFrame); LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
} }
bool Implementation::getTenGigaEnable() const { bool Implementation::getTenGigaEnable() const {
@ -1524,8 +1539,8 @@ void Implementation::setTenGigaEnable(const bool b) {
case CHIPTESTBOARD: case CHIPTESTBOARD:
ctbAnalogDataBytes = generalData->setImageSize( ctbAnalogDataBytes = generalData->setImageSize(
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
numberOfAnalogSamples, numberOfDigitalSamples, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
tengigaEnable, readoutType); readoutType);
break; break;
default: default:
break; break;
@ -1534,8 +1549,7 @@ void Implementation::setTenGigaEnable(const bool b) {
SetupFifoStructure(); SetupFifoStructure();
} }
LOG(logINFO) << "Ten Giga: " << (tengigaEnable ? "enabled" : "disabled"); LOG(logINFO) << "Ten Giga: " << (tengigaEnable ? "enabled" : "disabled");
LOG(logINFO) << "Packets per Frame: " LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
<< (generalData->packetsPerFrame);
} }
int Implementation::getFlippedDataX() const { int Implementation::getFlippedDataX() const {
@ -1551,8 +1565,7 @@ void Implementation::setFlippedDataX(int enable) {
for (const auto &it : dataStreamer) { for (const auto &it : dataStreamer) {
it->SetFlippedDataX(flippedDataX); it->SetFlippedDataX(flippedDataX);
} }
} } else {
else {
if (dataStreamer.size() == 2) { if (dataStreamer.size() == 2) {
dataStreamer[0]->SetFlippedDataX(0); dataStreamer[0]->SetFlippedDataX(0);
dataStreamer[1]->SetFlippedDataX(1); dataStreamer[1]->SetFlippedDataX(1);
@ -1625,8 +1638,7 @@ void Implementation::setReadNLines(const int value) {
LOG(logINFO) << "Number of Lines to readout: " << numLinesReadout; LOG(logINFO) << "Number of Lines to readout: " << numLinesReadout;
} }
slsDetectorDefs::readoutMode slsDetectorDefs::readoutMode Implementation::getReadoutMode() const {
Implementation::getReadoutMode() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
return readoutType; return readoutType;
} }
@ -1638,16 +1650,15 @@ void Implementation::setReadoutMode(const readoutMode f) {
// side effects // side effects
ctbAnalogDataBytes = generalData->setImageSize( ctbAnalogDataBytes = generalData->setImageSize(
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
numberOfAnalogSamples, numberOfDigitalSamples, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
tengigaEnable, readoutType); readoutType);
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetPixelDimension(); it->SetPixelDimension();
SetupFifoStructure(); SetupFifoStructure();
} }
LOG(logINFO) << "Readout Mode: " << sls::ToString(f); LOG(logINFO) << "Readout Mode: " << sls::ToString(f);
LOG(logINFO) << "Packets per Frame: " LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
<< (generalData->packetsPerFrame);
} }
uint32_t Implementation::getADCEnableMask() const { uint32_t Implementation::getADCEnableMask() const {
@ -1661,18 +1672,17 @@ void Implementation::setADCEnableMask(uint32_t mask) {
ctbAnalogDataBytes = generalData->setImageSize( ctbAnalogDataBytes = generalData->setImageSize(
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
numberOfAnalogSamples, numberOfDigitalSamples, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
tengigaEnable, readoutType); readoutType);
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetPixelDimension(); it->SetPixelDimension();
SetupFifoStructure(); SetupFifoStructure();
} }
LOG(logINFO) << "ADC Enable Mask for 1Gb mode: 0x" << std::hex << adcEnableMaskOneGiga LOG(logINFO) << "ADC Enable Mask for 1Gb mode: 0x" << std::hex
<< std::dec; << adcEnableMaskOneGiga << std::dec;
LOG(logINFO) << "Packets per Frame: " LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
<< (generalData->packetsPerFrame);
} }
uint32_t Implementation::getTenGigaADCEnableMask() const { uint32_t Implementation::getTenGigaADCEnableMask() const {
@ -1686,18 +1696,17 @@ void Implementation::setTenGigaADCEnableMask(uint32_t mask) {
ctbAnalogDataBytes = generalData->setImageSize( ctbAnalogDataBytes = generalData->setImageSize(
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
numberOfAnalogSamples, numberOfDigitalSamples, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
tengigaEnable, readoutType); readoutType);
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetPixelDimension(); it->SetPixelDimension();
SetupFifoStructure(); SetupFifoStructure();
} }
LOG(logINFO) << "ADC Enable Mask for 10Gb mode: 0x" << std::hex << adcEnableMaskTenGiga LOG(logINFO) << "ADC Enable Mask for 10Gb mode: 0x" << std::hex
<< std::dec; << adcEnableMaskTenGiga << std::dec;
LOG(logINFO) << "Packets per Frame: " LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
<< (generalData->packetsPerFrame);
} }
std::vector<int> Implementation::getDbitList() const { std::vector<int> Implementation::getDbitList() const {
@ -1720,20 +1729,21 @@ void Implementation::setDbitOffset(const int s) {
ctbDbitOffset = s; ctbDbitOffset = s;
} }
/************************************************** /**************************************************
* * * *
* Callbacks * * Callbacks *
* * * *
* ************************************************/ * ************************************************/
void Implementation::registerCallBackStartAcquisition( void Implementation::registerCallBackStartAcquisition(
int (*func)(std::string, std::string, uint64_t, uint32_t, void *), void *arg) { int (*func)(std::string, std::string, uint64_t, uint32_t, void *),
void *arg) {
startAcquisitionCallBack = func; startAcquisitionCallBack = func;
pStartAcquisition = arg; pStartAcquisition = arg;
} }
void Implementation::registerCallBackAcquisitionFinished( void Implementation::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
void (*func)(uint64_t, void *), void *arg) { void *),
void *arg) {
acquisitionFinishedCallBack = func; acquisitionFinishedCallBack = func;
pAcquisitionFinished = arg; pAcquisitionFinished = arg;
} }
@ -1754,4 +1764,3 @@ void Implementation::registerCallBackRawDataModifyReady(
it->registerCallBackRawDataModifyReady(rawDataModifyReadyCallBack, it->registerCallBackRawDataModifyReady(rawDataModifyReadyCallBack,
pRawDataReady); pRawDataReady);
} }

46
slsReceiverSoftware/src/Implementation.h Executable file → Normal file
View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "container_utils.h" #include "container_utils.h"
#include "logger.h" #include "logger.h"
#include "receiver_defs.h"
#include "network_utils.h" #include "network_utils.h"
#include "receiver_defs.h"
class GeneralData; class GeneralData;
class Listener; class Listener;
class DataProcessor; class DataProcessor;
@ -12,9 +12,9 @@ class slsDetectorDefs;
#include <atomic> #include <atomic>
#include <exception> #include <exception>
#include <map>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <map>
class Implementation : private virtual slsDetectorDefs { class Implementation : private virtual slsDetectorDefs {
public: public:
@ -33,7 +33,7 @@ class Implementation : private virtual slsDetectorDefs {
int getDetectorPositionId() const; int getDetectorPositionId() const;
void setDetectorPositionId(const int id); void setDetectorPositionId(const int id);
std::string getDetectorHostname() const; std::string getDetectorHostname() const;
void setDetectorHostname(const std::string& c); void setDetectorHostname(const std::string &c);
bool getSilentMode() const; bool getSilentMode() const;
void setSilentMode(const bool i); void setSilentMode(const bool i);
uint32_t getFifoDepth() const; uint32_t getFifoDepth() const;
@ -52,9 +52,9 @@ class Implementation : private virtual slsDetectorDefs {
void setFileFormat(slsDetectorDefs::fileFormat f); void setFileFormat(slsDetectorDefs::fileFormat f);
std::string getFilePath() const; std::string getFilePath() const;
/* check for existence */ /* check for existence */
void setFilePath(const std::string& c); void setFilePath(const std::string &c);
std::string getFileName() const; std::string getFileName() const;
void setFileName(const std::string& c); void setFileName(const std::string &c);
uint64_t getFileIndex() const; uint64_t getFileIndex() const;
void setFileIndex(const uint64_t i); void setFileIndex(const uint64_t i);
bool getFileWriteEnable() const; bool getFileWriteEnable() const;
@ -85,7 +85,6 @@ class Implementation : private virtual slsDetectorDefs {
void closeFiles(); void closeFiles();
void restreamStop(); void restreamStop();
/************************************************** /**************************************************
* * * *
* Network Configuration (UDP) * * Network Configuration (UDP) *
@ -108,7 +107,6 @@ class Implementation : private virtual slsDetectorDefs {
void setUDPSocketBufferSize(const int64_t s); void setUDPSocketBufferSize(const int64_t s);
int64_t getActualUDPSocketBufferSize() const; int64_t getActualUDPSocketBufferSize() const;
/************************************************** /**************************************************
* * * *
* ZMQ Streaming Parameters (ZMQ) * * ZMQ Streaming Parameters (ZMQ) *
@ -128,7 +126,8 @@ class Implementation : private virtual slsDetectorDefs {
std::map<std::string, std::string> getAdditionalJsonHeader() const; std::map<std::string, std::string> getAdditionalJsonHeader() const;
void setAdditionalJsonHeader(const std::map<std::string, std::string> &c); void setAdditionalJsonHeader(const std::map<std::string, std::string> &c);
std::string getAdditionalJsonParameter(const std::string &key) const; std::string getAdditionalJsonParameter(const std::string &key) const;
void setAdditionalJsonParameter(const std::string &key, const std::string &value); void setAdditionalJsonParameter(const std::string &key,
const std::string &value);
/************************************************** /**************************************************
* * * *
@ -180,7 +179,8 @@ class Implementation : private virtual slsDetectorDefs {
/* [Eiger] */ /* [Eiger] */
void setQuad(const bool b); void setQuad(const bool b);
bool getActivate() const; bool getActivate() const;
/** [Eiger] If deactivated, receiver will create dummy data if deactivated padding is enabled (as it will receive nothing from detector) */ /** [Eiger] If deactivated, receiver will create dummy data if deactivated
* padding is enabled (as it will receive nothing from detector) */
bool setActivate(const bool enable); bool setActivate(const bool enable);
bool getDeactivatedPadding() const; bool getDeactivatedPadding() const;
/* [Eiger] */ /* [Eiger] */
@ -209,14 +209,18 @@ class Implementation : private virtual slsDetectorDefs {
* Callbacks * * Callbacks *
* * * *
* ************************************************/ * ************************************************/
void registerCallBackStartAcquisition( void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
int (*func)(std::string, std::string, uint64_t, uint32_t, void *), void *arg); uint64_t, uint32_t,
void registerCallBackAcquisitionFinished( void *),
void (*func)(uint64_t, void *), void *arg); void *arg);
void registerCallBackRawDataReady( void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *),
void (*func)(char *, char *, uint32_t, void *), void *arg); void *arg);
void registerCallBackRawDataModifyReady( void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
void (*func)(char *, char *, uint32_t &, void *), void *arg); void *),
void *arg);
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
uint32_t &, void *),
void *arg);
private: private:
void DeleteMembers(); void DeleteMembers();
@ -230,7 +234,6 @@ class Implementation : private virtual slsDetectorDefs {
void SetupWriter(); void SetupWriter();
void StartRunning(); void StartRunning();
/************************************************** /**************************************************
* * * *
* Class Members * * Class Members *
@ -264,8 +267,8 @@ class Implementation : private virtual slsDetectorDefs {
// network configuration (UDP) // network configuration (UDP)
int numUDPInterfaces; int numUDPInterfaces;
std::vector <std::string> eth; std::vector<std::string> eth;
std::vector <uint32_t> udpPortNum; std::vector<uint32_t> udpPortNum;
int64_t udpSocketBufferSize; int64_t udpSocketBufferSize;
int64_t actualUDPSocketBufferSize; int64_t actualUDPSocketBufferSize;
@ -308,7 +311,8 @@ class Implementation : private virtual slsDetectorDefs {
int ctbAnalogDataBytes; int ctbAnalogDataBytes;
// callbacks // callbacks
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t, uint32_t, void *); int (*startAcquisitionCallBack)(std::string, std::string, uint64_t,
uint32_t, void *);
void *pStartAcquisition; void *pStartAcquisition;
void (*acquisitionFinishedCallBack)(uint64_t, void *); void (*acquisitionFinishedCallBack)(uint64_t, void *);
void *pAcquisitionFinished; void *pAcquisitionFinished;

417
slsReceiverSoftware/src/Listener.cpp Executable file → Normal file
View File

@ -5,14 +5,13 @@
* & puts pointers to their memory addresses into fifos * & puts pointers to their memory addresses into fifos
***********************************************/ ***********************************************/
#include "Listener.h" #include "Listener.h"
#include "Fifo.h" #include "Fifo.h"
#include "GeneralData.h" #include "GeneralData.h"
#include "container_utils.h" // For sls::make_unique<>
#include "sls_detector_exceptions.h"
#include "UdpRxSocket.h" #include "UdpRxSocket.h"
#include "container_utils.h" // For sls::make_unique<>
#include "network_utils.h" #include "network_utils.h"
#include "sls_detector_exceptions.h"
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
@ -20,53 +19,41 @@
const std::string Listener::TypeName = "Listener"; const std::string Listener::TypeName = "Listener";
Listener::Listener(int ind, detectorType dtype, Fifo *f,
Listener::Listener(int ind, detectorType dtype, Fifo* f, std::atomic<runStatus>* s, std::atomic<runStatus> *s, uint32_t *portno, std::string *e,
uint32_t* portno, std::string* e, uint64_t* nf, uint32_t* dr, uint64_t *nf, uint32_t *dr, int64_t *us, int64_t *as,
int64_t* us, int64_t* as, uint32_t* fpf, uint32_t *fpf, frameDiscardPolicy *fdp, bool *act,
frameDiscardPolicy* fdp, bool* act, bool* depaden, bool* sm) : bool *depaden, bool *sm)
ThreadObject(ind, TypeName), : ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype), status(s),
fifo(f), udpPortNumber(portno), eth(e), numImages(nf), dynamicRange(dr),
myDetectorType(dtype), udpSocketBufferSize(us), actualUDPSocketBufferSize(as),
status(s), framesPerFile(fpf), frameDiscardMode(fdp), activated(act),
udpPortNumber(portno), deactivatedPaddingEnable(depaden), silentMode(sm) {
eth(e),
numImages(nf),
dynamicRange(dr),
udpSocketBufferSize(us),
actualUDPSocketBufferSize(as),
framesPerFile(fpf),
frameDiscardMode(fdp),
activated(act),
deactivatedPaddingEnable(depaden),
silentMode(sm)
{
LOG(logDEBUG) << "Listener " << ind << " created"; LOG(logDEBUG) << "Listener " << ind << " created";
} }
Listener::~Listener() = default; Listener::~Listener() = default;
uint64_t Listener::GetPacketsCaught() const { uint64_t Listener::GetPacketsCaught() const { return numPacketsCaught; }
return numPacketsCaught;
}
uint64_t Listener::GetLastFrameIndexCaught() const { uint64_t Listener::GetLastFrameIndexCaught() const {
return lastCaughtFrameIndex; return lastCaughtFrameIndex;
} }
uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const { uint64_t Listener::GetNumMissingPacket(bool stoppedFlag,
uint64_t numPackets) const {
if (!stoppedFlag) { if (!stoppedFlag) {
return (numPackets - numPacketsCaught); return (numPackets - numPacketsCaught);
} }
if (numPacketsCaught == 0) { if (numPacketsCaught == 0) {
return numPacketsCaught; return numPacketsCaught;
} }
return (lastCaughtFrameIndex - firstIndex + 1) * generalData->packetsPerFrame - numPacketsCaught; return (lastCaughtFrameIndex - firstIndex + 1) *
generalData->packetsPerFrame -
numPacketsCaught;
} }
void Listener::SetFifo(Fifo* f) { void Listener::SetFifo(Fifo *f) { fifo = f; }
fifo = f;
}
void Listener::ResetParametersforNewAcquisition() { void Listener::ResetParametersforNewAcquisition() {
StopRunning(); StopRunning();
@ -77,47 +64,42 @@ void Listener::ResetParametersforNewAcquisition() {
lastCaughtFrameIndex = 0; lastCaughtFrameIndex = 0;
carryOverFlag = false; carryOverFlag = false;
carryOverPacket = sls::make_unique<char[]>(generalData->packetSize); carryOverPacket = sls::make_unique<char[]>(generalData->packetSize);
memset(carryOverPacket.get(),0,generalData->packetSize); memset(carryOverPacket.get(), 0, generalData->packetSize);
listeningPacket = sls::make_unique<char[]>(generalData->packetSize); listeningPacket = sls::make_unique<char[]>(generalData->packetSize);
memset(carryOverPacket.get(),0,generalData->packetSize); memset(carryOverPacket.get(), 0, generalData->packetSize);
numPacketsStatistic = 0; numPacketsStatistic = 0;
numFramesStatistic = 0; numFramesStatistic = 0;
//reset fifo statistic // reset fifo statistic
fifo->GetMaxLevelForFifoBound(); fifo->GetMaxLevelForFifoBound();
fifo->GetMinLevelForFifoFree(); fifo->GetMinLevelForFifoFree();
} }
void Listener::RecordFirstIndex(uint64_t fnum) { void Listener::RecordFirstIndex(uint64_t fnum) {
//listen to this fnum, later +1 // listen to this fnum, later +1
currentFrameIndex = fnum; currentFrameIndex = fnum;
startedFlag = true; startedFlag = true;
firstIndex = fnum; firstIndex = fnum;
if(!(*silentMode)) { if (!(*silentMode)) {
if (!index) { if (!index) {
LOG(logINFOBLUE) << index << LOG(logINFOBLUE) << index << " First Index: " << firstIndex;
" First Index: " << firstIndex;
} }
} }
} }
void Listener::SetGeneralData(GeneralData *g) {
void Listener::SetGeneralData(GeneralData* g) {
generalData = g; generalData = g;
generalData->Print(); generalData->Print();
} }
void Listener::CreateUDPSockets() { void Listener::CreateUDPSockets() {
if (!(*activated)) { if (!(*activated)) {
return; return;
} }
//if eth is mistaken with ip address // if eth is mistaken with ip address
if ((*eth).find('.') != std::string::npos) { if ((*eth).find('.') != std::string::npos) {
(*eth) = ""; (*eth) = "";
} }
@ -127,13 +109,16 @@ void Listener::CreateUDPSockets() {
ShutDownUDPSocket(); ShutDownUDPSocket();
// InterfaceNameToIp(eth).str().c_str() // InterfaceNameToIp(eth).str().c_str()
try{ try {
udpSocket = sls::make_unique<sls::UdpRxSocket>(*udpPortNumber, udpSocket = sls::make_unique<sls::UdpRxSocket>(
generalData->packetSize, ((*eth).length() ? sls::InterfaceNameToIp(*eth).str().c_str() : nullptr), *udpPortNumber, generalData->packetSize,
((*eth).length() ? sls::InterfaceNameToIp(*eth).str().c_str()
: nullptr),
*udpSocketBufferSize); *udpSocketBufferSize);
LOG(logINFO) << index << ": UDP port opened at port " << *udpPortNumber; LOG(logINFO) << index << ": UDP port opened at port " << *udpPortNumber;
} catch (...) { } catch (...) {
throw sls::RuntimeError("Could not create UDP socket on port "+ std::to_string(*udpPortNumber)); throw sls::RuntimeError("Could not create UDP socket on port " +
std::to_string(*udpPortNumber));
} }
udpSocketAlive = true; udpSocketAlive = true;
@ -142,40 +127,41 @@ void Listener::CreateUDPSockets() {
*actualUDPSocketBufferSize = udpSocket->getBufferSize(); *actualUDPSocketBufferSize = udpSocket->getBufferSize();
} }
void Listener::ShutDownUDPSocket() { void Listener::ShutDownUDPSocket() {
if(udpSocket){ if (udpSocket) {
udpSocketAlive = false; udpSocketAlive = false;
udpSocket->Shutdown(); udpSocket->Shutdown();
LOG(logINFO) << "Shut down of UDP port " << *udpPortNumber; LOG(logINFO) << "Shut down of UDP port " << *udpPortNumber;
} }
} }
void Listener::CreateDummySocketForUDPSocketBufferSize(int64_t s) { void Listener::CreateDummySocketForUDPSocketBufferSize(int64_t s) {
LOG(logINFO) << "Testing UDP Socket Buffer size " << s << " with test port " << *udpPortNumber; LOG(logINFO) << "Testing UDP Socket Buffer size " << s << " with test port "
<< *udpPortNumber;
if (!(*activated)) { if (!(*activated)) {
*actualUDPSocketBufferSize = (s*2); *actualUDPSocketBufferSize = (s * 2);
return; return;
} }
int64_t temp = *udpSocketBufferSize; int64_t temp = *udpSocketBufferSize;
*udpSocketBufferSize = s; *udpSocketBufferSize = s;
//if eth is mistaken with ip address // if eth is mistaken with ip address
if ((*eth).find('.') != std::string::npos) { if ((*eth).find('.') != std::string::npos) {
(*eth) = ""; (*eth) = "";
} }
//create dummy socket // create dummy socket
try { try {
sls::UdpRxSocket g(*udpPortNumber, sls::UdpRxSocket g(*udpPortNumber, generalData->packetSize,
generalData->packetSize, ((*eth).length() ? sls::InterfaceNameToIp(*eth).str().c_str() : nullptr), ((*eth).length()
? sls::InterfaceNameToIp(*eth).str().c_str()
: nullptr),
*udpSocketBufferSize); *udpSocketBufferSize);
// doubled due to kernel bookkeeping (could also be less due to permissions) // doubled due to kernel bookkeeping (could also be less due to
// permissions)
*actualUDPSocketBufferSize = g.getBufferSize(); *actualUDPSocketBufferSize = g.getBufferSize();
if (*actualUDPSocketBufferSize == -1) { if (*actualUDPSocketBufferSize == -1) {
*udpSocketBufferSize = temp; *udpSocketBufferSize = temp;
@ -184,7 +170,8 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int64_t s) {
} }
} catch (...) { } catch (...) {
throw sls::RuntimeError("Could not create a test UDP socket on port " + std::to_string(*udpPortNumber)); throw sls::RuntimeError("Could not create a test UDP socket on port " +
std::to_string(*udpPortNumber));
} }
} }
@ -194,33 +181,37 @@ void Listener::SetHardCodedPosition(uint16_t r, uint16_t c) {
} }
void Listener::ThreadExecution() { void Listener::ThreadExecution() {
char* buffer; char *buffer;
int rc = 0; int rc = 0;
fifo->GetNewAddress(buffer); fifo->GetNewAddress(buffer);
LOG(logDEBUG5) << "Listener " << index << ", " LOG(logDEBUG5) << "Listener " << index
"pop 0x" << std::hex << (void*)(buffer) << std::dec << ":" << buffer; << ", "
"pop 0x"
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
//udpsocket doesnt exist // udpsocket doesnt exist
if (*activated && !udpSocketAlive && !carryOverFlag) { if (*activated && !udpSocketAlive && !carryOverFlag) {
//LOG(logERROR) << "Listening_Thread " << index << ": UDP Socket not created or shut down earlier"; // LOG(logERROR) << "Listening_Thread " << index << ": UDP Socket not
(*((uint32_t*)buffer)) = 0; // created or shut down earlier";
(*((uint32_t *)buffer)) = 0;
StopListening(buffer); StopListening(buffer);
return; return;
} }
//get data // get data
if ((*status != TRANSMITTING && (!(*activated) || udpSocketAlive)) || carryOverFlag) { if ((*status != TRANSMITTING && (!(*activated) || udpSocketAlive)) ||
carryOverFlag) {
rc = ListenToAnImage(buffer); rc = ListenToAnImage(buffer);
} }
// error check, (should not be here) if not transmitting yet (previous if)
//error check, (should not be here) if not transmitting yet (previous if) rc should be > 0 // rc should be > 0
if (rc == 0) { if (rc == 0) {
if (!udpSocketAlive) { if (!udpSocketAlive) {
(*((uint32_t*)buffer)) = 0; (*((uint32_t *)buffer)) = 0;
StopListening(buffer); StopListening(buffer);
}else } else
fifo->FreeAddress(buffer); fifo->FreeAddress(buffer);
return; return;
} }
@ -233,36 +224,36 @@ void Listener::ThreadExecution() {
return; return;
} }
(*((uint32_t*)buffer)) = rc; (*((uint32_t *)buffer)) = rc;
(*((uint64_t*)(buffer + FIFO_HEADER_NUMBYTES ))) = currentFrameIndex; //for those returning earlier (*((uint64_t *)(buffer + FIFO_HEADER_NUMBYTES))) =
currentFrameIndex; // for those returning earlier
currentFrameIndex++; currentFrameIndex++;
//push into fifo // push into fifo
fifo->PushAddress(buffer); fifo->PushAddress(buffer);
//Statistics // Statistics
if(!(*silentMode)) { if (!(*silentMode)) {
numFramesStatistic++; numFramesStatistic++;
if (numFramesStatistic >= if (numFramesStatistic >=
//second condition also for infinite #number of frames // second condition also for infinite #number of frames
(((*framesPerFile) == 0) ? STATISTIC_FRAMENUMBER_INFINITE : (*framesPerFile)) ) (((*framesPerFile) == 0) ? STATISTIC_FRAMENUMBER_INFINITE
: (*framesPerFile)))
PrintFifoStatistics(); PrintFifoStatistics();
} }
} }
void Listener::StopListening(char *buf) {
(*((uint32_t *)buf)) = DUMMY_PACKET_VALUE;
void Listener::StopListening(char* buf) {
(*((uint32_t*)buf)) = DUMMY_PACKET_VALUE;
fifo->PushAddress(buf); fifo->PushAddress(buf);
StopRunning(); StopRunning();
LOG(logDEBUG1) << index << ": Listening Packets (" << *udpPortNumber << ") : " << numPacketsCaught; LOG(logDEBUG1) << index << ": Listening Packets (" << *udpPortNumber
<< ") : " << numPacketsCaught;
LOG(logDEBUG1) << index << ": Listening Completed"; LOG(logDEBUG1) << index << ": Listening Completed";
} }
/* buf includes the fifo header and packet header */ /* buf includes the fifo header and packet header */
uint32_t Listener::ListenToAnImage(char* buf) { uint32_t Listener::ListenToAnImage(char *buf) {
int rc = 0; int rc = 0;
uint64_t fnum = 0; uint64_t fnum = 0;
@ -273,23 +264,24 @@ uint32_t Listener::ListenToAnImage(char* buf) {
uint32_t fifohsize = generalData->fifoBufferHeaderSize; uint32_t fifohsize = generalData->fifoBufferHeaderSize;
uint32_t pperFrame = generalData->packetsPerFrame; uint32_t pperFrame = generalData->packetsPerFrame;
bool isHeaderEmpty = true; bool isHeaderEmpty = true;
sls_detector_header* old_header = nullptr; sls_detector_header *old_header = nullptr;
sls_receiver_header* new_header = nullptr; sls_receiver_header *new_header = nullptr;
bool standardheader = generalData->standardheader; bool standardheader = generalData->standardheader;
uint32_t corrected_dsize = dsize - ((pperFrame * dsize) - generalData->imageSize); uint32_t corrected_dsize =
dsize - ((pperFrame * dsize) - generalData->imageSize);
// reset to -1
//reset to -1
memset(buf, 0, fifohsize); memset(buf, 0, fifohsize);
/*memset(buf + fifohsize, 0xFF, generalData->imageSize);*/ /*memset(buf + fifohsize, 0xFF, generalData->imageSize);*/
new_header = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES); new_header = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
// deactivated (eiger) // deactivated (eiger)
if (!(*activated)) { if (!(*activated)) {
// no padding // no padding
if (!(*deactivatedPaddingEnable)) if (!(*deactivatedPaddingEnable))
return 0; return 0;
// padding without setting bitmask (all missing packets padded in dataProcessor) // padding without setting bitmask (all missing packets padded in
// dataProcessor)
if (currentFrameIndex >= *numImages) if (currentFrameIndex >= *numImages)
return 0; return 0;
@ -300,36 +292,38 @@ uint32_t Listener::ListenToAnImage(char* buf) {
new_header->detHeader.frameNumber = currentFrameIndex; new_header->detHeader.frameNumber = currentFrameIndex;
new_header->detHeader.row = row; new_header->detHeader.row = row;
new_header->detHeader.column = column; new_header->detHeader.column = column;
new_header->detHeader.detType = (uint8_t) generalData->myDetectorType; new_header->detHeader.detType = (uint8_t)generalData->myDetectorType;
new_header->detHeader.version = (uint8_t) SLS_DETECTOR_HEADER_VERSION; new_header->detHeader.version = (uint8_t)SLS_DETECTOR_HEADER_VERSION;
return generalData->imageSize; return generalData->imageSize;
} }
// look for carry over
//look for carry over
if (carryOverFlag) { if (carryOverFlag) {
LOG(logDEBUG3) << index << "carry flag"; LOG(logDEBUG3) << index << "carry flag";
//check if its the current image packet // check if its the current image packet
// -------------------------- new header ---------------------------------------------------------------------- // -------------------------- new header
// ----------------------------------------------------------------------
if (standardheader) { if (standardheader) {
old_header = (sls_detector_header*) (&carryOverPacket[0]); old_header = (sls_detector_header *)(&carryOverPacket[0]);
fnum = old_header->frameNumber; fnum = old_header->frameNumber;
pnum = old_header->packetNumber; pnum = old_header->packetNumber;
} }
// -------------------old header ----------------------------------------------------------------------------- // -------------------old header
// -----------------------------------------------------------------------------
else { else {
generalData->GetHeaderInfo(index, &carryOverPacket[0], oddStartingPacket, fnum, pnum); generalData->GetHeaderInfo(index, &carryOverPacket[0],
oddStartingPacket, fnum, pnum);
} }
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
if (fnum != currentFrameIndex) { if (fnum != currentFrameIndex) {
if (fnum < currentFrameIndex) { if (fnum < currentFrameIndex) {
LOG(logERROR) << "(Weird), With carry flag: Frame number " << LOG(logERROR)
fnum << " less than current frame number " << currentFrameIndex; << "(Weird), With carry flag: Frame number " << fnum
<< " less than current frame number " << currentFrameIndex;
carryOverFlag = false; carryOverFlag = false;
return 0; return 0;
} }
switch(*frameDiscardMode) { switch (*frameDiscardMode) {
case DISCARD_EMPTY_FRAMES: case DISCARD_EMPTY_FRAMES:
if (!numpackets) if (!numpackets)
return -1; return -1;
@ -340,71 +334,84 @@ uint32_t Listener::ListenToAnImage(char* buf) {
break; break;
} }
new_header->detHeader.packetNumber = numpackets; new_header->detHeader.packetNumber = numpackets;
if(isHeaderEmpty) { if (isHeaderEmpty) {
new_header->detHeader.row = row; new_header->detHeader.row = row;
new_header->detHeader.column = column; new_header->detHeader.column = column;
} }
return generalData->imageSize; return generalData->imageSize;
} }
//copy packet // copy packet
switch(myDetectorType) { switch (myDetectorType) {
//for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes data // for gotthard, 1st packet: 4 bytes fnum, CACA
// 2nd packet: 4 bytes fnum, previous 1*2 bytes data + 640*2 bytes data !! // + CACA, 639*2 bytes data 2nd packet: 4 bytes fnum, previous 1*2 bytes
//data + 640*2 bytes data !!
case GOTTHARD: case GOTTHARD:
if(!pnum) if (!pnum)
memcpy(buf + fifohsize , &carryOverPacket[hsize+4], dsize-2); memcpy(buf + fifohsize, &carryOverPacket[hsize + 4], dsize - 2);
else else
memcpy(buf + fifohsize + dsize - 2, &carryOverPacket[hsize], dsize+2); memcpy(buf + fifohsize + dsize - 2, &carryOverPacket[hsize],
dsize + 2);
break; break;
case CHIPTESTBOARD: case CHIPTESTBOARD:
case MOENCH: case MOENCH:
if (pnum == (pperFrame-1)) if (pnum == (pperFrame - 1))
memcpy(buf + fifohsize + (pnum * dsize), &carryOverPacket[hsize], corrected_dsize); memcpy(buf + fifohsize + (pnum * dsize),
&carryOverPacket[hsize], corrected_dsize);
else else
memcpy(buf + fifohsize + (pnum * dsize), &carryOverPacket[hsize], dsize); memcpy(buf + fifohsize + (pnum * dsize),
&carryOverPacket[hsize], dsize);
break; break;
default: default:
memcpy(buf + fifohsize + (pnum * dsize), &carryOverPacket[hsize], dsize); memcpy(buf + fifohsize + (pnum * dsize), &carryOverPacket[hsize],
dsize);
break; break;
} }
carryOverFlag = false; carryOverFlag = false;
++numpackets; //number of packets in this image (each time its copied to buf) ++numpackets; // number of packets in this image (each time its copied
new_header->packetsMask[((pnum < MAX_NUM_PACKETS) ? pnum : MAX_NUM_PACKETS - 1)] = 1; // to buf)
new_header->packetsMask[(
(pnum < MAX_NUM_PACKETS) ? pnum : MAX_NUM_PACKETS - 1)] = 1;
//writer header // writer header
if(isHeaderEmpty) { if (isHeaderEmpty) {
// -------------------------- new header ---------------------------------------------------------------------- // -------------------------- new header
// ----------------------------------------------------------------------
if (standardheader) { if (standardheader) {
memcpy((char*)new_header, (char*)old_header, sizeof(sls_detector_header)); memcpy((char *)new_header, (char *)old_header,
sizeof(sls_detector_header));
} }
// -------------------old header ------------------------------------------------------------------------------ // -------------------old header
// ------------------------------------------------------------------------------
else { else {
new_header->detHeader.frameNumber = fnum; new_header->detHeader.frameNumber = fnum;
new_header->detHeader.row = row; new_header->detHeader.row = row;
new_header->detHeader.column = column; new_header->detHeader.column = column;
new_header->detHeader.detType = (uint8_t) generalData->myDetectorType; new_header->detHeader.detType =
new_header->detHeader.version = (uint8_t) SLS_DETECTOR_HEADER_VERSION; (uint8_t)generalData->myDetectorType;
new_header->detHeader.version =
(uint8_t)SLS_DETECTOR_HEADER_VERSION;
} }
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
isHeaderEmpty = false; isHeaderEmpty = false;
} }
} }
//until last packet isHeaderEmpty to account for gotthard short frame, else never entering this loop) // until last packet isHeaderEmpty to account for gotthard short frame, else
while ( numpackets < pperFrame) { // never entering this loop)
//listen to new packet while (numpackets < pperFrame) {
// listen to new packet
rc = 0; rc = 0;
if (udpSocketAlive){ if (udpSocketAlive) {
rc = udpSocket->ReceiveDataOnly(&listeningPacket[0]); rc = udpSocket->ReceiveDataOnly(&listeningPacket[0]);
} }
// end of acquisition // end of acquisition
if(rc <= 0) { if (rc <= 0) {
if (numpackets == 0) return 0; //empty image if (numpackets == 0)
return 0; // empty image
switch(*frameDiscardMode) { switch (*frameDiscardMode) {
case DISCARD_EMPTY_FRAMES: case DISCARD_EMPTY_FRAMES:
if (!numpackets) if (!numpackets)
return -1; return -1;
@ -414,38 +421,47 @@ uint32_t Listener::ListenToAnImage(char* buf) {
default: default:
break; break;
} }
new_header->detHeader.packetNumber = numpackets; //number of packets caught new_header->detHeader.packetNumber =
if(isHeaderEmpty) { numpackets; // number of packets caught
if (isHeaderEmpty) {
new_header->detHeader.row = row; new_header->detHeader.row = row;
new_header->detHeader.column = column; new_header->detHeader.column = column;
} }
return generalData->imageSize; //empty packet now, but not empty image return generalData
->imageSize; // empty packet now, but not empty image
} }
//update parameters // update parameters
numPacketsCaught++; //record immediately to get more time before socket shutdown numPacketsCaught++; // record immediately to get more time before socket
// shutdown
numPacketsStatistic++; numPacketsStatistic++;
// -------------------------- new header ---------------------------------------------------------------------- // -------------------------- new header
// ----------------------------------------------------------------------
if (standardheader) { if (standardheader) {
old_header = (sls_detector_header*) (&listeningPacket[0]); old_header = (sls_detector_header *)(&listeningPacket[0]);
fnum = old_header->frameNumber; fnum = old_header->frameNumber;
pnum = old_header->packetNumber; pnum = old_header->packetNumber;
} }
// -------------------old header ----------------------------------------------------------------------------- // -------------------old header
// -----------------------------------------------------------------------------
else { else {
// set first packet to be odd or even (check required when switching from roi to no roi) // set first packet to be odd or even (check required when switching
// from roi to no roi)
if (myDetectorType == GOTTHARD && !startedFlag) { if (myDetectorType == GOTTHARD && !startedFlag) {
oddStartingPacket = generalData->SetOddStartingPacket(index, &listeningPacket[0]); oddStartingPacket = generalData->SetOddStartingPacket(
index, &listeningPacket[0]);
} }
generalData->GetHeaderInfo(index, &listeningPacket[0], oddStartingPacket, fnum, pnum); generalData->GetHeaderInfo(index, &listeningPacket[0],
oddStartingPacket, fnum, pnum);
} }
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
// Eiger Firmware in a weird state // Eiger Firmware in a weird state
if (myDetectorType == EIGER && fnum == 0) { if (myDetectorType == EIGER && fnum == 0) {
LOG(logERROR) << "[" << *udpPortNumber << "]: Got Frame Number " LOG(logERROR) << "[" << *udpPortNumber
<< "]: Got Frame Number "
"Zero from Firmware. Discarding Packet"; "Zero from Firmware. Discarding Packet";
numPacketsCaught--; numPacketsCaught--;
return 0; return 0;
@ -453,25 +469,30 @@ uint32_t Listener::ListenToAnImage(char* buf) {
lastCaughtFrameIndex = fnum; lastCaughtFrameIndex = fnum;
LOG(logDEBUG5) << "Listening " << index << ": currentfindex:" << currentFrameIndex << LOG(logDEBUG5) << "Listening " << index
", fnum:" << fnum << ", pnum:" << pnum << ", numpackets:" << numpackets; << ": currentfindex:" << currentFrameIndex
<< ", fnum:" << fnum << ", pnum:" << pnum
<< ", numpackets:" << numpackets;
if (!startedFlag) if (!startedFlag)
RecordFirstIndex(fnum); RecordFirstIndex(fnum);
if (pnum >= pperFrame ) { if (pnum >= pperFrame) {
LOG(logERROR) << "Bad packet " << pnum << LOG(logERROR) << "Bad packet " << pnum << "(fnum: " << fnum
"(fnum: " << fnum << "), throwing away. " << "), throwing away. "
"Packets caught so far: " << numpackets; "Packets caught so far: "
<< numpackets;
return 0; // bad packet return 0; // bad packet
} }
//future packet by looking at image number (all other detectors) // future packet by looking at image number (all other
// detectors)
if (fnum != currentFrameIndex) { if (fnum != currentFrameIndex) {
carryOverFlag = true; carryOverFlag = true;
memcpy(carryOverPacket.get(), &listeningPacket[0], generalData->packetSize); memcpy(carryOverPacket.get(), &listeningPacket[0],
generalData->packetSize);
switch(*frameDiscardMode) { switch (*frameDiscardMode) {
case DISCARD_EMPTY_FRAMES: case DISCARD_EMPTY_FRAMES:
if (!numpackets) if (!numpackets)
return -1; return -1;
@ -481,50 +502,64 @@ uint32_t Listener::ListenToAnImage(char* buf) {
default: default:
break; break;
} }
new_header->detHeader.packetNumber = numpackets; //number of packets caught new_header->detHeader.packetNumber =
if(isHeaderEmpty) { numpackets; // number of packets caught
if (isHeaderEmpty) {
new_header->detHeader.row = row; new_header->detHeader.row = row;
new_header->detHeader.column = column; new_header->detHeader.column = column;
} }
return generalData->imageSize; return generalData->imageSize;
} }
//copy packet // copy packet
switch(myDetectorType) { switch (myDetectorType) {
//for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes data // for gotthard, 1st packet: 4 bytes fnum, CACA
// 2nd packet: 4 bytes fnum, previous 1*2 bytes data + 640*2 bytes data !! // + CACA, 639*2 bytes data 2nd packet: 4 bytes fnum, previous 1*2 bytes
//data + 640*2 bytes data !!
case GOTTHARD: case GOTTHARD:
if(!pnum) if (!pnum)
memcpy(buf + fifohsize + (pnum * dsize), &listeningPacket[hsize+4], dsize-2); memcpy(buf + fifohsize + (pnum * dsize),
&listeningPacket[hsize + 4], dsize - 2);
else else
memcpy(buf + fifohsize + (pnum * dsize) - 2, &listeningPacket[hsize], dsize+2); memcpy(buf + fifohsize + (pnum * dsize) - 2,
&listeningPacket[hsize], dsize + 2);
break; break;
case CHIPTESTBOARD: case CHIPTESTBOARD:
case MOENCH: case MOENCH:
if (pnum == (pperFrame-1)) if (pnum == (pperFrame - 1))
memcpy(buf + fifohsize + (pnum * dsize), &listeningPacket[hsize], corrected_dsize); memcpy(buf + fifohsize + (pnum * dsize),
&listeningPacket[hsize], corrected_dsize);
else else
memcpy(buf + fifohsize + (pnum * dsize), &listeningPacket[hsize], dsize); memcpy(buf + fifohsize + (pnum * dsize),
&listeningPacket[hsize], dsize);
break; break;
default: default:
memcpy(buf + fifohsize + (pnum * dsize), &listeningPacket[hsize], dsize); memcpy(buf + fifohsize + (pnum * dsize), &listeningPacket[hsize],
dsize);
break; break;
} }
++numpackets; //number of packets in this image (each time its copied to buf) ++numpackets; // number of packets in this image (each time its copied
new_header->packetsMask[((pnum < MAX_NUM_PACKETS) ? pnum : MAX_NUM_PACKETS - 1)] = 1; // to buf)
new_header->packetsMask[(
(pnum < MAX_NUM_PACKETS) ? pnum : MAX_NUM_PACKETS - 1)] = 1;
if(isHeaderEmpty) { if (isHeaderEmpty) {
// -------------------------- new header ---------------------------------------------------------------------- // -------------------------- new header
// ----------------------------------------------------------------------
if (standardheader) { if (standardheader) {
memcpy((char*)new_header, (char*)old_header, sizeof(sls_detector_header)); memcpy((char *)new_header, (char *)old_header,
sizeof(sls_detector_header));
} }
// -------------------old header ------------------------------------------------------------------------------ // -------------------old header
// ------------------------------------------------------------------------------
else { else {
new_header->detHeader.frameNumber = fnum; new_header->detHeader.frameNumber = fnum;
new_header->detHeader.row = row; new_header->detHeader.row = row;
new_header->detHeader.column = column; new_header->detHeader.column = column;
new_header->detHeader.detType = (uint8_t) generalData->myDetectorType; new_header->detHeader.detType =
new_header->detHeader.version = (uint8_t) SLS_DETECTOR_HEADER_VERSION; (uint8_t)generalData->myDetectorType;
new_header->detHeader.version =
(uint8_t)SLS_DETECTOR_HEADER_VERSION;
} }
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
isHeaderEmpty = false; isHeaderEmpty = false;
@ -532,26 +567,26 @@ uint32_t Listener::ListenToAnImage(char* buf) {
} }
// complete image // complete image
new_header->detHeader.packetNumber = numpackets; //number of packets caught new_header->detHeader.packetNumber = numpackets; // number of packets caught
return generalData->imageSize; return generalData->imageSize;
} }
void Listener::PrintFifoStatistics() { void Listener::PrintFifoStatistics() {
LOG(logDEBUG1) << "numFramesStatistic:" << numFramesStatistic << " numPacketsStatistic:" << numPacketsStatistic; LOG(logDEBUG1) << "numFramesStatistic:" << numFramesStatistic
<< " numPacketsStatistic:" << numPacketsStatistic;
//calculate packet loss // calculate packet loss
int64_t loss = (numFramesStatistic*(generalData->packetsPerFrame)) - numPacketsStatistic; int64_t loss = (numFramesStatistic * (generalData->packetsPerFrame)) -
numPacketsStatistic;
numPacketsStatistic = 0; numPacketsStatistic = 0;
numFramesStatistic = 0; numFramesStatistic = 0;
const auto color = loss ? logINFORED : logINFOGREEN; const auto color = loss ? logINFORED : logINFOGREEN;
LOG(color) << "[" << *udpPortNumber << "]: " LOG(color) << "[" << *udpPortNumber
"Packet_Loss:" << loss << << "]: "
" Used_Fifo_Max_Level:" << fifo->GetMaxLevelForFifoBound() << "Packet_Loss:"
" \tFree_Slots_Min_Level:" << fifo->GetMinLevelForFifoFree() << << loss
" \tCurrent_Frame#:" << currentFrameIndex; << " Used_Fifo_Max_Level:" << fifo->GetMaxLevelForFifoBound()
<< " \tFree_Slots_Min_Level:" << fifo->GetMinLevelForFifoFree()
<< " \tCurrent_Frame#:" << currentFrameIndex;
} }

69
slsReceiverSoftware/src/Listener.h Executable file → Normal file
View File

@ -9,10 +9,10 @@
*@short creates & manages a listener thread each *@short creates & manages a listener thread each
*/ */
#include <memory>
#include <atomic>
#include "ThreadObject.h" #include "ThreadObject.h"
#include "UdpRxSocket.h" #include "UdpRxSocket.h"
#include <atomic>
#include <memory>
class GeneralData; class GeneralData;
class Fifo; class Fifo;
@ -22,7 +22,8 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
public: public:
/** /**
* Constructor * Constructor
* Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofListerners * Calls Base Class CreateThread(), sets ErrorMask if error and increments
* NumberofListerners
* @param ind self index * @param ind self index
* @param dtype detector type * @param dtype detector type
* @param f address of Fifo pointer * @param f address of Fifo pointer
@ -39,10 +40,10 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
* @param depaden pointer to deactivated padding enable * @param depaden pointer to deactivated padding enable
* @param sm pointer to silent mode * @param sm pointer to silent mode
*/ */
Listener(int ind, detectorType dtype, Fifo* f, std::atomic<runStatus>* s, Listener(int ind, detectorType dtype, Fifo *f, std::atomic<runStatus> *s,
uint32_t* portno, std::string* e, uint64_t* nf, uint32_t* dr, uint32_t *portno, std::string *e, uint64_t *nf, uint32_t *dr,
int64_t* us, int64_t* as, uint32_t* fpf, int64_t *us, int64_t *as, uint32_t *fpf, frameDiscardPolicy *fdp,
frameDiscardPolicy* fdp, bool* act, bool* depaden, bool* sm); bool *act, bool *depaden, bool *sm);
/** /**
* Destructor * Destructor
@ -69,7 +70,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
* Set Fifo pointer to the one given * Set Fifo pointer to the one given
* @param f address of Fifo pointer * @param f address of Fifo pointer
*/ */
void SetFifo(Fifo* f); void SetFifo(Fifo *f);
/** /**
* Reset parameters for new acquisition * Reset parameters for new acquisition
@ -80,7 +81,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
* Set GeneralData pointer to the one given * Set GeneralData pointer to the one given
* @param g address of GeneralData (Detector Data) pointer * @param g address of GeneralData (Detector Data) pointer
*/ */
void SetGeneralData(GeneralData* g); void SetGeneralData(GeneralData *g);
/** /**
* Creates UDP Sockets * Creates UDP Sockets
@ -102,14 +103,12 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
/** /**
* Set hard coded (calculated but not from detector) row and column * Set hard coded (calculated but not from detector) row and column
* r is in row index if detector has not send them yet in firmware, * r is in row index if detector has not send them yet in firmware,
* c is in col index for jungfrau and eiger (for missing packets/deactivated eiger) * c is in col index for jungfrau and eiger (for missing packets/deactivated
* c when used is in 2d * eiger) c when used is in 2d
*/ */
void SetHardCodedPosition(uint16_t r, uint16_t c); void SetHardCodedPosition(uint16_t r, uint16_t c);
private: private:
/** /**
* Record First Acquisition Index * Record First Acquisition Index
* @param fnum frame index to record * @param fnum frame index to record
@ -129,16 +128,16 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
* and reset running mask by calling StopRunning() * and reset running mask by calling StopRunning()
* @param buf address of buffer * @param buf address of buffer
*/ */
void StopListening(char* buf); void StopListening(char *buf);
/** /**
* Listen to the UDP Socket for an image, * Listen to the UDP Socket for an image,
* place them in the right order * place them in the right order
* @param buffer * @param buffer
* @returns number of bytes of relevant data, can be image size or 0 (stop acquisition) * @returns number of bytes of relevant data, can be image size or 0 (stop
* or -1 to discard image * acquisition) or -1 to discard image
*/ */
uint32_t ListenToAnImage(char* buf); uint32_t ListenToAnImage(char *buf);
/** /**
* Print Fifo Statistics * Print Fifo Statistics
@ -149,53 +148,53 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
static const std::string TypeName; static const std::string TypeName;
/** GeneralData (Detector Data) object */ /** GeneralData (Detector Data) object */
GeneralData* generalData{nullptr}; GeneralData *generalData{nullptr};
/** Fifo structure */ /** Fifo structure */
Fifo* fifo; Fifo *fifo;
// individual members // individual members
/** Detector Type */ /** Detector Type */
detectorType myDetectorType; detectorType myDetectorType;
/** Receiver Status */ /** Receiver Status */
std::atomic<runStatus>* status; std::atomic<runStatus> *status;
/** UDP Socket - Detector to Receiver */ /** UDP Socket - Detector to Receiver */
std::unique_ptr<sls::UdpRxSocket> udpSocket{nullptr}; std::unique_ptr<sls::UdpRxSocket> udpSocket{nullptr};
/** UDP Port Number */ /** UDP Port Number */
uint32_t* udpPortNumber; uint32_t *udpPortNumber;
/** ethernet interface */ /** ethernet interface */
std::string* eth; std::string *eth;
/** Number of Images to catch */ /** Number of Images to catch */
uint64_t* numImages; uint64_t *numImages;
/** Dynamic Range */ /** Dynamic Range */
uint32_t* dynamicRange; uint32_t *dynamicRange;
/** UDP Socket Buffer Size */ /** UDP Socket Buffer Size */
int64_t* udpSocketBufferSize; int64_t *udpSocketBufferSize;
/** actual UDP Socket Buffer Size (double due to kernel bookkeeping) */ /** actual UDP Socket Buffer Size (double due to kernel bookkeeping) */
int64_t* actualUDPSocketBufferSize; int64_t *actualUDPSocketBufferSize;
/** frames per file */ /** frames per file */
uint32_t* framesPerFile; uint32_t *framesPerFile;
/** frame discard policy */ /** frame discard policy */
frameDiscardPolicy* frameDiscardMode; frameDiscardPolicy *frameDiscardMode;
/** Activated/Deactivated */ /** Activated/Deactivated */
bool* activated; bool *activated;
/** Deactivated padding enable */ /** Deactivated padding enable */
bool* deactivatedPaddingEnable; bool *deactivatedPaddingEnable;
/** Silent Mode */ /** Silent Mode */
bool* silentMode; bool *silentMode;
/** row hardcoded as 1D or 2d, /** row hardcoded as 1D or 2d,
* if detector does not send them yet or * if detector does not send them yet or
@ -230,10 +229,11 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
bool carryOverFlag{false}; bool carryOverFlag{false};
/** Carry over packet buffer */ /** Carry over packet buffer */
std::unique_ptr<char []> carryOverPacket; std::unique_ptr<char[]> carryOverPacket;
/** Listening buffer for one packet - might be removed when we can peek and eiger fnum is in header */ /** Listening buffer for one packet - might be removed when we can peek and
std::unique_ptr<char []> listeningPacket; * eiger fnum is in header */
std::unique_ptr<char[]> listeningPacket;
/** if the udp socket is connected */ /** if the udp socket is connected */
std::atomic<bool> udpSocketAlive{false}; std::atomic<bool> udpSocketAlive{false};
@ -251,4 +251,3 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
* (pecific to gotthard, can vary between modules, hence defined here) */ * (pecific to gotthard, can vary between modules, hence defined here) */
bool oddStartingPacket{true}; bool oddStartingPacket{true};
}; };

174
slsReceiverSoftware/src/MultiReceiverApp.cpp Executable file → Normal file
View File

@ -1,19 +1,21 @@
/* Creates the slsMultiReceiver for running multiple receivers form a single binary */ /* Creates the slsMultiReceiver for running multiple receivers form a single
#include "sls_detector_defs.h" * binary */
#include "Receiver.h" #include "Receiver.h"
#include "container_utils.h" #include "container_utils.h"
#include "sls_detector_defs.h"
#include <csignal> //SIGINT #include <csignal> //SIGINT
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
#include <sys/wait.h> //wait
#include <sys/syscall.h>
#include <unistd.h>
#include <semaphore.h> #include <semaphore.h>
#include <sys/syscall.h>
#include <sys/wait.h> //wait
#include <unistd.h>
/** Define Colors to print data call back in different colors for different recievers */ /** Define Colors to print data call back in different colors for different
#define PRINT_IN_COLOR(c,f, ...) printf ("\033[%dm" f RESET, 30 + c+1, ##__VA_ARGS__) * recievers */
#define PRINT_IN_COLOR(c, f, ...) \
printf("\033[%dm" f RESET, 30 + c + 1, ##__VA_ARGS__)
sem_t semaphore; sem_t semaphore;
@ -21,23 +23,23 @@ sem_t semaphore;
* Control+C Interrupt Handler * Control+C Interrupt Handler
* to let all the processes know to exit properly * to let all the processes know to exit properly
*/ */
void sigInterruptHandler(int p){ void sigInterruptHandler(int p) { sem_post(&semaphore); }
sem_post(&semaphore);
}
/** /**
* prints usage of this example program * prints usage of this example program
*/ */
void printHelp() { void printHelp() {
cprintf(RESET, "Usage:\n" cprintf(RESET, "Usage:\n"
"./slsMultiReceiver(detReceiver) [start_tcp_port] [num_receivers] [1 for call back, 0 for none]\n\n"); "./slsMultiReceiver(detReceiver) [start_tcp_port] "
"[num_receivers] [1 for call back, 0 for none]\n\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/** /**
* Start Acquisition Call back * Start Acquisition Call back
* slsReceiver writes data if file write enabled. * slsReceiver writes data if file write enabled.
* Users get data to write using call back if registerCallBackRawDataReady is registered. * Users get data to write using call back if registerCallBackRawDataReady is
* registered.
* @param filepath file path * @param filepath file path
* @param filename file name * @param filename file name
* @param fileindex file index * @param fileindex file index
@ -45,8 +47,11 @@ void printHelp() {
* @param p pointer to object * @param p pointer to object
* \returns ignored * \returns ignored
*/ */
int StartAcq(std::string filepath, std::string filename, uint64_t fileindex, uint32_t datasize, void*p){ int StartAcq(std::string filepath, std::string filename, uint64_t fileindex,
LOG(logINFOBLUE) << "#### StartAcq: filepath:" << filepath << " filename:" << filename << " fileindex:" << fileindex << " datasize:" << datasize << " ####"; uint32_t datasize, void *p) {
LOG(logINFOBLUE) << "#### StartAcq: filepath:" << filepath
<< " filename:" << filename << " fileindex:" << fileindex
<< " datasize:" << datasize << " ####";
return 0; return 0;
} }
@ -55,24 +60,27 @@ int StartAcq(std::string filepath, std::string filename, uint64_t fileindex, uin
* @param frames Number of frames caught * @param frames Number of frames caught
* @param p pointer to object * @param p pointer to object
*/ */
void AcquisitionFinished(uint64_t frames, void*p){ void AcquisitionFinished(uint64_t frames, void *p) {
LOG(logINFOBLUE) << "#### AcquisitionFinished: frames:" << frames << " ####"; LOG(logINFOBLUE) << "#### AcquisitionFinished: frames:" << frames
<< " ####";
} }
/** /**
* Get Receiver Data Call back * Get Receiver Data Call back
* Prints in different colors(for each receiver process) the different headers for each image call back. * Prints in different colors(for each receiver process) the different headers
* for each image call back.
* @param metadata sls_receiver_header metadata * @param metadata sls_receiver_header metadata
* @param datapointer pointer to data * @param datapointer pointer to data
* @param datasize data size in bytes. * @param datasize data size in bytes.
* @param p pointer to object * @param p pointer to object
*/ */
void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){ void GetData(char *metadata, char *datapointer, uint32_t datasize, void *p) {
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata; slsDetectorDefs::sls_receiver_header *header =
(slsDetectorDefs::sls_receiver_header *)metadata;
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader; slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row, PRINT_IN_COLOR(
detectorHeader.modId ? detectorHeader.modId : detectorHeader.row,
"#### %d GetData: ####\n" "#### %d GetData: ####\n"
"frameNumber: %lu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %lu" "frameNumber: %lu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %lu"
"\t\ttimestamp: %lu\t\tmodId: %u\t\t" "\t\ttimestamp: %lu\t\tmodId: %u\t\t"
@ -81,20 +89,20 @@ void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){
//"\t\tpacketsMask:%s" //"\t\tpacketsMask:%s"
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", "\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
detectorHeader.row, (long unsigned int)detectorHeader.frameNumber, detectorHeader.row, (long unsigned int)detectorHeader.frameNumber,
detectorHeader.expLength, detectorHeader.packetNumber, (long unsigned int)detectorHeader.bunchId, detectorHeader.expLength, detectorHeader.packetNumber,
(long unsigned int)detectorHeader.bunchId,
(long unsigned int)detectorHeader.timestamp, detectorHeader.modId, (long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
detectorHeader.row, detectorHeader.column, detectorHeader.reserved, detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
detectorHeader.debug, detectorHeader.roundRNumber, detectorHeader.debug, detectorHeader.roundRNumber,
detectorHeader.detType, detectorHeader.version, detectorHeader.detType, detectorHeader.version,
//header->packetsMask.to_string().c_str(), // header->packetsMask.to_string().c_str(),
((uint8_t)(*((uint8_t*)(datapointer)))), datasize); ((uint8_t)(*((uint8_t *)(datapointer)))), datasize);
} }
/** /**
* Get Receiver Data Call back (modified) * Get Receiver Data Call back (modified)
* Prints in different colors(for each receiver process) the different headers for each image call back. * Prints in different colors(for each receiver process) the different headers
* for each image call back.
* @param metadata sls_receiver_header metadata * @param metadata sls_receiver_header metadata
* @param datapointer pointer to data * @param datapointer pointer to data
* @param datasize data size in bytes. * @param datasize data size in bytes.
@ -102,34 +110,36 @@ void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){
* This will be the size written/streamed. (only smaller value is allowed). * This will be the size written/streamed. (only smaller value is allowed).
* @param p pointer to object * @param p pointer to object
*/ */
void GetData(char* metadata, char* datapointer, uint32_t &revDatasize, void* p){ void GetData(char *metadata, char *datapointer, uint32_t &revDatasize,
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata; void *p) {
slsDetectorDefs::sls_receiver_header *header =
(slsDetectorDefs::sls_receiver_header *)metadata;
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader; slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row, PRINT_IN_COLOR(
detectorHeader.modId ? detectorHeader.modId : detectorHeader.row,
"#### %d GetData: ####\n" "#### %d GetData: ####\n"
"frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu" "frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: "
"%llu"
"\t\ttimestamp: %llu\t\tmodId: %u\t\t" "\t\ttimestamp: %llu\t\tmodId: %u\t\t"
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u" "row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u" "\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
//"\t\tpacketsMask:%s" //"\t\tpacketsMask:%s"
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", "\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber, detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber,
detectorHeader.expLength, detectorHeader.packetNumber, (long long unsigned int)detectorHeader.bunchId, detectorHeader.expLength, detectorHeader.packetNumber,
(long long unsigned int)detectorHeader.bunchId,
(long long unsigned int)detectorHeader.timestamp, detectorHeader.modId, (long long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
detectorHeader.row, detectorHeader.column, detectorHeader.reserved, detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
detectorHeader.debug, detectorHeader.roundRNumber, detectorHeader.debug, detectorHeader.roundRNumber,
detectorHeader.detType, detectorHeader.version, detectorHeader.detType, detectorHeader.version,
//header->packetsMask.to_string().c_str(), // header->packetsMask.to_string().c_str(),
((uint8_t)(*((uint8_t*)(datapointer)))), revDatasize); ((uint8_t)(*((uint8_t *)(datapointer)))), revDatasize);
// if data is modified, eg ROI and size is reduced // if data is modified, eg ROI and size is reduced
revDatasize = 26000; revDatasize = 26000;
} }
/** /**
* Example of main program using the Receiver class * Example of main program using the Receiver class
* *
@ -143,63 +153,72 @@ int main(int argc, char *argv[]) {
int numReceivers = 1; int numReceivers = 1;
int startTCPPort = 1954; int startTCPPort = 1954;
int withCallback = 0; int withCallback = 0;
sem_init(&semaphore,1,0); sem_init(&semaphore, 1, 0);
/** - get number of receivers and start tcp port from command line arguments */ /** - get number of receivers and start tcp port from command line
if ( (argc != 4) || (!sscanf(argv[1],"%d", &startTCPPort)) || (!sscanf(argv[2],"%d", &numReceivers)) || (!sscanf(argv[3],"%d", &withCallback)) ) * arguments */
if ((argc != 4) || (!sscanf(argv[1], "%d", &startTCPPort)) ||
(!sscanf(argv[2], "%d", &numReceivers)) ||
(!sscanf(argv[3], "%d", &withCallback)))
printHelp(); printHelp();
cprintf(BLUE,"Parent Process Created [ Tid: %ld ]\n", (long)syscall(SYS_gettid)); cprintf(BLUE, "Parent Process Created [ Tid: %ld ]\n",
(long)syscall(SYS_gettid));
cprintf(RESET, "Number of Receivers: %d\n", numReceivers); cprintf(RESET, "Number of Receivers: %d\n", numReceivers);
cprintf(RESET, "Start TCP Port: %d\n", startTCPPort); cprintf(RESET, "Start TCP Port: %d\n", startTCPPort);
cprintf(RESET, "Callback Enable: %d\n", withCallback); cprintf(RESET, "Callback Enable: %d\n", withCallback);
/** - Catch signal SIGINT to close files and call destructors properly */ /** - Catch signal SIGINT to close files and call destructors properly */
struct sigaction sa; struct sigaction sa;
sa.sa_flags=0; // no flags sa.sa_flags = 0; // no flags
sa.sa_handler=sigInterruptHandler; // handler function sa.sa_handler = sigInterruptHandler; // handler function
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
// of handler
if (sigaction(SIGINT, &sa, nullptr) == -1) { if (sigaction(SIGINT, &sa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGINT\n"); cprintf(RED, "Could not set handler function for SIGINT\n");
} }
/** - Ignore SIG_PIPE, prevents global signal handler, handle locally, /** - Ignore SIG_PIPE, prevents global signal handler, handle locally,
instead of a server crashing due to client crash when writing, it just gives error */ instead of a server crashing due to client crash when writing, it just
gives error */
struct sigaction asa; struct sigaction asa;
asa.sa_flags=0; // no flags asa.sa_flags = 0; // no flags
asa.sa_handler=SIG_IGN; // handler function asa.sa_handler = SIG_IGN; // handler function
sigemptyset(&asa.sa_mask); // dont block additional signals during invocation of handler sigemptyset(&asa.sa_mask); // dont block additional signals during
// invocation of handler
if (sigaction(SIGPIPE, &asa, nullptr) == -1) { if (sigaction(SIGPIPE, &asa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGPIPE\n"); cprintf(RED, "Could not set handler function for SIGPIPE\n");
} }
/** - loop over number of receivers */ /** - loop over number of receivers */
for (int i = 0; i < numReceivers; ++i) { for (int i = 0; i < numReceivers; ++i) {
/** - fork process to create child process */ /** - fork process to create child process */
pid_t pid = fork(); pid_t pid = fork();
/** - if fork failed, raise SIGINT and properly destroy all child processes */ /** - if fork failed, raise SIGINT and properly destroy all child
* processes */
if (pid < 0) { if (pid < 0) {
cprintf(RED,"fork() failed. Killing all the receiver objects\n"); cprintf(RED, "fork() failed. Killing all the receiver objects\n");
raise(SIGINT); raise(SIGINT);
} }
/** - if child process */ /** - if child process */
else if (pid == 0) { else if (pid == 0) {
cprintf(BLUE,"Child process %d [ Tid: %ld ]\n", i, (long)syscall(SYS_gettid)); cprintf(BLUE, "Child process %d [ Tid: %ld ]\n", i,
(long)syscall(SYS_gettid));
std::unique_ptr<Receiver> receiver = nullptr; std::unique_ptr<Receiver> receiver = nullptr;
try { try {
receiver = sls::make_unique<Receiver>(startTCPPort + i); receiver = sls::make_unique<Receiver>(startTCPPort + i);
} catch (...) { } catch (...) {
LOG(logINFOBLUE) << "Exiting Child Process [ Tid: " << syscall(SYS_gettid) << " ]"; LOG(logINFOBLUE)
<< "Exiting Child Process [ Tid: " << syscall(SYS_gettid)
<< " ]";
throw; throw;
} }
/** - register callbacks. remember to set file write enable to 0 (using the client) /** - register callbacks. remember to set file write enable to 0
if we should not write files and you will write data using the callbacks */ (using the client) if we should not write files and you will write data
using the callbacks */
if (withCallback) { if (withCallback) {
/** - Call back for start acquisition */ /** - Call back for start acquisition */
@ -208,56 +227,63 @@ int main(int argc, char *argv[]) {
/** - Call back for acquisition finished */ /** - Call back for acquisition finished */
cprintf(BLUE, "Registering AcquisitionFinished()\n"); cprintf(BLUE, "Registering AcquisitionFinished()\n");
receiver->registerCallBackAcquisitionFinished(AcquisitionFinished, nullptr); receiver->registerCallBackAcquisitionFinished(
AcquisitionFinished, nullptr);
/* - Call back for raw data */ /* - Call back for raw data */
cprintf(BLUE, "Registering GetData() \n"); cprintf(BLUE, "Registering GetData() \n");
if (withCallback == 1) receiver->registerCallBackRawDataReady(GetData,nullptr); if (withCallback == 1)
else if (withCallback == 2) receiver->registerCallBackRawDataModifyReady(GetData,nullptr); receiver->registerCallBackRawDataReady(GetData, nullptr);
else if (withCallback == 2)
receiver->registerCallBackRawDataModifyReady(GetData,
nullptr);
} }
/** - as long as no Ctrl+C */ /** - as long as no Ctrl+C */
sem_wait(&semaphore); sem_wait(&semaphore);
sem_destroy(&semaphore); sem_destroy(&semaphore);
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long)syscall(SYS_gettid)); cprintf(BLUE, "Exiting Child Process [ Tid: %ld ]\n",
(long)syscall(SYS_gettid));
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
} }
} }
/** - Parent process ignores SIGINT (exits only when all child process exits) */ /** - Parent process ignores SIGINT (exits only when all child process
sa.sa_flags=0; // no flags * exits) */
sa.sa_handler=SIG_IGN; // handler function sa.sa_flags = 0; // no flags
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler sa.sa_handler = SIG_IGN; // handler function
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
// of handler
if (sigaction(SIGINT, &sa, nullptr) == -1) { if (sigaction(SIGINT, &sa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGINT\n"); cprintf(RED, "Could not set handler function for SIGINT\n");
} }
/** - Print Ready and Instructions how to exit */ /** - Print Ready and Instructions how to exit */
std::cout << "Ready ... \n"; std::cout << "Ready ... \n";
cprintf(RESET, "\n[ Press \'Ctrl+c\' to exit ]\n"); cprintf(RESET, "\n[ Press \'Ctrl+c\' to exit ]\n");
/** - Parent process waits for all child processes to exit */ /** - Parent process waits for all child processes to exit */
for(;;) { for (;;) {
pid_t childPid = waitpid (-1, nullptr, 0); pid_t childPid = waitpid(-1, nullptr, 0);
// no child closed // no child closed
if (childPid == -1) { if (childPid == -1) {
if (errno == ECHILD) { if (errno == ECHILD) {
cprintf(GREEN,"All Child Processes have been closed\n"); cprintf(GREEN, "All Child Processes have been closed\n");
break; break;
} else { } else {
cprintf(RED, "Unexpected error from waitpid(): (%s)\n",strerror(errno)); cprintf(RED, "Unexpected error from waitpid(): (%s)\n",
strerror(errno));
break; break;
} }
} }
//child closed // child closed
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long int) childPid); cprintf(BLUE, "Exiting Child Process [ Tid: %ld ]\n",
(long int)childPid);
} }
std::cout << "Goodbye!\n"; std::cout << "Goodbye!\n";
return 0; return 0;
} }

91
slsReceiverSoftware/src/Receiver.cpp Executable file → Normal file
View File

@ -1,9 +1,9 @@
#include "Receiver.h" #include "Receiver.h"
#include "ClientInterface.h" #include "ClientInterface.h"
#include "sls_detector_exceptions.h"
#include "versionAPI.h"
#include "container_utils.h" #include "container_utils.h"
#include "logger.h" #include "logger.h"
#include "sls_detector_exceptions.h"
#include "versionAPI.h"
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
@ -17,40 +17,40 @@
Receiver::~Receiver() = default; Receiver::~Receiver() = default;
Receiver::Receiver(int argc, char *argv[]): Receiver::Receiver(int argc, char *argv[]) : tcpipInterface(nullptr) {
tcpipInterface (nullptr) {
// options // options
std::map<std::string, std::string> configuration_map; std::map<std::string, std::string> configuration_map;
int tcpip_port_no = 1954; int tcpip_port_no = 1954;
uid_t userid = -1; uid_t userid = -1;
//parse command line for config // parse command line for config
static struct option long_options[] = { static struct option long_options[] = {
// These options set a flag. // These options set a flag.
//{"verbose", no_argument, &verbose_flag, 1}, //{"verbose", no_argument, &verbose_flag, 1},
// These options dont set a flag. We distinguish them by their indices. // These options dont set a flag. We distinguish them by their indices.
{"rx_tcpport", required_argument, nullptr, 't'}, //TODO change or backward compatible to "port, p"? {"rx_tcpport", required_argument, nullptr,
't'}, // TODO change or backward compatible to "port, p"?
{"uid", required_argument, nullptr, 'u'}, {"uid", required_argument, nullptr, 'u'},
{"version", no_argument, nullptr, 'v'}, {"version", no_argument, nullptr, 'v'},
{"help", no_argument, nullptr, 'h'}, {"help", no_argument, nullptr, 'h'},
{nullptr, 0, nullptr, 0} {nullptr, 0, nullptr, 0}};
};
//initialize global optind variable (required when instantiating multiple receivers in the same process) // initialize global optind variable (required when instantiating multiple
// receivers in the same process)
optind = 1; optind = 1;
// getopt_long stores the option index here. // getopt_long stores the option index here.
int option_index = 0; int option_index = 0;
int c = 0; int c = 0;
while ( c != -1 ){ while (c != -1) {
c = getopt_long (argc, argv, "hvf:t:u:", long_options, &option_index); c = getopt_long(argc, argv, "hvf:t:u:", long_options, &option_index);
// Detect the end of the options. // Detect the end of the options.
if (c == -1) if (c == -1)
break; break;
switch(c){ switch (c) {
case 't': case 't':
sscanf(optarg, "%d", &tcpip_port_no); sscanf(optarg, "%d", &tcpip_port_no);
@ -63,21 +63,26 @@ Receiver::Receiver(int argc, char *argv[]):
break; break;
case 'v': case 'v':
std::cout << "SLS Receiver Version: " << GITBRANCH << " (0x" << std::hex << APIRECEIVER << ")" << std::endl; std::cout << "SLS Receiver Version: " << GITBRANCH << " (0x"
LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]"; << std::hex << APIRECEIVER << ")" << std::endl;
LOG(logINFOBLUE)
<< "Exiting [ Tid: " << syscall(SYS_gettid) << " ]";
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
case 'h': case 'h':
default: default:
std::cout << std::endl; std::cout << std::endl;
std::string help_message = "Usage: " + std::string(argv[0]) + " [arguments]\n" std::string help_message =
+ "Possible arguments are:\n" "Usage: " + std::string(argv[0]) + " [arguments]\n" +
+ "\t-t, --rx_tcpport <port> : TCP Communication Port with client. \n" "Possible arguments are:\n" +
+ "\t-u, --uid <user id> : Set effective user id if receiver \n" "\t-t, --rx_tcpport <port> : TCP Communication Port with "
+ "\t started with privileges. \n\n"; "client. \n" +
"\t-u, --uid <user id> : Set effective user id if receiver "
"\n" +
"\t started with privileges. \n\n";
//std::cout << help_message << std::endl; // std::cout << help_message << std::endl;
throw sls::RuntimeError(help_message); throw sls::RuntimeError(help_message);
} }
} }
@ -85,16 +90,18 @@ Receiver::Receiver(int argc, char *argv[]):
// set effective id if provided // set effective id if provided
if (userid != static_cast<uid_t>(-1)) { if (userid != static_cast<uid_t>(-1)) {
if (geteuid() == userid) { if (geteuid() == userid) {
LOG(logINFO) << "Process already has the same Effective UID " << userid; LOG(logINFO) << "Process already has the same Effective UID "
<< userid;
} else { } else {
if (seteuid(userid) != 0) { if (seteuid(userid) != 0) {
std::ostringstream oss; std::ostringstream oss;
oss << "Could not set Effective UID to " << userid; oss << "Could not set Effective UID to " << userid;
throw sls::RuntimeError(oss.str()); throw sls::RuntimeError(oss.str());
} }
if(geteuid() != userid) { if (geteuid() != userid) {
std::ostringstream oss; std::ostringstream oss;
oss << "Could not set Effective UID to " << userid << ". Got " << geteuid(); oss << "Could not set Effective UID to " << userid << ". Got "
<< geteuid();
throw sls::RuntimeError(oss.str()); throw sls::RuntimeError(oss.str());
} }
LOG(logINFO) << "Process Effective UID changed to " << userid; LOG(logINFO) << "Process Effective UID changed to " << userid;
@ -105,38 +112,34 @@ Receiver::Receiver(int argc, char *argv[]):
tcpipInterface = sls::make_unique<ClientInterface>(tcpip_port_no); tcpipInterface = sls::make_unique<ClientInterface>(tcpip_port_no);
} }
Receiver::Receiver(int tcpip_port_no) {
Receiver::Receiver(int tcpip_port_no)
{
// might throw an exception // might throw an exception
tcpipInterface = sls::make_unique<ClientInterface>(tcpip_port_no); tcpipInterface = sls::make_unique<ClientInterface>(tcpip_port_no);
} }
int64_t Receiver::getReceiverVersion(){ int64_t Receiver::getReceiverVersion() {
return tcpipInterface->getReceiverVersion(); return tcpipInterface->getReceiverVersion();
} }
void Receiver::registerCallBackStartAcquisition(
void Receiver::registerCallBackStartAcquisition(int (*func)( int (*func)(std::string, std::string, uint64_t, uint32_t, void *),
std::string, std::string, uint64_t, uint32_t, void*),void *arg){ void *arg) {
tcpipInterface->registerCallBackStartAcquisition(func,arg); tcpipInterface->registerCallBackStartAcquisition(func, arg);
} }
void Receiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
void Receiver::registerCallBackAcquisitionFinished( void *),
void (*func)(uint64_t, void*),void *arg){ void *arg) {
tcpipInterface->registerCallBackAcquisitionFinished(func,arg); tcpipInterface->registerCallBackAcquisitionFinished(func, arg);
} }
void Receiver::registerCallBackRawDataReady(void (*func)(char *, char *,
void Receiver::registerCallBackRawDataReady(void (*func)(char*, uint32_t, void *),
char*, uint32_t, void*),void *arg){ void *arg) {
tcpipInterface->registerCallBackRawDataReady(func,arg); tcpipInterface->registerCallBackRawDataReady(func, arg);
} }
void Receiver::registerCallBackRawDataModifyReady(
void Receiver::registerCallBackRawDataModifyReady(void (*func)(char*, void (*func)(char *, char *, uint32_t &, void *), void *arg) {
char*, uint32_t &, void*),void *arg){ tcpipInterface->registerCallBackRawDataModifyReady(func, arg);
tcpipInterface->registerCallBackRawDataModifyReady(func,arg);
} }

31
slsReceiverSoftware/src/ReceiverApp.cpp Executable file → Normal file
View File

@ -1,43 +1,41 @@
/* slsReceiver */ /* slsReceiver */
#include "logger.h"
#include "Receiver.h" #include "Receiver.h"
#include "sls_detector_defs.h"
#include "container_utils.h" #include "container_utils.h"
#include "logger.h"
#include "sls_detector_defs.h"
#include <csignal> //SIGINT #include <csignal> //SIGINT
#include <semaphore.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <unistd.h> #include <unistd.h>
#include <semaphore.h>
sem_t semaphore; sem_t semaphore;
void sigInterruptHandler(int p){ void sigInterruptHandler(int p) { sem_post(&semaphore); }
sem_post(&semaphore);
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
sem_init(&semaphore,1,0); sem_init(&semaphore, 1, 0);
LOG(logINFOBLUE) << "Created [ Tid: " << syscall(SYS_gettid) << " ]"; LOG(logINFOBLUE) << "Created [ Tid: " << syscall(SYS_gettid) << " ]";
// Catch signal SIGINT to close files and call destructors properly // Catch signal SIGINT to close files and call destructors properly
struct sigaction sa; struct sigaction sa;
sa.sa_flags=0; // no flags sa.sa_flags = 0; // no flags
sa.sa_handler=sigInterruptHandler; // handler function sa.sa_handler = sigInterruptHandler; // handler function
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
// of handler
if (sigaction(SIGINT, &sa, nullptr) == -1) { if (sigaction(SIGINT, &sa, nullptr) == -1) {
LOG(logERROR) << "Could not set handler function for SIGINT"; LOG(logERROR) << "Could not set handler function for SIGINT";
} }
// if socket crash, ignores SISPIPE, prevents global signal handler // if socket crash, ignores SISPIPE, prevents global signal handler
// subsequent read/write to socket gives error - must handle locally // subsequent read/write to socket gives error - must handle locally
struct sigaction asa; struct sigaction asa;
asa.sa_flags=0; // no flags asa.sa_flags = 0; // no flags
asa.sa_handler=SIG_IGN; // handler function asa.sa_handler = SIG_IGN; // handler function
sigemptyset(&asa.sa_mask); // dont block additional signals during invocation of handler sigemptyset(&asa.sa_mask); // dont block additional signals during
// invocation of handler
if (sigaction(SIGPIPE, &asa, nullptr) == -1) { if (sigaction(SIGPIPE, &asa, nullptr) == -1) {
LOG(logERROR) << "Could not set handler function for SIGPIPE"; LOG(logERROR) << "Could not set handler function for SIGPIPE";
} }
@ -48,10 +46,9 @@ int main(int argc, char *argv[]) {
sem_wait(&semaphore); sem_wait(&semaphore);
sem_destroy(&semaphore); sem_destroy(&semaphore);
} catch (...) { } catch (...) {
//pass // pass
} }
LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]"; LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]";
LOG(logINFO) << "Exiting Receiver"; LOG(logINFO) << "Exiting Receiver";
return 0; return 0;
} }

40
slsReceiverSoftware/src/ThreadObject.cpp Executable file → Normal file
View File

@ -12,11 +12,12 @@
ThreadObject::ThreadObject(int threadIndex, std::string threadType) ThreadObject::ThreadObject(int threadIndex, std::string threadType)
: index(threadIndex), type(threadType) { : index(threadIndex), type(threadType) {
LOG(logDEBUG) << type << " thread created: " << index; LOG(logDEBUG) << type << " thread created: " << index;
sem_init(&semaphore,1,0); sem_init(&semaphore, 1, 0);
try { try {
threadObject = std::thread(&ThreadObject::RunningThread, this); threadObject = std::thread(&ThreadObject::RunningThread, this);
} catch (...) { } catch (...) {
throw sls::RuntimeError("Could not create " + type + " thread with index " + std::to_string(index)); throw sls::RuntimeError("Could not create " + type +
" thread with index " + std::to_string(index));
} }
} }
@ -27,41 +28,36 @@ ThreadObject::~ThreadObject() {
sem_destroy(&semaphore); sem_destroy(&semaphore);
} }
bool ThreadObject::IsRunning() const{ bool ThreadObject::IsRunning() const { return runningFlag; }
return runningFlag;
}
void ThreadObject::StartRunning() { void ThreadObject::StartRunning() { runningFlag = true; }
runningFlag = true;
}
void ThreadObject::StopRunning() { void ThreadObject::StopRunning() { runningFlag = false; }
runningFlag = false;
}
void ThreadObject::RunningThread() { void ThreadObject::RunningThread() {
LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]"; LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index
while(!killThread) { << ", Tid: " << syscall(SYS_gettid) << "]";
while(IsRunning()) { while (!killThread) {
while (IsRunning()) {
ThreadExecution(); ThreadExecution();
} }
//wait till the next acquisition // wait till the next acquisition
sem_wait(&semaphore); sem_wait(&semaphore);
} }
LOG(logINFOBLUE) << "Exiting [ " << type << " Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]"; LOG(logINFOBLUE) << "Exiting [ " << type << " Thread " << index
<< ", Tid: " << syscall(SYS_gettid) << "]";
} }
void ThreadObject::Continue() { sem_post(&semaphore); }
void ThreadObject::Continue() {
sem_post(&semaphore);
}
void ThreadObject::SetThreadPriority(int priority) { void ThreadObject::SetThreadPriority(int priority) {
struct sched_param param; struct sched_param param;
param.sched_priority = priority; 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) { if (index == 0) {
LOG(logWARNING) << "Could not prioritize " << type << " thread. " LOG(logWARNING) << "Could not prioritize " << type
<< " thread. "
"(No Root Privileges?)"; "(No Root Privileges?)";
} }
} else { } else {

2
slsReceiverSoftware/src/ThreadObject.h Executable file → Normal file
View File

@ -11,9 +11,9 @@
#include "sls_detector_defs.h" #include "sls_detector_defs.h"
#include <atomic> #include <atomic>
#include <thread>
#include <semaphore.h> #include <semaphore.h>
#include <string> #include <string>
#include <thread>
class ThreadObject : private virtual slsDetectorDefs { class ThreadObject : private virtual slsDetectorDefs {
protected: protected:

View File

@ -6,14 +6,13 @@
#define MAX_DIMENSIONS (2) #define MAX_DIMENSIONS (2)
#define MAX_NUMBER_OF_LISTENING_THREADS (2) #define MAX_NUMBER_OF_LISTENING_THREADS (2)
//socket // socket
#define GOODBYE (-200) #define GOODBYE (-200)
#define RECEIVE_SOCKET_BUFFER_SIZE (100*1024*1024) #define RECEIVE_SOCKET_BUFFER_SIZE (100 * 1024 * 1024)
#define MAX_SOCKET_INPUT_PACKET_QUEUE (250000) #define MAX_SOCKET_INPUT_PACKET_QUEUE (250000)
// files
//files
#define MAX_FRAMES_PER_FILE 20000 #define MAX_FRAMES_PER_FILE 20000
#define SHORT_MAX_FRAMES_PER_FILE 100000 #define SHORT_MAX_FRAMES_PER_FILE 100000
#define MOENCH_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 100000
@ -28,31 +27,29 @@
#define STATISTIC_FRAMENUMBER_INFINITE (20000) #define STATISTIC_FRAMENUMBER_INFINITE (20000)
//binary // binary
#define FILE_BUFFER_SIZE (16*1024*1024) //16mb #define FILE_BUFFER_SIZE (16 * 1024 * 1024) // 16mb
//fifo // fifo
#define FIFO_HEADER_NUMBYTES (8) #define FIFO_HEADER_NUMBYTES (8)
#define FIFO_DATASIZE_NUMBYTES (4) #define FIFO_DATASIZE_NUMBYTES (4)
#define FIFO_PADDING_NUMBYTES (4) // for 8 byte alignment due to sls_receiver_header structure #define FIFO_PADDING_NUMBYTES \
(4) // for 8 byte alignment due to sls_receiver_header structure
// hdf5
//hdf5
#define MAX_CHUNKED_IMAGES (1) #define MAX_CHUNKED_IMAGES (1)
//versions // versions
#define HDF5_WRITER_VERSION (5.0) //1 decimal places #define HDF5_WRITER_VERSION (5.0) // 1 decimal places
#define BINARY_WRITER_VERSION (5.0) //1 decimal places #define BINARY_WRITER_VERSION (5.0) // 1 decimal places
// parameters to calculate fifo depth
//parameters to calculate fifo depth #define SAMPLE_TIME_IN_NS (100000000) // 100ms
#define SAMPLE_TIME_IN_NS (100000000)//100ms
#define MAX_EIGER_ROWS_PER_READOUT (256) #define MAX_EIGER_ROWS_PER_READOUT (256)
//to differentiate between gotthard and short gotthard // to differentiate between gotthard and short gotthard
#define GOTTHARD_PACKET_SIZE (1286) #define GOTTHARD_PACKET_SIZE (1286)
#define DUMMY_PACKET_VALUE (0xFFFFFFFF) #define DUMMY_PACKET_VALUE (0xFFFFFFFF)
#define LISTENER_PRIORITY (90) #define LISTENER_PRIORITY (90)
@ -82,4 +79,4 @@ struct masterAttributes {
uint64_t dbitlist; uint64_t dbitlist;
uint32_t roiXmin; uint32_t roiXmin;
uint32_t roiXmax; uint32_t roiXmax;
}; };

View File

@ -1,52 +1,49 @@
#include "catch.hpp"
#include "CircularFifo.h" #include "CircularFifo.h"
#include "catch.hpp"
#include <vector> #include <vector>
TEST_CASE("Empty buffer"){ TEST_CASE("Empty buffer") {
CircularFifo<char> fifo(0); CircularFifo<char> fifo(0);
//Since the fifo can hold zero elements // Since the fifo can hold zero elements
//its both empty and full // its both empty and full
CHECK(fifo.isEmpty()== true); CHECK(fifo.isEmpty() == true);
CHECK(fifo.isFull()== true); CHECK(fifo.isFull() == true);
// push fails
//push fails char *c = new char;
char* c = new char;
*c = 'h'; *c = 'h';
CHECK(fifo.push(c, true) == false); CHECK(fifo.push(c, true) == false);
//pop fails // pop fails
CHECK(fifo.pop(c, true) == false); CHECK(fifo.pop(c, true) == false);
delete c; delete c;
} }
TEST_CASE("Push pop"){ TEST_CASE("Push pop") {
CircularFifo<int> fifo(5); CircularFifo<int> fifo(5);
std::vector<int> vec{3,7,12,3,4}; std::vector<int> vec{3, 7, 12, 3, 4};
int* p = &vec[0]; int *p = &vec[0];
for(size_t i =0; i!=vec.size(); ++i){ for (size_t i = 0; i != vec.size(); ++i) {
fifo.push(p); fifo.push(p);
++p; ++p;
CHECK(fifo.getDataValue() == i+1); CHECK(fifo.getDataValue() == i + 1);
CHECK(fifo.getFreeValue() == 4-i); CHECK(fifo.getFreeValue() == 4 - i);
} }
CHECK(fifo.isEmpty()== false); CHECK(fifo.isEmpty() == false);
CHECK(fifo.isFull()== true); CHECK(fifo.isFull() == true);
for(size_t i = 0; i!= vec.size(); ++i){ for (size_t i = 0; i != vec.size(); ++i) {
fifo.pop(p); fifo.pop(p);
CHECK(*p == vec[i]); CHECK(*p == vec[i]);
CHECK(fifo.getDataValue() == 4-i); CHECK(fifo.getDataValue() == 4 - i);
CHECK(fifo.getFreeValue() == i+1); CHECK(fifo.getFreeValue() == i + 1);
} }
CHECK(fifo.isEmpty()== true); CHECK(fifo.isEmpty() == true);
CHECK(fifo.isFull()== false); CHECK(fifo.isFull() == false);
} }

3
slsReceiverSoftware/tests/test-GeneralData.cpp Executable file → Normal file
View File

@ -2,11 +2,8 @@
#include "GeneralData.h" #include "GeneralData.h"
#include "catch.hpp" #include "catch.hpp"
#include <iostream> #include <iostream>
// using namespace sls; // using namespace sls;
// TEST_CASE("Parse jungfrauctb header", "[receiver]") { // TEST_CASE("Parse jungfrauctb header", "[receiver]") {