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

@ -3,4 +3,5 @@ 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

@ -16,7 +16,7 @@ class detectorData;
#include <vector> #include <vector>
#define MULTI_SHMAPIVERSION 0x190809 #define MULTI_SHMAPIVERSION 0x190809
#define MULTI_SHMVERSION 0x200319 #define MULTI_SHMVERSION 0x200319
#define SHORT_STRING_LENGTH 50 #define SHORT_STRING_LENGTH 50
#include <future> #include <future>

View File

@ -14,7 +14,7 @@
class ServerInterface; class ServerInterface;
#define SLS_SHMAPIVERSION 0x190726 #define SLS_SHMAPIVERSION 0x190726
#define SLS_SHMVERSION 0x200402 #define SLS_SHMVERSION 0x200402
namespace sls { namespace sls {

View File

@ -23,8 +23,8 @@
#include <unistd.h> #include <unistd.h>
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_" #define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
#define SHM_SLS_PREFIX "_sls_" #define SHM_SLS_PREFIX "_sls_"
#define SHM_ENV_NAME "SLSDETNAME" #define SHM_ENV_NAME "SLSDETNAME"
#include <iostream> #include <iostream>
#include <string> #include <string>

View File

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

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

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

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

@ -5,65 +5,70 @@
class ClientInterface; class ClientInterface;
class Receiver : private virtual slsDetectorDefs { class Receiver : private virtual slsDetectorDefs {
public:
/**
* Constructor
* Starts up a Receiver server. Reads configuration file, options, and
* assembles a Receiver using TCP and UDP detector interfaces
* throws an exception in case of failure
* @param argc from command line
* @param argv from command line
*/
Receiver(int argc, char *argv[]);
/**
* Constructor
* Starts up a Receiver server. Reads configuration file, options, and
* assembles a Receiver using TCP and UDP detector interfaces
* throws an exception in case of failure
* @param tcpip_port_no TCP/IP port number
*/
Receiver(int tcpip_port_no = 1954);
~Receiver(); public:
/**
* Constructor
* Starts up a Receiver server. Reads configuration file, options, and
* assembles a Receiver using TCP and UDP detector interfaces
* throws an exception in case of failure
* @param argc from command line
* @param argv from command line
*/
Receiver(int argc, char *argv[]);
/** /**
* get get Receiver Version * Constructor
\returns id * Starts up a Receiver server. Reads configuration file, options, and
*/ * assembles a Receiver using TCP and UDP detector interfaces
int64_t getReceiverVersion(); * throws an exception in case of failure
* @param tcpip_port_no TCP/IP port number
*/
Receiver(int tcpip_port_no = 1954);
/** ~Receiver();
* Call back for start acquisition
* callback arguments are
* filepath
* filename
* fileindex
* datasize
*
* return value is undefined at the moment
* we write depending on file write enable
* 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);
/** /**
* Call back for acquisition finished * get get Receiver Version
* callback argument is \returns id
* @param total frames caught */
*/ int64_t getReceiverVersion();
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg);
/** /**
* Call back for raw data * Call back for start acquisition
* args to raw data ready callback are * callback arguments are
* @param sls_receiver_header frame metadata * filepath
* @param dataPointer is the pointer to the data * filename
* @param dataSize in bytes is the size of the data in bytes. * fileindex
*/ * datasize
void registerCallBackRawDataReady(void (*func)(char* , *
char*, uint32_t, void*),void *arg); * return value is undefined at the moment
* we write depending on file write enable
* 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);
/**
* Call back for acquisition finished
* callback argument is
* @param total frames caught
*/
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *),
void *arg);
/**
* Call back for raw data
* args to raw data ready callback are
* @param sls_receiver_header frame metadata
* @param dataPointer is the pointer to the data
* @param dataSize in bytes is the size of the data in bytes.
*/
void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
void *),
void *arg);
/** /**
* Call back for raw data (modified) * Call back for raw data (modified)
@ -71,12 +76,13 @@ 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;
}; };

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

@ -8,236 +8,237 @@
#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);
LOG(logINFO) << "Max Frames Per File: " << *maxFramesPerFile; LOG(logINFO) << "Max Frames Per File: " << *maxFramesPerFile;
LOG(logINFO) << "Number of Frames in File: " << numFramesInFile; LOG(logINFO) << "Number of Frames in File: " << numFramesInFile;
} }
void BinaryFile::CreateFile() { void BinaryFile::CreateFile() {
numFramesInFile = 0; numFramesInFile = 0;
numActualPacketsInFile = 0; numActualPacketsInFile = 0;
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 = 0; (filefd = fopen((const char *)currentFileName.c_str(), "wx"))) {
throw sls::RuntimeError("Could not create/overwrite file " + currentFileName); filefd = 0;
} throw sls::RuntimeError("Could not create/overwrite file " +
} else if (NULL == (filefd = fopen((const char *) currentFileName.c_str(), "w"))){ currentFileName);
filefd = 0; }
throw sls::RuntimeError("Could not create file " + currentFileName); } else if (NULL ==
} (filefd = fopen((const char *)currentFileName.c_str(), "w"))) {
//setting to no file buffering filefd = 0;
setvbuf(filefd, NULL, _IONBF, 0); throw sls::RuntimeError("Could not create file " + currentFileName);
}
// setting to no file buffering
setvbuf(filefd, NULL, _IONBF, 0);
if(!(*silentMode)) { if (!(*silentMode)) {
LOG(logINFO) << "[" << *udpPortNumber << "]: Binary File created: " << currentFileName; LOG(logINFO) << "[" << *udpPortNumber
} << "]: Binary File created: " << currentFileName;
}
void BinaryFile::CloseCurrentFile() {
if (filefd)
fclose(filefd);
filefd = 0;
}
void BinaryFile::CloseAllFiles() {
CloseCurrentFile();
if (master) {
if (masterfd)
fclose(masterfd);
masterfd = 0;
}
}
int BinaryFile::WriteData(char* buf, int bsize) {
if (!filefd)
return 0;
return fwrite(buf, 1, bsize, filefd);
}
void BinaryFile::WriteToFile(char* buffer, int buffersize, uint64_t currentFrameNumber,
uint32_t numPacketsCaught) {
// check if maxframesperfile = 0 for infinite
if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) {
CloseCurrentFile();
++subFileIndex;
CreateFile();
}
numFramesInFile++;
numActualPacketsInFile += numPacketsCaught;
// write to file
int ret = 0;
// contiguous bitset
if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
ret = WriteData(buffer, buffersize);
}
// not contiguous bitset
else {
// write detector header
ret = WriteData(buffer, sizeof(sls_detector_header));
// get contiguous representation of bit mask
bitset_storage storage;
memset(storage, 0 , sizeof(bitset_storage));
sls_bitset bits = *(sls_bitset*)(buffer + sizeof(sls_detector_header));
for (int i = 0; i < MAX_NUM_PACKETS; ++i)
storage[i >> 3] |= (bits[i] << (i & 7));
// write bitmask
ret += WriteData((char*)storage, sizeof(bitset_storage));
// write data
ret += WriteData(buffer + sizeof(sls_detector_header),
buffersize - sizeof(sls_receiver_header));
}
// if write error
if (ret != buffersize) {
throw sls::RuntimeError(std::to_string(index) + " : Write to file failed for image number " +
std::to_string(currentFrameNumber));
} }
} }
void BinaryFile::CloseCurrentFile() {
void BinaryFile::CreateMasterFile(bool masterFileWriteEnable, masterAttributes& masterFileAttributes) { if (filefd)
//beginning of every acquisition fclose(filefd);
numFramesInFile = 0; filefd = 0;
numActualPacketsInFile = 0;
if (masterFileWriteEnable && master) {
std::ostringstream os;
os << *filePath << "/" << *fileNamePrefix << "_master"
<< "_" << *fileIndex << ".raw";
masterFileName = os.str();
if(!(*silentMode)) {
LOG(logINFO) << "Master File: " << masterFileName;
}
masterFileAttributes.version = BINARY_WRITER_VERSION;
// create master file
if (!(*overWriteEnable)){
if (NULL == (masterfd = fopen((const char *) masterFileName.c_str(), "wx"))) {
masterfd = 0;
throw sls::RuntimeError("Could not create binary master file "
"(without overwrite enable) " + masterFileName);
}
}else if (NULL == (masterfd = fopen((const char *) masterFileName.c_str(), "w"))) {
masterfd = 0;
throw sls::RuntimeError("Could not create binary master file "
"(with overwrite enable) " + masterFileName);
}
// create master file data
time_t t = time(0);
char message[maxMasterFileSize];
sprintf(message,
"Version : %.1f\n"
"Detector Type : %d\n"
"Dynamic Range : %d\n"
"Ten Giga : %d\n"
"Image Size : %d bytes\n"
"nPixelsX : %d pixels\n"
"nPixelsY : %d pixels\n"
"Max Frames Per File : %u\n"
"Total Frames : %lld\n"
"Exptime (ns) : %lld\n"
"SubExptime (ns) : %lld\n"
"SubPeriod(ns) : %lld\n"
"Period (ns) : %lld\n"
"Quad Enable : %d\n"
"Analog Flag : %d\n"
"Digital Flag : %d\n"
"ADC Mask : %d\n"
"Dbit Offset : %d\n"
"Dbit Bitset : %lld\n"
"Roi (xmin, xmax) : %d %d\n"
"Timestamp : %s\n\n"
"#Frame Header\n"
"Frame Number : 8 bytes\n"
"SubFrame Number/ExpLength : 4 bytes\n"
"Packet Number : 4 bytes\n"
"Bunch ID : 8 bytes\n"
"Timestamp : 8 bytes\n"
"Module Id : 2 bytes\n"
"Row : 2 bytes\n"
"Column : 2 bytes\n"
"Reserved : 2 bytes\n"
"Debug : 4 bytes\n"
"Round Robin Number : 2 bytes\n"
"Detector Type : 1 byte\n"
"Header Version : 1 byte\n"
"Packets Caught Mask : 64 bytes\n"
,
masterFileAttributes.version,
masterFileAttributes.detectorType,
masterFileAttributes.dynamicRange,
masterFileAttributes.tenGiga,
masterFileAttributes.imageSize,
masterFileAttributes.nPixelsX,
masterFileAttributes.nPixelsY,
masterFileAttributes.maxFramesPerFile,
(long long int)masterFileAttributes.totalFrames,
(long long int)masterFileAttributes.exptimeNs,
(long long int)masterFileAttributes.subExptimeNs,
(long long int)masterFileAttributes.subPeriodNs,
(long long int)masterFileAttributes.periodNs,
masterFileAttributes.quadEnable,
masterFileAttributes.analogFlag,
masterFileAttributes.digitalFlag,
masterFileAttributes.adcmask,
masterFileAttributes.dbitoffset,
(long long int)masterFileAttributes.dbitlist,
masterFileAttributes.roiXmin,
masterFileAttributes.roiXmax,
ctime(&t));
if (strlen(message) > maxMasterFileSize) {
throw sls::RuntimeError("Master File Size " + std::to_string(strlen(message)) +
" is greater than max str size " + std::to_string(maxMasterFileSize));
}
// write and close file
if (fwrite((void*)message, 1, strlen(message), masterfd) != strlen(message)) {
throw sls::RuntimeError("Master binary file incorrect number of bytes written to file");
}
if (masterfd)
fclose(masterfd);
masterfd = 0;
}
} }
void BinaryFile::CloseAllFiles() {
CloseCurrentFile();
if (master) {
if (masterfd)
fclose(masterfd);
masterfd = 0;
}
}
int BinaryFile::WriteData(char *buf, int bsize) {
if (!filefd)
return 0;
return fwrite(buf, 1, bsize, filefd);
}
void BinaryFile::WriteToFile(char *buffer, int buffersize,
uint64_t currentFrameNumber,
uint32_t numPacketsCaught) {
// check if maxframesperfile = 0 for infinite
if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) {
CloseCurrentFile();
++subFileIndex;
CreateFile();
}
numFramesInFile++;
numActualPacketsInFile += numPacketsCaught;
// write to file
int ret = 0;
// contiguous bitset
if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
ret = WriteData(buffer, buffersize);
}
// not contiguous bitset
else {
// write detector header
ret = WriteData(buffer, sizeof(sls_detector_header));
// get contiguous representation of bit mask
bitset_storage storage;
memset(storage, 0, sizeof(bitset_storage));
sls_bitset bits = *(sls_bitset *)(buffer + sizeof(sls_detector_header));
for (int i = 0; i < MAX_NUM_PACKETS; ++i)
storage[i >> 3] |= (bits[i] << (i & 7));
// write bitmask
ret += WriteData((char *)storage, sizeof(bitset_storage));
// write data
ret += WriteData(buffer + sizeof(sls_detector_header),
buffersize - sizeof(sls_receiver_header));
}
// if write error
if (ret != buffersize) {
throw sls::RuntimeError(std::to_string(index) +
" : Write to file failed for image number " +
std::to_string(currentFrameNumber));
}
}
void BinaryFile::CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes) {
// beginning of every acquisition
numFramesInFile = 0;
numActualPacketsInFile = 0;
if (masterFileWriteEnable && master) {
std::ostringstream os;
os << *filePath << "/" << *fileNamePrefix << "_master"
<< "_" << *fileIndex << ".raw";
masterFileName = os.str();
if (!(*silentMode)) {
LOG(logINFO) << "Master File: " << masterFileName;
}
masterFileAttributes.version = BINARY_WRITER_VERSION;
// create master file
if (!(*overWriteEnable)) {
if (NULL == (masterfd = fopen((const char *)masterFileName.c_str(),
"wx"))) {
masterfd = 0;
throw sls::RuntimeError("Could not create binary master file "
"(without overwrite enable) " +
masterFileName);
}
} else if (NULL == (masterfd = fopen(
(const char *)masterFileName.c_str(), "w"))) {
masterfd = 0;
throw sls::RuntimeError("Could not create binary master file "
"(with overwrite enable) " +
masterFileName);
}
// create master file data
time_t t = time(0);
char message[maxMasterFileSize];
sprintf(message,
"Version : %.1f\n"
"Detector Type : %d\n"
"Dynamic Range : %d\n"
"Ten Giga : %d\n"
"Image Size : %d bytes\n"
"nPixelsX : %d pixels\n"
"nPixelsY : %d pixels\n"
"Max Frames Per File : %u\n"
"Total Frames : %lld\n"
"Exptime (ns) : %lld\n"
"SubExptime (ns) : %lld\n"
"SubPeriod(ns) : %lld\n"
"Period (ns) : %lld\n"
"Quad Enable : %d\n"
"Analog Flag : %d\n"
"Digital Flag : %d\n"
"ADC Mask : %d\n"
"Dbit Offset : %d\n"
"Dbit Bitset : %lld\n"
"Roi (xmin, xmax) : %d %d\n"
"Timestamp : %s\n\n"
"#Frame Header\n"
"Frame Number : 8 bytes\n"
"SubFrame Number/ExpLength : 4 bytes\n"
"Packet Number : 4 bytes\n"
"Bunch ID : 8 bytes\n"
"Timestamp : 8 bytes\n"
"Module Id : 2 bytes\n"
"Row : 2 bytes\n"
"Column : 2 bytes\n"
"Reserved : 2 bytes\n"
"Debug : 4 bytes\n"
"Round Robin Number : 2 bytes\n"
"Detector Type : 1 byte\n"
"Header Version : 1 byte\n"
"Packets Caught Mask : 64 bytes\n",
masterFileAttributes.version, masterFileAttributes.detectorType,
masterFileAttributes.dynamicRange, masterFileAttributes.tenGiga,
masterFileAttributes.imageSize, masterFileAttributes.nPixelsX,
masterFileAttributes.nPixelsY,
masterFileAttributes.maxFramesPerFile,
(long long int)masterFileAttributes.totalFrames,
(long long int)masterFileAttributes.exptimeNs,
(long long int)masterFileAttributes.subExptimeNs,
(long long int)masterFileAttributes.subPeriodNs,
(long long int)masterFileAttributes.periodNs,
masterFileAttributes.quadEnable,
masterFileAttributes.analogFlag,
masterFileAttributes.digitalFlag, masterFileAttributes.adcmask,
masterFileAttributes.dbitoffset,
(long long int)masterFileAttributes.dbitlist,
masterFileAttributes.roiXmin, masterFileAttributes.roiXmax,
ctime(&t));
if (strlen(message) > maxMasterFileSize) {
throw sls::RuntimeError("Master File Size " +
std::to_string(strlen(message)) +
" is greater than max str size " +
std::to_string(maxMasterFileSize));
}
// write and close file
if (fwrite((void *)message, 1, strlen(message), masterfd) !=
strlen(message)) {
throw sls::RuntimeError(
"Master binary file incorrect number of bytes written to file");
}
if (masterfd)
fclose(masterfd);
masterfd = 0;
}
}

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

@ -5,57 +5,55 @@
* 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:
/**
* Constructor
* creates the File Writer
* @param ind self index
* @param maxf pointer to max frames per file
* @param nd pointer to number of detectors in each dimension
* @param fname pointer to file name prefix
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of theads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to udp port number for logging
* @param smode pointer to silent mode
*/
BinaryFile(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,
bool* smode);
~BinaryFile();
void PrintMembers(TLogLevel level = logDEBUG1) override; public:
void CreateFile() override; /**
void CreateMasterFile(bool masterFileWriteEnable, * Constructor
masterAttributes& masterFileAttributes) override; * creates the File Writer
void CloseCurrentFile() override; * @param ind self index
void CloseAllFiles() override; * @param maxf pointer to max frames per file
void WriteToFile(char* buffer, int buffersize, uint64_t currentFrameNumber, * @param nd pointer to number of detectors in each dimension
uint32_t numPacketsCaught) override; * @param fname pointer to file name prefix
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of theads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to udp port number for logging
* @param smode pointer to silent mode
*/
BinaryFile(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, bool *smode);
~BinaryFile();
private: void PrintMembers(TLogLevel level = logDEBUG1) override;
int WriteData(char* buf, int bsize); void CreateFile() override;
void CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes) override;
void CloseCurrentFile() override;
void CloseAllFiles() override;
void WriteToFile(char *buffer, int buffersize, uint64_t currentFrameNumber,
uint32_t numPacketsCaught) override;
FILE* filefd; private:
static FILE* masterfd; int WriteData(char *buf, int bsize);
uint32_t numFramesInFile;
uint64_t numActualPacketsInFile;
const size_t maxMasterFileSize;
FILE *filefd;
static FILE *masterfd;
uint32_t numFramesInFile;
uint64_t numActualPacketsInFile;
const size_t maxMasterFileSize;
}; };

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

@ -1,28 +1,28 @@
#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;
using Interface = sls::ServerInterface; using Interface = sls::ServerInterface;
ClientInterface::~ClientInterface() { ClientInterface::~ClientInterface() {
killTcpThread = true; killTcpThread = true;
LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber; LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber;
server.shutdown(); server.shutdown();
@ -31,25 +31,28 @@ ClientInterface::~ClientInterface() {
} }
ClientInterface::ClientInterface(int portNumber) ClientInterface::ClientInterface(int portNumber)
: myDetectorType(GOTTHARD), : myDetectorType(GOTTHARD),
portNumber(portNumber > 0 ? portNumber : DEFAULT_PORTNO + 2), portNumber(portNumber > 0 ? portNumber : DEFAULT_PORTNO + 2),
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,12 +213,11 @@ 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;
} }
@ -226,15 +230,15 @@ void ClientInterface::functionNotImplemented() {
} }
void ClientInterface::modeNotImplemented(const std::string &modename, void ClientInterface::modeNotImplemented(const std::string &modename,
int mode) { int mode) {
std::ostringstream os; std::ostringstream os;
os << modename << " (" << mode << ") is not implemented for this detector"; os << modename << " (" << mode << ") is not implemented for this detector";
throw RuntimeError(os.str()); throw RuntimeError(os.str());
} }
template <typename T> template <typename T>
void ClientInterface::validate(T arg, T retval, const std::string& modename, void ClientInterface::validate(T arg, T retval, const std::string &modename,
numberMode hex) { numberMode hex) {
if (ret == OK && arg != -1 && retval != arg) { if (ret == OK && arg != -1 && retval != arg) {
auto format = (hex == HEX) ? std::hex : std::dec; auto format = (hex == HEX) ? std::hex : std::dec;
auto prefix = (hex == HEX) ? "0x" : ""; auto prefix = (hex == HEX) ? "0x" : "";
@ -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,41 +334,40 @@ 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 << "hostname:" << arg.hostname << std::endl
<< "hostname:" << arg.hostname << std::endl << "udpInterfaces:" << arg.udpInterfaces << std::endl
<< "udpInterfaces:" << arg.udpInterfaces << std::endl << "udp_dstport:" << arg.udp_dstport << std::endl
<< "udp_dstport:" << arg.udp_dstport << std::endl << "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl
<< "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl << "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)
<< "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2) << std::endl << 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
<< "analogSamples:" << arg.analogSamples << std::endl << "analogSamples:" << arg.analogSamples << std::endl
<< "digitalSamples:" << arg.digitalSamples << std::endl << "digitalSamples:" << arg.digitalSamples << std::endl
<< "expTimeNs:" << arg.expTimeNs << std::endl << "expTimeNs:" << arg.expTimeNs << std::endl
<< "periodNs:" << arg.periodNs << std::endl << "periodNs:" << arg.periodNs << std::endl
<< "subExpTimeNs:" << arg.subExpTimeNs << std::endl << "subExpTimeNs:" << arg.subExpTimeNs << std::endl
<< "subDeadTimeNs:" << arg.subDeadTimeNs << std::endl << "subDeadTimeNs:" << arg.subDeadTimeNs << std::endl
<< "activate:" << arg.activate << std::endl << "activate:" << arg.activate << std::endl
<< "quad:" << arg.quad << std::endl << "quad:" << arg.quad << std::endl
<< "dynamicRange:" << arg.dynamicRange << std::endl << "dynamicRange:" << arg.dynamicRange << std::endl
<< "timMode:" << arg.timMode << std::endl << "timMode:" << arg.timMode << std::endl
<< "tenGiga:" << arg.tenGiga << std::endl << "tenGiga:" << arg.tenGiga << std::endl
<< "roMode:" << arg.roMode << std::endl << "roMode:" << arg.roMode << std::endl
<< "adcMask:" << arg.adcMask << std::endl << "adcMask:" << arg.adcMask << std::endl
<< "adc10gMask:" << arg.adc10gMask << std::endl << "adc10gMask:" << arg.adc10gMask << std::endl
<< "roi.xmin:" << arg.roi.xmin << std::endl << "roi.xmin:" << arg.roi.xmin << std::endl
<< "roi.xmax:" << arg.roi.xmax << std::endl << "roi.xmax:" << arg.roi.xmax << std::endl
<< "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)
@ -378,7 +383,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
} }
impl()->setDetectorPositionId(arg.detId); impl()->setDetectorPositionId(arg.detId);
impl()->setDetectorHostname(arg.hostname); impl()->setDetectorHostname(arg.hostname);
// udp setup // udp setup
sls::MacAddr retvals[2]; sls::MacAddr retvals[2];
if (arg.udp_dstmac == 0 && arg.udp_dstip != 0) { if (arg.udp_dstmac == 0 && arg.udp_dstip != 0) {
@ -392,9 +397,9 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == JUNGFRAU) { if (myDetectorType == JUNGFRAU) {
try { try {
impl()->setNumberofUDPInterfaces(arg.udpInterfaces); impl()->setNumberofUDPInterfaces(arg.udpInterfaces);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Failed to set number of interfaces to " + throw RuntimeError("Failed to set number of interfaces to " +
std::to_string(arg.udpInterfaces)); std::to_string(arg.udpInterfaces));
} }
} }
impl()->setUDPSocketBufferSize(0); impl()->setUDPSocketBufferSize(0);
@ -408,19 +413,19 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (myDetectorType == MOENCH || myDetectorType == CHIPTESTBOARD) { if (myDetectorType == MOENCH || myDetectorType == CHIPTESTBOARD) {
try { try {
impl()->setNumberofAnalogSamples(arg.analogSamples); impl()->setNumberofAnalogSamples(arg.analogSamples);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set num analog samples to " + throw RuntimeError("Could not set num analog samples to " +
std::to_string(arg.analogSamples) + std::to_string(arg.analogSamples) +
" due to fifo structure memory allocation."); " due to fifo structure memory allocation.");
} }
} }
if (myDetectorType == CHIPTESTBOARD) { if (myDetectorType == CHIPTESTBOARD) {
try { try {
impl()->setNumberofDigitalSamples(arg.digitalSamples); impl()->setNumberofDigitalSamples(arg.digitalSamples);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set num digital samples to " throw RuntimeError("Could not set num digital samples to " +
+ std::to_string(arg.analogSamples) + std::to_string(arg.analogSamples) +
" due to fifo structure memory allocation."); " due to fifo structure memory allocation.");
} }
} }
impl()->setAcquisitionTime(arg.expTimeNs); impl()->setAcquisitionTime(arg.expTimeNs);
@ -431,55 +436,56 @@ int ClientInterface::setup_receiver(Interface &socket) {
impl()->setActivate(static_cast<bool>(arg.activate)); impl()->setActivate(static_cast<bool>(arg.activate));
try { try {
impl()->setQuad(arg.quad == 0 ? false : true); impl()->setQuad(arg.quad == 0 ? false : true);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set quad to " + throw RuntimeError("Could not set quad to " +
std::to_string(arg.quad) + std::to_string(arg.quad) +
" due to fifo strucutre memory allocation"); " due to fifo strucutre memory allocation");
} }
} }
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) { if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
try { try {
impl()->setDynamicRange(arg.dynamicRange); impl()->setDynamicRange(arg.dynamicRange);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set dynamic range. Could not allocate " throw RuntimeError(
"memory for fifo or could not start listening/writing threads"); "Could not set dynamic range. Could not allocate "
"memory for fifo or could not start listening/writing threads");
} }
} }
impl()->setTimingMode(arg.timMode); impl()->setTimingMode(arg.timMode);
if (myDetectorType == EIGER || myDetectorType == MOENCH || if (myDetectorType == EIGER || myDetectorType == MOENCH ||
myDetectorType == CHIPTESTBOARD) { myDetectorType == CHIPTESTBOARD) {
try { try {
impl()->setTenGigaEnable(arg.tenGiga); impl()->setTenGigaEnable(arg.tenGiga);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10GbE."); throw RuntimeError("Could not set 10GbE.");
} }
} }
if (myDetectorType == CHIPTESTBOARD) { if (myDetectorType == CHIPTESTBOARD) {
try { try {
impl()->setReadoutMode(arg.roMode); impl()->setReadoutMode(arg.roMode);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set read out mode " throw RuntimeError("Could not set read out mode "
"due to fifo memory allocation."); "due to fifo memory allocation.");
} }
} }
if (myDetectorType == CHIPTESTBOARD || myDetectorType == MOENCH) { if (myDetectorType == CHIPTESTBOARD || myDetectorType == MOENCH) {
try { try {
impl()->setADCEnableMask(arg.adcMask); impl()->setADCEnableMask(arg.adcMask);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set adc enable mask " throw RuntimeError("Could not set adc enable mask "
"due to fifo memory allcoation"); "due to fifo memory allcoation");
} }
try { try {
impl()->setTenGigaADCEnableMask(arg.adc10gMask); impl()->setTenGigaADCEnableMask(arg.adc10gMask);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10Gb adc enable mask " throw RuntimeError("Could not set 10Gb adc enable mask "
"due to fifo memory allcoation"); "due to fifo memory allcoation");
} }
} }
if (myDetectorType == GOTTHARD) { if (myDetectorType == GOTTHARD) {
try { try {
impl()->setROI(arg.roi); impl()->setROI(arg.roi);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set ROI"); throw RuntimeError("Could not set ROI");
} }
} }
@ -520,16 +526,16 @@ void ClientInterface::setDetectorType(detectorType arg) {
// callbacks after (in setdetectortype, the object is reinitialized) // callbacks after (in setdetectortype, the object is reinitialized)
if (startAcquisitionCallBack != nullptr) if (startAcquisitionCallBack != nullptr)
impl()->registerCallBackStartAcquisition(startAcquisitionCallBack, impl()->registerCallBackStartAcquisition(startAcquisitionCallBack,
pStartAcquisition); pStartAcquisition);
if (acquisitionFinishedCallBack != nullptr) if (acquisitionFinishedCallBack != nullptr)
impl()->registerCallBackAcquisitionFinished( impl()->registerCallBackAcquisitionFinished(acquisitionFinishedCallBack,
acquisitionFinishedCallBack, pAcquisitionFinished); pAcquisitionFinished);
if (rawDataReadyCallBack != nullptr) if (rawDataReadyCallBack != nullptr)
impl()->registerCallBackRawDataReady(rawDataReadyCallBack, impl()->registerCallBackRawDataReady(rawDataReadyCallBack,
pRawDataReady); pRawDataReady);
if (rawDataModifyReadyCallBack != nullptr) if (rawDataModifyReadyCallBack != nullptr)
impl()->registerCallBackRawDataModifyReady( impl()->registerCallBackRawDataModifyReady(rawDataModifyReadyCallBack,
rawDataModifyReadyCallBack, pRawDataReady); pRawDataReady);
} }
int ClientInterface::set_roi(Interface &socket) { int ClientInterface::set_roi(Interface &socket) {
@ -544,7 +550,7 @@ int ClientInterface::set_roi(Interface &socket) {
verifyIdle(socket); verifyIdle(socket);
try { try {
impl()->setROI(arg); impl()->setROI(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set ROI"); throw RuntimeError("Could not set ROI");
} }
return socket.Send(OK); return socket.Send(OK);
@ -553,8 +559,7 @@ int ClientInterface::set_roi(Interface &socket) {
int ClientInterface::set_num_frames(Interface &socket) { int ClientInterface::set_num_frames(Interface &socket) {
auto value = socket.Receive<int64_t>(); auto value = socket.Receive<int64_t>();
if (value <= 0) { if (value <= 0) {
throw RuntimeError("Invalid number of frames " + throw RuntimeError("Invalid number of frames " + std::to_string(value));
std::to_string(value));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting num frames to " << value; LOG(logDEBUG1) << "Setting num frames to " << value;
@ -567,8 +572,8 @@ int ClientInterface::set_num_frames(Interface &socket) {
int ClientInterface::set_num_triggers(Interface &socket) { int ClientInterface::set_num_triggers(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 triggers " + throw RuntimeError("Invalid number of triggers " +
std::to_string(value)); std::to_string(value));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting num triggers to " << value; LOG(logDEBUG1) << "Setting num triggers 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;
@ -595,8 +599,8 @@ int ClientInterface::set_num_bursts(Interface &socket) {
int ClientInterface::set_num_add_storage_cells(Interface &socket) { int ClientInterface::set_num_add_storage_cells(Interface &socket) {
auto value = socket.Receive<int>(); auto value = socket.Receive<int>();
if (value < 0) { if (value < 0) {
throw RuntimeError("Invalid number of additional storage cells " + throw RuntimeError("Invalid number of additional storage cells " +
std::to_string(value)); std::to_string(value));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting num additional storage cells to " << value; LOG(logDEBUG1) << "Setting num additional storage cells to " << value;
@ -608,9 +612,8 @@ 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;
@ -622,9 +625,8 @@ 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;
@ -639,11 +641,13 @@ int ClientInterface::set_num_analog_samples(Interface &socket) {
LOG(logDEBUG1) << "Setting num analog samples to " << value; LOG(logDEBUG1) << "Setting num analog samples to " << value;
if (myDetectorType != CHIPTESTBOARD && myDetectorType != MOENCH) { if (myDetectorType != CHIPTESTBOARD && myDetectorType != MOENCH) {
functionNotImplemented(); functionNotImplemented();
} }
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);
} }
@ -653,11 +657,13 @@ int ClientInterface::set_num_digital_samples(Interface &socket) {
LOG(logDEBUG1) << "Setting num digital samples to " << value; LOG(logDEBUG1) << "Setting num digital samples to " << value;
if (myDetectorType != CHIPTESTBOARD) { if (myDetectorType != CHIPTESTBOARD) {
functionNotImplemented(); functionNotImplemented();
} }
try { try {
impl()->setNumberofDigitalSamples(value); impl()->setNumberofDigitalSamples(value);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set num digital samples to " + std::to_string(value) + " due to fifo structure memory allocation."); throw RuntimeError("Could not set num digital samples to " +
std::to_string(value) +
" due to fifo structure memory allocation.");
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -689,7 +695,8 @@ int ClientInterface::set_subdeadtime(Interface &socket) {
auto value = socket.Receive<int64_t>(); auto value = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Setting sub deadtime to " << value << "ns"; LOG(logDEBUG1) << "Setting sub deadtime to " << value << "ns";
impl()->setSubPeriod(value + impl()->getSubExpTime()); impl()->setSubPeriod(value + impl()->getSubExpTime());
LOG(logDEBUG1) << "Setting sub period to " << impl()->getSubPeriod() << "ns"; LOG(logDEBUG1) << "Setting sub period to " << impl()->getSubPeriod()
<< "ns";
return socket.Send(OK); return socket.Send(OK);
} }
@ -699,7 +706,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting dynamic range: " << dr; LOG(logDEBUG1) << "Setting dynamic range: " << dr;
bool exists = false; bool exists = false;
switch(myDetectorType) { switch (myDetectorType) {
case EIGER: case EIGER:
if (dr == 4 || dr == 8 || dr == 16 || dr == 32) { if (dr == 4 || dr == 8 || dr == 16 || dr == 32) {
exists = true; exists = true;
@ -711,7 +718,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
} }
break; break;
default: default:
if (dr == 16) { if (dr == 16) {
exists = true; exists = true;
} }
break; break;
@ -721,7 +728,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
} else { } else {
try { try {
impl()->setDynamicRange(dr); impl()->setDynamicRange(dr);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not allocate memory for fifo or " throw RuntimeError("Could not allocate memory for fifo or "
"could not start listening/writing threads"); "could not start listening/writing threads");
} }
@ -736,13 +743,13 @@ 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;
impl()->setStreamingFrequency(index); impl()->setStreamingFrequency(index);
int retval = impl()->getStreamingFrequency(); int retval = impl()->getStreamingFrequency();
validate(index, retval, "set streaming frequency", DEC); validate(index, retval, "set streaming frequency", DEC);
return socket.Send(OK); return socket.Send(OK);
@ -791,11 +798,11 @@ int ClientInterface::set_file_dir(Interface &socket) {
if (strlen(fPath) == 0) { if (strlen(fPath) == 0) {
throw RuntimeError("Cannot set empty file path"); throw RuntimeError("Cannot set empty file path");
} }
if(fPath[0] != '/') if (fPath[0] != '/')
throw RuntimeError("Receiver path needs to be absolute path"); throw RuntimeError("Receiver path needs to be absolute path");
LOG(logDEBUG1) << "Setting file path: " << fPath; LOG(logDEBUG1) << "Setting file path: " << fPath;
impl()->setFilePath(fPath); impl()->setFilePath(fPath);
std::string s = impl()->getFilePath(); std::string s = impl()->getFilePath();
sls::strcpy_safe(retval, s.c_str()); sls::strcpy_safe(retval, s.c_str());
if ((s.empty()) || (strlen(fPath) && strcasecmp(fPath, retval))) if ((s.empty()) || (strlen(fPath) && strcasecmp(fPath, retval)))
@ -823,7 +830,7 @@ int ClientInterface::set_file_name(Interface &socket) {
} }
LOG(logDEBUG1) << "Setting file name: " << fName; LOG(logDEBUG1) << "Setting file name: " << fName;
impl()->setFileName(fName); impl()->setFileName(fName);
std::string s = impl()->getFileName(); std::string s = impl()->getFileName();
sls::strcpy_safe(retval, s.c_str()); sls::strcpy_safe(retval, s.c_str());
LOG(logDEBUG1) << "file name:" << retval; LOG(logDEBUG1) << "file name:" << retval;
@ -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,13 +915,13 @@ 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;
impl()->setMasterFileWriteEnable(enable); impl()->setMasterFileWriteEnable(enable);
int retval = impl()->getMasterFileWriteEnable(); int retval = impl()->getMasterFileWriteEnable();
validate(enable, retval, "set master file write enable", DEC); validate(enable, retval, "set master file write enable", DEC);
LOG(logDEBUG1) << "master file write enable:" << retval; LOG(logDEBUG1) << "master file write enable:" << retval;
@ -930,13 +937,13 @@ 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;
impl()->setOverwriteEnable(index); impl()->setOverwriteEnable(index);
int retval = impl()->getOverwriteEnable(); int retval = impl()->getOverwriteEnable();
validate(index, retval, "set file overwrite enable", DEC); validate(index, retval, "set file overwrite enable", DEC);
LOG(logDEBUG1) << "file overwrite enable:" << retval; LOG(logDEBUG1) << "file overwrite enable:" << retval;
@ -960,8 +967,8 @@ int ClientInterface::enable_tengiga(Interface &socket) {
LOG(logDEBUG1) << "Setting 10GbE:" << val; LOG(logDEBUG1) << "Setting 10GbE:" << val;
try { try {
impl()->setTenGigaEnable(val); impl()->setTenGigaEnable(val);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10GbE." ); throw RuntimeError("Could not set 10GbE.");
} }
} }
int retval = impl()->getTenGigaEnable(); int retval = impl()->getTenGigaEnable();
@ -977,8 +984,9 @@ int ClientInterface::set_fifo_depth(Interface &socket) {
LOG(logDEBUG1) << "Setting fifo depth:" << value; LOG(logDEBUG1) << "Setting fifo depth:" << value;
try { try {
impl()->setFifoDepth(value); impl()->setFifoDepth(value);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set fifo depth due to fifo structure memory allocation."); throw RuntimeError("Could not set fifo depth due to fifo structure "
"memory allocation.");
} }
} }
int retval = impl()->getFifoDepth(); int retval = impl()->getFifoDepth();
@ -1006,17 +1014,18 @@ 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());
validate(index, retval, "set data stream enable", DEC); validate(index, retval, "set data stream enable", DEC);
LOG(logDEBUG1) << "data streaming enable:" << retval; LOG(logDEBUG1) << "data streaming enable:" << retval;
@ -1063,13 +1072,12 @@ 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;
impl()->setFileFormat(f); impl()->setFileFormat(f);
auto retval = impl()->getFileFormat(); auto retval = impl()->getFileFormat();
validate(f, retval, "set file format", DEC); validate(f, retval, "set file format", DEC);
LOG(logDEBUG1) << "File Format: " << retval; LOG(logDEBUG1) << "File Format: " << retval;
@ -1106,19 +1114,19 @@ int ClientInterface::get_streaming_port(Interface &socket) {
int ClientInterface::set_streaming_source_ip(Interface &socket) { int ClientInterface::set_streaming_source_ip(Interface &socket) {
sls::IpAddr arg; sls::IpAddr arg;
socket.Receive(arg); socket.Receive(arg);
if (arg == 0) { if (arg == 0) {
throw RuntimeError("Invalid zmq ip " + arg.str()); throw RuntimeError("Invalid zmq ip " + arg.str());
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting streaming source ip:" << arg; LOG(logDEBUG1) << "Setting streaming source ip:" << arg;
impl()->setStreamingSourceIP(arg); impl()->setStreamingSourceIP(arg);
sls::IpAddr retval = impl()->getStreamingSourceIP(); sls::IpAddr retval = impl()->getStreamingSourceIP();
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,13 +1141,12 @@ 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;
impl()->setSilentMode(value); impl()->setSilentMode(value);
auto retval = static_cast<int>(impl()->getSilentMode()); auto retval = static_cast<int>(impl()->getSilentMode());
validate(value, retval, "set silent mode", DEC); validate(value, retval, "set silent mode", DEC);
LOG(logDEBUG1) << "silent mode:" << retval; LOG(logDEBUG1) << "silent mode:" << retval;
@ -1173,7 +1180,7 @@ int ClientInterface::set_additional_json_header(Interface &socket) {
socket.Receive(args, sizeof(args)); socket.Receive(args, sizeof(args));
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
json[args[2 * i]] = args[2 * i + 1]; json[args[2 * i]] = args[2 * i + 1];
} }
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting additional json header: " << sls::ToString(json); LOG(logDEBUG1) << "Setting additional json header: " << sls::ToString(json);
@ -1190,7 +1197,7 @@ int ClientInterface::get_additional_json_header(Interface &socket) {
char retvals[size * 2][SHORT_STR_LENGTH]; char retvals[size * 2][SHORT_STR_LENGTH];
memset(retvals, 0, sizeof(retvals)); memset(retvals, 0, sizeof(retvals));
int iarg = 0; int iarg = 0;
for (auto & it : json) { for (auto &it : json) {
sls::strcpy_safe(retvals[iarg], it.first.c_str()); sls::strcpy_safe(retvals[iarg], it.first.c_str());
sls::strcpy_safe(retvals[iarg + 1], it.second.c_str()); sls::strcpy_safe(retvals[iarg + 1], it.second.c_str());
iarg += 2; iarg += 2;
@ -1216,8 +1223,7 @@ int ClientInterface::set_udp_socket_buffer_size(Interface &socket) {
return socket.sendResult(retval); return socket.sendResult(retval);
} }
int ClientInterface::get_real_udp_socket_buffer_size( int ClientInterface::get_real_udp_socket_buffer_size(Interface &socket) {
Interface &socket) {
auto size = impl()->getActualUDPSocketBufferSize(); auto size = impl()->getActualUDPSocketBufferSize();
LOG(logDEBUG1) << "Actual UDP socket size :" << size; LOG(logDEBUG1) << "Actual UDP socket size :" << size;
return socket.sendResult(size); return socket.sendResult(size);
@ -1226,13 +1232,12 @@ 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;
impl()->setFramesPerFile(index); impl()->setFramesPerFile(index);
auto retval = static_cast<int>(impl()->getFramesPerFile()); auto retval = static_cast<int>(impl()->getFramesPerFile());
validate(index, retval, "set frames per file", DEC); validate(index, retval, "set frames per file", DEC);
LOG(logDEBUG1) << "frames per file:" << retval; LOG(logDEBUG1) << "frames per file:" << retval;
@ -1247,8 +1252,7 @@ int ClientInterface::get_frames_per_file(Interface &socket) {
int ClientInterface::check_version_compatibility(Interface &socket) { int ClientInterface::check_version_compatibility(Interface &socket) {
auto arg = socket.Receive<int64_t>(); auto arg = socket.Receive<int64_t>();
LOG(logDEBUG1) << "Checking versioning compatibility with value " LOG(logDEBUG1) << "Checking versioning compatibility with value " << arg;
<< arg;
int64_t client_requiredVersion = arg; int64_t client_requiredVersion = arg;
int64_t rx_apiVersion = APIRECEIVER; int64_t rx_apiVersion = APIRECEIVER;
int64_t rx_version = getReceiverVersion(); int64_t rx_version = getReceiverVersion();
@ -1314,15 +1318,14 @@ int ClientInterface::get_padding_enable(Interface &socket) {
return socket.sendResult(retval); return socket.sendResult(retval);
} }
int ClientInterface::set_deactivated_padding_enable( int ClientInterface::set_deactivated_padding_enable(Interface &socket) {
Interface &socket) {
auto enable = socket.Receive<int>(); auto enable = socket.Receive<int>();
if (myDetectorType != EIGER) { if (myDetectorType != EIGER) {
functionNotImplemented(); functionNotImplemented();
} }
if (enable < 0) { if (enable < 0) {
throw RuntimeError("Invalid Deactivated padding: " throw RuntimeError("Invalid Deactivated padding: " +
+ std::to_string(enable)); std::to_string(enable));
} }
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting deactivated padding enable: " << enable; LOG(logDEBUG1) << "Setting deactivated padding enable: " << enable;
@ -1334,8 +1337,7 @@ int ClientInterface::set_deactivated_padding_enable(
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::get_deactivated_padding_enable( int ClientInterface::get_deactivated_padding_enable(Interface &socket) {
Interface &socket) {
if (myDetectorType != EIGER) if (myDetectorType != EIGER)
functionNotImplemented(); functionNotImplemented();
auto retval = static_cast<int>(impl()->getDeactivatedPadding()); auto retval = static_cast<int>(impl()->getDeactivatedPadding());
@ -1354,8 +1356,9 @@ int ClientInterface::set_readout_mode(Interface &socket) {
LOG(logDEBUG1) << "Setting readout mode: " << arg; LOG(logDEBUG1) << "Setting readout mode: " << arg;
try { try {
impl()->setReadoutMode(arg); impl()->setReadoutMode(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set read out mode due to fifo memory allocation."); throw RuntimeError(
"Could not set read out mode due to fifo memory allocation.");
} }
} }
auto retval = impl()->getReadoutMode(); auto retval = impl()->getReadoutMode();
@ -1371,8 +1374,9 @@ int ClientInterface::set_adc_mask(Interface &socket) {
LOG(logDEBUG1) << "Setting 1Gb ADC enable mask: " << arg; LOG(logDEBUG1) << "Setting 1Gb ADC enable mask: " << arg;
try { try {
impl()->setADCEnableMask(arg); impl()->setADCEnableMask(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set adc enable mask due to fifo memory allcoation"); throw RuntimeError(
"Could not set adc enable mask due to fifo memory allcoation");
} }
auto retval = impl()->getADCEnableMask(); auto retval = impl()->getADCEnableMask();
if (retval != arg) { if (retval != arg) {
@ -1414,13 +1418,12 @@ 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;
impl()->setDbitOffset(arg); impl()->setDbitOffset(arg);
int retval = impl()->getDbitOffset(); int retval = impl()->getDbitOffset();
validate(arg, retval, "set dbit offset", DEC); validate(arg, retval, "set dbit offset", DEC);
LOG(logDEBUG1) << "Dbit offset retval: " << retval; LOG(logDEBUG1) << "Dbit offset retval: " << retval;
@ -1442,8 +1445,10 @@ int ClientInterface::set_quad_type(Interface &socket) {
LOG(logDEBUG1) << "Setting quad:" << quadEnable; LOG(logDEBUG1) << "Setting quad:" << quadEnable;
try { try {
impl()->setQuad(quadEnable == 0 ? false : true); impl()->setQuad(quadEnable == 0 ? false : true);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set quad to " + std::to_string(quadEnable) + " due to fifo strucutre memory allocation"); throw RuntimeError("Could not set quad to " +
std::to_string(quadEnable) +
" due to fifo strucutre memory allocation");
} }
} }
int retval = impl()->getQuad() ? 1 : 0; int retval = impl()->getQuad() ? 1 : 0;
@ -1469,12 +1474,14 @@ 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) {
impl()->setEthernetInterface2(eth); impl()->setEthernetInterface2(eth);
@ -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,8 +1553,9 @@ 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);
return socket.Send(OK); return socket.Send(OK);
@ -1552,13 +1566,15 @@ int ClientInterface::set_num_interfaces(Interface &socket) {
arg = (arg > 1 ? 2 : 1); arg = (arg > 1 ? 2 : 1);
verifyIdle(socket); verifyIdle(socket);
if (myDetectorType != JUNGFRAU) { if (myDetectorType != JUNGFRAU) {
throw RuntimeError("Number of interfaces not implemented for this detector"); throw RuntimeError(
} "Number of interfaces not implemented for this detector");
}
LOG(logDEBUG1) << "Setting Number of UDP Interfaces:" << arg; LOG(logDEBUG1) << "Setting Number of UDP Interfaces:" << arg;
try { try {
impl()->setNumberofUDPInterfaces(arg); impl()->setNumberofUDPInterfaces(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Failed to set number of interfaces to " + std::to_string(arg)); throw RuntimeError("Failed to set number of interfaces to " +
std::to_string(arg));
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -1569,8 +1585,9 @@ int ClientInterface::set_adc_mask_10g(Interface &socket) {
LOG(logDEBUG1) << "Setting 10Gb ADC enable mask: " << arg; LOG(logDEBUG1) << "Setting 10Gb ADC enable mask: " << arg;
try { try {
impl()->setTenGigaADCEnableMask(arg); impl()->setTenGigaADCEnableMask(arg);
} catch(const RuntimeError &e) { } catch (const RuntimeError &e) {
throw RuntimeError("Could not set 10Gb adc enable mask due to fifo memory allcoation"); throw RuntimeError(
"Could not set 10Gb adc enable mask due to fifo memory allcoation");
} }
auto retval = impl()->getTenGigaADCEnableMask(); auto retval = impl()->getTenGigaADCEnableMask();
if (retval != arg) { if (retval != arg) {
@ -1600,12 +1617,12 @@ int ClientInterface::increment_file_index(Interface &socket) {
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::set_additional_json_parameter(Interface &socket) { int ClientInterface::set_additional_json_parameter(Interface &socket) {
char args[2][SHORT_STR_LENGTH]{}; char args[2][SHORT_STR_LENGTH]{};
socket.Receive(args); socket.Receive(args);
verifyIdle(socket); verifyIdle(socket);
LOG(logDEBUG1) << "Setting additional json parameter (" << args[0] << "): " << args[1]; LOG(logDEBUG1) << "Setting additional json parameter (" << args[0]
<< "): " << args[1];
impl()->setAdditionalJsonParameter(args[0], args[1]); impl()->setAdditionalJsonParameter(args[0], args[1]);
return socket.Send(OK); return socket.Send(OK);
} }

37
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>
@ -19,9 +18,8 @@ class ClientInterface : private virtual slsDetectorDefs {
int ret{OK}; int ret{OK};
int fnum{-1}; int fnum{-1};
int lockedByClient{0}; int lockedByClient{0};
std::atomic<bool> killTcpThread{false}; std::atomic<bool> killTcpThread{false};
public: public:
virtual ~ClientInterface(); virtual ~ClientInterface();
@ -30,8 +28,9 @@ class ClientInterface : private virtual slsDetectorDefs {
//***callback functions*** //***callback functions***
/** params: filepath, filename, fileindex, datasize */ /** params: filepath, filename, fileindex, datasize */
void registerCallBackStartAcquisition(int (*func)(std::string, std::string, uint64_t, void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
uint32_t, void *), uint64_t, uint32_t,
void *),
void *arg); void *arg);
/** params: total frames caught */ /** params: total frames caught */
@ -43,7 +42,8 @@ class ClientInterface : private virtual slsDetectorDefs {
void *), void *),
void *arg); void *arg);
/** params: sls_receiver_header frame metadata, dataPointer, modified size */ /** params: sls_receiver_header frame metadata, dataPointer, modified size
*/
void registerCallBackRawDataModifyReady(void (*func)(char *, char *, void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
uint32_t &, void *), uint32_t &, void *),
void *arg); void *arg);
@ -53,9 +53,9 @@ class ClientInterface : private virtual slsDetectorDefs {
int functionTable(); int functionTable();
int decodeFunction(sls::ServerInterface &socket); int decodeFunction(sls::ServerInterface &socket);
void functionNotImplemented(); void functionNotImplemented();
void modeNotImplemented(const std::string& modename, int mode); void modeNotImplemented(const std::string &modename, int mode);
template <typename T> template <typename T>
void validate(T arg, T retval, const std::string& modename, numberMode hex); void validate(T arg, T retval, const std::string &modename, numberMode hex);
void verifyLock(); void verifyLock();
void verifyIdle(sls::ServerInterface &socket); void verifyIdle(sls::ServerInterface &socket);
@ -146,13 +146,13 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_udp_port(sls::ServerInterface &socket); int set_udp_port(sls::ServerInterface &socket);
int set_udp_port2(sls::ServerInterface &socket); int set_udp_port2(sls::ServerInterface &socket);
int set_num_interfaces(sls::ServerInterface &socket); int set_num_interfaces(sls::ServerInterface &socket);
int set_adc_mask_10g(sls::ServerInterface &socket); int set_adc_mask_10g(sls::ServerInterface &socket);
int set_num_counters(sls::ServerInterface &socket); int set_num_counters(sls::ServerInterface &socket);
int increment_file_index(sls::ServerInterface &socket); int increment_file_index(sls::ServerInterface &socket);
int set_additional_json_parameter(sls::ServerInterface &socket); int set_additional_json_parameter(sls::ServerInterface &socket);
int get_additional_json_parameter(sls::ServerInterface &socket); int get_additional_json_parameter(sls::ServerInterface &socket);
int get_progress(sls::ServerInterface &socket); int get_progress(sls::ServerInterface &socket);
Implementation *impl() { Implementation *impl() {
if (receiver != nullptr) { if (receiver != nullptr) {
return receiver.get(); return receiver.get();
@ -164,11 +164,11 @@ class ClientInterface : private virtual slsDetectorDefs {
int (ClientInterface::*flist[NUM_REC_FUNCTIONS])( int (ClientInterface::*flist[NUM_REC_FUNCTIONS])(
sls::ServerInterface &socket); sls::ServerInterface &socket);
//***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};
}; };

671
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,241 +21,218 @@
const std::string DataProcessor::TypeName = "DataProcessor"; const std::string DataProcessor::TypeName = "DataProcessor";
DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo *f,
DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat *ftype, bool fwenable, bool *mfwenable,
fileFormat* ftype, bool fwenable, bool* mfwenable, bool *dsEnable, uint32_t *dr, uint32_t *freq,
bool* dsEnable, uint32_t* dr, uint32_t *timer, bool *fp, bool *act,
uint32_t* freq, uint32_t* timer, bool *depaden, bool *sm, bool *qe,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, std::vector<int> *cdl, int *cdo, int *cad)
std::vector <int> * cdl, int* cdo, int* cad) : : ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype),
ThreadObject(ind, TypeName), dataStreamEnable(dsEnable), fileFormatType(ftype),
fifo(f), fileWriteEnable(fwenable), masterFileWriteEnable(mfwenable),
myDetectorType(dtype), dynamicRange(dr), streamingFrequency(freq), streamingTimerInMs(timer),
dataStreamEnable(dsEnable), activated(act), deactivatedPaddingEnable(depaden), silentMode(sm),
fileFormatType(ftype), quadEnable(qe), framePadding(fp), ctbDbitList(cdl), ctbDbitOffset(cdo),
fileWriteEnable(fwenable), ctbAnalogDataBytes(cad) {
masterFileWriteEnable(mfwenable),
dynamicRange(dr),
streamingFrequency(freq),
streamingTimerInMs(timer),
activated(act),
deactivatedPaddingEnable(depaden),
silentMode(sm),
quadEnable(qe),
framePadding(fp),
ctbDbitList(cdl),
ctbDbitOffset(cdo),
ctbAnalogDataBytes(cad)
{
LOG(logDEBUG) << "DataProcessor " << ind << " created"; LOG(logDEBUG) << "DataProcessor " << ind << " created";
memset((void*)&timerBegin, 0, sizeof(timespec)); memset((void *)&timerBegin, 0, sizeof(timespec));
} }
DataProcessor::~DataProcessor() { delete file; }
DataProcessor::~DataProcessor() {
delete file;
}
/** getters */ /** getters */
bool DataProcessor::GetStartedFlag(){ bool DataProcessor::GetStartedFlag() { return startedFlag; }
return startedFlag;
}
uint64_t DataProcessor::GetNumFramesCaught() { uint64_t DataProcessor::GetNumFramesCaught() { return numFramesCaught; }
return numFramesCaught;
}
uint64_t DataProcessor::GetCurrentFrameIndex() { uint64_t DataProcessor::GetCurrentFrameIndex() { return currentFrameIndex; }
return currentFrameIndex;
}
uint64_t DataProcessor::GetProcessedIndex() { uint64_t DataProcessor::GetProcessedIndex() {
return currentFrameIndex - firstIndex; return currentFrameIndex - firstIndex;
} }
void DataProcessor::SetFifo(Fifo* f) { void DataProcessor::SetFifo(Fifo *f) { fifo = f; }
fifo = f;
}
void DataProcessor::ResetParametersforNewAcquisition(){ void DataProcessor::ResetParametersforNewAcquisition() {
StopRunning(); StopRunning();
startedFlag = false; startedFlag = false;
numFramesCaught = 0; numFramesCaught = 0;
firstIndex = 0; firstIndex = 0;
currentFrameIndex = 0; currentFrameIndex = 0;
} }
void DataProcessor::RecordFirstIndex(uint64_t fnum) { void DataProcessor::RecordFirstIndex(uint64_t fnum) {
//listen to this fnum, later +1 // listen to this fnum, later +1
currentFrameIndex = fnum; currentFrameIndex = fnum;
startedFlag = true; startedFlag = true;
firstIndex = fnum; firstIndex = 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,
file->SetNumberofPixels(generalData->nPixelsX, generalData->nPixelsY); generalData->nPixelsY);
} }
} }
} }
void DataProcessor::SetFileFormat(const fileFormat f) { void DataProcessor::SetFileFormat(const fileFormat f) {
if ((file != nullptr) && file->GetFileType() != f) { if ((file != nullptr) && file->GetFileType() != f) {
//remember the pointer values before they are destroyed // remember the pointer values before they are destroyed
int nd[MAX_DIMENSIONS];nd[0] = 0; nd[1] = 0; int nd[MAX_DIMENSIONS];
uint32_t* maxf = nullptr; nd[0] = 0;
std::string* fname=nullptr; std::string* fpath=nullptr; nd[1] = 0;
uint64_t* findex=nullptr; bool* owenable=nullptr; int* dindex=nullptr; uint32_t *maxf = nullptr;
int* nunits=nullptr; uint64_t* nf = nullptr; std::string *fname = nullptr;
uint32_t* dr = nullptr; uint32_t* port = nullptr; std::string *fpath = nullptr;
file->GetMemberPointerValues(nd, maxf, fname, fpath, findex, uint64_t *findex = nullptr;
owenable, dindex, nunits, nf, dr, port); bool *owenable = nullptr;
//create file writer with same pointers int *dindex = nullptr;
SetupFileWriter(fileWriteEnable, nd, maxf, fname, fpath, findex, int *nunits = nullptr;
owenable, dindex, nunits, nf, dr, port); uint64_t *nf = nullptr;
} uint32_t *dr = nullptr;
uint32_t *port = nullptr;
file->GetMemberPointerValues(nd, maxf, fname, fpath, findex, owenable,
dindex, nunits, nf, dr, port);
// create file writer with same pointers
SetupFileWriter(fileWriteEnable, nd, maxf, fname, fpath, findex,
owenable, dindex, nunits, nf, dr, port);
}
} }
void DataProcessor::SetupFileWriter(bool fwe, int *nd, uint32_t *maxf,
std::string *fname, std::string *fpath,
uint64_t *findex, bool *owenable,
int *dindex, int *nunits, uint64_t *nf,
uint32_t *dr, uint32_t *portno,
GeneralData *g) {
fileWriteEnable = fwe;
if (g != nullptr)
generalData = g;
void DataProcessor::SetupFileWriter(bool fwe, int* nd, uint32_t* maxf, if (file != nullptr) {
std::string* fname, std::string* fpath, uint64_t* findex, delete file;
bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, file = nullptr;
uint32_t* portno, }
GeneralData* g)
{
fileWriteEnable = fwe;
if (g != nullptr)
generalData = g;
if (fileWriteEnable) {
if (file != nullptr) { switch (*fileFormatType) {
delete file;
file = nullptr;
}
if (fileWriteEnable) {
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,
generalData->nPixelsX, generalData->nPixelsY, silentMode); 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;
} }
} }
} }
// only the first file // only the first file
void DataProcessor::CreateNewFile(masterAttributes& attr) { void DataProcessor::CreateNewFile(masterAttributes &attr) {
if (file == nullptr) { if (file == nullptr) {
throw sls::RuntimeError("file object not contstructed"); throw sls::RuntimeError("file object not contstructed");
} }
file->CloseAllFiles(); file->CloseAllFiles();
file->resetSubFileIndex(); file->resetSubFileIndex();
file->CreateMasterFile(*masterFileWriteEnable, attr); file->CreateMasterFile(*masterFileWriteEnable, attr);
file->CreateFile(); file->CreateFile();
} }
void DataProcessor::CloseFiles() { void DataProcessor::CloseFiles() {
if (file != nullptr) if (file != nullptr)
file->CloseAllFiles(); file->CloseAllFiles();
} }
void DataProcessor::EndofAcquisition(bool anyPacketsCaught, uint64_t numf) { void DataProcessor::EndofAcquisition(bool anyPacketsCaught, uint64_t numf) {
if ((file != nullptr) && file->GetFileType() == HDF5) { if ((file != nullptr) && file->GetFileType() == HDF5) {
try { try {
file->EndofAcquisition(anyPacketsCaught, numf); file->EndofAcquisition(anyPacketsCaught, numf);
} catch (const sls::RuntimeError &e) { } catch (const sls::RuntimeError &e) {
;// ignore for now //TODO: send error to client via stop receiver ; // ignore for now //TODO: send error to client via stop receiver
} }
} }
} }
void DataProcessor::ThreadExecution() { void DataProcessor::ThreadExecution() {
char* buffer=nullptr; char *buffer = nullptr;
fifo->PopAddress(buffer); fifo->PopAddress(buffer);
LOG(logDEBUG5) << "DataProcessor " << index << ", " LOG(logDEBUG5) << "DataProcessor " << index
"pop 0x" << std::hex << (void*)(buffer) << std::dec << ":" << buffer; << ", "
"pop 0x"
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
//check dummy // check dummy
auto numBytes = (uint32_t)(*((uint32_t*)buffer)); auto numBytes = (uint32_t)(*((uint32_t *)buffer));
LOG(logDEBUG1) << "DataProcessor " << index << ", Numbytes:" << numBytes; LOG(logDEBUG1) << "DataProcessor " << index << ", Numbytes:" << numBytes;
if (numBytes == DUMMY_PACKET_VALUE) { if (numBytes == DUMMY_PACKET_VALUE) {
StopProcessing(buffer); StopProcessing(buffer);
return; return;
} }
ProcessAnImage(buffer); ProcessAnImage(buffer);
//stream (if time/freq to stream) or free // stream (if time/freq to stream) or free
if (*dataStreamEnable && SendToStreamer()) if (*dataStreamEnable && SendToStreamer())
fifo->PushAddressToStream(buffer); fifo->PushAddressToStream(buffer);
else else
fifo->FreeAddress(buffer); fifo->FreeAddress(buffer);
} }
void DataProcessor::StopProcessing(char *buf) {
LOG(logDEBUG1) << "DataProcessing " << index << ": Dummy";
void DataProcessor::StopProcessing(char* buf) { // stream or free
LOG(logDEBUG1) << "DataProcessing " << index << ": Dummy"; if (*dataStreamEnable)
fifo->PushAddressToStream(buf);
else
fifo->FreeAddress(buf);
//stream or free if (file != nullptr)
if (*dataStreamEnable) file->CloseCurrentFile();
fifo->PushAddressToStream(buf); StopRunning();
else LOG(logDEBUG1) << index << ": Processing Completed";
fifo->FreeAddress(buf);
if (file != nullptr)
file->CloseCurrentFile();
StopRunning();
LOG(logDEBUG1) << index << ": Processing Completed";
} }
void DataProcessor::ProcessAnImage(char *buf) {
void DataProcessor::ProcessAnImage(char* buf) { auto *rheader = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
sls_detector_header header = rheader->detHeader;
uint64_t fnum = header.frameNumber;
currentFrameIndex = fnum;
uint32_t nump = header.packetNumber;
if (nump == generalData->packetsPerFrame) {
numFramesCaught++;
}
auto* rheader = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES); LOG(logDEBUG1) << "DataProcessing " << index << ": fnum:" << fnum;
sls_detector_header header = rheader->detHeader;
uint64_t fnum = header.frameNumber;
currentFrameIndex = fnum;
uint32_t nump = header.packetNumber;
if (nump == generalData->packetsPerFrame) {
numFramesCaught++;
}
LOG(logDEBUG1) << "DataProcessing " << index << ": fnum:" << fnum; if (!startedFlag) {
RecordFirstIndex(fnum);
if (!startedFlag) { if (*dataStreamEnable) {
RecordFirstIndex(fnum); // restart timer
clock_gettime(CLOCK_REALTIME, &timerBegin);
timerBegin.tv_sec -= (*streamingTimerInMs) / 1000;
timerBegin.tv_nsec -= ((*streamingTimerInMs) % 1000) * 1000000;
if (*dataStreamEnable) { // to send first image
//restart timer currentFreqCount = *streamingFrequency;
clock_gettime(CLOCK_REALTIME, &timerBegin); }
timerBegin.tv_sec -= (*streamingTimerInMs) / 1000; }
timerBegin.tv_nsec -= ((*streamingTimerInMs) % 1000) * 1000000;
//to send first image
currentFreqCount = *streamingFrequency;
}
}
// frame padding // frame padding
if (*activated && *framePadding && nump < generalData->packetsPerFrame) if (*activated && *framePadding && nump < generalData->packetsPerFrame)
@ -264,208 +240,213 @@ void DataProcessor::ProcessAnImage(char* buf) {
// deactivated and padding enabled // deactivated and padding enabled
else if (!(*activated) && *deactivatedPaddingEnable) else if (!(*activated) && *deactivatedPaddingEnable)
PadMissingPackets(buf); PadMissingPackets(buf);
// rearrange ctb digital bits (if ctbDbitlist is not empty) // rearrange ctb digital bits (if ctbDbitlist is not empty)
if (!(*ctbDbitList).empty()) { if (!(*ctbDbitList).empty()) {
RearrangeDbitData(buf); RearrangeDbitData(buf);
}
// normal call back
if (rawDataReadyCallBack != nullptr) {
rawDataReadyCallBack(
(char*)rheader,
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
(uint32_t)(*((uint32_t*)buf)),
pRawDataReady);
}
// call back with modified size
else if (rawDataModifyReadyCallBack != nullptr) {
auto revsize = (uint32_t)(*((uint32_t*)buf));
rawDataModifyReadyCallBack(
(char*)rheader,
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
revsize,
pRawDataReady);
(*((uint32_t*)buf)) = revsize;
} }
// write to file // normal call back
if (file != nullptr) { if (rawDataReadyCallBack != nullptr) {
try { rawDataReadyCallBack((char *)rheader,
file->WriteToFile(buf + FIFO_HEADER_NUMBYTES, buf + FIFO_HEADER_NUMBYTES +
sizeof(sls_receiver_header) + (uint32_t)(*((uint32_t*)buf)), //+ size of data (resizable from previous call back sizeof(sls_receiver_header),
fnum-firstIndex, nump); (uint32_t)(*((uint32_t *)buf)), pRawDataReady);
} catch(const sls::RuntimeError &e) { }
; //ignore write exception for now (TODO: send error message via stopReceiver tcp)
}
}
// call back with modified size
else if (rawDataModifyReadyCallBack != nullptr) {
auto revsize = (uint32_t)(*((uint32_t *)buf));
rawDataModifyReadyCallBack((char *)rheader,
buf + FIFO_HEADER_NUMBYTES +
sizeof(sls_receiver_header),
revsize, pRawDataReady);
(*((uint32_t *)buf)) = revsize;
}
// write to file
if (file != nullptr) {
try {
file->WriteToFile(
buf + FIFO_HEADER_NUMBYTES,
sizeof(sls_receiver_header) +
(uint32_t)(*((uint32_t *)buf)), //+ size of data (resizable
//from previous call back
fnum - firstIndex, nump);
} catch (const sls::RuntimeError &e) {
; // ignore write exception for now (TODO: send error message via
// stopReceiver tcp)
}
}
} }
bool DataProcessor::SendToStreamer() { bool DataProcessor::SendToStreamer() {
//skip // skip
if ((*streamingFrequency) == 0u) { if ((*streamingFrequency) == 0u) {
if (!CheckTimer()) if (!CheckTimer())
return false; return false;
} else { } else {
if (!CheckCount()) if (!CheckCount())
return false; return false;
} }
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) +
<< " seconds"; (end.tv_nsec - timerBegin.tv_nsec) / 1000000000.0)
//still less than streaming timer, keep waiting << " seconds";
if((( end.tv_sec - timerBegin.tv_sec ) + ( end.tv_nsec - timerBegin.tv_nsec ) // still less than streaming timer, keep waiting
/ 1000000000.0) < ((double)*streamingTimerInMs/1000.00)) if (((end.tv_sec - timerBegin.tv_sec) +
return false; (end.tv_nsec - timerBegin.tv_nsec) / 1000000000.0) <
((double)*streamingTimerInMs / 1000.00))
return false;
//restart timer // restart timer
clock_gettime(CLOCK_REALTIME, &timerBegin); clock_gettime(CLOCK_REALTIME, &timerBegin);
return true; return true;
} }
bool DataProcessor::CheckCount() { bool DataProcessor::CheckCount() {
if (currentFreqCount == *streamingFrequency ) { if (currentFreqCount == *streamingFrequency) {
currentFreqCount = 1; currentFreqCount = 1;
return true; return true;
} }
currentFreqCount++; currentFreqCount++;
return false; return false;
} }
void DataProcessor::SetPixelDimension() { void DataProcessor::SetPixelDimension() {
if (file != nullptr) { if (file != nullptr) {
if (file->GetFileType() == HDF5) { if (file->GetFileType() == HDF5) {
file->SetNumberofPixels(generalData->nPixelsX, generalData->nPixelsY); file->SetNumberofPixels(generalData->nPixelsX,
} generalData->nPixelsY);
} }
}
} }
void DataProcessor::registerCallBackRawDataReady(void (*func)(char* , void DataProcessor::registerCallBackRawDataReady(void (*func)(char *, char *,
char*, uint32_t, void*),void *arg) { uint32_t, void *),
rawDataReadyCallBack=func; void *arg) {
pRawDataReady=arg; rawDataReadyCallBack = func;
pRawDataReady = arg;
} }
void DataProcessor::registerCallBackRawDataModifyReady(void (*func)(char* , void DataProcessor::registerCallBackRawDataModifyReady(
char*, uint32_t&, void*),void *arg) { void (*func)(char *, char *, uint32_t &, void *), void *arg) {
rawDataModifyReadyCallBack=func; rawDataModifyReadyCallBack = func;
pRawDataReady=arg; pRawDataReady = arg;
} }
void DataProcessor::PadMissingPackets(char* buf) { void DataProcessor::PadMissingPackets(char *buf) {
LOG(logDEBUG) << index << ": Padding Missing Packets"; LOG(logDEBUG) << index << ": Padding Missing Packets";
uint32_t pperFrame = generalData->packetsPerFrame; uint32_t pperFrame = generalData->packetsPerFrame;
auto* header = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES); auto *header = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
uint32_t nmissing = pperFrame - header->detHeader.packetNumber; uint32_t nmissing = pperFrame - header->detHeader.packetNumber;
sls_bitset pmask = header->packetsMask; sls_bitset pmask = header->packetsMask;
uint32_t dsize = generalData->dataSize; uint32_t dsize = generalData->dataSize;
uint32_t fifohsize = generalData->fifoBufferHeaderSize; uint32_t fifohsize = generalData->fifoBufferHeaderSize;
uint32_t corrected_dsize = dsize - ((pperFrame * dsize) - generalData->imageSize); uint32_t corrected_dsize =
LOG(logDEBUG1) << "bitmask: " << pmask.to_string(); dsize - ((pperFrame * dsize) - generalData->imageSize);
LOG(logDEBUG1) << "bitmask: " << pmask.to_string();
for (unsigned int pnum = 0; pnum < pperFrame; ++pnum) { for (unsigned int pnum = 0; pnum < pperFrame; ++pnum) {
// not missing packet // not missing packet
if (pmask[pnum]) if (pmask[pnum])
continue; continue;
// done with padding, exit loop earlier // done with padding, exit loop earlier
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
case GOTTHARD: // 2nd packet: 4 bytes fnum, previous 1*2 bytes data +
if(pnum == 0u) // 640*2 bytes data !!
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize-2); case GOTTHARD:
else if (pnum == 0u)
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize+2); memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize - 2);
break; else
case CHIPTESTBOARD: memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize + 2);
case MOENCH: break;
if (pnum == (pperFrame-1)) case CHIPTESTBOARD:
memset(buf + fifohsize + (pnum * dsize), 0xFF, corrected_dsize); case MOENCH:
else if (pnum == (pperFrame - 1))
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize); memset(buf + fifohsize + (pnum * dsize), 0xFF, corrected_dsize);
break; else
default: memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize);
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize); break;
break; default:
} memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize);
--nmissing; break;
} }
--nmissing;
}
} }
/** 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 digOffset = FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header) + (*ctbAnalogDataBytes);
// ceil as numResult8Bits could be decimal
const int numResult8Bits = ceil((double)(numSamples * (*ctbDbitList).size()) / 8.00);
uint8_t result[numResult8Bits];
memset(result, 0, numResult8Bits * sizeof(uint8_t));
uint8_t* dest = result;
auto* source = (uint64_t*)(buf + digOffset + (*ctbDbitOffset));
// loop through digital bit enable vector
int bitoffset = 0;
for (auto bi : (*ctbDbitList)) {
// where numbits * numsamples is not a multiple of 8
if (bitoffset != 0) {
bitoffset = 0;
++dest;
}
// loop through the frame digital data
for (auto ptr = source; ptr < (source + numSamples);) {
// get selected bit from each 8 bit
uint8_t bit = (*ptr++ >> bi) & 1;
*dest |= bit << bitoffset;
++bitoffset;
// extract destination in 8 bit batches
if (bitoffset == 8) {
bitoffset = 0;
++dest;
}
}
} }
const int numSamples = (ctbDigitalDataBytes / sizeof(uint64_t));
const int digOffset = FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header) +
(*ctbAnalogDataBytes);
// copy back to buf and update size // ceil as numResult8Bits could be decimal
memcpy(buf + digOffset, result, numResult8Bits * sizeof(uint8_t)); const int numResult8Bits =
(*((uint32_t*)buf)) = numResult8Bits * sizeof(uint8_t); ceil((double)(numSamples * (*ctbDbitList).size()) / 8.00);
uint8_t result[numResult8Bits];
memset(result, 0, numResult8Bits * sizeof(uint8_t));
uint8_t *dest = result;
auto *source = (uint64_t *)(buf + digOffset + (*ctbDbitOffset));
// loop through digital bit enable vector
int bitoffset = 0;
for (auto bi : (*ctbDbitList)) {
// where numbits * numsamples is not a multiple of 8
if (bitoffset != 0) {
bitoffset = 0;
++dest;
}
// loop through the frame digital data
for (auto ptr = source; ptr < (source + numSamples);) {
// get selected bit from each 8 bit
uint8_t bit = (*ptr++ >> bi) & 1;
*dest |= bit << bitoffset;
++bitoffset;
// extract destination in 8 bit batches
if (bitoffset == 8) {
bitoffset = 0;
++dest;
}
}
}
// copy back to buf and update size
memcpy(buf + digOffset, result, numResult8Bits * sizeof(uint8_t));
(*((uint32_t *)buf)) = numResult8Bits * sizeof(uint8_t);
} }

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

@ -17,308 +17,141 @@ 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
* @param ftype pointer to file format type * @param ftype pointer to file format type
* @param fwenable file writer enable * @param fwenable file writer enable
* @apram mfwenable pointer to master file write enable * @apram mfwenable pointer to master file write enable
* @param dsEnable pointer to data stream enable * @param dsEnable pointer to data stream enable
* @param dr pointer to dynamic range * @param dr pointer to dynamic range
* @param freq pointer to streaming frequency * @param freq pointer to streaming frequency
* @param timer pointer to timer if streaming frequency is random * @param timer pointer to timer if streaming frequency is random
* @param fp pointer to frame padding enable * @param fp pointer to frame padding enable
* @param act pointer to activated * @param act pointer to activated
* @param depaden pointer to deactivated padding enable * @param depaden pointer to deactivated padding enable
* @param sm pointer to silent mode * @param sm pointer to silent mode
* @param qe pointer to quad Enable * @param qe pointer to quad Enable
* @param cdl pointer to vector or ctb digital bits enable * @param cdl pointer to vector or ctb digital bits enable
* @param cdo pointer to digital bits offset * @param cdo pointer to digital bits offset
* @param cad pointer to ctb analog databytes * @param cad pointer to ctb analog databytes
*/ */
DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat* ftype, DataProcessor(int ind, detectorType dtype, Fifo *f, fileFormat *ftype,
bool fwenable, bool* mfwenable, bool* dsEnable, uint32_t* dr, bool fwenable, bool *mfwenable, bool *dsEnable, uint32_t *dr,
uint32_t* freq, uint32_t* timer, uint32_t *freq, uint32_t *timer, bool *fp, bool *act,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, bool *depaden, bool *sm, bool *qe, std::vector<int> *cdl,
std::vector <int> * cdl, int* cdo, int* cad); int *cdo, int *cad);
/**
* Destructor
* Calls Base Class DestroyThread() and decrements NumberofDataProcessors
*/
~DataProcessor() override;
//*** getters ***
/**
* Get acquisition started flag
* @return acquisition started flag
*/
bool GetStartedFlag();
/**
* Get Frames Complete Caught
* @return number of frames
*/
uint64_t GetNumFramesCaught();
/**
* 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
*/
uint64_t GetCurrentFrameIndex();
/**
* Get Current Frame Index thats been processed
* @return -1 if no frames have been caught, else current frame index
*/
uint64_t GetProcessedIndex();
/**
* Set Fifo pointer to the one given
* @param f address of Fifo pointer
*/
void SetFifo(Fifo* f);
/**
* Reset parameters for new acquisition
*/
void ResetParametersforNewAcquisition();
/**
* Set GeneralData pointer to the one given
* @param g address of GeneralData (Detector Data) pointer
*/
void SetGeneralData(GeneralData* g);
/**
* Set File Format
* @param f file format
*/
void SetFileFormat(const fileFormat fs);
/**
* Set up file writer object and call backs
* @param fwe file write enable
* @param nd pointer to number of detectors in each dimension
* @param maxf pointer to max frames per file
* @param fname pointer to file name prefix
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of threads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to udp port number
* @param g address of GeneralData (Detector Data) pointer
*/
void SetupFileWriter(bool fwe, int* nd, uint32_t* maxf, std::string* fname,
std::string* fpath, uint64_t* findex,
bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr,
uint32_t* portno, GeneralData* g = nullptr);
/**
* Create New File
* @param attr master file attributes
*/
void CreateNewFile(masterAttributes& attr);
/**
* Closes files
*/
void CloseFiles();
/**
* End of Acquisition
* @param anyPacketsCaught true if any packets are caught, else false
* @param numf number of images caught
*/
void EndofAcquisition(bool anyPacketsCaught, uint64_t numf);
/**
* Update pixel dimensions in file writer
*/
void SetPixelDimension();
/**
* Call back for raw data
* args to raw data ready callback are
* sls_receiver_header frame metadata
* dataPointer is the pointer to the data
* dataSize in bytes is the size of the data in bytes.
*/
void registerCallBackRawDataReady(void (*func)(char* ,
char*, uint32_t, void*),void *arg);
/** /**
* Call back for raw data (modified) * Destructor
* args to raw data ready callback are * Calls Base Class DestroyThread() and decrements NumberofDataProcessors
* sls_receiver_header frame metadata
* 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).
*/ */
void registerCallBackRawDataModifyReady(void (*func)(char* , ~DataProcessor() override;
char*, uint32_t &, void*),void *arg);
//*** getters ***
/**
* Get acquisition started flag
* @return acquisition started flag
*/
bool GetStartedFlag();
private: /**
* Get Frames Complete Caught
* @return number of frames
*/
uint64_t GetNumFramesCaught();
/** /**
* Record First Index * Gets Actual Current Frame Index (that has not been subtracted from
* @param fnum frame index to record * firstIndex) thats been processed
*/ * @return -1 if no frames have been caught, else current frame index
void RecordFirstIndex(uint64_t fnum); */
uint64_t GetCurrentFrameIndex();
/** /**
* Thread Exeution for DataProcessor Class * Get Current Frame Index thats been processed
* Pop bound addresses, process them, * @return -1 if no frames have been caught, else current frame index
* write to file if needed & free the address */
*/ uint64_t GetProcessedIndex();
void ThreadExecution() override;
/** /**
* Frees dummy buffer, * Set Fifo pointer to the one given
* reset running mask by calling StopRunning() * @param f address of Fifo pointer
* @param buf address of pointer */
*/ void SetFifo(Fifo *f);
void StopProcessing(char* buf);
/** /**
* Process an image popped from fifo, * Reset parameters for new acquisition
* write to file if fw enabled & update parameters */
* @param buffer void ResetParametersforNewAcquisition();
*/
void ProcessAnImage(char* buf);
/** /**
* Calls CheckTimer and CheckCount for streaming frequency and timer * Set GeneralData pointer to the one given
* and determines if the current image should be sent to streamer * @param g address of GeneralData (Detector Data) pointer
* @returns true if it should to streamer, else false */
*/ void SetGeneralData(GeneralData *g);
bool SendToStreamer();
/** /**
* This function should be called only in random frequency mode * Set File Format
* Checks if timer is done and ready to send to stream * @param f file format
* @returns true if ready to send to stream, else false */
*/ void SetFileFormat(const fileFormat fs);
bool CheckTimer();
/** /**
* This function should be called only in non random frequency mode * Set up file writer object and call backs
* Checks if count is done and ready to send to stream * @param fwe file write enable
* @returns true if ready to send to stream, else false * @param nd pointer to number of detectors in each dimension
*/ * @param maxf pointer to max frames per file
bool CheckCount(); * @param fname pointer to file name prefix
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of threads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to udp port number
* @param g address of GeneralData (Detector Data) pointer
*/
void SetupFileWriter(bool fwe, int *nd, uint32_t *maxf, std::string *fname,
std::string *fpath, uint64_t *findex, bool *owenable,
int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
uint32_t *portno, GeneralData *g = nullptr);
/** /**
* Pad Missing Packets from the bit mask * Create New File
* @param buf buffer * @param attr master file attributes
*/ */
void PadMissingPackets(char* buf); void CreateNewFile(masterAttributes &attr);
/** /**
* Align corresponding digital bits together (CTB only if ctbDbitlist is not empty) * Closes files
*/ */
void RearrangeDbitData(char* buf); void CloseFiles();
/** type of thread */ /**
static const std::string TypeName; * End of Acquisition
* @param anyPacketsCaught true if any packets are caught, else false
* @param numf number of images caught
*/
void EndofAcquisition(bool anyPacketsCaught, uint64_t numf);
/** GeneralData (Detector Data) object */ /**
const GeneralData* generalData{nullptr}; * Update pixel dimensions in file writer
*/
void SetPixelDimension();
/** Fifo structure */
Fifo* fifo;
//individual members
/** Detector Type */
detectorType myDetectorType;
/** File writer implemented as binary or hdf5 File */
File* file{nullptr};
/** Data Stream Enable */
bool* dataStreamEnable;
/** File Format Type */
fileFormat* fileFormatType;
/** File Write Enable */
bool fileWriteEnable;
/** Master File Write Enable */
bool* masterFileWriteEnable;
/** Dynamic Range */
uint32_t* dynamicRange;
/** Pointer to Streaming frequency, if 0, sending random images with a timer */
uint32_t* streamingFrequency;
/** Pointer to the timer if Streaming frequency is random */
uint32_t* streamingTimerInMs;
/** Current frequency count */
uint32_t currentFreqCount{0};
/** timer beginning stamp for random streaming */
struct timespec timerBegin;
/** Activated/Deactivated */
bool* activated;
/** Deactivated padding enable */
bool* deactivatedPaddingEnable;
/** Silent Mode */
bool* silentMode;
/** quad enable */
bool* quadEnable;
/** frame padding */
bool* framePadding;
/** ctb digital bits enable list */
std::vector <int> *ctbDbitList;
/** ctb digital bits offset */
int* ctbDbitOffset;
/** ctb analog databytes */
int* ctbAnalogDataBytes;
//acquisition start
/** Aquisition Started flag */
std::atomic<bool> startedFlag{false};
/** Frame Number of First Frame */
std::atomic<uint64_t> firstIndex{0};
//for statistics
/** Number of complete frames caught */
uint64_t numFramesCaught{0};
/** Frame Number of latest processed frame number */
std::atomic<uint64_t> currentFrameIndex{0};
//call back
/** /**
* Call back for raw data * Call back for raw data
* args to raw data ready callback are * args to raw data ready callback are
@ -326,24 +159,186 @@ 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 registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
char*, uint32_t, void*) = nullptr; void *),
void *arg);
/** /**
* 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 registerCallBackRawDataModifyReady(void (*func)(char *, char *,
char*, uint32_t &, void*) = nullptr; uint32_t &, void *),
void *arg);
void *pRawDataReady{nullptr};
private:
/**
* Record First Index
* @param fnum frame index to record
*/
void RecordFirstIndex(uint64_t fnum);
/**
* Thread Exeution for DataProcessor Class
* Pop bound addresses, process them,
* write to file if needed & free the address
*/
void ThreadExecution() override;
/**
* Frees dummy buffer,
* reset running mask by calling StopRunning()
* @param buf address of pointer
*/
void StopProcessing(char *buf);
/**
* Process an image popped from fifo,
* write to file if fw enabled & update parameters
* @param buffer
*/
void ProcessAnImage(char *buf);
/**
* Calls CheckTimer and CheckCount for streaming frequency and timer
* and determines if the current image should be sent to streamer
* @returns true if it should to streamer, else false
*/
bool SendToStreamer();
/**
* This function should be called only in random frequency mode
* Checks if timer is done and ready to send to stream
* @returns true if ready to send to stream, else false
*/
bool CheckTimer();
/**
* This function should be called only in non random frequency mode
* Checks if count is done and ready to send to stream
* @returns true if ready to send to stream, else false
*/
bool CheckCount();
/**
* Pad Missing Packets from the bit mask
* @param buf buffer
*/
void PadMissingPackets(char *buf);
/**
* Align corresponding digital bits together (CTB only if ctbDbitlist is not
* empty)
*/
void RearrangeDbitData(char *buf);
/** type of thread */
static const std::string TypeName;
/** GeneralData (Detector Data) object */
const GeneralData *generalData{nullptr};
/** Fifo structure */
Fifo *fifo;
// individual members
/** Detector Type */
detectorType myDetectorType;
/** File writer implemented as binary or hdf5 File */
File *file{nullptr};
/** Data Stream Enable */
bool *dataStreamEnable;
/** File Format Type */
fileFormat *fileFormatType;
/** File Write Enable */
bool fileWriteEnable;
/** Master File Write Enable */
bool *masterFileWriteEnable;
/** Dynamic Range */
uint32_t *dynamicRange;
/** Pointer to Streaming frequency, if 0, sending random images with a timer
*/
uint32_t *streamingFrequency;
/** Pointer to the timer if Streaming frequency is random */
uint32_t *streamingTimerInMs;
/** Current frequency count */
uint32_t currentFreqCount{0};
/** timer beginning stamp for random streaming */
struct timespec timerBegin;
/** Activated/Deactivated */
bool *activated;
/** Deactivated padding enable */
bool *deactivatedPaddingEnable;
/** Silent Mode */
bool *silentMode;
/** quad enable */
bool *quadEnable;
/** frame padding */
bool *framePadding;
/** ctb digital bits enable list */
std::vector<int> *ctbDbitList;
/** ctb digital bits offset */
int *ctbDbitOffset;
/** ctb analog databytes */
int *ctbAnalogDataBytes;
// acquisition start
/** Aquisition Started flag */
std::atomic<bool> startedFlag{false};
/** Frame Number of First Frame */
std::atomic<uint64_t> firstIndex{0};
// for statistics
/** Number of complete frames caught */
uint64_t numFramesCaught{0};
/** Frame Number of latest processed frame number */
std::atomic<uint64_t> currentFrameIndex{0};
// call back
/**
* Call back for raw data
* args to raw data ready callback are
* sls_receiver_header frame metadata
* dataPointer is the pointer to the data
* dataSize in bytes is the size of the data in bytes.
*/
void (*rawDataReadyCallBack)(char *, char *, uint32_t, void *) = nullptr;
/**
* Call back for raw data (modified)
* args to raw data ready callback are
* sls_receiver_header frame metadata
* 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).
*/
void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &,
void *) = nullptr;
void *pRawDataReady{nullptr};
}; };

317
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,211 +14,210 @@
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,
int fd, int *nd, bool *qe, uint64_t *tot)
: ThreadObject(ind, TypeName), fifo(f), dynamicRange(dr), roi(r),
fileIndex(fi), flippedDataX(fd), quadEnable(qe), totalNumFrames(tot) {
numDet[0] = nd[0];
numDet[1] = nd[1];
DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot) :
ThreadObject(ind, TypeName),
fifo(f),
dynamicRange(dr),
roi(r),
fileIndex(fi),
flippedDataX(fd),
quadEnable(qe),
totalNumFrames(tot)
{
numDet[0] = nd[0];
numDet[1] = nd[1];
LOG(logDEBUG) << "DataStreamer " << ind << " created"; LOG(logDEBUG) << "DataStreamer " << ind << " created";
} }
DataStreamer::~DataStreamer() { DataStreamer::~DataStreamer() {
CloseZmqSocket(); CloseZmqSocket();
delete [] completeBuffer; delete[] completeBuffer;
} }
void DataStreamer::SetFifo(Fifo* f) { void DataStreamer::SetFifo(Fifo *f) { fifo = f; }
fifo = f;
}
void DataStreamer::ResetParametersforNewAcquisition(const std::string& fname){ void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
StopRunning(); StopRunning();
startedFlag = false; startedFlag = false;
firstIndex = 0; firstIndex = 0;
fileNametoStream = fname; fileNametoStream = fname;
if (completeBuffer) { if (completeBuffer) {
delete[] completeBuffer; delete[] completeBuffer;
completeBuffer = nullptr; completeBuffer = nullptr;
} }
if (roi->xmin != -1) { if (roi->xmin != -1) {
if (generalData->myDetectorType == GOTTHARD) { if (generalData->myDetectorType == GOTTHARD) {
adcConfigured = generalData->GetAdcConfigured(index, *roi); adcConfigured = generalData->GetAdcConfigured(index, *roi);
} }
completeBuffer = new char[generalData->imageSizeComplete]; completeBuffer = new char[generalData->imageSizeComplete];
memset(completeBuffer, 0, generalData->imageSizeComplete); memset(completeBuffer, 0, generalData->imageSizeComplete);
} }
} }
void DataStreamer::RecordFirstIndex(uint64_t fnum) { void DataStreamer::RecordFirstIndex(uint64_t fnum) {
startedFlag = true; startedFlag = true;
firstIndex = fnum; firstIndex = fnum;
LOG(logDEBUG1) << index << " First Index: " << firstIndex; LOG(logDEBUG1) << index << " First Index: " << firstIndex;
} }
void DataStreamer::SetGeneralData(GeneralData* g) { void DataStreamer::SetGeneralData(GeneralData *g) {
generalData = g; generalData = g;
generalData->Print(); generalData->Print();
} }
void DataStreamer::SetNumberofDetectors(int* nd) { void DataStreamer::SetNumberofDetectors(int *nd) {
numDet[0] = nd[0]; numDet[0] = nd[0];
numDet[1] = nd[1]; numDet[1] = nd[1];
} }
void DataStreamer::SetFlippedDataX(int fd) { void DataStreamer::SetFlippedDataX(int fd) { flippedDataX = fd; }
flippedDataX = fd;
void DataStreamer::SetAdditionalJsonHeader(
const std::map<std::string, std::string> &json) {
additionJsonHeader = json;
} }
void DataStreamer::SetAdditionalJsonHeader(const std::map<std::string, std::string> &json) { void DataStreamer::CreateZmqSockets(int *nunits, uint32_t port,
additionJsonHeader = json; const sls::IpAddr ip) {
uint32_t portnum = port + index;
std::string sip = ip.str();
try {
zmqSocket = new ZmqSocket(portnum, (ip != 0 ? sip.c_str() : nullptr));
} catch (...) {
LOG(logERROR) << "Could not create Zmq socket on port " << portnum
<< " for Streamer " << index;
throw;
}
LOG(logINFO) << index << " Streamer: Zmq Server started at "
<< zmqSocket->GetZmqServerAddress();
} }
void DataStreamer::CreateZmqSockets(int* nunits, uint32_t port, const sls::IpAddr ip) {
uint32_t portnum = port + index;
std::string sip = ip.str();
try {
zmqSocket = new ZmqSocket(portnum, (ip != 0? sip.c_str(): nullptr));
} catch (...) {
LOG(logERROR) << "Could not create Zmq socket on port " << portnum << " for Streamer " << index;
throw;
}
LOG(logINFO) << index << " Streamer: Zmq Server started at " << zmqSocket->GetZmqServerAddress();
}
void DataStreamer::CloseZmqSocket() { void DataStreamer::CloseZmqSocket() {
if (zmqSocket) { if (zmqSocket) {
delete zmqSocket; delete zmqSocket;
zmqSocket = nullptr; zmqSocket = nullptr;
} }
} }
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
uint32_t numBytes = (uint32_t)(*((uint32_t *)buffer));
LOG(logDEBUG1) << "DataStreamer " << index << ", Numbytes:" << numBytes;
if (numBytes == DUMMY_PACKET_VALUE) {
StopProcessing(buffer);
return;
}
//check dummy ProcessAnImage(buffer);
uint32_t numBytes = (uint32_t)(*((uint32_t*)buffer));
LOG(logDEBUG1) << "DataStreamer " << index << ", Numbytes:" << numBytes;
if (numBytes == DUMMY_PACKET_VALUE) {
StopProcessing(buffer);
return;
}
ProcessAnImage(buffer);
//free
fifo->FreeAddress(buffer);
// free
fifo->FreeAddress(buffer);
} }
void DataStreamer::StopProcessing(char *buf) {
LOG(logDEBUG1) << "DataStreamer " << index << ": Dummy";
sls_receiver_header *header = (sls_receiver_header *)(buf);
// send dummy header and data
if (!SendHeader(header, 0, 0, 0, true)) {
LOG(logERROR) << "Could not send zmq dummy header for streamer "
<< index;
}
void DataStreamer::StopProcessing(char* buf) { fifo->FreeAddress(buf);
LOG(logDEBUG1) << "DataStreamer " << index << ": Dummy"; StopRunning();
LOG(logDEBUG1) << index << ": Streaming Completed";
sls_receiver_header* header = (sls_receiver_header*) (buf);
//send dummy header and data
if (!SendHeader(header, 0, 0, 0, true)) {
LOG(logERROR) << "Could not send zmq dummy header for streamer " << index;
}
fifo->FreeAddress(buf);
StopRunning();
LOG(logDEBUG1) << index << ": Streaming Completed";
} }
/** 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 =
uint64_t fnum = header->detHeader.frameNumber; (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
LOG(logDEBUG1) << "DataStreamer " << index << ": fnum:" << fnum; uint64_t fnum = header->detHeader.frameNumber;
LOG(logDEBUG1) << "DataStreamer " << index << ": fnum:" << fnum;
if (!startedFlag) { if (!startedFlag) {
RecordFirstIndex(fnum); RecordFirstIndex(fnum);
} }
//shortframe gotthard // shortframe gotthard
if (completeBuffer) { if (completeBuffer) {
//disregarding the size modified from callback (always using imageSizeComplete // disregarding the size modified from callback (always using
// instead of buf (32 bit) because gui needs imagesizecomplete and listener // imageSizeComplete
//write imagesize // instead of buf (32 bit) because gui needs imagesizecomplete and
// listener
// write imagesize
if (!SendHeader(header, generalData->imageSizeComplete, if (!SendHeader(header, generalData->imageSizeComplete,
generalData->nPixelsXComplete, generalData->nPixelsYComplete, false)) { generalData->nPixelsXComplete,
LOG(logERROR) << "Could not send zmq header for fnum " << fnum << " and streamer " << index; generalData->nPixelsYComplete, false)) {
} LOG(logERROR) << "Could not send zmq header for fnum " << fnum
memcpy(completeBuffer + ((generalData->imageSize) * adcConfigured), << " and streamer " << index;
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), }
(uint32_t)(*((uint32_t*)buf)) ); memcpy(completeBuffer + ((generalData->imageSize) * adcConfigured),
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
(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
else {
//normal if (!SendHeader(header, (uint32_t)(*((uint32_t *)buf)),
else { generalData->nPixelsX, generalData->nPixelsY,
false)) { // new size possibly from callback
if (!SendHeader(header, (uint32_t)(*((uint32_t*)buf)), LOG(logERROR) << "Could not send zmq header for fnum " << fnum
generalData->nPixelsX, generalData->nPixelsY, false)) {// new size possibly from callback << " and streamer " << index;
LOG(logERROR) << "Could not send zmq header for fnum " << fnum << " and streamer " << index; }
} if (!zmqSocket->SendData(
if (!zmqSocket->SendData(buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header), buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
(uint32_t)(*((uint32_t*)buf)) )) {// new size possibly from callback (uint32_t)(
LOG(logERROR) << "Could not send zmq data for fnum " << fnum << " and streamer " << index; *((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) {
zmqHeader zHeader;
zHeader.data = !dummy;
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32_t nx, uint32_t ny, bool dummy) { if (dummy) {
return zmqSocket->SendHeader(index, zHeader);
}
zmqHeader zHeader; sls_detector_header header = rheader->detHeader;
zHeader.data = !dummy;
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
if (dummy) { uint64_t frameIndex = header.frameNumber - firstIndex;
return zmqSocket->SendHeader(index, zHeader); uint64_t acquisitionIndex = header.frameNumber;
}
sls_detector_header header = rheader->detHeader; zHeader.dynamicRange = *dynamicRange;
zHeader.fileIndex = *fileIndex;
uint64_t frameIndex = header.frameNumber - firstIndex; zHeader.ndetx = numDet[0];
uint64_t acquisitionIndex = header.frameNumber; zHeader.ndety = numDet[1];
zHeader.dynamicRange = *dynamicRange;
zHeader.fileIndex = *fileIndex;
zHeader.ndetx = numDet[0];
zHeader.ndety = numDet[1];
zHeader.npixelsx = nx; zHeader.npixelsx = nx;
zHeader.npixelsy = ny; zHeader.npixelsy = ny;
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 =
zHeader.fname = fileNametoStream; 100 * ((double)(frameIndex + 1) / (double)(*totalNumFrames));
zHeader.fname = fileNametoStream;
zHeader.frameNumber = header.frameNumber; zHeader.frameNumber = header.frameNumber;
zHeader.expLength = header.expLength; zHeader.expLength = header.expLength;
zHeader.packetNumber = header.packetNumber; zHeader.packetNumber = header.packetNumber;
@ -235,23 +233,22 @@ int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32
zHeader.version = header.version; zHeader.version = header.version;
zHeader.flippedDataX = flippedDataX; zHeader.flippedDataX = flippedDataX;
zHeader.quad = *quadEnable; zHeader.quad = *quadEnable;
zHeader.completeImage = (header.packetNumber < generalData->packetsPerFrame ? false : true); zHeader.completeImage =
(header.packetNumber < generalData->packetsPerFrame ? false : true);
zHeader.addJsonHeader = additionJsonHeader; zHeader.addJsonHeader = additionJsonHeader;
return zmqSocket->SendHeader(index, zHeader); return zmqSocket->SendHeader(index, zHeader);
} }
void DataStreamer::RestreamStop() { void DataStreamer::RestreamStop() {
//send dummy header // send dummy header
zmqHeader zHeader; zmqHeader zHeader;
zHeader.data = false; zHeader.data = false;
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION; zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
int ret = zmqSocket->SendHeader(index, zHeader); int ret = zmqSocket->SendHeader(index, zHeader);
if (!ret) { if (!ret) {
throw sls::RuntimeError("Could not restream Dummy Header via ZMQ for port " + std::to_string(zmqSocket->GetPortNumber())); throw sls::RuntimeError(
} "Could not restream Dummy Header via ZMQ for port " +
std::to_string(zmqSocket->GetPortNumber()));
}
} }

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

@ -18,174 +18,173 @@ class ZmqSocket;
#include <map> #include <map>
class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { 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
* @param r roi * @param r roi
* @param fi pointer to file index * @param fi pointer to file index
* @param fd flipped data enable for x dimension * @param fd flipped data enable for x dimension
* @param nd pointer to number of detectors in each dimension * @param nd pointer to number of detectors in each dimension
* @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
* Calls Base Class DestroyThread() and decrements NumberofDataStreamers * Calls Base Class DestroyThread() and decrements NumberofDataStreamers
*/ */
~DataStreamer(); ~DataStreamer();
/** /**
* Set Fifo pointer to the one given * Set Fifo pointer to the one given
* @param f address of Fifo pointer * @param f address of Fifo pointer
*/ */
void SetFifo(Fifo* f); void SetFifo(Fifo *f);
/** /**
* Reset parameters for new acquisition * Reset parameters for new acquisition
*/ */
void ResetParametersforNewAcquisition(const std::string& fname); void ResetParametersforNewAcquisition(const std::string &fname);
/** /**
* Set GeneralData pointer to the one given * Set GeneralData pointer to the one given
* @param g address of GeneralData (Detector Data) pointer * @param g address of GeneralData (Detector Data) pointer
*/ */
void SetGeneralData(GeneralData* g); void SetGeneralData(GeneralData *g);
/** /**
* Set number of detectors * Set number of detectors
* @param number of detectors in both dimensions * @param number of detectors in both dimensions
*/ */
void SetNumberofDetectors(int* nd); void SetNumberofDetectors(int *nd);
/** /**
* Set Flipped data enable across x dimension * Set Flipped data enable across x dimension
* @param flipped data enable in x dimension * @param flipped data enable in x dimension
*/ */
void SetFlippedDataX(int fd); void SetFlippedDataX(int fd);
/** /**
* 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
* (throws an exception if it couldnt create zmq sockets)
* @param nunits pointer to number of theads/ units per detector
* @param port streaming port start index
* @param ip streaming source ip
*/
void CreateZmqSockets(int* nunits, uint32_t port, const sls::IpAddr ip);
/** /**
* Shuts down and deletes Zmq Sockets * Creates Zmq Sockets
*/ * (throws an exception if it couldnt create zmq sockets)
void CloseZmqSocket(); * @param nunits pointer to number of theads/ units per detector
* @param port streaming port start index
* @param ip streaming source ip
*/
void CreateZmqSockets(int *nunits, uint32_t port, const sls::IpAddr ip);
/** /**
* Restream stop dummy packet * Shuts down and deletes Zmq Sockets
*/ */
void RestreamStop(); void CloseZmqSocket();
/**
* Restream stop dummy packet
*/
void RestreamStop();
private: private:
/**
* Record First Index
* @param fnum frame index to record
*/
void RecordFirstIndex(uint64_t fnum);
/** /**
* Record First Index * Thread Exeution for DataStreamer Class
* @param fnum frame index to record * Stream an image via zmq
*/ */
void RecordFirstIndex(uint64_t fnum); void ThreadExecution();
/** /**
* Thread Exeution for DataStreamer Class * Frees dummy buffer,
* Stream an image via zmq * reset running mask by calling StopRunning()
*/ * @param buf address of pointer
void ThreadExecution(); */
void StopProcessing(char *buf);
/** /**
* Frees dummy buffer, * Process an image popped from fifo,
* reset running mask by calling StopRunning() * write to file if fw enabled & update parameters
* @param buf address of pointer * @param buffer
*/ */
void StopProcessing(char* buf); void ProcessAnImage(char *buf);
/** /**
* Process an image popped from fifo, * Create and send Json Header
* write to file if fw enabled & update parameters * @param rheader header of image
* @param buffer * @param size data size (could have been modified in call back)
*/ * @param nx number of pixels in x dim
void ProcessAnImage(char* buf); * @param ny number of pixels in y dim
* @param dummy true if its a dummy header
* @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);
/** /** type of thread */
* Create and send Json Header static const std::string TypeName;
* @param rheader header of image
* @param size data size (could have been modified in call back)
* @param nx number of pixels in x dim
* @param ny number of pixels in y dim
* @param dummy true if its a dummy header
* @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);
/** type of thread */ /** GeneralData (Detector Data) object */
static const std::string TypeName; const GeneralData *generalData{nullptr};
/** GeneralData (Detector Data) object */ /** Fifo structure */
const GeneralData* generalData{nullptr}; Fifo *fifo;
/** Fifo structure */ /** ZMQ Socket - Receiver to Client */
Fifo* fifo; ZmqSocket *zmqSocket{nullptr};
/** ZMQ Socket - Receiver to Client */ /** Pointer to dynamic range */
ZmqSocket* zmqSocket{nullptr}; uint32_t *dynamicRange;
/** Pointer to dynamic range */ /** ROI */
uint32_t* dynamicRange; ROI *roi;
/** ROI */ /** adc Configured */
ROI* roi; int adcConfigured{-1};
/** adc Configured */ /** Pointer to file index */
int adcConfigured{-1}; uint64_t *fileIndex;
/** Pointer to file index */ /** flipped data across x axis */
uint64_t* fileIndex; int flippedDataX;
/** flipped data across x axis */ /** additional json header */
int flippedDataX; std::map<std::string, std::string> additionJsonHeader;
/** additional json header */ /** Aquisition Started flag */
std::map<std::string, std::string> additionJsonHeader; bool startedFlag{nullptr};
/** Aquisition Started flag */ /** Frame Number of First Frame */
bool startedFlag{nullptr}; uint64_t firstIndex{0};
/** Frame Number of First Frame */ /* File name to stream */
uint64_t firstIndex{0}; std::string fileNametoStream;
/* File name to stream */ /** Complete buffer used for roi, eg. shortGotthard */
std::string fileNametoStream; char *completeBuffer{nullptr};
/** Complete buffer used for roi, eg. shortGotthard */ /** Number of Detectors in X and Y dimension */
char* completeBuffer{nullptr}; int numDet[2];
/** Number of Detectors in X and Y dimension */ /** Quad Enable */
int numDet[2]; bool *quadEnable;
/** Quad Enable */
bool* quadEnable;
/** Total number of frames */
uint64_t* totalNumFrames;
/** Total number of frames */
uint64_t *totalNumFrames;
}; };

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

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

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

@ -9,102 +9,100 @@
*@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"
class Fifo : private virtual slsDetectorDefs { class Fifo : private virtual slsDetectorDefs {
public:
/**
* Constructor
* Calls CreateFifos that creates fifos and allocates memory
* @param ind self index
* @param fifoItemSize size of each fifo item
* @param depth fifo depth
*/
Fifo(int ind, uint32_t fifoItemSize, uint32_t depth);
/** public:
* Destructor /**
*/ * Constructor
~Fifo(); * Calls CreateFifos that creates fifos and allocates memory
* @param ind self index
* @param fifoItemSize size of each fifo item
* @param depth fifo depth
*/
Fifo(int ind, uint32_t fifoItemSize, uint32_t depth);
/** /**
* Frees the bound address by pushing into fifoFree * Destructor
*/ */
void FreeAddress(char*& address); ~Fifo();
/** /**
* Pops free address from fifoFree * Frees the bound address by pushing into fifoFree
*/ */
void GetNewAddress(char*& address); void FreeAddress(char *&address);
/** /**
* Pushes bound address into fifoBound * Pops free address from fifoFree
*/ */
void PushAddress(char*& address); void GetNewAddress(char *&address);
/** /**
* Pops bound address from fifoBound to process data * Pushes bound address into fifoBound
*/ */
void PopAddress(char*& address); void PushAddress(char *&address);
/** /**
* Pushes bound address into fifoStream * Pops bound address from fifoBound to process data
*/ */
void PushAddressToStream(char*& address); void PopAddress(char *&address);
/** /**
* Pops bound address from fifoStream to stream data * Pushes bound address into fifoStream
*/ */
void PopAddressToStream(char*& address); void PushAddressToStream(char *&address);
/** /**
* Get Maximum Level filled in Fifo Bound * Pops bound address from fifoStream to stream data
* and reset this value for next intake */
*/ void PopAddressToStream(char *&address);
int GetMaxLevelForFifoBound();
/** /**
* Get Minimum Level filled in Fifo Free * Get Maximum Level filled in Fifo Bound
* and reset this value to max for next intake * and reset this value for next intake
*/ */
int GetMinLevelForFifoFree(); int GetMaxLevelForFifoBound();
private: /**
* Get Minimum Level filled in Fifo Free
* and reset this value to max for next intake
*/
int GetMinLevelForFifoFree();
/** private:
* Create Fifos, allocate memory & push addresses into fifo /**
* @param fifoItemSize size of each fifo item * Create Fifos, allocate memory & push addresses into fifo
*/ * @param fifoItemSize size of each fifo item
void CreateFifos(uint32_t fifoItemSize); */
void CreateFifos(uint32_t fifoItemSize);
/** /**
* Destroy Fifos and deallocate memory * Destroy Fifos and deallocate memory
*/ */
void DestroyFifos(); void DestroyFifos();
/** Self Index */
int index;
/** Self Index */ /** Memory allocated, whose addresses are pushed into the fifos */
int index; char *memory;
/** Memory allocated, whose addresses are pushed into the fifos */ /** Circular Fifo pointing to addresses of bound data in memory */
char* memory; CircularFifo<char> *fifoBound;
/** Circular Fifo pointing to addresses of bound data in memory */ /** Circular Fifo pointing to addresses of freed data in memory */
CircularFifo<char>* fifoBound; CircularFifo<char> *fifoFree;
/** Circular Fifo pointing to addresses of freed data in memory */ /** Circular Fifo pointing to addresses of to be streamed data in memory */
CircularFifo<char>* fifoFree; CircularFifo<char> *fifoStream;
/** Circular Fifo pointing to addresses of to be streamed data in memory */ /** Fifo depth set */
CircularFifo<char>* fifoStream; int fifoDepth;
/** Fifo depth set */ volatile int status_fifoBound;
int fifoDepth; volatile int status_fifoFree;
volatile int status_fifoBound;
volatile int status_fifoFree;
}; };

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

@ -8,82 +8,64 @@
#include <iostream> #include <iostream>
File::File(int ind, slsDetectorDefs::fileFormat type, uint32_t *maxf, int *nd,
File::File(int ind, slsDetectorDefs::fileFormat type, uint32_t* maxf, std::string *fname, std::string *fpath, uint64_t *findex,
int* nd, std::string* fname, std::string* fpath, uint64_t* findex, bool *owenable, int *dindex, int *nunits, uint64_t *nf, uint32_t *dr,
bool* owenable, int* dindex, int* nunits, uint64_t* nf, uint32_t* dr, uint32_t *portno, bool *smode)
uint32_t* portno, bool* smode): : index(ind), formatType(type), maxFramesPerFile(maxf), numDetX(nd[0]),
index(ind), numDetY(nd[1]), fileNamePrefix(fname), filePath(fpath), fileIndex(findex),
formatType(type), overWriteEnable(owenable), detIndex(dindex), numUnitsPerDetector(nunits),
maxFramesPerFile(maxf), numImages(nf), dynamicRange(dr), udpPortNumber(portno), silentMode(smode)
numDetX(nd[0]),
numDetY(nd[1]),
fileNamePrefix(fname),
filePath(fpath),
fileIndex(findex),
overWriteEnable(owenable),
detIndex(dindex),
numUnitsPerDetector(nunits),
numImages(nf),
dynamicRange(dr),
udpPortNumber(portno),
silentMode(smode)
{ {
master = ((index == 0) && (*detIndex == 0)) ? true : false; master = ((index == 0) && (*detIndex == 0)) ? true : false;
} }
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
<< "Index: " << index << std::endl << "Index: " << index << std::endl
<< "Max Frames Per File: " << *maxFramesPerFile << std::endl << "Max Frames Per File: " << *maxFramesPerFile << std::endl
<< "Number of Detectors in x dir: " << numDetX << std::endl << "Number of Detectors in x dir: " << numDetX << std::endl
<< "Number of Detectors in y dir: " << numDetY << std::endl << "Number of Detectors in y dir: " << numDetY << std::endl
<< "File Name Prefix: " << fileNamePrefix << std::endl << "File Name Prefix: " << fileNamePrefix << std::endl
<< "File Path: " << filePath << std::endl << "File Path: " << filePath << std::endl
<< "File Index: " << *fileIndex << std::endl << "File Index: " << *fileIndex << std::endl
<< "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
<< "Number of Images in Acquisition: " << *numImages << std::endl << std::endl
<< "Dynamic Range: " << *dynamicRange << std::endl << "Number of Images in Acquisition: " << *numImages << std::endl
<< "UDP Port number: " << *udpPortNumber << std::endl << "Dynamic Range: " << *dynamicRange << std::endl
<< "Master File Name: " << masterFileName << std::endl << "UDP Port number: " << *udpPortNumber << std::endl
<< "Current File Name: " << currentFileName << std::endl << "Master File Name: " << masterFileName << std::endl
<< "Silent Mode: " << *silentMode; << "Current File Name: " << currentFileName << std::endl
<< "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,
nd[0] = numDetX; uint32_t *&portno) {
nd[1] = numDetY; nd[0] = numDetX;
maxf = maxFramesPerFile; nd[1] = numDetY;
fname = fileNamePrefix; maxf = maxFramesPerFile;
fpath = filePath; fname = fileNamePrefix;
findex = fileIndex; fpath = filePath;
owenable = overWriteEnable; findex = fileIndex;
dindex = detIndex; owenable = overWriteEnable;
nunits = numUnitsPerDetector; dindex = detIndex;
nf = numImages; nunits = numUnitsPerDetector;
dr = dynamicRange; nf = numImages;
portno = udpPortNumber; dr = dynamicRange;
portno = udpPortNumber;
} }

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

@ -5,125 +5,127 @@
* 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:
/**
* Constructor
* creates the File Writer
* @param ind self index
* @param type file format type
* @param maxf pointer to max frames per file
* @param nd pointer to number of detectors in each dimension
* @param fname pointer to file name prefix
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of theads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to udp port number for logging
* @param smode pointer to silent mode
*/
File(int ind, slsDetectorDefs::fileFormat type, 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, bool* smode);
virtual ~File(); public:
fileFormat GetFileType(); /**
std::string GetCurrentFileName(); * Constructor
void resetSubFileIndex(); * creates the File Writer
virtual void PrintMembers(TLogLevel level = logDEBUG1); * @param ind self index
* @param type file format type
* @param maxf pointer to max frames per file
* @param nd pointer to number of detectors in each dimension
* @param fname pointer to file name prefix
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of theads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to udp port number for logging
* @param smode pointer to silent mode
*/
File(int ind, slsDetectorDefs::fileFormat type, 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, bool *smode);
/** virtual ~File();
* Get Member Pointer Values before the object is destroyed fileFormat GetFileType();
* @param nd pointer to number of detectors in each dimension std::string GetCurrentFileName();
* @param maxf pointer to max frames per file void resetSubFileIndex();
* @param fname pointer to file name prefix virtual void PrintMembers(TLogLevel level = logDEBUG1);
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of theads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to dynamic range
*/
void GetMemberPointerValues(int* nd, uint32_t*& maxf, std::string*& fname,
std::string*& fpath, uint64_t*& findex, bool*& owenable, int*& dindex,
int*& nunits, uint64_t*& nf, uint32_t*& dr, uint32_t*& portno);
virtual void CreateFile() = 0; /**
virtual void CloseCurrentFile() = 0; * Get Member Pointer Values before the object is destroyed
virtual void CloseAllFiles() = 0; * @param nd pointer to number of detectors in each dimension
* @param maxf pointer to max frames per file
* @param fname pointer to file name prefix
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of theads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to dynamic range
*/
void GetMemberPointerValues(int *nd, uint32_t *&maxf, std::string *&fname,
std::string *&fpath, uint64_t *&findex,
bool *&owenable, int *&dindex, int *&nunits,
uint64_t *&nf, uint32_t *&dr,
uint32_t *&portno);
/** virtual void CreateFile() = 0;
* Write data to file virtual void CloseCurrentFile() = 0;
* @param buffer buffer to write from virtual void CloseAllFiles() = 0;
* @param fnum current image number
* @param nump number of packets caught
*/
virtual void WriteToFile(char* buffer, int buffersize, uint64_t fnum, uint32_t nump) = 0;
/** /**
* Create master file * Write data to file
* @param mfwenable master file write enable * @param buffer buffer to write from
* @param attr master file attributes * @param fnum current image number
*/ * @param nump number of packets caught
virtual void CreateMasterFile(bool mfwenable, masterAttributes& attr) = 0; */
virtual void WriteToFile(char *buffer, int buffersize, uint64_t fnum,
uint32_t nump) = 0;
// HDf5 specific /**
/** * Create master file
* Set Number of pixels * @param mfwenable master file write enable
* @param nx number of pixels in x direction * @param attr master file attributes
* @param ny number of pixels in y direction */
*/ virtual void CreateMasterFile(bool mfwenable, masterAttributes &attr) = 0;
virtual void SetNumberofPixels(uint32_t nx, uint32_t ny) {
LOG(logERROR) << "This is a generic function SetNumberofPixels that "
"should be overloaded by a derived class";
}
/**
* End of Acquisition
* @param anyPacketsCaught true if any packets are caught, else false
* @param numf number of images caught
*/
virtual void EndofAcquisition(bool anyPacketsCaught, uint64_t numf) {
LOG(logERROR) << "This is a generic function EndofAcquisition that "
"should be overloaded by a derived class";
}
protected: // HDf5 specific
bool master; /**
int index; * Set Number of pixels
slsDetectorDefs::fileFormat formatType; * @param nx number of pixels in x direction
uint32_t* maxFramesPerFile; * @param ny number of pixels in y direction
std::string masterFileName; */
std::string currentFileName; virtual void SetNumberofPixels(uint32_t nx, uint32_t ny) {
int numDetX; LOG(logERROR) << "This is a generic function SetNumberofPixels that "
int numDetY; "should be overloaded by a derived class";
std::string* fileNamePrefix; }
std::string* filePath;
uint64_t* fileIndex; /**
uint64_t subFileIndex{0}; * End of Acquisition
bool* overWriteEnable; * @param anyPacketsCaught true if any packets are caught, else false
int* detIndex; * @param numf number of images caught
int* numUnitsPerDetector; */
uint64_t* numImages; virtual void EndofAcquisition(bool anyPacketsCaught, uint64_t numf) {
uint32_t* dynamicRange; LOG(logERROR) << "This is a generic function EndofAcquisition that "
uint32_t* udpPortNumber; "should be overloaded by a derived class";
bool* silentMode; }
protected:
bool master;
int index;
slsDetectorDefs::fileFormat formatType;
uint32_t *maxFramesPerFile;
std::string masterFileName;
std::string currentFileName;
int numDetX;
int numDetY;
std::string *fileNamePrefix;
std::string *filePath;
uint64_t *fileIndex;
uint64_t subFileIndex{0};
bool *overWriteEnable;
int *detIndex;
int *numUnitsPerDetector;
uint64_t *numImages;
uint32_t *dynamicRange;
uint32_t *udpPortNumber;
bool *silentMode;
}; };

1104
slsReceiverSoftware/src/GeneralData.h Executable file → Normal file

File diff suppressed because it is too large Load Diff

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

File diff suppressed because it is too large Load Diff

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

@ -6,90 +6,89 @@
* creates/closes the file and writes data to it * creates/closes the file and writes data to it
***********************************************/ ***********************************************/
/** /**
*@short sets/gets properties for the HDF5 file, creates/closes the file and writes data to it *@short sets/gets properties for the HDF5 file, creates/closes the file and
*writes data to it
*/ */
#include "File.h" #include "File.h"
#include "H5Cpp.h" #include "H5Cpp.h"
#ifndef H5_NO_NAMESPACE #ifndef H5_NO_NAMESPACE
using namespace H5; using namespace H5;
#endif #endif
#include <mutex> #include <mutex>
class HDF5File : private virtual slsDetectorDefs, public File { class HDF5File : private virtual slsDetectorDefs, public File {
public:
/**
* Constructor
* creates the File Writer
* @param ind self index
* @param maxf pointer to max frames per file
* @param nd pointer to number of detectors in each dimension
* @param fname pointer to file name prefix
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of theads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to udp port number for logging
* @param nx number of pixels in x direction
* @param ny number of pixels in y direction
* @param smode pointer to silent mode
*/
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();
void SetNumberofPixels(uint32_t nx, uint32_t ny);
void CreateFile();
void CloseCurrentFile();
void CloseAllFiles();
void WriteToFile(char* buffer, int bufferSize, uint64_t currentFrameNumber, uint32_t numPacketsCaught);
void CreateMasterFile(bool masterFileWriteEnable, masterAttributes& masterFileAttributes);
void EndofAcquisition(bool anyPacketsCaught, uint64_t numImagesCaught);
private: public:
/**
* Constructor
* creates the File Writer
* @param ind self index
* @param maxf pointer to max frames per file
* @param nd pointer to number of detectors in each dimension
* @param fname pointer to file name prefix
* @param fpath pointer to file path
* @param findex pointer to file index
* @param owenable pointer to over write enable
* @param dindex pointer to detector index
* @param nunits pointer to number of theads/ units per detector
* @param nf pointer to number of images in acquisition
* @param dr pointer to dynamic range
* @param portno pointer to udp port number for logging
* @param nx number of pixels in x direction
* @param ny number of pixels in y direction
* @param smode pointer to silent mode
*/
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();
void SetNumberofPixels(uint32_t nx, uint32_t ny);
void CreateFile();
void CloseCurrentFile();
void CloseAllFiles();
void WriteToFile(char *buffer, int bufferSize, uint64_t currentFrameNumber,
uint32_t numPacketsCaught);
void CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes);
void EndofAcquisition(bool anyPacketsCaught, uint64_t numImagesCaught);
void CloseFile(H5File*& fd, bool masterFile); private:
void WriteDataFile(uint64_t currentFrameNumber, char* buffer); void CloseFile(H5File *&fd, bool masterFile);
void WriteParameterDatasets(uint64_t currentFrameNumber, sls_receiver_header* rheader); void WriteDataFile(uint64_t currentFrameNumber, char *buffer);
void ExtendDataset(); void WriteParameterDatasets(uint64_t currentFrameNumber,
void CreateDataFile(); sls_receiver_header *rheader);
void CreateMasterDataFile(masterAttributes& masterFileAttributes); void ExtendDataset();
void CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf); void CreateDataFile();
void LinkVirtualInMaster(std::string fname, std::string dsetname); void CreateMasterDataFile(masterAttributes &masterFileAttributes);
hid_t GetDataTypeinC(DataType dtype); void CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf);
void LinkVirtualInMaster(std::string fname, std::string dsetname);
hid_t GetDataTypeinC(DataType dtype);
static std::mutex hdf5Lib; static std::mutex hdf5Lib;
H5File* masterfd; H5File *masterfd;
/** Virtual File handle ( only file name because /** Virtual File handle ( only file name because
code in C as H5Pset_virtual doesnt exist yet in C++) */ code in C as H5Pset_virtual doesnt exist yet in C++) */
hid_t virtualfd; hid_t virtualfd;
H5File* filefd; H5File *filefd;
DataSpace* dataspace; DataSpace *dataspace;
DataSet* dataset; DataSet *dataset;
DataType datatype; DataType datatype;
uint32_t nPixelsX; uint32_t nPixelsX;
uint32_t nPixelsY; uint32_t nPixelsY;
uint32_t numFramesInFile; uint32_t numFramesInFile;
uint64_t numActualPacketsInFile; uint64_t numActualPacketsInFile;
int numFilesinAcquisition; int numFilesinAcquisition;
std::vector <const char*> parameterNames; std::vector<const char *> parameterNames;
std::vector <DataType> parameterDataTypes; std::vector<DataType> parameterDataTypes;
DataSpace* dataspace_para; DataSpace *dataspace_para;
std::vector <DataSet*> dataset_para; std::vector<DataSet *> dataset_para;
uint64_t extNumImages;
uint64_t extNumImages;
}; };
#endif #endif

435
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
@ -82,7 +82,7 @@ void Implementation::InitializeMembers() {
udpPortNum.resize(MAX_NUMBER_OF_LISTENING_THREADS); udpPortNum.resize(MAX_NUMBER_OF_LISTENING_THREADS);
for (int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i) { for (int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i) {
eth[i] = ""; eth[i] = "";
udpPortNum[i] = DEFAULT_UDP_PORTNO + i; udpPortNum[i] = DEFAULT_UDP_PORTNO + i;
} }
udpSocketBufferSize = 0; udpSocketBufferSize = 0;
actualUDPSocketBufferSize = 0; actualUDPSocketBufferSize = 0;
@ -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
@ -201,15 +202,14 @@ 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) /
<< " MB"; (double)(1024 * 1024)
<< " 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
@ -253,10 +253,10 @@ void Implementation::setDetectorType(const detectorType d) {
break; break;
case MYTHEN3: case MYTHEN3:
generalData = new Mythen3Data(); generalData = new Mythen3Data();
break; break;
case GOTTHARD2: case GOTTHARD2:
generalData = new Gotthard2Data(); generalData = new Gotthard2Data();
break; break;
default: default:
break; break;
} }
@ -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) + ")");
} }
} }
@ -327,13 +328,13 @@ void Implementation::setMultiDetectorSize(const int *size) {
log_message += ")"; log_message += ")";
int nd[2] = {numDet[0], numDet[1]}; int nd[2] = {numDet[0], numDet[1]};
if (quadEnable) { if (quadEnable) {
nd[0] = 1; nd[0] = 1;
nd[1] = 2; nd[1] = 2;
} }
for (const auto &it : dataStreamer) { for (const auto &it : dataStreamer) {
it->SetNumberofDetectors(nd); it->SetNumberofDetectors(nd);
} }
LOG(logINFO) << log_message; LOG(logINFO) << log_message;
} }
@ -349,14 +350,14 @@ void Implementation::setDetectorPositionId(const int id) {
LOG(logINFO) << "Detector Position Id:" << detID; LOG(logINFO) << "Detector Position Id:" << detID;
// update zmq port // update zmq port
streamingPort = DEFAULT_ZMQ_RX_PORTNO + streamingPort =
(detID * (myDetectorType == EIGER ? 2 : 1)); DEFAULT_ZMQ_RX_PORTNO + (detID * (myDetectorType == EIGER ? 2 : 1));
for (unsigned int i = 0; i < dataProcessor.size(); ++i) { for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->SetupFileWriter( dataProcessor[i]->SetupFileWriter(
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, &filePath, fileWriteEnable, (int *)numDet, &framesPerFile, &fileName,
&fileIndex, &overwriteEnable, &detID, &numThreads, &numberOfTotalFrames, &filePath, &fileIndex, &overwriteEnable, &detID, &numThreads,
&dynamicRange, &udpPortNum[i], generalData); &numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData);
} }
assert(numDet[1] != 0); assert(numDet[1] != 0);
for (unsigned int i = 0; i < listener.size(); ++i) { for (unsigned int i = 0; i < listener.size(); ++i) {
@ -373,7 +374,7 @@ std::string Implementation::getDetectorHostname() const {
return detHostname; return detHostname;
} }
void Implementation::setDetectorHostname(const std::string& c) { void Implementation::setDetectorHostname(const std::string &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
if (!c.empty()) if (!c.empty())
@ -412,15 +413,13 @@ Implementation::getFrameDiscardPolicy() const {
return frameDiscardMode; return frameDiscardMode;
} }
void Implementation::setFrameDiscardPolicy( void Implementation::setFrameDiscardPolicy(const frameDiscardPolicy i) {
const frameDiscardPolicy i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
if (i >= 0 && i < NUM_DISCARD_POLICIES) if (i >= 0 && i < NUM_DISCARD_POLICIES)
frameDiscardMode = i; frameDiscardMode = i;
LOG(logINFO) << "Frame Discard Policy: " LOG(logINFO) << "Frame Discard Policy: " << sls::ToString(frameDiscardMode);
<< sls::ToString(frameDiscardMode);
} }
bool Implementation::getFramePaddingEnable() const { bool Implementation::getFramePaddingEnable() const {
@ -435,7 +434,6 @@ void Implementation::setFramePaddingEnable(const bool i) {
LOG(logINFO) << "Frame Padding: " << framePadding; LOG(logINFO) << "Frame Padding: " << framePadding;
} }
/************************************************** /**************************************************
* * * *
* File Parameters * * File Parameters *
@ -469,11 +467,11 @@ std::string Implementation::getFilePath() const {
return filePath; return filePath;
} }
void Implementation::setFilePath(const std::string& c) { void Implementation::setFilePath(const std::string &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
if (!c.empty()) { if (!c.empty()) {
mkdir_p(c); //throws if it can't create mkdir_p(c); // throws if it can't create
filePath = c; filePath = c;
} }
LOG(logINFO) << "File path: " << filePath; LOG(logINFO) << "File path: " << filePath;
@ -484,11 +482,11 @@ std::string Implementation::getFileName() const {
return fileName; return fileName;
} }
void Implementation::setFileName(const std::string& c) { void Implementation::setFileName(const std::string &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
if (!c.empty()) if (!c.empty())
fileName = c; fileName = c;
LOG(logINFO) << "File name: " << fileName; LOG(logINFO) << "File name: " << fileName;
} }
@ -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 {
@ -532,7 +532,7 @@ void Implementation::setMasterFileWriteEnable(const bool b) {
masterFileWriteEnable = b; masterFileWriteEnable = b;
LOG(logINFO) << "Master File Write Enable: " LOG(logINFO) << "Master File Write Enable: "
<< (masterFileWriteEnable ? "enabled" : "disabled"); << (masterFileWriteEnable ? "enabled" : "disabled");
} }
bool Implementation::getOverwriteEnable() const { bool Implementation::getOverwriteEnable() 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 *
@ -577,7 +577,7 @@ uint64_t Implementation::getFramesCaught() const {
for (const auto &it : dataProcessor) { for (const auto &it : dataProcessor) {
flagsum += it->GetStartedFlag(); flagsum += it->GetStartedFlag();
uint64_t curr = it->GetNumFramesCaught(); uint64_t curr = it->GetNumFramesCaught();
min = curr < min ? curr : min; min = curr < min ? curr : min;
} }
// no data processed // no data processed
if (flagsum != dataProcessor.size()) if (flagsum != dataProcessor.size())
@ -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 {
@ -628,7 +629,7 @@ std::vector<uint64_t> Implementation::getNumMissingPackets() const {
// partial readout // partial readout
if (numLinesReadout != MAX_EIGER_ROWS_PER_READOUT) { if (numLinesReadout != MAX_EIGER_ROWS_PER_READOUT) {
totnp = ((numLinesReadout * np) / MAX_EIGER_ROWS_PER_READOUT); totnp = ((numLinesReadout * np) / MAX_EIGER_ROWS_PER_READOUT);
} }
totnp *= numberOfTotalFrames; totnp *= numberOfTotalFrames;
mp[i] = listener[i]->GetNumMissingPacket(stoppedFlag, totnp); mp[i] = listener[i]->GetNumMissingPacket(stoppedFlag, totnp);
} }
@ -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,16 +731,15 @@ 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
"Summary of Port " << udpPortNum[i] "Summary of Port " << udpPortNum[i]
<< "\n\tMissing Packets\t\t: " << mp[i] << "\n\tMissing Packets\t\t: " << mp[i]
<< "\n\tComplete Frames\t\t: " << nf << "\n\tComplete Frames\t\t: " << nf
<< "\n\tLast Frame Caught\t: " << "\n\tLast Frame Caught\t: "
<< listener[i]->GetLastFrameIndexCaught(); << listener[i]->GetLastFrameIndexCaught();
} }
if (!activated) { if (!activated) {
LOG(logINFORED) << "Deactivated Receiver"; LOG(logINFORED) << "Deactivated Receiver";
@ -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)
@ -785,7 +783,7 @@ void Implementation::startReadout() {
totalPacketsReceived += it->GetPacketsCaught(); totalPacketsReceived += it->GetPacketsCaught();
LOG(logDEBUG3) << "\tupdated: totalPacketsReceived:" LOG(logDEBUG3) << "\tupdated: totalPacketsReceived:"
<< totalPacketsReceived; << totalPacketsReceived;
} }
} }
status = TRANSMITTING; status = TRANSMITTING;
@ -808,8 +806,7 @@ void Implementation::closeFiles() {
bool anycaught = false; bool anycaught = false;
for (const auto &it : dataProcessor) { for (const auto &it : dataProcessor) {
it->CloseFiles(); it->CloseFiles();
maxIndexCaught = maxIndexCaught = std::max(maxIndexCaught, it->GetProcessedIndex());
std::max(maxIndexCaught, it->GetProcessedIndex());
if (it->GetStartedFlag()) if (it->GetStartedFlag())
anycaught = true; anycaught = true;
} }
@ -846,11 +843,11 @@ void Implementation::ResetParametersforNewAcquisition() {
void Implementation::CreateUDPSockets() { void Implementation::CreateUDPSockets() {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
try{ try {
for (unsigned int i = 0; i < listener.size(); ++i) { for (unsigned int i = 0; i < listener.size(); ++i) {
listener[i]->CreateUDPSockets(); listener[i]->CreateUDPSockets();
} }
} catch(const sls::RuntimeError &e) { } catch (const sls::RuntimeError &e) {
shutDownUDPSockets(); shutDownUDPSockets();
throw sls::RuntimeError("Could not create UDP Socket(s)."); throw sls::RuntimeError("Could not create UDP Socket(s).");
} }
@ -860,22 +857,26 @@ void Implementation::CreateUDPSockets() {
void Implementation::SetupWriter() { void Implementation::SetupWriter() {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
masterAttributes attr; masterAttributes attr;
attr.detectorType = myDetectorType; attr.detectorType = myDetectorType;
attr.dynamicRange = dynamicRange; attr.dynamicRange = dynamicRange;
attr.tenGiga = tengigaEnable; attr.tenGiga = tengigaEnable;
attr.imageSize = generalData->imageSize; attr.imageSize = generalData->imageSize;
attr.nPixelsX = generalData->nPixelsX; attr.nPixelsX = generalData->nPixelsX;
attr.nPixelsY = generalData->nPixelsY; attr.nPixelsY = generalData->nPixelsY;
attr.maxFramesPerFile = framesPerFile; attr.maxFramesPerFile = framesPerFile;
attr.totalFrames = numberOfTotalFrames; attr.totalFrames = numberOfTotalFrames;
attr.exptimeNs = acquisitionTime; attr.exptimeNs = acquisitionTime;
attr.subExptimeNs = subExpTime; attr.subExptimeNs = subExpTime;
attr.subPeriodNs = subPeriod; attr.subPeriodNs = subPeriod;
attr.periodNs = acquisitionPeriod; attr.periodNs = acquisitionPeriod;
attr.quadEnable = quadEnable; attr.quadEnable = quadEnable;
attr.analogFlag = (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0; attr.analogFlag =
attr.digitalFlag = (readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0; (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
: 0;
attr.digitalFlag =
(readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1
: 0;
attr.adcmask = tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga; attr.adcmask = tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
attr.dbitoffset = ctbDbitOffset; attr.dbitoffset = ctbDbitOffset;
attr.dbitlist = 0; attr.dbitlist = 0;
@ -889,7 +890,7 @@ void Implementation::SetupWriter() {
for (unsigned int i = 0; i < dataProcessor.size(); ++i) { for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->CreateNewFile(attr); dataProcessor[i]->CreateNewFile(attr);
} }
} catch(const sls::RuntimeError &e) { } catch (const sls::RuntimeError &e) {
shutDownUDPSockets(); shutDownUDPSockets();
closeFiles(); closeFiles();
throw sls::RuntimeError("Could not create file."); throw sls::RuntimeError("Could not create file.");
@ -914,7 +915,6 @@ void Implementation::StartRunning() {
} }
} }
/************************************************** /**************************************************
* * * *
* Network Configuration (UDP) * * Network Configuration (UDP) *
@ -967,15 +967,17 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
dataProcessor.push_back(sls::make_unique<DataProcessor>( dataProcessor.push_back(sls::make_unique<DataProcessor>(
i, myDetectorType, fifo_ptr, &fileFormatType, i, myDetectorType, fifo_ptr, &fileFormatType,
fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable, fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable,
&dynamicRange, &streamingFrequency, &dynamicRange, &streamingFrequency, &streamingTimerInMs,
&streamingTimerInMs, &framePadding, &activated, &framePadding, &activated, &deactivatedPaddingEnable,
&deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList, &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset,
&ctbDbitOffset, &ctbAnalogDataBytes)); &ctbAnalogDataBytes));
dataProcessor[i]->SetGeneralData(generalData); dataProcessor[i]->SetGeneralData(generalData);
} catch (...) { } catch (...) {
listener.clear(); listener.clear();
dataProcessor.clear(); dataProcessor.clear();
throw sls::RuntimeError("Could not create listener/dataprocessor threads (index:" + std::to_string(i) + ")"); throw sls::RuntimeError(
"Could not create listener/dataprocessor threads (index:" +
std::to_string(i) + ")");
} }
// streamer threads // streamer threads
if (dataStreamEnable) { if (dataStreamEnable) {
@ -988,19 +990,22 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
nd[1] = 2; nd[1] = 2;
} }
dataStreamer.push_back(sls::make_unique<DataStreamer>( dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, fd,
fd, (int*)nd, &quadEnable, &numberOfTotalFrames)); (int *)nd, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets( dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP); &numThreads, streamingPort, streamingSrcIP);
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader); dataStreamer[i]->SetAdditionalJsonHeader(
additionalJsonHeader);
} catch (...) { } catch (...) {
if (dataStreamEnable) { if (dataStreamEnable) {
dataStreamer.clear(); dataStreamer.clear();
dataStreamEnable = false; dataStreamEnable = false;
} }
throw sls::RuntimeError("Could not create datastreamer threads (index:" + std::to_string(i) + ")"); throw sls::RuntimeError(
"Could not create datastreamer threads (index:" +
std::to_string(i) + ")");
} }
} }
} }
@ -1089,7 +1094,9 @@ void Implementation::setUDPSocketBufferSize(const int64_t s) {
size_t listSize = listener.size(); size_t listSize = listener.size();
if (myDetectorType == JUNGFRAU && (int)listSize != numUDPInterfaces) { if (myDetectorType == JUNGFRAU && (int)listSize != numUDPInterfaces) {
throw sls::RuntimeError("Number of Interfaces " + std::to_string(numUDPInterfaces) + " do not match listener size " + std::to_string(listSize)); throw sls::RuntimeError(
"Number of Interfaces " + std::to_string(numUDPInterfaces) +
" do not match listener size " + std::to_string(listSize));
} }
for (unsigned int i = 0; i < listSize; ++i) { for (unsigned int i = 0; i < listSize; ++i) {
@ -1102,7 +1109,6 @@ int64_t Implementation::getActualUDPSocketBufferSize() const {
return actualUDPSocketBufferSize; return actualUDPSocketBufferSize;
} }
/************************************************** /**************************************************
* * * *
* ZMQ Streaming Parameters (ZMQ) * * ZMQ Streaming Parameters (ZMQ) *
@ -1132,16 +1138,18 @@ void Implementation::setDataStreamEnable(const bool enable) {
nd[1] = 2; nd[1] = 2;
} }
dataStreamer.push_back(sls::make_unique<DataStreamer>( dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, fd,
fd, (int*)nd, &quadEnable, &numberOfTotalFrames)); (int *)nd, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets( dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP); &numThreads, streamingPort, streamingSrcIP);
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader); dataStreamer[i]->SetAdditionalJsonHeader(
additionalJsonHeader);
} catch (...) { } catch (...) {
dataStreamer.clear(); dataStreamer.clear();
dataStreamEnable = false; dataStreamEnable = false;
throw sls::RuntimeError("Could not set data stream enable."); throw sls::RuntimeError(
"Could not set data stream enable.");
} }
} }
SetThreadPriorities(); SetThreadPriorities();
@ -1196,54 +1204,65 @@ void Implementation::setStreamingSourceIP(const sls::IpAddr ip) {
LOG(logINFO) << "Streaming Source IP: " << streamingSrcIP; LOG(logINFO) << "Streaming Source IP: " << streamingSrcIP;
} }
std::map<std::string, std::string> Implementation::getAdditionalJsonHeader() const { std::map<std::string, std::string>
Implementation::getAdditionalJsonHeader() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
return additionalJsonHeader; return additionalJsonHeader;
} }
void Implementation::setAdditionalJsonHeader(const std::map<std::string, std::string> &c) { void Implementation::setAdditionalJsonHeader(
const std::map<std::string, std::string> &c) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
additionalJsonHeader = c; additionalJsonHeader = c;
for (const auto &it : dataStreamer) { for (const auto &it : dataStreamer) {
it->SetAdditionalJsonHeader(c); it->SetAdditionalJsonHeader(c);
} }
LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader); LOG(logINFO) << "Additional JSON Header: "
<< sls::ToString(additionalJsonHeader);
} }
std::string Implementation::getAdditionalJsonParameter(const std::string &key) const { std::string
Implementation::getAdditionalJsonParameter(const std::string &key) const {
if (additionalJsonHeader.find(key) != additionalJsonHeader.end()) { if (additionalJsonHeader.find(key) != additionalJsonHeader.end()) {
return additionalJsonHeader.at(key); return additionalJsonHeader.at(key);
} }
throw sls::RuntimeError("No key " + key + " found in additional json header"); throw sls::RuntimeError("No key " + key +
" found in additional json header");
} }
void Implementation::setAdditionalJsonParameter(const std::string &key, const std::string &value) { void Implementation::setAdditionalJsonParameter(const std::string &key,
const std::string &value) {
auto pos = additionalJsonHeader.find(key); auto pos = additionalJsonHeader.find(key);
// if value is empty, delete // if value is empty, delete
if (value.empty()) { if (value.empty()) {
// doesnt exist // doesnt exist
if (pos == additionalJsonHeader.end()) { if (pos == additionalJsonHeader.end()) {
LOG(logINFO) << "Additional json parameter (" << key << ") does not exist anyway"; LOG(logINFO) << "Additional json parameter (" << key
<< ") does not exist anyway";
} else { } else {
LOG(logINFO) << "Deleting additional json parameter (" << key << ")"; LOG(logINFO) << "Deleting additional json parameter (" << key
<< ")";
additionalJsonHeader.erase(pos); additionalJsonHeader.erase(pos);
} }
} }
// if found, set it // if found, set it
else if (pos != additionalJsonHeader.end()) { else if (pos != additionalJsonHeader.end()) {
additionalJsonHeader[key] = value; additionalJsonHeader[key] = value;
LOG(logINFO) << "Setting additional json parameter (" << key << ") to " << value; LOG(logINFO) << "Setting additional json parameter (" << key << ") to "
} << value;
}
// append if not found // append if not found
else { else {
additionalJsonHeader[key] = value; additionalJsonHeader[key] = value;
LOG(logINFO) << "Adding additional json parameter (" << key << ") to " << value; LOG(logINFO) << "Adding additional json parameter (" << key << ") to "
<< value;
} }
for (const auto &it : dataStreamer) { for (const auto &it : dataStreamer) {
it->SetAdditionalJsonHeader(additionalJsonHeader); it->SetAdditionalJsonHeader(additionalJsonHeader);
} }
LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader); LOG(logINFO) << "Additional JSON Header: "
<< sls::ToString(additionalJsonHeader);
} }
/************************************************** /**************************************************
@ -1253,18 +1272,18 @@ void Implementation::setAdditionalJsonParameter(const std::string &key, const st
* ************************************************/ * ************************************************/
void Implementation::updateTotalNumberOfFrames() { void Implementation::updateTotalNumberOfFrames() {
int64_t repeats = numberOfTriggers; int64_t repeats = numberOfTriggers;
// gotthard2: auto mode // gotthard2: auto mode
// burst mode: (bursts instead of triggers) // burst mode: (bursts instead of triggers)
// non burst mode: no bursts or triggers // non burst mode: no bursts or triggers
if (myDetectorType == GOTTHARD2 &&timingMode == AUTO_TIMING) { if (myDetectorType == GOTTHARD2 && timingMode == AUTO_TIMING) {
if (burstMode == BURST_OFF) { if (burstMode == BURST_OFF) {
repeats = numberOfBursts; repeats = numberOfBursts;
} else { } else {
repeats = 1; repeats = 1;
} }
} }
numberOfTotalFrames = numberOfFrames * repeats * numberOfTotalFrames = numberOfFrames * repeats *
(int64_t)(numberOfAdditionalStorageCells + 1); (int64_t)(numberOfAdditionalStorageCells + 1);
if (numberOfTotalFrames == 0) { if (numberOfTotalFrames == 0) {
throw sls::RuntimeError("Invalid total number of frames to receive: 0"); throw sls::RuntimeError("Invalid total number of frames to receive: 0");
} }
@ -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 {
@ -1366,7 +1386,7 @@ void Implementation::setAcquisitionTime(const uint64_t i) {
acquisitionTime = i; acquisitionTime = i;
LOG(logINFO) << "Acquisition Time: " << (double)acquisitionTime / (1E9) LOG(logINFO) << "Acquisition Time: " << (double)acquisitionTime / (1E9)
<< "s"; << "s";
} }
uint64_t Implementation::getSubExpTime() const { uint64_t Implementation::getSubExpTime() 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 {
@ -1405,17 +1423,16 @@ void Implementation::setNumberofAnalogSamples(const uint32_t i) {
numberOfAnalogSamples = i; numberOfAnalogSamples = 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 {
@ -1428,18 +1445,16 @@ void Implementation::setNumberofDigitalSamples(const uint32_t i) {
numberOfDigitalSamples = i; numberOfDigitalSamples = 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 {
@ -1523,9 +1538,9 @@ void Implementation::setTenGigaEnable(const bool b) {
case MOENCH: case MOENCH:
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 {
@ -1547,47 +1561,46 @@ void Implementation::setFlippedDataX(int enable) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
flippedDataX = (enable == 0) ? 0 : 1; flippedDataX = (enable == 0) ? 0 : 1;
if (!quadEnable) { if (!quadEnable) {
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); }
} }
}
LOG(logINFO) << "Flipped Data X: " << flippedDataX; LOG(logINFO) << "Flipped Data X: " << flippedDataX;
} }
bool Implementation::getQuad() const { bool Implementation::getQuad() const {
LOG(logDEBUG) << __AT__ << " starting"; LOG(logDEBUG) << __AT__ << " starting";
return quadEnable; return quadEnable;
} }
void Implementation::setQuad(const bool b) { void Implementation::setQuad(const bool b) {
if (quadEnable != b) { if (quadEnable != b) {
quadEnable = b; quadEnable = b;
if (!quadEnable) { if (!quadEnable) {
for (const auto &it : dataStreamer) { for (const auto &it : dataStreamer) {
it->SetNumberofDetectors(numDet); it->SetNumberofDetectors(numDet);
it->SetFlippedDataX(flippedDataX); it->SetFlippedDataX(flippedDataX);
} }
} else { } else {
int size[2] = {1, 2}; int size[2] = {1, 2};
for (const auto &it : dataStreamer) { for (const auto &it : dataStreamer) {
it->SetNumberofDetectors(size); it->SetNumberofDetectors(size);
} }
if (dataStreamer.size() == 2) { if (dataStreamer.size() == 2) {
dataStreamer[0]->SetFlippedDataX(0); dataStreamer[0]->SetFlippedDataX(0);
dataStreamer[1]->SetFlippedDataX(1); dataStreamer[1]->SetFlippedDataX(1);
} }
} }
} }
LOG(logINFO) << "Quad Enable: " << quadEnable; LOG(logINFO) << "Quad Enable: " << quadEnable;
} }
bool Implementation::getActivate() const { bool Implementation::getActivate() const {
@ -1611,22 +1624,21 @@ bool Implementation::setDeactivatedPadding(bool enable) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
deactivatedPaddingEnable = enable; deactivatedPaddingEnable = enable;
LOG(logINFO) << "Deactivated Padding Enable: " LOG(logINFO) << "Deactivated Padding Enable: "
<< (deactivatedPaddingEnable ? "enabled" : "disabled"); << (deactivatedPaddingEnable ? "enabled" : "disabled");
return deactivatedPaddingEnable; return deactivatedPaddingEnable;
} }
int Implementation::getReadNLines() const { int Implementation::getReadNLines() const {
LOG(logDEBUG) << __AT__ << " starting"; LOG(logDEBUG) << __AT__ << " starting";
return numLinesReadout; return numLinesReadout;
} }
void Implementation::setReadNLines(const int value) { void Implementation::setReadNLines(const int value) {
numLinesReadout = value; numLinesReadout = 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;
} }
@ -1637,17 +1649,16 @@ 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 {
@ -1660,19 +1671,18 @@ void Implementation::setADCEnableMask(uint32_t mask) {
adcEnableMaskOneGiga = mask; adcEnableMaskOneGiga = 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 {
@ -1685,19 +1695,18 @@ void Implementation::setTenGigaADCEnableMask(uint32_t mask) {
adcEnableMaskTenGiga = mask; adcEnableMaskTenGiga = 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);
} }

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

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "container_utils.h" #include "container_utils.h"
#include "logger.h" #include "logger.h"
#include "receiver_defs.h"
#include "network_utils.h" #include "network_utils.h"
#include "receiver_defs.h"
class GeneralData; class GeneralData;
class Listener; class Listener;
class DataProcessor; class DataProcessor;
@ -12,9 +12,9 @@ class slsDetectorDefs;
#include <atomic> #include <atomic>
#include <exception> #include <exception>
#include <map>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <map>
class Implementation : private virtual slsDetectorDefs { class Implementation : private virtual slsDetectorDefs {
public: public:
@ -33,7 +33,7 @@ class Implementation : private virtual slsDetectorDefs {
int getDetectorPositionId() const; int getDetectorPositionId() const;
void setDetectorPositionId(const int id); void setDetectorPositionId(const int id);
std::string getDetectorHostname() const; std::string getDetectorHostname() const;
void setDetectorHostname(const std::string& c); void setDetectorHostname(const std::string &c);
bool getSilentMode() const; bool getSilentMode() const;
void setSilentMode(const bool i); void setSilentMode(const bool i);
uint32_t getFifoDepth() const; uint32_t getFifoDepth() const;
@ -52,9 +52,9 @@ class Implementation : private virtual slsDetectorDefs {
void setFileFormat(slsDetectorDefs::fileFormat f); void setFileFormat(slsDetectorDefs::fileFormat f);
std::string getFilePath() const; std::string getFilePath() const;
/* check for existence */ /* check for existence */
void setFilePath(const std::string& c); void setFilePath(const std::string &c);
std::string getFileName() const; std::string getFileName() const;
void setFileName(const std::string& c); void setFileName(const std::string &c);
uint64_t getFileIndex() const; uint64_t getFileIndex() const;
void setFileIndex(const uint64_t i); void setFileIndex(const uint64_t i);
bool getFileWriteEnable() const; bool getFileWriteEnable() const;
@ -85,7 +85,6 @@ class Implementation : private virtual slsDetectorDefs {
void closeFiles(); void closeFiles();
void restreamStop(); void restreamStop();
/************************************************** /**************************************************
* * * *
* Network Configuration (UDP) * * Network Configuration (UDP) *
@ -106,8 +105,7 @@ class Implementation : private virtual slsDetectorDefs {
void setUDPPortNumber2(const uint32_t i); void setUDPPortNumber2(const uint32_t i);
int64_t getUDPSocketBufferSize() const; int64_t getUDPSocketBufferSize() const;
void setUDPSocketBufferSize(const int64_t s); void setUDPSocketBufferSize(const int64_t s);
int64_t getActualUDPSocketBufferSize() const; int64_t getActualUDPSocketBufferSize() const;
/************************************************** /**************************************************
* * * *
@ -117,18 +115,19 @@ class Implementation : private virtual slsDetectorDefs {
bool getDataStreamEnable() const; bool getDataStreamEnable() const;
void setDataStreamEnable(const bool enable); void setDataStreamEnable(const bool enable);
uint32_t getStreamingFrequency() const; uint32_t getStreamingFrequency() const;
/* 0 for timer */ /* 0 for timer */
void setStreamingFrequency(const uint32_t freq); void setStreamingFrequency(const uint32_t freq);
uint32_t getStreamingTimer() const; uint32_t getStreamingTimer() const;
void setStreamingTimer(const uint32_t time_in_ms); void setStreamingTimer(const uint32_t time_in_ms);
uint32_t getStreamingPort() const; uint32_t getStreamingPort() const;
void setStreamingPort(const uint32_t i); void setStreamingPort(const uint32_t i);
sls::IpAddr getStreamingSourceIP() const; sls::IpAddr getStreamingSourceIP() const;
void setStreamingSourceIP(const sls::IpAddr ip); void setStreamingSourceIP(const sls::IpAddr ip);
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);
/************************************************** /**************************************************
* * * *
@ -172,7 +171,7 @@ class Implementation : private virtual slsDetectorDefs {
/* [Gotthard] */ /* [Gotthard] */
void setROI(ROI arg); void setROI(ROI arg);
bool getTenGigaEnable() const; bool getTenGigaEnable() const;
/* [Eiger][Ctb] */ /* [Eiger][Ctb] */
void setTenGigaEnable(const bool b); void setTenGigaEnable(const bool b);
int getFlippedDataX() const; int getFlippedDataX() const;
void setFlippedDataX(int enable = -1); void setFlippedDataX(int enable = -1);
@ -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] */
@ -196,7 +196,7 @@ class Implementation : private virtual slsDetectorDefs {
void setADCEnableMask(const uint32_t mask); void setADCEnableMask(const uint32_t mask);
uint32_t getTenGigaADCEnableMask() const; uint32_t getTenGigaADCEnableMask() const;
/* [Ctb][Moench] */ /* [Ctb][Moench] */
void setTenGigaADCEnableMask(const uint32_t mask); void setTenGigaADCEnableMask(const uint32_t mask);
std::vector<int> getDbitList() const; std::vector<int> getDbitList() const;
/* [Ctb] */ /* [Ctb] */
void setDbitList(const std::vector<int> v); void setDbitList(const std::vector<int> v);
@ -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();
@ -224,19 +228,18 @@ class Implementation : private virtual slsDetectorDefs {
void SetLocalNetworkParameters(); void SetLocalNetworkParameters();
void SetThreadPriorities(); void SetThreadPriorities();
void SetupFifoStructure(); void SetupFifoStructure();
void ResetParametersforNewAcquisition(); void ResetParametersforNewAcquisition();
void CreateUDPSockets(); void CreateUDPSockets();
void SetupWriter(); void SetupWriter();
void StartRunning(); void StartRunning();
/************************************************** /**************************************************
* * * *
* Class Members * * Class Members *
* * * *
* ************************************************/ * ************************************************/
// config parameters // config parameters
int numThreads; int numThreads;
detectorType myDetectorType; detectorType myDetectorType;
@ -264,8 +267,8 @@ class Implementation : private virtual slsDetectorDefs {
// network configuration (UDP) // network configuration (UDP)
int numUDPInterfaces; int numUDPInterfaces;
std::vector <std::string> eth; std::vector<std::string> eth;
std::vector <uint32_t> udpPortNum; std::vector<uint32_t> udpPortNum;
int64_t udpSocketBufferSize; int64_t udpSocketBufferSize;
int64_t actualUDPSocketBufferSize; int64_t actualUDPSocketBufferSize;
@ -296,19 +299,20 @@ class Implementation : private virtual slsDetectorDefs {
ROI roi; ROI roi;
bool tengigaEnable; bool tengigaEnable;
int flippedDataX; int flippedDataX;
bool quadEnable; bool quadEnable;
bool activated; bool activated;
bool deactivatedPaddingEnable; bool deactivatedPaddingEnable;
int numLinesReadout; int numLinesReadout;
readoutMode readoutType; readoutMode readoutType;
uint32_t adcEnableMaskOneGiga; uint32_t adcEnableMaskOneGiga;
uint32_t adcEnableMaskTenGiga; uint32_t adcEnableMaskTenGiga;
std::vector<int> ctbDbitList; std::vector<int> ctbDbitList;
int ctbDbitOffset; int ctbDbitOffset;
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;

933
slsReceiverSoftware/src/Listener.cpp Executable file → Normal file

File diff suppressed because it is too large Load Diff

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

@ -9,88 +9,89 @@
*@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;
class Listener : private virtual slsDetectorDefs, public ThreadObject { class Listener : private virtual slsDetectorDefs, public ThreadObject {
public:
/**
* Constructor
* Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofListerners
* @param ind self index
* @param dtype detector type
* @param f address of Fifo pointer
* @param s pointer to receiver status
* @param portno pointer to udp port number
* @param e ethernet interface
* @param nf pointer to number of images to catch
* @param dr pointer to dynamic range
* @param us pointer to udp socket buffer size
* @param as pointer to actual udp socket buffer size
* @param fpf pointer to frames per file
* @param fdp frame discard policy
* @param act pointer to activated
* @param depaden pointer to deactivated padding enable
* @param sm pointer to silent mode
*/
Listener(int ind, detectorType dtype, Fifo* f, std::atomic<runStatus>* s,
uint32_t* portno, std::string* e, uint64_t* nf, uint32_t* dr,
int64_t* us, int64_t* as, uint32_t* fpf,
frameDiscardPolicy* fdp, bool* act, bool* depaden, bool* sm);
/** public:
* Destructor /**
* Calls Base Class DestroyThread() and decrements NumberofListerners * Constructor
*/ * Calls Base Class CreateThread(), sets ErrorMask if error and increments
~Listener(); * NumberofListerners
* @param ind self index
* @param dtype detector type
* @param f address of Fifo pointer
* @param s pointer to receiver status
* @param portno pointer to udp port number
* @param e ethernet interface
* @param nf pointer to number of images to catch
* @param dr pointer to dynamic range
* @param us pointer to udp socket buffer size
* @param as pointer to actual udp socket buffer size
* @param fpf pointer to frames per file
* @param fdp frame discard policy
* @param act pointer to activated
* @param depaden pointer to deactivated padding enable
* @param sm pointer to silent mode
*/
Listener(int ind, detectorType dtype, Fifo *f, std::atomic<runStatus> *s,
uint32_t *portno, std::string *e, uint64_t *nf, uint32_t *dr,
int64_t *us, int64_t *as, uint32_t *fpf, frameDiscardPolicy *fdp,
bool *act, bool *depaden, bool *sm);
/** /**
* Get Packets caught * Destructor
* @return Packets caught * Calls Base Class DestroyThread() and decrements NumberofListerners
*/ */
uint64_t GetPacketsCaught() const; ~Listener();
/** /**
* Get Last Frame index caught * Get Packets caught
* @return last frame index caught * @return Packets caught
*/ */
uint64_t GetLastFrameIndexCaught() const; uint64_t GetPacketsCaught() const;
/** Get number of missing packets */ /**
uint64_t GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const; * Get Last Frame index caught
* @return last frame index caught
*/
uint64_t GetLastFrameIndexCaught() const;
/** /** Get number of missing packets */
* Set Fifo pointer to the one given uint64_t GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const;
* @param f address of Fifo pointer
*/
void SetFifo(Fifo* f);
/** /**
* Reset parameters for new acquisition * Set Fifo pointer to the one given
*/ * @param f address of Fifo pointer
void ResetParametersforNewAcquisition(); */
void SetFifo(Fifo *f);
/** /**
* Set GeneralData pointer to the one given * Reset parameters for new acquisition
* @param g address of GeneralData (Detector Data) pointer */
*/ void ResetParametersforNewAcquisition();
void SetGeneralData(GeneralData* g);
/** /**
* Creates UDP Sockets * Set GeneralData pointer to the one given
*/ * @param g address of GeneralData (Detector Data) pointer
void CreateUDPSockets(); */
void SetGeneralData(GeneralData *g);
/** /**
* Shuts down and deletes UDP Sockets * Creates UDP Sockets
*/ */
void ShutDownUDPSocket(); void CreateUDPSockets();
/**
* Shuts down and deletes UDP Sockets
*/
void ShutDownUDPSocket();
/** /**
* Create & closes a dummy UDP socket * Create & closes a dummy UDP socket
@ -102,148 +103,147 @@ 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:
/**
* Record First Acquisition Index
* @param fnum frame index to record
*/
void RecordFirstIndex(uint64_t fnum);
private: /**
* Thread Execution for Listener Class
* Pop free addresses, listen to udp socket,
* write to memory & push the address into fifo
*/
void ThreadExecution() override;
/** /**
* Record First Acquisition Index * Pushes non empty buffers into fifo/ frees empty buffer,
* @param fnum frame index to record * pushes dummy buffer into fifo
*/ * and reset running mask by calling StopRunning()
void RecordFirstIndex(uint64_t fnum); * @param buf address of buffer
*/
void StopListening(char *buf);
/** /**
* Thread Execution for Listener Class * Listen to the UDP Socket for an image,
* Pop free addresses, listen to udp socket, * place them in the right order
* write to memory & push the address into fifo * @param buffer
*/ * @returns number of bytes of relevant data, can be image size or 0 (stop
void ThreadExecution() override; * acquisition) or -1 to discard image
*/
uint32_t ListenToAnImage(char *buf);
/** /**
* Pushes non empty buffers into fifo/ frees empty buffer, * Print Fifo Statistics
* pushes dummy buffer into fifo */
* and reset running mask by calling StopRunning() void PrintFifoStatistics();
* @param buf address of buffer
*/
void StopListening(char* buf);
/** /** type of thread */
* Listen to the UDP Socket for an image, static const std::string TypeName;
* place them in the right order
* @param buffer
* @returns number of bytes of relevant data, can be image size or 0 (stop acquisition)
* or -1 to discard image
*/
uint32_t ListenToAnImage(char* buf);
/** /** GeneralData (Detector Data) object */
* Print Fifo Statistics GeneralData *generalData{nullptr};
*/
void PrintFifoStatistics();
/** type of thread */ /** Fifo structure */
static const std::string TypeName; Fifo *fifo;
/** GeneralData (Detector Data) object */ // individual members
GeneralData* generalData{nullptr}; /** Detector Type */
detectorType myDetectorType;
/** Fifo structure */ /** Receiver Status */
Fifo* fifo; std::atomic<runStatus> *status;
// individual members /** UDP Socket - Detector to Receiver */
/** Detector Type */ std::unique_ptr<sls::UdpRxSocket> udpSocket{nullptr};
detectorType myDetectorType;
/** Receiver Status */ /** UDP Port Number */
std::atomic<runStatus>* status; uint32_t *udpPortNumber;
/** UDP Socket - Detector to Receiver */ /** ethernet interface */
std::unique_ptr<sls::UdpRxSocket> udpSocket{nullptr}; std::string *eth;
/** UDP Port Number */ /** Number of Images to catch */
uint32_t* udpPortNumber; uint64_t *numImages;
/** ethernet interface */ /** Dynamic Range */
std::string* eth; uint32_t *dynamicRange;
/** Number of Images to catch */ /** UDP Socket Buffer Size */
uint64_t* numImages; int64_t *udpSocketBufferSize;
/** Dynamic Range */ /** actual UDP Socket Buffer Size (double due to kernel bookkeeping) */
uint32_t* dynamicRange; int64_t *actualUDPSocketBufferSize;
/** UDP Socket Buffer Size */ /** frames per file */
int64_t* udpSocketBufferSize; uint32_t *framesPerFile;
/** actual UDP Socket Buffer Size (double due to kernel bookkeeping) */ /** frame discard policy */
int64_t* actualUDPSocketBufferSize; frameDiscardPolicy *frameDiscardMode;
/** frames per file */ /** Activated/Deactivated */
uint32_t* framesPerFile; bool *activated;
/** frame discard policy */ /** Deactivated padding enable */
frameDiscardPolicy* frameDiscardMode; bool *deactivatedPaddingEnable;
/** Activated/Deactivated */
bool* activated;
/** Deactivated padding enable */
bool* deactivatedPaddingEnable;
/** Silent Mode */ /** Silent Mode */
bool* silentMode; bool *silentMode;
/** row hardcoded as 1D or 2d, /** row hardcoded as 1D or 2d,
* if detector does not send them yet or * if detector does not send them yet or
* missing packets/deactivated (eiger/jungfrau sends 2d pos) **/ * missing packets/deactivated (eiger/jungfrau sends 2d pos) **/
uint16_t row{0}; uint16_t row{0};
/** column hardcoded as 2D, /** column hardcoded as 2D,
* deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/ * deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/
uint16_t column{0}; uint16_t column{0};
// acquisition start // acquisition start
/** Aquisition Started flag */ /** Aquisition Started flag */
std::atomic<bool> startedFlag{false}; std::atomic<bool> startedFlag{false};
/** Frame Number of First Frame */ /** Frame Number of First Frame */
uint64_t firstIndex{0}; uint64_t firstIndex{0};
// for acquisition summary // for acquisition summary
/** Number of complete Packets caught */ /** Number of complete Packets caught */
std::atomic<uint64_t> numPacketsCaught{0}; std::atomic<uint64_t> numPacketsCaught{0};
/** Last Frame Index caught from udp network */ /** Last Frame Index caught from udp network */
std::atomic<uint64_t> lastCaughtFrameIndex{0}; std::atomic<uint64_t> lastCaughtFrameIndex{0};
// parameters to acquire image // parameters to acquire image
/** Current Frame Index, default value is 0 /** Current Frame Index, default value is 0
* ( always check startedFlag for validity first) * ( always check startedFlag for validity first)
*/ */
uint64_t currentFrameIndex{0}; uint64_t currentFrameIndex{0};
/** True if there is a packet carry over from previous Image */ /** True if there is a packet carry over from previous Image */
bool carryOverFlag{false}; bool carryOverFlag{false};
/** Carry over packet buffer */ /** Carry over packet buffer */
std::unique_ptr<char []> carryOverPacket; std::unique_ptr<char[]> carryOverPacket;
/** Listening buffer for one packet - might be removed when we can peek and eiger fnum is in header */ /** Listening buffer for one packet - might be removed when we can peek and
std::unique_ptr<char []> listeningPacket; * eiger fnum is in header */
std::unique_ptr<char[]> listeningPacket;
/** if the udp socket is connected */ /** if the udp socket is connected */
std::atomic<bool> udpSocketAlive{false}; std::atomic<bool> udpSocketAlive{false};
// for print progress during acquisition // for print progress during acquisition
/** number of packets for statistic */ /** number of packets for statistic */
uint32_t numPacketsStatistic{0}; uint32_t numPacketsStatistic{0};
/** number of images for statistic */ /** number of images for statistic */
uint32_t numFramesStatistic{0}; uint32_t numFramesStatistic{0};
/** /**
* starting packet number is odd or even, accordingly increment frame number * starting packet number is odd or even, accordingly increment frame number
@ -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};
}; };

370
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] "
exit(EXIT_FAILURE); "[num_receivers] [1 for call back, 0 for none]\n\n");
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,9 +47,12 @@ 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) {
return 0; LOG(logINFOBLUE) << "#### StartAcq: filepath:" << filepath
<< " filename:" << filename << " fileindex:" << fileindex
<< " datasize:" << datasize << " ####";
return 0;
} }
/** /**
@ -55,46 +60,49 @@ int StartAcq(std::string filepath, std::string filename, uint64_t fileindex, uin
* @param frames Number of frames caught * @param frames Number of frames caught
* @param p pointer to object * @param p pointer to object
*/ */
void AcquisitionFinished(uint64_t frames, void*p){ void AcquisitionFinished(uint64_t frames, void *p) {
LOG(logINFOBLUE) << "#### AcquisitionFinished: frames:" << frames << " ####"; LOG(logINFOBLUE) << "#### AcquisitionFinished: frames:" << frames
<< " ####";
} }
/** /**
* Get Receiver Data Call back * Get Receiver Data Call back
* Prints in different colors(for each receiver process) the different headers for each image call back. * Prints in different colors(for each receiver process) the different headers
* for each image call back.
* @param metadata sls_receiver_header metadata * @param metadata sls_receiver_header metadata
* @param datapointer pointer to data * @param datapointer pointer to data
* @param datasize data size in bytes. * @param datasize data size in bytes.
* @param p pointer to object * @param p pointer to object
*/ */
void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){ void GetData(char *metadata, char *datapointer, uint32_t datasize, void *p) {
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata; slsDetectorDefs::sls_receiver_header *header =
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader; (slsDetectorDefs::sls_receiver_header *)metadata;
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row, PRINT_IN_COLOR(
"#### %d GetData: ####\n" detectorHeader.modId ? detectorHeader.modId : detectorHeader.row,
"frameNumber: %lu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %lu" "#### %d GetData: ####\n"
"\t\ttimestamp: %lu\t\tmodId: %u\t\t" "frameNumber: %lu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %lu"
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u" "\t\ttimestamp: %lu\t\tmodId: %u\t\t"
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u" "row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
//"\t\tpacketsMask:%s" "\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", //"\t\tpacketsMask:%s"
detectorHeader.row, (long unsigned int)detectorHeader.frameNumber, "\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
detectorHeader.expLength, detectorHeader.packetNumber, (long unsigned int)detectorHeader.bunchId, detectorHeader.row, (long unsigned int)detectorHeader.frameNumber,
(long unsigned int)detectorHeader.timestamp, detectorHeader.modId, detectorHeader.expLength, detectorHeader.packetNumber,
detectorHeader.row, detectorHeader.column, detectorHeader.reserved, (long unsigned int)detectorHeader.bunchId,
detectorHeader.debug, detectorHeader.roundRNumber, (long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
detectorHeader.detType, detectorHeader.version, detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
//header->packetsMask.to_string().c_str(), detectorHeader.debug, detectorHeader.roundRNumber,
((uint8_t)(*((uint8_t*)(datapointer)))), datasize); detectorHeader.detType, detectorHeader.version,
// header->packetsMask.to_string().c_str(),
((uint8_t)(*((uint8_t *)(datapointer)))), datasize);
} }
/** /**
* Get Receiver Data Call back (modified) * Get Receiver Data Call back (modified)
* Prints in different colors(for each receiver process) the different headers for each image call back. * Prints in different colors(for each receiver process) the different headers
* for each image call back.
* @param metadata sls_receiver_header metadata * @param metadata sls_receiver_header metadata
* @param datapointer pointer to data * @param datapointer pointer to data
* @param datasize data size in bytes. * @param datasize data size in bytes.
@ -102,34 +110,36 @@ void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){
* This will be the size written/streamed. (only smaller value is allowed). * This will be the size written/streamed. (only smaller value is allowed).
* @param p pointer to object * @param p pointer to object
*/ */
void GetData(char* metadata, char* datapointer, uint32_t &revDatasize, void* p){ void GetData(char *metadata, char *datapointer, uint32_t &revDatasize,
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata; void *p) {
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader; slsDetectorDefs::sls_receiver_header *header =
(slsDetectorDefs::sls_receiver_header *)metadata;
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
PRINT_IN_COLOR (detectorHeader.modId?detectorHeader.modId:detectorHeader.row, PRINT_IN_COLOR(
"#### %d GetData: ####\n" detectorHeader.modId ? detectorHeader.modId : detectorHeader.row,
"frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu" "#### %d GetData: ####\n"
"\t\ttimestamp: %llu\t\tmodId: %u\t\t" "frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: "
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u" "%llu"
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u" "\t\ttimestamp: %llu\t\tmodId: %u\t\t"
//"\t\tpacketsMask:%s" "row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n", "\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber, //"\t\tpacketsMask:%s"
detectorHeader.expLength, detectorHeader.packetNumber, (long long unsigned int)detectorHeader.bunchId, "\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
(long long unsigned int)detectorHeader.timestamp, detectorHeader.modId, detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber,
detectorHeader.row, detectorHeader.column, detectorHeader.reserved, detectorHeader.expLength, detectorHeader.packetNumber,
detectorHeader.debug, detectorHeader.roundRNumber, (long long unsigned int)detectorHeader.bunchId,
detectorHeader.detType, detectorHeader.version, (long long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
//header->packetsMask.to_string().c_str(), detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
((uint8_t)(*((uint8_t*)(datapointer)))), revDatasize); detectorHeader.debug, detectorHeader.roundRNumber,
detectorHeader.detType, detectorHeader.version,
// header->packetsMask.to_string().c_str(),
((uint8_t)(*((uint8_t *)(datapointer)))), revDatasize);
// if data is modified, eg ROI and size is reduced // if data is modified, eg ROI and size is reduced
revDatasize = 26000; revDatasize = 26000;
} }
/** /**
* Example of main program using the Receiver class * Example of main program using the Receiver class
* *
@ -139,125 +149,141 @@ void GetData(char* metadata, char* datapointer, uint32_t &revDatasize, void* p){
*/ */
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
/** - set default values */ /** - set default values */
int numReceivers = 1; int numReceivers = 1;
int startTCPPort = 1954; int startTCPPort = 1954;
int withCallback = 0; int withCallback = 0;
sem_init(&semaphore,1,0); sem_init(&semaphore, 1, 0);
/** - get number of receivers and start tcp port from command line arguments */ /** - get number of receivers and start tcp port from command line
if ( (argc != 4) || (!sscanf(argv[1],"%d", &startTCPPort)) || (!sscanf(argv[2],"%d", &numReceivers)) || (!sscanf(argv[3],"%d", &withCallback)) ) * arguments */
printHelp(); if ((argc != 4) || (!sscanf(argv[1], "%d", &startTCPPort)) ||
cprintf(BLUE,"Parent Process Created [ Tid: %ld ]\n", (long)syscall(SYS_gettid)); (!sscanf(argv[2], "%d", &numReceivers)) ||
cprintf(RESET, "Number of Receivers: %d\n", numReceivers); (!sscanf(argv[3], "%d", &withCallback)))
cprintf(RESET, "Start TCP Port: %d\n", startTCPPort); printHelp();
cprintf(RESET, "Callback Enable: %d\n", withCallback); cprintf(BLUE, "Parent Process Created [ Tid: %ld ]\n",
(long)syscall(SYS_gettid));
cprintf(RESET, "Number of Receivers: %d\n", numReceivers);
cprintf(RESET, "Start TCP Port: %d\n", startTCPPort);
cprintf(RESET, "Callback Enable: %d\n", withCallback);
/** - Catch signal SIGINT to close files and call destructors properly */
struct sigaction sa;
sa.sa_flags = 0; // no flags
sa.sa_handler = sigInterruptHandler; // handler function
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
// of handler
if (sigaction(SIGINT, &sa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGINT\n");
}
/** - Ignore SIG_PIPE, prevents global signal handler, handle locally,
instead of a server crashing due to client crash when writing, it just
gives error */
struct sigaction asa;
asa.sa_flags = 0; // no flags
asa.sa_handler = SIG_IGN; // handler function
sigemptyset(&asa.sa_mask); // dont block additional signals during
// invocation of handler
if (sigaction(SIGPIPE, &asa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGPIPE\n");
}
/** - Catch signal SIGINT to close files and call destructors properly */ /** - loop over number of receivers */
struct sigaction sa; for (int i = 0; i < numReceivers; ++i) {
sa.sa_flags=0; // no flags
sa.sa_handler=sigInterruptHandler; // handler function
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler
if (sigaction(SIGINT, &sa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGINT\n");
}
/** - Ignore SIG_PIPE, prevents global signal handler, handle locally, /** - fork process to create child process */
instead of a server crashing due to client crash when writing, it just gives error */ pid_t pid = fork();
struct sigaction asa;
asa.sa_flags=0; // no flags
asa.sa_handler=SIG_IGN; // handler function
sigemptyset(&asa.sa_mask); // dont block additional signals during invocation of handler
if (sigaction(SIGPIPE, &asa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGPIPE\n");
}
/** - if fork failed, raise SIGINT and properly destroy all child
* processes */
if (pid < 0) {
cprintf(RED, "fork() failed. Killing all the receiver objects\n");
raise(SIGINT);
}
/** - loop over number of receivers */ /** - if child process */
for (int i = 0; i < numReceivers; ++i) { else if (pid == 0) {
cprintf(BLUE, "Child process %d [ Tid: %ld ]\n", i,
(long)syscall(SYS_gettid));
/** - fork process to create child process */ std::unique_ptr<Receiver> receiver = nullptr;
pid_t pid = fork(); try {
receiver = sls::make_unique<Receiver>(startTCPPort + i);
} catch (...) {
LOG(logINFOBLUE)
<< "Exiting Child Process [ Tid: " << syscall(SYS_gettid)
<< " ]";
throw;
}
/** - register callbacks. remember to set file write enable to 0
(using the client) if we should not write files and you will write data
using the callbacks */
if (withCallback) {
/** - if fork failed, raise SIGINT and properly destroy all child processes */ /** - Call back for start acquisition */
if (pid < 0) { cprintf(BLUE, "Registering StartAcq()\n");
cprintf(RED,"fork() failed. Killing all the receiver objects\n"); receiver->registerCallBackStartAcquisition(StartAcq, nullptr);
raise(SIGINT);
}
/** - if child process */ /** - Call back for acquisition finished */
else if (pid == 0) { cprintf(BLUE, "Registering AcquisitionFinished()\n");
cprintf(BLUE,"Child process %d [ Tid: %ld ]\n", i, (long)syscall(SYS_gettid)); receiver->registerCallBackAcquisitionFinished(
AcquisitionFinished, nullptr);
std::unique_ptr<Receiver> receiver = nullptr;
try {
receiver = sls::make_unique<Receiver>(startTCPPort + i);
} catch (...) {
LOG(logINFOBLUE) << "Exiting Child Process [ Tid: " << syscall(SYS_gettid) << " ]";
throw;
}
/** - register callbacks. remember to set file write enable to 0 (using the client)
if we should not write files and you will write data using the callbacks */
if (withCallback) {
/** - Call back for start acquisition */ /* - Call back for raw data */
cprintf(BLUE, "Registering StartAcq()\n"); cprintf(BLUE, "Registering GetData() \n");
receiver->registerCallBackStartAcquisition(StartAcq, nullptr); if (withCallback == 1)
receiver->registerCallBackRawDataReady(GetData, nullptr);
else if (withCallback == 2)
receiver->registerCallBackRawDataModifyReady(GetData,
nullptr);
}
/** - Call back for acquisition finished */ /** - as long as no Ctrl+C */
cprintf(BLUE, "Registering AcquisitionFinished()\n"); sem_wait(&semaphore);
receiver->registerCallBackAcquisitionFinished(AcquisitionFinished, nullptr); sem_destroy(&semaphore);
cprintf(BLUE, "Exiting Child Process [ Tid: %ld ]\n",
(long)syscall(SYS_gettid));
exit(EXIT_SUCCESS);
break;
}
}
/* - Call back for raw data */ /** - Parent process ignores SIGINT (exits only when all child process
cprintf(BLUE, "Registering GetData() \n"); * exits) */
if (withCallback == 1) receiver->registerCallBackRawDataReady(GetData,nullptr); sa.sa_flags = 0; // no flags
else if (withCallback == 2) receiver->registerCallBackRawDataModifyReady(GetData,nullptr); sa.sa_handler = SIG_IGN; // handler function
} sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
// of handler
if (sigaction(SIGINT, &sa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGINT\n");
}
/** - as long as no Ctrl+C */ /** - Print Ready and Instructions how to exit */
sem_wait(&semaphore); std::cout << "Ready ... \n";
sem_destroy(&semaphore); cprintf(RESET, "\n[ Press \'Ctrl+c\' to exit ]\n");
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
exit(EXIT_SUCCESS);
break;
}
}
/** - Parent process ignores SIGINT (exits only when all child process exits) */ /** - Parent process waits for all child processes to exit */
sa.sa_flags=0; // no flags for (;;) {
sa.sa_handler=SIG_IGN; // handler function pid_t childPid = waitpid(-1, nullptr, 0);
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation of handler
if (sigaction(SIGINT, &sa, nullptr) == -1) {
cprintf(RED, "Could not set handler function for SIGINT\n");
}
// no child closed
if (childPid == -1) {
if (errno == ECHILD) {
cprintf(GREEN, "All Child Processes have been closed\n");
break;
} else {
cprintf(RED, "Unexpected error from waitpid(): (%s)\n",
strerror(errno));
break;
}
}
/** - Print Ready and Instructions how to exit */ // child closed
std::cout << "Ready ... \n"; cprintf(BLUE, "Exiting Child Process [ Tid: %ld ]\n",
cprintf(RESET, "\n[ Press \'Ctrl+c\' to exit ]\n"); (long int)childPid);
}
/** - Parent process waits for all child processes to exit */ std::cout << "Goodbye!\n";
for(;;) { return 0;
pid_t childPid = waitpid (-1, nullptr, 0);
// no child closed
if (childPid == -1) {
if (errno == ECHILD) {
cprintf(GREEN,"All Child Processes have been closed\n");
break;
} else {
cprintf(RED, "Unexpected error from waitpid(): (%s)\n",strerror(errno));
break;
}
}
//child closed
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long int) childPid);
}
std::cout << "Goodbye!\n";
return 0;
} }

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

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

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

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

@ -10,61 +10,57 @@
#include <unistd.h> #include <unistd.h>
ThreadObject::ThreadObject(int threadIndex, std::string threadType) ThreadObject::ThreadObject(int threadIndex, std::string threadType)
: index(threadIndex), type(threadType) { : index(threadIndex), type(threadType) {
LOG(logDEBUG) << type << " thread created: " << index; LOG(logDEBUG) << type << " thread created: " << index;
sem_init(&semaphore,1,0); sem_init(&semaphore, 1, 0);
try { try {
threadObject = std::thread(&ThreadObject::RunningThread, this); threadObject = std::thread(&ThreadObject::RunningThread, this);
} catch (...) { } catch (...) {
throw sls::RuntimeError("Could not create " + type + " thread with index " + std::to_string(index)); throw sls::RuntimeError("Could not create " + type +
} " thread with index " + std::to_string(index));
}
} }
ThreadObject::~ThreadObject() { ThreadObject::~ThreadObject() {
killThread = true; killThread = true;
sem_post(&semaphore); sem_post(&semaphore);
threadObject.join(); threadObject.join();
sem_destroy(&semaphore); sem_destroy(&semaphore);
} }
bool ThreadObject::IsRunning() const{ bool ThreadObject::IsRunning() const { return runningFlag; }
return runningFlag;
}
void ThreadObject::StartRunning() { void ThreadObject::StartRunning() { runningFlag = true; }
runningFlag = true;
}
void ThreadObject::StopRunning() { void ThreadObject::StopRunning() { runningFlag = false; }
runningFlag = false;
}
void ThreadObject::RunningThread() { void ThreadObject::RunningThread() {
LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]"; LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index
while(!killThread) { << ", Tid: " << syscall(SYS_gettid) << "]";
while(IsRunning()) { while (!killThread) {
ThreadExecution(); while (IsRunning()) {
} ThreadExecution();
//wait till the next acquisition }
sem_wait(&semaphore); // wait till the next acquisition
} 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,
if (index == 0) { &param) == EPERM) {
LOG(logWARNING) << "Could not prioritize " << type << " thread. " if (index == 0) {
"(No Root Privileges?)"; LOG(logWARNING) << "Could not prioritize " << type
} << " thread. "
} else { "(No Root Privileges?)";
LOG(logINFO) << "Priorities set - " << type << ": " << priority; }
} } else {
LOG(logINFO) << "Priorities set - " << type << ": " << priority;
}
} }

4
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:
@ -22,7 +22,7 @@ class ThreadObject : private virtual slsDetectorDefs {
private: private:
std::atomic<bool> killThread{false}; std::atomic<bool> killThread{false};
std::atomic<bool> runningFlag{false}; std::atomic<bool> runningFlag{false};
std::thread threadObject; std::thread threadObject;
sem_t semaphore; sem_t semaphore;
const std::string type; const std::string type;

View File

@ -1,64 +1,61 @@
#pragma once #pragma once
#include "sls_detector_defs.h" #include "sls_detector_defs.h"
#include <cstdint> #include <cstdint>
#define MAX_DIMENSIONS (2) #define MAX_DIMENSIONS (2)
#define MAX_NUMBER_OF_LISTENING_THREADS (2) #define MAX_NUMBER_OF_LISTENING_THREADS (2)
//socket // socket
#define GOODBYE (-200) #define GOODBYE (-200)
#define RECEIVE_SOCKET_BUFFER_SIZE (100*1024*1024) #define RECEIVE_SOCKET_BUFFER_SIZE (100 * 1024 * 1024)
#define MAX_SOCKET_INPUT_PACKET_QUEUE (250000) #define MAX_SOCKET_INPUT_PACKET_QUEUE (250000)
// files
//files #define MAX_FRAMES_PER_FILE 20000
#define MAX_FRAMES_PER_FILE 20000 #define SHORT_MAX_FRAMES_PER_FILE 100000
#define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 100000
#define MOENCH_MAX_FRAMES_PER_FILE 100000 #define EIGER_MAX_FRAMES_PER_FILE 10000
#define EIGER_MAX_FRAMES_PER_FILE 10000 #define JFRAU_MAX_FRAMES_PER_FILE 10000
#define JFRAU_MAX_FRAMES_PER_FILE 10000 #define CTB_MAX_FRAMES_PER_FILE 20000
#define CTB_MAX_FRAMES_PER_FILE 20000 #define MYTHEN3_MAX_FRAMES_PER_FILE 10000
#define MYTHEN3_MAX_FRAMES_PER_FILE 10000
#define GOTTHARD2_MAX_FRAMES_PER_FILE 20000 #define GOTTHARD2_MAX_FRAMES_PER_FILE 20000
#define DO_NOTHING (0) #define DO_NOTHING (0)
#define DO_EVERYTHING (1) #define DO_EVERYTHING (1)
#define STATISTIC_FRAMENUMBER_INFINITE (20000) #define STATISTIC_FRAMENUMBER_INFINITE (20000)
//binary // binary
#define FILE_BUFFER_SIZE (16*1024*1024) //16mb #define FILE_BUFFER_SIZE (16 * 1024 * 1024) // 16mb
//fifo // fifo
#define FIFO_HEADER_NUMBYTES (8) #define FIFO_HEADER_NUMBYTES (8)
#define FIFO_DATASIZE_NUMBYTES (4) #define FIFO_DATASIZE_NUMBYTES (4)
#define FIFO_PADDING_NUMBYTES (4) // for 8 byte alignment due to sls_receiver_header structure #define FIFO_PADDING_NUMBYTES \
(4) // for 8 byte alignment due to sls_receiver_header structure
// hdf5
#define MAX_CHUNKED_IMAGES (1)
//hdf5 // versions
#define MAX_CHUNKED_IMAGES (1) #define HDF5_WRITER_VERSION (5.0) // 1 decimal places
#define BINARY_WRITER_VERSION (5.0) // 1 decimal places
//versions // parameters to calculate fifo depth
#define HDF5_WRITER_VERSION (5.0) //1 decimal places #define SAMPLE_TIME_IN_NS (100000000) // 100ms
#define BINARY_WRITER_VERSION (5.0) //1 decimal places #define MAX_EIGER_ROWS_PER_READOUT (256)
// to differentiate between gotthard and short gotthard
#define GOTTHARD_PACKET_SIZE (1286)
//parameters to calculate fifo depth #define DUMMY_PACKET_VALUE (0xFFFFFFFF)
#define SAMPLE_TIME_IN_NS (100000000)//100ms
#define MAX_EIGER_ROWS_PER_READOUT (256)
//to differentiate between gotthard and short gotthard #define LISTENER_PRIORITY (90)
#define GOTTHARD_PACKET_SIZE (1286) #define PROCESSOR_PRIORITY (70)
#define STREAMER_PRIORITY (10)
#define TCP_PRIORITY (10)
#define DUMMY_PACKET_VALUE (0xFFFFFFFF)
#define LISTENER_PRIORITY (90)
#define PROCESSOR_PRIORITY (70)
#define STREAMER_PRIORITY (10)
#define TCP_PRIORITY (10)
struct masterAttributes { struct masterAttributes {
double version; double version;
@ -82,4 +79,4 @@ struct masterAttributes {
uint64_t dbitlist; uint64_t dbitlist;
uint32_t roiXmin; uint32_t roiXmin;
uint32_t roiXmax; uint32_t roiXmax;
}; };

View File

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

5
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]") {
@ -55,7 +52,7 @@
// CHECK(subFrameNumber == -1); // CHECK(subFrameNumber == -1);
// } // }
// TEST_CASE("Parse header gotthard data", "[receiver]") { // TEST_CASE("Parse header gotthard data", "[receiver]") {
// GotthardData data; // GotthardData data;
// struct packet { // struct packet {
// uint32_t frameNumber; // uint32_t frameNumber;