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

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

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;

95
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,16 +41,19 @@ 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);
} }
@ -62,7 +61,8 @@ void BinaryFile::CreateFile() {
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;
} }
} }
@ -87,8 +87,8 @@ int BinaryFile::WriteData(char* buf, int bsize) {
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))) {
@ -128,13 +128,14 @@ void BinaryFile::WriteToFile(char* buffer, int buffersize, uint64_t currentFrame
// 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;
@ -152,15 +153,19 @@ void BinaryFile::CreateMasterFile(bool masterFileWriteEnable, masterAttributes&
// 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;
} }
} }

14
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,10 +33,10 @@ 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;
@ -56,6 +56,4 @@ class BinaryFile : private virtual slsDetectorDefs, public File {
uint32_t numFramesInFile; uint32_t numFramesInFile;
uint64_t numActualPacketsInFile; uint64_t numActualPacketsInFile;
const size_t maxMasterFileSize; const size_t maxMasterFileSize;
}; };

193
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;
@ -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) {
@ -418,8 +423,8 @@ int ClientInterface::setup_receiver(Interface &socket) {
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.");
} }
} }
@ -441,7 +446,8 @@ int ClientInterface::setup_receiver(Interface &socket) {
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");
} }
} }
@ -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) {
@ -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;
@ -643,7 +645,9 @@ 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);
} }
@ -657,7 +661,9 @@ 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);
} }
@ -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;
@ -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;
@ -978,7 +985,8 @@ int ClientInterface::set_fifo_depth(Interface &socket) {
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;
@ -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());
@ -1355,7 +1357,8 @@ int ClientInterface::set_readout_mode(Interface &socket) {
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();
@ -1372,7 +1375,8 @@ int ClientInterface::set_adc_mask(Interface &socket) {
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;
@ -1443,7 +1446,9 @@ int ClientInterface::set_quad_type(Interface &socket) {
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);
} }
@ -1570,7 +1586,8 @@ int ClientInterface::set_adc_mask_10g(Interface &socket) {
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);
} }

21
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);
@ -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};
}; };

199
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,62 +21,38 @@
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, bool *dsEnable, uint32_t *dr, uint32_t *freq,
uint32_t* freq, uint32_t* timer, 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, int* cdo, int* cad) : std::vector<int> *cdl, int *cdo, int *cad)
ThreadObject(ind, TypeName), : ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype),
fifo(f), dataStreamEnable(dsEnable), fileFormatType(ftype),
myDetectorType(dtype), fileWriteEnable(fwenable), masterFileWriteEnable(mfwenable),
dataStreamEnable(dsEnable), dynamicRange(dr), streamingFrequency(freq), streamingTimerInMs(timer),
fileFormatType(ftype), activated(act), deactivatedPaddingEnable(depaden), silentMode(sm),
fileWriteEnable(fwenable), quadEnable(qe), framePadding(fp), ctbDbitList(cdl), ctbDbitOffset(cdo),
masterFileWriteEnable(mfwenable), ctbAnalogDataBytes(cad) {
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();
@ -87,7 +62,6 @@ 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;
@ -98,47 +72,51 @@ 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];
nd[0] = 0;
nd[1] = 0;
uint32_t *maxf = nullptr; uint32_t *maxf = nullptr;
std::string* fname=nullptr; std::string* fpath=nullptr; std::string *fname = nullptr;
uint64_t* findex=nullptr; bool* owenable=nullptr; int* dindex=nullptr; std::string *fpath = nullptr;
int* nunits=nullptr; uint64_t* nf = nullptr; uint64_t *findex = nullptr;
uint32_t* dr = nullptr; uint32_t* port = nullptr; bool *owenable = nullptr;
file->GetMemberPointerValues(nd, maxf, fname, fpath, findex, int *dindex = nullptr;
owenable, dindex, nunits, nf, dr, port); 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 // 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, uint64_t* findex, std::string *fname, std::string *fpath,
bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint64_t *findex, bool *owenable,
uint32_t* portno, int *dindex, int *nunits, uint64_t *nf,
GeneralData* g) uint32_t *dr, uint32_t *portno,
{ 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;
@ -148,15 +126,15 @@ void DataProcessor::SetupFileWriter(bool fwe, int* nd, uint32_t* maxf,
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;
} }
@ -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();
@ -190,12 +167,13 @@ void DataProcessor::EndofAcquisition(bool anyPacketsCaught, uint64_t numf) {
} }
} }
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));
@ -214,7 +192,6 @@ void DataProcessor::ThreadExecution() {
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";
@ -230,7 +207,6 @@ 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);
@ -273,40 +249,38 @@ 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,
sizeof(sls_receiver_header) +
(uint32_t)(*((uint32_t *)buf)), //+ size of data (resizable
//from previous call back
fnum - firstIndex, nump); fnum - firstIndex, nump);
} catch (const sls::RuntimeError &e) { } catch (const sls::RuntimeError &e) {
; //ignore write exception for now (TODO: send error message via stopReceiver tcp) ; // 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) {
@ -319,17 +293,18 @@ 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
@ -337,7 +312,6 @@ bool DataProcessor::CheckTimer() {
return true; return true;
} }
bool DataProcessor::CheckCount() { bool DataProcessor::CheckCount() {
if (currentFreqCount == *streamingFrequency) { if (currentFreqCount == *streamingFrequency) {
currentFreqCount = 1; currentFreqCount = 1;
@ -347,23 +321,24 @@ 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 *),
void *arg) {
rawDataReadyCallBack = func; rawDataReadyCallBack = func;
pRawDataReady = arg; 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;
} }
@ -378,7 +353,8 @@ void DataProcessor::PadMissingPackets(char* buf) {
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,12 +367,15 @@ 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);
@ -421,19 +400,23 @@ 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;
@ -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);
} }

59
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
@ -47,9 +48,9 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
*/ */
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();
@ -124,8 +125,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* @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);
/** /**
@ -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
@ -231,7 +232,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
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);
@ -244,7 +246,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
/** Fifo structure */ /** Fifo structure */
Fifo *fifo; Fifo *fifo;
// individual members // individual members
/** Detector Type */ /** Detector Type */
detectorType myDetectorType; detectorType myDetectorType;
@ -267,7 +268,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
/** 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 */
@ -310,7 +312,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
/** 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};
@ -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};
}; };

109
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,33 +14,22 @@
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();
@ -79,27 +67,28 @@ void DataStreamer::SetNumberofDetectors(int* nd) {
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,13 +96,13 @@ 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));
@ -127,18 +116,16 @@ void DataStreamer::ThreadExecution() {
// 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);
@ -149,7 +136,8 @@ 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;
@ -160,41 +148,50 @@ void DataStreamer::ProcessAnImage(char* buf) {
// 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
// instead of buf (32 bit) because gui needs imagesizecomplete and
// listener
// write imagesize // 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,14 +233,13 @@ 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;
@ -250,8 +247,8 @@ void DataStreamer::RestreamStop() {
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()));
} }
} }

17
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
@ -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
@ -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
@ -134,7 +134,8 @@ 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;
@ -186,6 +187,4 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
/** Total number of frames */ /** Total number of frames */
uint64_t *totalNumFrames; uint64_t *totalNumFrames;
}; };

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

@ -13,27 +13,19 @@
#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),
fifoFree(nullptr),
fifoStream(nullptr),
fifoDepth(depth),
status_fifoBound(0),
status_fifoFree(depth) { 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";
@ -55,7 +47,8 @@ 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;
@ -65,10 +58,10 @@ void Fifo::CreateFifos(uint32_t fifoItemSize) {
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";
@ -84,10 +77,7 @@ void Fifo::DestroyFifos(){
fifoStream = nullptr; fifoStream = nullptr;
} }
void Fifo::FreeAddress(char *&address) { fifoFree->push(address); }
void Fifo::FreeAddress(char*& address) {
fifoFree->push(address);
}
void Fifo::GetNewAddress(char *&address) { void Fifo::GetNewAddress(char *&address) {
int temp = fifoFree->getDataValue(); int temp = fifoFree->getDataValue();
@ -100,23 +90,18 @@ 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;
} }

4
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"
@ -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,7 +85,6 @@ class Fifo : private virtual slsDetectorDefs {
*/ */
void DestroyFifos(); void DestroyFifos();
/** Self Index */ /** Self Index */
int index; int index;

52
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), : index(ind), formatType(type), maxFramesPerFile(maxf), numDetX(nd[0]),
formatType(type), numDetY(nd[1]), fileNamePrefix(fname), filePath(fpath), fileIndex(findex),
maxFramesPerFile(maxf), overWriteEnable(owenable), detIndex(dindex), numUnitsPerDetector(nunits),
numDetX(nd[0]), numImages(nf), dynamicRange(dr), udpPortNumber(portno), silentMode(smode)
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;
} }

20
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,8 +36,8 @@ 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);
@ -62,8 +62,10 @@ class File : private virtual slsDetectorDefs {
* @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,7 +77,8 @@ 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
@ -126,4 +129,3 @@ class File : private virtual slsDetectorDefs {
uint32_t *udpPortNumber; uint32_t *udpPortNumber;
bool *silentMode; bool *silentMode;
}; };

170
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,9 +107,9 @@ 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;
@ -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";
}; };
/** /**
@ -149,7 +132,8 @@ public:
* @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";
}; };
/** /**
@ -178,7 +164,8 @@ public:
* @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,15 +234,14 @@ 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;
@ -266,11 +256,11 @@ private:
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
@ -280,8 +270,7 @@ private:
* @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)
@ -294,7 +283,6 @@ private:
} }
} }
/** /**
* Set ROI * Set ROI
* @param i ROI * @param i ROI
@ -311,7 +299,8 @@ private:
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;
@ -329,7 +318,8 @@ private:
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;
@ -349,10 +339,10 @@ private:
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 << ": Deleting ROI. " LOG(logWARNING) << index
<< ": Deleting ROI. "
"Adc value should be between 0 and 4"; "Adc value should be between 0 and 4";
adc = -1; adc = -1;
} }
@ -394,14 +384,11 @@ 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;
@ -413,7 +400,8 @@ class EigerData : public GeneralData {
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;
@ -442,15 +430,11 @@ class EigerData : public GeneralData {
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;
@ -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
@ -498,8 +482,8 @@ 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;
@ -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,10 +543,8 @@ public:
} }
}; };
class Gotthard2Data : public GeneralData { class Gotthard2Data : public GeneralData {
public: public:
/** Constructor */ /** Constructor */
Gotthard2Data() { Gotthard2Data() {
myDetectorType = slsDetectorDefs::GOTTHARD2; myDetectorType = slsDetectorDefs::GOTTHARD2;
@ -570,14 +556,14 @@ 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 */
@ -588,8 +574,6 @@ private:
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;
@ -603,9 +587,11 @@ public:
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,13 +654,10 @@ 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;
@ -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;
} }
}; };

511
slsReceiverSoftware/src/HDF5File.cpp Executable file → Normal file
View File

@ -4,39 +4,28 @@
* creates/closes the file and writes data to it * creates/closes the file and writes data to it
***********************************************/ ***********************************************/
#include "HDF5File.h" #include "HDF5File.h"
#include "receiver_defs.h"
#include "Fifo.h" #include "Fifo.h"
#include "receiver_defs.h"
#include <iostream>
#include <iomanip> #include <iomanip>
#include <iostream>
#include <libgen.h> //basename #include <libgen.h> //basename
#include <string.h> #include <string.h>
std::mutex HDF5File::hdf5Lib; std::mutex HDF5File::hdf5Lib;
HDF5File::HDF5File(int ind, uint32_t *maxf, int *nd, std::string *fname,
std::string *fpath, uint64_t *findex, bool *owenable,
int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
uint32_t *portno, uint32_t nx, uint32_t ny, bool *smode)
:
HDF5File::HDF5File(int ind, uint32_t* maxf, File(ind, HDF5, maxf, nd, fname, fpath, findex, owenable, dindex, nunits,
int* nd, std::string* fname, std::string* fpath, uint64_t* findex, bool* owenable, nf, dr, portno, smode),
int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t* portno, masterfd(0), virtualfd(0), filefd(0), dataspace(0), dataset(0),
uint32_t nx, uint32_t ny, datatype(PredType::STD_U16LE), nPixelsX(nx), nPixelsY(ny),
bool* smode): numFramesInFile(0), numActualPacketsInFile(0), numFilesinAcquisition(0),
dataspace_para(0), extNumImages(0) {
File(ind, HDF5, maxf, nd, fname, fpath, findex, owenable, dindex, nunits, nf, dr, portno, smode),
masterfd(0),
virtualfd(0),
filefd(0),
dataspace(0),
dataset(0),
datatype(PredType::STD_U16LE),
nPixelsX(nx),
nPixelsY(ny),
numFramesInFile(0),
numActualPacketsInFile(0),
numFilesinAcquisition(0),
dataspace_para(0),
extNumImages(0)
{
PrintMembers(); PrintMembers();
dataset_para.clear(); dataset_para.clear();
parameterNames.clear(); parameterNames.clear();
@ -86,9 +75,7 @@ HDF5File::HDF5File(int ind, uint32_t* maxf,
parameterDataTypes.push_back(strdatatype); parameterDataTypes.push_back(strdatatype);
} }
HDF5File::~HDF5File() { HDF5File::~HDF5File() { CloseAllFiles(); }
CloseAllFiles();
}
void HDF5File::SetNumberofPixels(uint32_t nx, uint32_t ny) { void HDF5File::SetNumberofPixels(uint32_t nx, uint32_t ny) {
nPixelsX = nx; nPixelsX = nx;
@ -155,12 +142,17 @@ void HDF5File::CloseAllFiles() {
for (unsigned int i = 0; i < dataset_para.size(); ++i) for (unsigned int i = 0; i < dataset_para.size(); ++i)
delete dataset_para[i]; delete dataset_para[i];
dataset_para.clear(); dataset_para.clear();
if(dataspace_para) delete dataspace_para; if (dataspace_para)
if(dataset) delete dataset; delete dataspace_para;
if(dataspace) delete dataspace; if (dataset)
delete dataset;
if (dataspace)
delete dataspace;
} }
void HDF5File::WriteToFile(char* buffer, int bufferSize, uint64_t currentFrameNumber, uint32_t numPacketsCaught) { void HDF5File::WriteToFile(char *buffer, int bufferSize,
uint64_t currentFrameNumber,
uint32_t numPacketsCaught) {
// check if maxframesperfile = 0 for infinite // check if maxframesperfile = 0 for infinite
if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) { if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) {
@ -171,7 +163,8 @@ void HDF5File::WriteToFile(char* buffer, int bufferSize, uint64_t currentFrameNu
numFramesInFile++; numFramesInFile++;
numActualPacketsInFile += numPacketsCaught; numActualPacketsInFile += numPacketsCaught;
// extend dataset (when receiver start followed by many status starts (jungfrau))) // extend dataset (when receiver start followed by many status starts
// (jungfrau)))
if (currentFrameNumber >= extNumImages) { if (currentFrameNumber >= extNumImages) {
ExtendDataset(); ExtendDataset();
} }
@ -180,7 +173,8 @@ void HDF5File::WriteToFile(char* buffer, int bufferSize, uint64_t currentFrameNu
WriteParameterDatasets(currentFrameNumber, (sls_receiver_header *)(buffer)); WriteParameterDatasets(currentFrameNumber, (sls_receiver_header *)(buffer));
} }
void HDF5File::CreateMasterFile(bool masterFileWriteEnable, masterAttributes& masterFileAttributes) { void HDF5File::CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes) {
// beginning of every acquisition // beginning of every acquisition
numFramesInFile = 0; numFramesInFile = 0;
@ -193,7 +187,8 @@ void HDF5File::CreateMasterFile(bool masterFileWriteEnable, masterAttributes& ma
} }
} }
void HDF5File::EndofAcquisition(bool anyPacketsCaught, uint64_t numImagesCaught) { void HDF5File::EndofAcquisition(bool anyPacketsCaught,
uint64_t numImagesCaught) {
// not created before // not created before
if (!virtualfd && anyPacketsCaught) { if (!virtualfd && anyPacketsCaught) {
// called only by the one maser receiver // called only by the one maser receiver
@ -213,9 +208,10 @@ void HDF5File::EndofAcquisition(bool anyPacketsCaught, uint64_t numImagesCaught)
// create virutal file // create virutal file
else { else {
CreateVirtualDataFile( CreateVirtualDataFile(
// infinite images in 1 file, then maxfrperfile = numImagesCaught // infinite images in 1 file, then maxfrperfile =
((*maxFramesPerFile == 0) ? // numImagesCaught
numImagesCaught+1 : *maxFramesPerFile), ((*maxFramesPerFile == 0) ? numImagesCaught + 1
: *maxFramesPerFile),
numImagesCaught + 1); numImagesCaught + 1);
} }
} }
@ -233,8 +229,7 @@ void HDF5File::CloseFile(H5File*& fd, bool masterFile) {
fd = 0; fd = 0;
} }
} catch (const Exception &error) { } catch (const Exception &error) {
LOG(logERROR) << "Could not close " LOG(logERROR) << "Could not close " << (masterFile ? "master" : "data")
<< (masterFile ? "master" : "data")
<< " HDF5 handles of index " << index; << " HDF5 handles of index " << index;
error.printErrorStack(); error.printErrorStack();
} }
@ -243,8 +238,9 @@ void HDF5File::CloseFile(H5File*& fd, bool masterFile) {
void HDF5File::WriteDataFile(uint64_t currentFrameNumber, char *buffer) { void HDF5File::WriteDataFile(uint64_t currentFrameNumber, char *buffer) {
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib); std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
uint64_t nDimx = ((*maxFramesPerFile == 0) ? uint64_t nDimx =
currentFrameNumber : currentFrameNumber % (*maxFramesPerFile)); ((*maxFramesPerFile == 0) ? currentFrameNumber
: currentFrameNumber % (*maxFramesPerFile));
uint32_t nDimy = nPixelsY; uint32_t nDimy = nPixelsY;
uint32_t nDimz = ((*dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX); uint32_t nDimz = ((*dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX);
@ -258,8 +254,7 @@ void HDF5File::WriteDataFile(uint64_t currentFrameNumber, char* buffer) {
DataSpace memspace(2, dims2); DataSpace memspace(2, dims2);
dataset->write(buffer, datatype, memspace, *dataspace); dataset->write(buffer, datatype, memspace, *dataspace);
memspace.close(); memspace.close();
} } catch (const Exception &error) {
catch(const Exception& error){
LOG(logERROR) << "Could not write to file in object " << index; LOG(logERROR) << "Could not write to file in object " << index;
error.printErrorStack(); error.printErrorStack();
throw sls::RuntimeError("Could not write to file in object " + throw sls::RuntimeError("Could not write to file in object " +
@ -271,8 +266,9 @@ void HDF5File::WriteParameterDatasets(uint64_t currentFrameNumber,
sls_receiver_header *rheader) { sls_receiver_header *rheader) {
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib); std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
uint64_t fnum = ((*maxFramesPerFile == 0) ? uint64_t fnum =
currentFrameNumber : currentFrameNumber % (*maxFramesPerFile)); ((*maxFramesPerFile == 0) ? currentFrameNumber
: currentFrameNumber % (*maxFramesPerFile));
sls_detector_header header = rheader->detHeader; sls_detector_header header = rheader->detHeader;
hsize_t count[1] = {1}; hsize_t count[1] = {1};
@ -282,37 +278,51 @@ void HDF5File::WriteParameterDatasets(uint64_t currentFrameNumber,
Exception::dontPrint(); // to handle errors Exception::dontPrint(); // to handle errors
dataspace_para->selectHyperslab(H5S_SELECT_SET, count, start); dataspace_para->selectHyperslab(H5S_SELECT_SET, count, start);
DataSpace memspace(H5S_SCALAR); DataSpace memspace(H5S_SCALAR);
dataset_para[0]->write(&header.frameNumber, dataset_para[0]->write(&header.frameNumber, parameterDataTypes[0],
parameterDataTypes[0], memspace, *dataspace_para);i=1; memspace, *dataspace_para);
dataset_para[1]->write(&header.expLength, i = 1;
parameterDataTypes[1], memspace, *dataspace_para);i=2; dataset_para[1]->write(&header.expLength, parameterDataTypes[1],
dataset_para[2]->write(&header.packetNumber, memspace, *dataspace_para);
parameterDataTypes[2], memspace, *dataspace_para);i=3; i = 2;
dataset_para[3]->write(&header.bunchId, dataset_para[2]->write(&header.packetNumber, parameterDataTypes[2],
parameterDataTypes[3], memspace, *dataspace_para);i=4; memspace, *dataspace_para);
dataset_para[4]->write(&header.timestamp, i = 3;
parameterDataTypes[4], memspace, *dataspace_para);i=5; dataset_para[3]->write(&header.bunchId, parameterDataTypes[3], memspace,
dataset_para[5]->write(&header.modId, *dataspace_para);
parameterDataTypes[5], memspace, *dataspace_para);i=6; i = 4;
dataset_para[6]->write(&header.row, dataset_para[4]->write(&header.timestamp, parameterDataTypes[4],
parameterDataTypes[6], memspace, *dataspace_para);i=7; memspace, *dataspace_para);
dataset_para[7]->write(&header.column, i = 5;
parameterDataTypes[7], memspace, *dataspace_para);i=8; dataset_para[5]->write(&header.modId, parameterDataTypes[5], memspace,
dataset_para[8]->write(&header.reserved, *dataspace_para);
parameterDataTypes[8], memspace, *dataspace_para);i=9; i = 6;
dataset_para[9]->write(&header.debug, dataset_para[6]->write(&header.row, parameterDataTypes[6], memspace,
parameterDataTypes[9], memspace, *dataspace_para);i=10; *dataspace_para);
dataset_para[10]->write(&header.roundRNumber, i = 7;
parameterDataTypes[10], memspace, *dataspace_para);i=11; dataset_para[7]->write(&header.column, parameterDataTypes[7], memspace,
dataset_para[11]->write(&header.detType, *dataspace_para);
parameterDataTypes[11], memspace, *dataspace_para);i=12; i = 8;
dataset_para[12]->write(&header.version, dataset_para[8]->write(&header.reserved, parameterDataTypes[8],
parameterDataTypes[12], memspace, *dataspace_para);i=13; memspace, *dataspace_para);
i = 9;
dataset_para[9]->write(&header.debug, parameterDataTypes[9], memspace,
*dataspace_para);
i = 10;
dataset_para[10]->write(&header.roundRNumber, parameterDataTypes[10],
memspace, *dataspace_para);
i = 11;
dataset_para[11]->write(&header.detType, parameterDataTypes[11],
memspace, *dataspace_para);
i = 12;
dataset_para[12]->write(&header.version, parameterDataTypes[12],
memspace, *dataspace_para);
i = 13;
// contiguous bitset // contiguous bitset
if (sizeof(sls_bitset) == sizeof(bitset_storage)) { if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
dataset_para[13]->write((char *)&(rheader->packetsMask), dataset_para[13]->write((char *)&(rheader->packetsMask),
parameterDataTypes[13], memspace, *dataspace_para); parameterDataTypes[13], memspace,
*dataspace_para);
} }
// not contiguous bitset // not contiguous bitset
@ -326,12 +336,13 @@ void HDF5File::WriteParameterDatasets(uint64_t currentFrameNumber,
// write bitmask // write bitmask
dataset_para[13]->write((char *)storage, parameterDataTypes[13], dataset_para[13]->write((char *)storage, parameterDataTypes[13],
memspace, *dataspace_para); memspace, *dataspace_para);
}i=14;
} }
catch(const Exception& error){ i = 14;
} catch (const Exception &error) {
error.printErrorStack(); error.printErrorStack();
throw sls::RuntimeError("Could not write parameters (index:" + throw sls::RuntimeError(
std::to_string(i) + ") to file in object " + std::to_string(index)); "Could not write parameters (index:" + std::to_string(i) +
") to file in object " + std::to_string(index));
} }
} }
@ -357,15 +368,14 @@ void HDF5File::ExtendDataset() {
dataspace_para = 0; dataspace_para = 0;
dataspace_para = new DataSpace(dataset_para[0]->getSpace()); dataspace_para = new DataSpace(dataset_para[0]->getSpace());
} } catch (const Exception &error) {
catch(const Exception& error){
error.printErrorStack(); error.printErrorStack();
throw sls::RuntimeError("Could not extend dataset in object " + throw sls::RuntimeError("Could not extend dataset in object " +
std::to_string(index)); std::to_string(index));
} }
if (!(*silentMode)) { if (!(*silentMode)) {
LOG(logINFO) << index << " Extending HDF5 dataset by " << LOG(logINFO) << index << " Extending HDF5 dataset by " << extNumImages
extNumImages << ", Total x Dimension: " << (extNumImages + *numImages); << ", Total x Dimension: " << (extNumImages + *numImages);
} }
extNumImages += *numImages; extNumImages += *numImages;
} }
@ -374,15 +384,18 @@ void HDF5File::CreateDataFile() {
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 << ".h5"; << '_' << *fileIndex << ".h5";
currentFileName = os.str(); currentFileName = os.str();
std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib); std::lock_guard<std::mutex> lock(HDF5File::hdf5Lib);
uint64_t framestosave = ((*maxFramesPerFile == 0) ? *numImages : // infinite images uint64_t framestosave =
(((extNumImages - subFileIndex) > (*maxFramesPerFile)) ? // save up to maximum at a time ((*maxFramesPerFile == 0) ? *numImages : // infinite images
(*maxFramesPerFile) : (extNumImages-subFileIndex))); (((extNumImages - subFileIndex) > (*maxFramesPerFile))
? // save up to maximum at a time
(*maxFramesPerFile)
: (extNumImages - subFileIndex)));
uint64_t nDimx = framestosave; uint64_t nDimx = framestosave;
uint32_t nDimy = nPixelsY; uint32_t nDimy = nPixelsY;
@ -397,18 +410,16 @@ void HDF5File::CreateDataFile() {
filefd = 0; filefd = 0;
if (!(*overWriteEnable)) if (!(*overWriteEnable))
filefd = new H5File(currentFileName.c_str(), H5F_ACC_EXCL, filefd = new H5File(currentFileName.c_str(), H5F_ACC_EXCL,
FileCreatPropList::DEFAULT, FileCreatPropList::DEFAULT, fapl);
fapl );
else else
filefd = new H5File(currentFileName.c_str(), H5F_ACC_TRUNC, filefd = new H5File(currentFileName.c_str(), H5F_ACC_TRUNC,
FileCreatPropList::DEFAULT, FileCreatPropList::DEFAULT, fapl);
fapl );
// attributes - version // attributes - version
double dValue = HDF5_WRITER_VERSION; double dValue = HDF5_WRITER_VERSION;
DataSpace dataspace_attr = DataSpace(H5S_SCALAR); DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
Attribute attribute = filefd->createAttribute("version", Attribute attribute = filefd->createAttribute(
PredType::NATIVE_DOUBLE, dataspace_attr); "version", PredType::NATIVE_DOUBLE, dataspace_attr);
attribute.write(PredType::NATIVE_DOUBLE, &dValue); attribute.write(PredType::NATIVE_DOUBLE, &dValue);
// dataspace // dataspace
@ -417,7 +428,6 @@ void HDF5File::CreateDataFile() {
dataspace = 0; dataspace = 0;
dataspace = new DataSpace(3, srcdims, srcdimsmax); dataspace = new DataSpace(3, srcdims, srcdimsmax);
// dataset name // dataset name
std::ostringstream osfn; std::ostringstream osfn;
osfn << "/data"; osfn << "/data";
@ -451,20 +461,22 @@ void HDF5File::CreateDataFile() {
paralist.setChunk(1, chunkpara_dims); paralist.setChunk(1, chunkpara_dims);
for (unsigned int i = 0; i < parameterNames.size(); ++i) { for (unsigned int i = 0; i < parameterNames.size(); ++i) {
DataSet* ds = new DataSet(filefd->createDataSet(parameterNames[i], DataSet *ds = new DataSet(
parameterDataTypes[i], *dataspace_para, paralist)); filefd->createDataSet(parameterNames[i], parameterDataTypes[i],
*dataspace_para, paralist));
dataset_para.push_back(ds); dataset_para.push_back(ds);
} }
} } catch (const Exception &error) {
catch(const Exception& error){
error.printErrorStack(); error.printErrorStack();
if (filefd) { if (filefd) {
filefd->close(); filefd->close();
} }
throw sls::RuntimeError("Could not create HDF5 handles in object " + index); throw sls::RuntimeError("Could not create HDF5 handles in object " +
index);
} }
if (!(*silentMode)) { if (!(*silentMode)) {
LOG(logINFO) << *udpPortNumber << ": HDF5 File created: " << currentFileName; LOG(logINFO) << *udpPortNumber
<< ": HDF5 File created: " << currentFileName;
} }
} }
@ -490,19 +502,18 @@ void HDF5File::CreateMasterDataFile(masterAttributes& masterFileAttributes) {
masterfd = 0; masterfd = 0;
if (!(*overWriteEnable)) if (!(*overWriteEnable))
masterfd = new H5File(masterFileName.c_str(), H5F_ACC_EXCL, masterfd = new H5File(masterFileName.c_str(), H5F_ACC_EXCL,
FileCreatPropList::DEFAULT, FileCreatPropList::DEFAULT, flist);
flist );
else else
masterfd = new H5File(masterFileName.c_str(), H5F_ACC_TRUNC, masterfd = new H5File(masterFileName.c_str(), H5F_ACC_TRUNC,
FileCreatPropList::DEFAULT, FileCreatPropList::DEFAULT, flist);
flist );
// create attributes // create attributes
// version // version
{ {
double dValue = masterFileAttributes.version; double dValue = masterFileAttributes.version;
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
Attribute attribute = masterfd->createAttribute("version",PredType::NATIVE_DOUBLE, dataspace); Attribute attribute = masterfd->createAttribute(
"version", PredType::NATIVE_DOUBLE, dataspace);
attribute.write(PredType::NATIVE_DOUBLE, &dValue); attribute.write(PredType::NATIVE_DOUBLE, &dValue);
} }
// Create a group in the file // Create a group in the file
@ -516,11 +527,14 @@ void HDF5File::CreateMasterDataFile(masterAttributes& masterFileAttributes) {
// Dynamic Range // Dynamic Range
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "dynamic range", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.dynamicRange), PredType::NATIVE_INT); "dynamic range", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.dynamicRange),
PredType::NATIVE_INT);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256); StrType strdatatype(PredType::C_S1, 256);
Attribute attribute = dataset.createAttribute("unit",strdatatype, dataspaceAttr); Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("bits")); attribute.write(strdatatype, std::string("bits"));
} }
@ -528,147 +542,187 @@ void HDF5File::CreateMasterDataFile(masterAttributes& masterFileAttributes) {
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
int iValue = masterFileAttributes.tenGiga; int iValue = masterFileAttributes.tenGiga;
DataSet dataset = group5.createDataSet ( "ten giga enable", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
"ten giga enable", PredType::NATIVE_INT, dataspace);
dataset.write(&iValue, PredType::NATIVE_INT); dataset.write(&iValue, PredType::NATIVE_INT);
} }
// Image Size // Image Size
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "image size", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.imageSize), PredType::NATIVE_INT); "image size", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.imageSize),
PredType::NATIVE_INT);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256); StrType strdatatype(PredType::C_S1, 256);
Attribute attribute = dataset.createAttribute("unit",strdatatype, dataspaceAttr); Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("bytes")); attribute.write(strdatatype, std::string("bytes"));
} }
// x // x
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "number of pixels in x axis", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.nPixelsX), PredType::NATIVE_INT); "number of pixels in x axis", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.nPixelsX),
PredType::NATIVE_INT);
} }
// y // y
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "number of pixels in y axis", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.nPixelsY), PredType::NATIVE_INT); "number of pixels in y axis", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.nPixelsY),
PredType::NATIVE_INT);
} }
// Maximum frames per file // Maximum frames per file
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "maximum frames per file", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.maxFramesPerFile), PredType::NATIVE_INT); "maximum frames per file", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.maxFramesPerFile),
PredType::NATIVE_INT);
} }
// Total Frames // Total Frames
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "total frames", PredType::STD_U64LE, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.totalFrames), PredType::STD_U64LE); "total frames", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.totalFrames),
PredType::STD_U64LE);
} }
// Exptime // Exptime
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "exposure time", PredType::STD_U64LE, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.exptimeNs), PredType::STD_U64LE); "exposure time", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.exptimeNs),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256); StrType strdatatype(PredType::C_S1, 256);
Attribute attribute = dataset.createAttribute("unit",strdatatype, dataspaceAttr); Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns")); attribute.write(strdatatype, std::string("ns"));
} }
// SubExptime // SubExptime
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "sub exposure time", PredType::STD_U64LE, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.subExptimeNs), PredType::STD_U64LE); "sub exposure time", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.subExptimeNs),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256); StrType strdatatype(PredType::C_S1, 256);
Attribute attribute = dataset.createAttribute("unit",strdatatype, dataspaceAttr); Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns")); attribute.write(strdatatype, std::string("ns"));
} }
// SubPeriod // SubPeriod
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "sub period", PredType::STD_U64LE, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.subPeriodNs), PredType::STD_U64LE); "sub period", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.subPeriodNs),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256); StrType strdatatype(PredType::C_S1, 256);
Attribute attribute = dataset.createAttribute("unit",strdatatype, dataspaceAttr); Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns")); attribute.write(strdatatype, std::string("ns"));
} }
// Period // Period
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "acquisition period", PredType::STD_U64LE, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.periodNs), PredType::STD_U64LE); "acquisition period", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.periodNs),
PredType::STD_U64LE);
DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 256); StrType strdatatype(PredType::C_S1, 256);
Attribute attribute = dataset.createAttribute("unit",strdatatype, dataspaceAttr); Attribute attribute =
dataset.createAttribute("unit", strdatatype, dataspaceAttr);
attribute.write(strdatatype, std::string("ns")); attribute.write(strdatatype, std::string("ns"));
} }
// Quad Enable // Quad Enable
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "quad enable", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.quadEnable), PredType::NATIVE_INT); "quad enable", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.quadEnable),
PredType::NATIVE_INT);
} }
// Analog Flag // Analog Flag
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "analog flag", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.analogFlag), PredType::NATIVE_INT); "analog flag", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.analogFlag),
PredType::NATIVE_INT);
} }
// Digital Flag // Digital Flag
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "digital flag", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.digitalFlag), PredType::NATIVE_INT); "digital flag", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.digitalFlag),
PredType::NATIVE_INT);
} }
// ADC Mask // ADC Mask
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "adc mask", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.adcmask), PredType::NATIVE_INT); "adc mask", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.adcmask),
PredType::NATIVE_INT);
} }
// Dbit Offset // Dbit Offset
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "dbit offset", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.dbitoffset), PredType::NATIVE_INT); "dbit offset", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.dbitoffset),
PredType::NATIVE_INT);
} }
// Dbit List // Dbit List
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "dbit bitset list", PredType::STD_U64LE, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.dbitlist), PredType::STD_U64LE); "dbit bitset list", PredType::STD_U64LE, dataspace);
dataset.write(&(masterFileAttributes.dbitlist),
PredType::STD_U64LE);
} }
// Roi xmin // Roi xmin
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "roi xmin", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.roiXmin), PredType::NATIVE_INT); "roi xmin", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.roiXmin),
PredType::NATIVE_INT);
} }
// Roi xmax // Roi xmax
{ {
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "roi xmax", PredType::NATIVE_INT, dataspace ); DataSet dataset = group5.createDataSet(
dataset.write ( &(masterFileAttributes.roiXmax), PredType::NATIVE_INT); "roi xmax", PredType::NATIVE_INT, dataspace);
dataset.write(&(masterFileAttributes.roiXmax),
PredType::NATIVE_INT);
} }
// Timestamp // Timestamp
@ -676,7 +730,8 @@ void HDF5File::CreateMasterDataFile(masterAttributes& masterFileAttributes) {
time_t t = time(0); time_t t = time(0);
StrType strdatatype(PredType::C_S1, 256); StrType strdatatype(PredType::C_S1, 256);
DataSpace dataspace = DataSpace(H5S_SCALAR); DataSpace dataspace = DataSpace(H5S_SCALAR);
DataSet dataset = group5.createDataSet ( "timestamp", strdatatype, dataspace ); DataSet dataset =
group5.createDataSet("timestamp", strdatatype, dataspace);
dataset.write(std::string(ctime(&t)), strdatatype); dataset.write(std::string(ctime(&t)), strdatatype);
} }
@ -714,9 +769,13 @@ void HDF5File::CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf) {
// file // file
hid_t dfal = H5Pcreate(H5P_FILE_ACCESS); hid_t dfal = H5Pcreate(H5P_FILE_ACCESS);
if (dfal < 0) if (dfal < 0)
throw sls::RuntimeError("Could not create file access property for virtual file " + vname); throw sls::RuntimeError(
"Could not create file access property for virtual file " +
vname);
if (H5Pset_fclose_degree(dfal, H5F_CLOSE_STRONG) < 0) if (H5Pset_fclose_degree(dfal, H5F_CLOSE_STRONG) < 0)
throw sls::RuntimeError("Could not set strong file close degree for virtual file " + vname); throw sls::RuntimeError(
"Could not set strong file close degree for virtual file " +
vname);
virtualfd = H5Fcreate(vname.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, dfal); virtualfd = H5Fcreate(vname.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, dfal);
if (virtualfd < 0) if (virtualfd < 0)
throw sls::RuntimeError("Could not create virtual file " + vname); throw sls::RuntimeError("Could not create virtual file " + vname);
@ -724,52 +783,71 @@ void HDF5File::CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf) {
// attributes - version // attributes - version
hid_t dataspace_attr = H5Screate(H5S_SCALAR); hid_t dataspace_attr = H5Screate(H5S_SCALAR);
if (dataspace_attr < 0) if (dataspace_attr < 0)
throw sls::RuntimeError("Could not create dataspace for attribute in virtual file " + vname); throw sls::RuntimeError(
hid_t attrid = H5Acreate2 (virtualfd, "version", H5T_NATIVE_DOUBLE, dataspace_attr, H5P_DEFAULT, H5P_DEFAULT); "Could not create dataspace for attribute in virtual file " +
vname);
hid_t attrid = H5Acreate2(virtualfd, "version", H5T_NATIVE_DOUBLE,
dataspace_attr, H5P_DEFAULT, H5P_DEFAULT);
if (attrid < 0) if (attrid < 0)
throw sls::RuntimeError("Could not create attribute in virtual file " + vname); throw sls::RuntimeError(
"Could not create attribute in virtual file " + vname);
double attr_data = HDF5_WRITER_VERSION; double attr_data = HDF5_WRITER_VERSION;
if (H5Awrite(attrid, H5T_NATIVE_DOUBLE, &attr_data) < 0) if (H5Awrite(attrid, H5T_NATIVE_DOUBLE, &attr_data) < 0)
throw sls::RuntimeError("Could not write attribute in virtual file " + vname); throw sls::RuntimeError(
"Could not write attribute in virtual file " + vname);
if (H5Aclose(attrid) < 0) if (H5Aclose(attrid) < 0)
throw sls::RuntimeError("Could not close attribute in virtual file " + vname); throw sls::RuntimeError(
"Could not close attribute in virtual file " + vname);
// virtual dataspace // virtual dataspace
hsize_t vdsdims[3] = {numf, numDetY * nDimy, numDetz * nDimz}; hsize_t vdsdims[3] = {numf, numDetY * nDimy, numDetz * nDimz};
hid_t vdsDataspace = H5Screate_simple(3, vdsdims, NULL); hid_t vdsDataspace = H5Screate_simple(3, vdsdims, NULL);
if (vdsDataspace < 0) if (vdsDataspace < 0)
throw sls::RuntimeError("Could not create virtual dataspace in virtual file " + vname); throw sls::RuntimeError(
"Could not create virtual dataspace in virtual file " + vname);
hsize_t vdsdims_para[2] = {numf, (unsigned int)numDetY * numDetz}; hsize_t vdsdims_para[2] = {numf, (unsigned int)numDetY * numDetz};
hid_t vdsDataspace_para = H5Screate_simple(2, vdsdims_para, NULL); hid_t vdsDataspace_para = H5Screate_simple(2, vdsdims_para, NULL);
if (vdsDataspace_para < 0) if (vdsDataspace_para < 0)
throw sls::RuntimeError("Could not create virtual dataspace (parameters) in virtual file " + vname); throw sls::RuntimeError("Could not create virtual dataspace "
"(parameters) in virtual file " +
vname);
// fill values // fill values
hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE); hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
if (dcpl < 0) if (dcpl < 0)
throw sls::RuntimeError("Could not create file creation properties in virtual file " + vname); throw sls::RuntimeError(
"Could not create file creation properties in virtual file " +
vname);
int fill_value = -1; int fill_value = -1;
if (H5Pset_fill_value(dcpl, GetDataTypeinC(datatype), &fill_value) < 0) if (H5Pset_fill_value(dcpl, GetDataTypeinC(datatype), &fill_value) < 0)
throw sls::RuntimeError("Could not create fill value in virtual file " + vname); throw sls::RuntimeError(
"Could not create fill value in virtual file " + vname);
hid_t dcpl_para[parameterNames.size()]; hid_t dcpl_para[parameterNames.size()];
for (unsigned int i = 0; i < parameterNames.size(); ++i) { for (unsigned int i = 0; i < parameterNames.size(); ++i) {
dcpl_para[i] = H5Pcreate(H5P_DATASET_CREATE); dcpl_para[i] = H5Pcreate(H5P_DATASET_CREATE);
if (dcpl_para[i] < 0) if (dcpl_para[i] < 0)
throw sls::RuntimeError("Could not create file creation properties (parameters) in virtual file " + vname); throw sls::RuntimeError(
if (H5Pset_fill_value (dcpl_para[i], GetDataTypeinC(parameterDataTypes[i]), &fill_value) < 0) "Could not create file creation properties (parameters) in "
throw sls::RuntimeError("Could not create fill value (parameters) in virtual file " + vname); "virtual file " +
vname);
if (H5Pset_fill_value(dcpl_para[i],
GetDataTypeinC(parameterDataTypes[i]),
&fill_value) < 0)
throw sls::RuntimeError("Could not create fill value "
"(parameters) in virtual file " +
vname);
} }
// hyperslab // hyperslab
int numMajorHyperslab = numf / maxFramesPerFile; int numMajorHyperslab = numf / maxFramesPerFile;
if (numf%maxFramesPerFile) numMajorHyperslab++; if (numf % maxFramesPerFile)
numMajorHyperslab++;
uint64_t framesSaved = 0; uint64_t framesSaved = 0;
for (int j = 0; j < numMajorHyperslab; j++) { for (int j = 0; j < numMajorHyperslab; j++) {
uint64_t nDimx = ((numf - framesSaved) > maxFramesPerFile) uint64_t nDimx = ((numf - framesSaved) > maxFramesPerFile)
? maxFramesPerFile : (numf-framesSaved); ? maxFramesPerFile
: (numf - framesSaved);
hsize_t offset[3] = {framesSaved, 0, 0}; hsize_t offset[3] = {framesSaved, 0, 0};
hsize_t count[3] = {nDimx, nDimy, nDimz}; hsize_t count[3] = {nDimx, nDimy, nDimz};
hsize_t offset_para[2] = {framesSaved, 0}; hsize_t offset_para[2] = {framesSaved, 0};
@ -778,19 +856,22 @@ void HDF5File::CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf) {
for (int i = 0; i < numDetY * numDetz; ++i) { for (int i = 0; i < numDetY * numDetz; ++i) {
// setect hyperslabs // setect hyperslabs
if (H5Sselect_hyperslab (vdsDataspace, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { if (H5Sselect_hyperslab(vdsDataspace, H5S_SELECT_SET, offset,
NULL, count, NULL) < 0) {
throw sls::RuntimeError("Could not select hyperslab"); throw sls::RuntimeError("Could not select hyperslab");
} }
if (H5Sselect_hyperslab(vdsDataspace_para, H5S_SELECT_SET, if (H5Sselect_hyperslab(vdsDataspace_para, H5S_SELECT_SET,
offset_para, NULL, count_para, NULL) < 0) { offset_para, NULL, count_para,
throw sls::RuntimeError("Could not select hyperslab for parameters"); NULL) < 0) {
throw sls::RuntimeError(
"Could not select hyperslab for parameters");
} }
// source file name // source file name
std::ostringstream os; std::ostringstream os;
os << *filePath << "/" << *fileNamePrefix << "_d" os << *filePath << "/" << *fileNamePrefix << "_d"
<< (*detIndex * (*numUnitsPerDetector) + i) << "_f" << j << '_' << (*detIndex * (*numUnitsPerDetector) + i) << "_f" << j
<< *fileIndex << ".h5"; << '_' << *fileIndex << ".h5";
std::string srcFileName = os.str(); std::string srcFileName = os.str();
LOG(logDEBUG1) << srcFileName; LOG(logDEBUG1) << srcFileName;
@ -799,7 +880,8 @@ void HDF5File::CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf) {
{ {
size_t i = srcFileName.rfind('/', srcFileName.length()); size_t i = srcFileName.rfind('/', srcFileName.length());
if (i != std::string::npos) if (i != std::string::npos)
relative_srcFileName = (srcFileName.substr(i+1, srcFileName.length() - i)); relative_srcFileName = (srcFileName.substr(
i + 1, srcFileName.length() - i));
} }
// source dataset name // source dataset name
@ -814,23 +896,34 @@ void HDF5File::CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf) {
hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz}; hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz};
hid_t srcDataspace = H5Screate_simple(3, srcdims, srcdimsmax); hid_t srcDataspace = H5Screate_simple(3, srcdims, srcdimsmax);
if (srcDataspace < 0) if (srcDataspace < 0)
throw sls::RuntimeError("Could not create source dataspace in virtual file " + vname); throw sls::RuntimeError(
"Could not create source dataspace in virtual file " +
vname);
hsize_t srcdims_para[1] = {nDimx}; hsize_t srcdims_para[1] = {nDimx};
hsize_t srcdimsmax_para[1] = {H5S_UNLIMITED}; hsize_t srcdimsmax_para[1] = {H5S_UNLIMITED};
hid_t srcDataspace_para = H5Screate_simple(1, srcdims_para, srcdimsmax_para); hid_t srcDataspace_para =
H5Screate_simple(1, srcdims_para, srcdimsmax_para);
if (srcDataspace_para < 0) if (srcDataspace_para < 0)
throw sls::RuntimeError("Could not create source dataspace (parameters) in virtual file " + vname); throw sls::RuntimeError("Could not create source dataspace "
"(parameters) in virtual file " +
vname);
// mapping // mapping
if (H5Pset_virtual(dcpl, vdsDataspace, relative_srcFileName.c_str(), if (H5Pset_virtual(dcpl, vdsDataspace,
relative_srcFileName.c_str(),
srcDatasetName.c_str(), srcDataspace) < 0) { srcDatasetName.c_str(), srcDataspace) < 0) {
throw sls::RuntimeError("Could not set mapping for paramter 1"); throw sls::RuntimeError(
"Could not set mapping for paramter 1");
} }
for (unsigned int k = 0; k < parameterNames.size(); ++k) { for (unsigned int k = 0; k < parameterNames.size(); ++k) {
if (H5Pset_virtual(dcpl_para[k], vdsDataspace_para, relative_srcFileName.c_str(), if (H5Pset_virtual(dcpl_para[k], vdsDataspace_para,
parameterNames[k], srcDataspace_para) < 0) { relative_srcFileName.c_str(),
throw sls::RuntimeError("Could not set mapping for paramter " + std::to_string(k)); parameterNames[k],
srcDataspace_para) < 0) {
throw sls::RuntimeError(
"Could not set mapping for paramter " +
std::to_string(k));
} }
} }
@ -849,19 +942,22 @@ void HDF5File::CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf) {
// dataset // dataset
std::string virtualDatasetName = "data"; std::string virtualDatasetName = "data";
hid_t vdsdataset = H5Dcreate2(virtualfd, virtualDatasetName.c_str(), hid_t vdsdataset = H5Dcreate2(virtualfd, virtualDatasetName.c_str(),
GetDataTypeinC(datatype), vdsDataspace, H5P_DEFAULT, dcpl, H5P_DEFAULT); GetDataTypeinC(datatype), vdsDataspace,
H5P_DEFAULT, dcpl, H5P_DEFAULT);
if (vdsdataset < 0) if (vdsdataset < 0)
throw sls::RuntimeError("Could not create virutal dataset in virtual file " + vname); throw sls::RuntimeError(
"Could not create virutal dataset in virtual file " + vname);
// virtual parameter dataset // virtual parameter dataset
for (unsigned int i = 0; i < parameterNames.size(); ++i) { for (unsigned int i = 0; i < parameterNames.size(); ++i) {
hid_t vdsdataset_para = H5Dcreate2 (virtualfd, hid_t vdsdataset_para = H5Dcreate2(
parameterNames[i], virtualfd, parameterNames[i],
GetDataTypeinC(parameterDataTypes[i]), vdsDataspace_para, GetDataTypeinC(parameterDataTypes[i]), vdsDataspace_para,
H5P_DEFAULT, dcpl_para[i], H5P_DEFAULT); H5P_DEFAULT, dcpl_para[i], H5P_DEFAULT);
if (vdsdataset_para < 0) if (vdsdataset_para < 0)
throw sls::RuntimeError("Could not create virutal dataset (parameters) in virtual file " + vname); throw sls::RuntimeError("Could not create virutal dataset "
"(parameters) in virtual file " +
vname);
} }
// close // close
@ -889,9 +985,11 @@ void HDF5File::LinkVirtualInMaster(std::string fname, std::string dsetname) {
try { try {
hid_t dfal = H5Pcreate(H5P_FILE_ACCESS); hid_t dfal = H5Pcreate(H5P_FILE_ACCESS);
if (dfal < 0) if (dfal < 0)
throw sls::RuntimeError("Could not create file access property for link"); throw sls::RuntimeError(
"Could not create file access property for link");
if (H5Pset_fclose_degree(dfal, H5F_CLOSE_STRONG) < 0) if (H5Pset_fclose_degree(dfal, H5F_CLOSE_STRONG) < 0)
throw sls::RuntimeError("Could not set strong file close degree for link"); throw sls::RuntimeError(
"Could not set strong file close degree for link");
// open master file // open master file
hid_t mfd = H5Fopen(masterFileName.c_str(), H5F_ACC_RDWR, dfal); hid_t mfd = H5Fopen(masterFileName.c_str(), H5F_ACC_RDWR, dfal);
@ -901,7 +999,8 @@ void HDF5File::LinkVirtualInMaster(std::string fname, std::string dsetname) {
// open virtual file // open virtual file
vfd = H5Fopen(fname.c_str(), H5F_ACC_RDWR, dfal); vfd = H5Fopen(fname.c_str(), H5F_ACC_RDWR, dfal);
if (vfd < 0) { if (vfd < 0) {
H5Fclose(mfd); mfd = 0; H5Fclose(mfd);
mfd = 0;
throw sls::RuntimeError("Could not open virtual file"); throw sls::RuntimeError("Could not open virtual file");
} }
@ -910,7 +1009,8 @@ void HDF5File::LinkVirtualInMaster(std::string fname, std::string dsetname) {
{ {
size_t i = fname.rfind('/', fname.length()); size_t i = fname.rfind('/', fname.length());
if (i != std::string::npos) if (i != std::string::npos)
relative_virtualfname = (fname.substr(i+1, fname.length() - i)); relative_virtualfname =
(fname.substr(i + 1, fname.length() - i));
} }
//**data dataset** //**data dataset**
@ -922,29 +1022,40 @@ void HDF5File::LinkVirtualInMaster(std::string fname, std::string dsetname) {
sprintf(linkname, "/entry/data/%s", dsetname.c_str()); sprintf(linkname, "/entry/data/%s", dsetname.c_str());
if (H5Lcreate_external(relative_virtualfname.c_str(), dsetname.c_str(), if (H5Lcreate_external(relative_virtualfname.c_str(), dsetname.c_str(),
mfd, linkname, H5P_DEFAULT, H5P_DEFAULT) < 0) { mfd, linkname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
H5Fclose(mfd); mfd = 0; H5Fclose(mfd);
mfd = 0;
throw sls::RuntimeError("Could not create link to data dataset"); throw sls::RuntimeError("Could not create link to data dataset");
} }
H5Dclose(vdset); H5Dclose(vdset);
//**paramter datasets** //**paramter datasets**
for (unsigned int i = 0; i < parameterNames.size(); ++i) { for (unsigned int i = 0; i < parameterNames.size(); ++i) {
hid_t vdset_para = H5Dopen2( vfd, (std::string (parameterNames[i])).c_str(), H5P_DEFAULT); hid_t vdset_para = H5Dopen2(
vfd, (std::string(parameterNames[i])).c_str(), H5P_DEFAULT);
if (vdset_para < 0) { if (vdset_para < 0) {
H5Fclose(mfd); mfd = 0; H5Fclose(mfd);
throw sls::RuntimeError("Could not open virtual parameter dataset to create link"); mfd = 0;
throw sls::RuntimeError(
"Could not open virtual parameter dataset to create link");
} }
sprintf(linkname, "/entry/data/%s",(std::string (parameterNames[i])).c_str()); sprintf(linkname, "/entry/data/%s",
(std::string(parameterNames[i])).c_str());
if(H5Lcreate_external( relative_virtualfname.c_str(), (std::string (parameterNames[i])).c_str(), if (H5Lcreate_external(relative_virtualfname.c_str(),
mfd, linkname, H5P_DEFAULT, H5P_DEFAULT) < 0) { (std::string(parameterNames[i])).c_str(),
H5Fclose(mfd); mfd = 0; mfd, linkname, H5P_DEFAULT,
throw sls::RuntimeError("Could not create link to virtual parameter dataset"); H5P_DEFAULT) < 0) {
H5Fclose(mfd);
mfd = 0;
throw sls::RuntimeError(
"Could not create link to virtual parameter dataset");
} }
} }
H5Fclose(mfd); mfd = 0; H5Fclose(mfd);
H5Fclose(vfd); vfd = 0; mfd = 0;
H5Fclose(vfd);
vfd = 0;
} catch (...) { } catch (...) {
if (vfd > 0) if (vfd > 0)
H5Fclose(vfd); H5Fclose(vfd);

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

@ -6,10 +6,10 @@
* 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"
@ -18,7 +18,6 @@
#endif #endif
#include <mutex> #include <mutex>
class HDF5File : private virtual slsDetectorDefs, public File { class HDF5File : private virtual slsDetectorDefs, public File {
public: public:
@ -41,25 +40,26 @@ 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, sls_receiver_header* rheader); void WriteParameterDatasets(uint64_t currentFrameNumber,
sls_receiver_header *rheader);
void ExtendDataset(); void ExtendDataset();
void CreateDataFile(); void CreateDataFile();
void CreateMasterDataFile(masterAttributes &masterFileAttributes); void CreateMasterDataFile(masterAttributes &masterFileAttributes);
@ -90,6 +90,5 @@ class HDF5File : private virtual slsDetectorDefs, public File {
std::vector<DataSet *> dataset_para; std::vector<DataSet *> dataset_para;
uint64_t extNumImages; uint64_t extNumImages;
}; };
#endif #endif

245
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) {
@ -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 *
@ -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;
} }
@ -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;
@ -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);
} }
/************************************************** /**************************************************
@ -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);
} }

36
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:
@ -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 *
@ -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;

293
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();
@ -88,8 +75,6 @@ void Listener::ResetParametersforNewAcquisition() {
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;
@ -99,19 +84,16 @@ void Listener::RecordFirstIndex(uint64_t 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;
@ -128,12 +110,15 @@ 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,8 +127,6 @@ void Listener::CreateUDPSockets() {
*actualUDPSocketBufferSize = udpSocket->getBufferSize(); *actualUDPSocketBufferSize = udpSocket->getBufferSize();
} }
void Listener::ShutDownUDPSocket() { void Listener::ShutDownUDPSocket() {
if (udpSocket) { if (udpSocket) {
udpSocketAlive = false; udpSocketAlive = false;
@ -152,9 +135,9 @@ void Listener::ShutDownUDPSocket() {
} }
} }
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);
@ -171,11 +154,14 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int64_t s) {
// 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));
} }
} }
@ -198,24 +185,28 @@ void Listener::ThreadExecution() {
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
// created or shut down earlier";
(*((uint32_t *)buffer)) = 0; (*((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;
@ -234,7 +225,8 @@ void Listener::ThreadExecution() {
} }
(*((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
@ -245,22 +237,21 @@ void Listener::ThreadExecution() {
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) { void Listener::StopListening(char *buf) {
(*((uint32_t *)buf)) = DUMMY_PACKET_VALUE; (*((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) {
@ -276,8 +267,8 @@ uint32_t Listener::ListenToAnImage(char* buf) {
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);
@ -289,7 +280,8 @@ uint32_t Listener::ListenToAnImage(char* buf) {
// 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;
@ -305,27 +297,29 @@ uint32_t Listener::ListenToAnImage(char* buf) {
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;
} }
@ -349,51 +343,63 @@ uint32_t Listener::ListenToAnImage(char* buf) {
// 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
// never entering this loop)
while (numpackets < pperFrame) { while (numpackets < pperFrame) {
// listen to new packet // listen to new packet
rc = 0; rc = 0;
@ -402,7 +408,8 @@ uint32_t Listener::ListenToAnImage(char* buf) {
} }
// 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:
@ -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 =
numpackets; // number of packets caught
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; //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,23 +469,28 @@ 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:
@ -481,7 +502,8 @@ uint32_t Listener::ListenToAnImage(char* buf) {
default: default:
break; break;
} }
new_header->detHeader.packetNumber = numpackets; //number of packets caught new_header->detHeader.packetNumber =
numpackets; // number of packets caught
if (isHeaderEmpty) { if (isHeaderEmpty) {
new_header->detHeader.row = row; new_header->detHeader.row = row;
new_header->detHeader.column = column; new_header->detHeader.column = column;
@ -491,40 +513,53 @@ uint32_t Listener::ListenToAnImage(char* buf) {
// 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;
@ -536,22 +571,22 @@ uint32_t Listener::ListenToAnImage(char* buf) {
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;
} }

25
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
@ -41,8 +42,8 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
*/ */
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
@ -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
@ -135,8 +134,8 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
* 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);
@ -232,7 +231,8 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
/** 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
* eiger fnum is in header */
std::unique_ptr<char[]> listeningPacket; std::unique_ptr<char[]> listeningPacket;
/** if the udp socket is connected */ /** if the udp socket is connected */
@ -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};
}; };

138
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;
} }
@ -56,23 +61,26 @@ int StartAcq(std::string filepath, std::string filename, uint64_t fileindex, uin
* @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,7 +89,8 @@ 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,
@ -90,11 +99,10 @@ void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){
((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,20 +110,25 @@ 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,
@ -127,9 +140,6 @@ void GetData(char* metadata, char* datapointer, uint32_t &revDatasize, void* p){
revDatasize = 26000; revDatasize = 26000;
} }
/** /**
* Example of main program using the Receiver class * Example of main program using the Receiver class
* *
@ -145,43 +155,48 @@ int main(int argc, char *argv[]) {
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);
@ -189,17 +204,21 @@ int main(int argc, char *argv[]) {
/** - 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,32 +227,38 @@ 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
* exits) */
sa.sa_flags = 0; // no flags sa.sa_flags = 0; // no flags
sa.sa_handler = SIG_IGN; // handler function sa.sa_handler = SIG_IGN; // 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");
} }
/** - 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");
@ -248,16 +273,17 @@ int main(int argc, char *argv[]) {
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;
} }

69
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,8 +17,7 @@
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;
@ -30,14 +29,15 @@ Receiver::Receiver(int argc, char *argv[]):
// 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;
@ -63,19 +63,24 @@ 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,7 +90,8 @@ 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;
@ -94,7 +100,8 @@ Receiver::Receiver(int argc, char *argv[]):
} }
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,9 +112,7 @@ 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);
} }
@ -116,27 +121,25 @@ 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);
} }

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

@ -1,20 +1,17 @@
/* 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[]) {
@ -26,18 +23,19 @@ int main(int argc, char *argv[]) {
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";
} }
@ -54,4 +52,3 @@ int main(int argc, char *argv[]) {
LOG(logINFO) << "Exiting Receiver"; LOG(logINFO) << "Exiting Receiver";
return 0; return 0;
} }

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

@ -16,7 +16,8 @@ ThreadObject::ThreadObject(int threadIndex, std::string threadType)
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,20 +28,15 @@ 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
<< ", Tid: " << syscall(SYS_gettid) << "]";
while (!killThread) { while (!killThread) {
while (IsRunning()) { while (IsRunning()) {
ThreadExecution(); ThreadExecution();
@ -48,20 +44,20 @@ void ThreadObject::RunningThread() {
// 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

@ -12,7 +12,6 @@
#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
@ -34,8 +33,8 @@
// 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)
@ -44,7 +43,6 @@
#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)
@ -52,7 +50,6 @@
// 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)

View File

@ -1,5 +1,5 @@
#include "catch.hpp"
#include "CircularFifo.h" #include "CircularFifo.h"
#include "catch.hpp"
#include <vector> #include <vector>
TEST_CASE("Empty buffer") { TEST_CASE("Empty buffer") {
@ -10,7 +10,6 @@ TEST_CASE("Empty buffer"){
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';
@ -20,7 +19,6 @@ TEST_CASE("Empty buffer"){
CHECK(fifo.pop(c, true) == false); CHECK(fifo.pop(c, true) == false);
delete c; delete c;
} }
TEST_CASE("Push pop") { TEST_CASE("Push pop") {
@ -48,5 +46,4 @@ TEST_CASE("Push pop"){
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]") {