mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-03 08:30:41 +02:00
format receiver
This commit is contained in:
parent
3618f6e5d3
commit
e599bb7c24
@ -3,4 +3,5 @@ IndentWidth: 4
|
||||
|
||||
UseTab: Never
|
||||
ColumnLimit: 80
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveMacros: true
|
@ -53,7 +53,6 @@ set(ClangFormat_EXCLUDE_PATTERNS "build/"
|
||||
"slsDetectorServers/"
|
||||
"ctbGui/"
|
||||
"slsSupportLib/"
|
||||
"slsReceiverSoftware/"
|
||||
"manual/"
|
||||
"slsDetectorGui/"
|
||||
"python/"
|
||||
|
@ -16,7 +16,7 @@ class detectorData;
|
||||
#include <vector>
|
||||
|
||||
#define MULTI_SHMAPIVERSION 0x190809
|
||||
#define MULTI_SHMVERSION 0x200319
|
||||
#define MULTI_SHMVERSION 0x200319
|
||||
#define SHORT_STRING_LENGTH 50
|
||||
|
||||
#include <future>
|
||||
|
@ -14,7 +14,7 @@
|
||||
class ServerInterface;
|
||||
|
||||
#define SLS_SHMAPIVERSION 0x190726
|
||||
#define SLS_SHMVERSION 0x200402
|
||||
#define SLS_SHMVERSION 0x200402
|
||||
|
||||
namespace sls {
|
||||
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
|
||||
#define SHM_SLS_PREFIX "_sls_"
|
||||
#define SHM_ENV_NAME "SLSDETNAME"
|
||||
#define SHM_SLS_PREFIX "_sls_"
|
||||
#define SHM_ENV_NAME "SLSDETNAME"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
@ -116,7 +116,8 @@ int slsDetectorUsers::size() const { return detector->size(); }
|
||||
// int slsDetectorUsers::setThresholdEnergy(int e_ev, int tb, int isettings, int
|
||||
// detPos) { return detector.setThresholdEnergy(e_ev,
|
||||
// (isettings == -1) ? slsDetectorDefs::GET_SETTINGS :
|
||||
// (slsDetectorDefs::detectorSettings)isettings, tb, detPos);
|
||||
// (slsDetectorDefs::detectorSettings)isettings,
|
||||
// tb, detPos);
|
||||
// }
|
||||
|
||||
// double slsDetectorUsers::setExposureTime(double t, bool inseconds, int
|
||||
|
2
slsReceiverSoftware/include/CircularFifo.h
Executable file → Normal file
2
slsReceiverSoftware/include/CircularFifo.h
Executable file → Normal file
@ -30,7 +30,7 @@ template <typename Element> class CircularFifo {
|
||||
}
|
||||
|
||||
CircularFifo(const CircularFifo &) = delete;
|
||||
CircularFifo(CircularFifo&&) = delete;
|
||||
CircularFifo(CircularFifo &&) = delete;
|
||||
|
||||
virtual ~CircularFifo() {
|
||||
sem_destroy(&data_mutex);
|
||||
|
126
slsReceiverSoftware/include/Receiver.h
Executable file → Normal file
126
slsReceiverSoftware/include/Receiver.h
Executable file → Normal file
@ -5,65 +5,70 @@
|
||||
class ClientInterface;
|
||||
|
||||
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
|
||||
\returns id
|
||||
*/
|
||||
int64_t getReceiverVersion();
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
~Receiver();
|
||||
|
||||
/**
|
||||
* Call back for acquisition finished
|
||||
* callback argument is
|
||||
* @param total frames caught
|
||||
*/
|
||||
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg);
|
||||
/**
|
||||
* get get Receiver Version
|
||||
\returns id
|
||||
*/
|
||||
int64_t getReceiverVersion();
|
||||
|
||||
/**
|
||||
* 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 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
|
||||
* 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)
|
||||
@ -71,12 +76,13 @@ class Receiver : private virtual slsDetectorDefs {
|
||||
* @param sls_receiver_header frame metadata
|
||||
* @param dataPointer is the pointer to the data
|
||||
* @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* ,
|
||||
char*, uint32_t &,void*),void *arg);
|
||||
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
|
||||
uint32_t &, void *),
|
||||
void *arg);
|
||||
|
||||
|
||||
private:
|
||||
std::unique_ptr<ClientInterface> tcpipInterface;
|
||||
private:
|
||||
std::unique_ptr<ClientInterface> tcpipInterface;
|
||||
};
|
||||
|
423
slsReceiverSoftware/src/BinaryFile.cpp
Executable file → Normal file
423
slsReceiverSoftware/src/BinaryFile.cpp
Executable file → Normal file
@ -8,236 +8,237 @@
|
||||
#include "Fifo.h"
|
||||
#include "receiver_defs.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
FILE* BinaryFile::masterfd = nullptr;
|
||||
FILE *BinaryFile::masterfd = nullptr;
|
||||
|
||||
BinaryFile::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):
|
||||
File(ind, BINARY, maxf, nd, fname, fpath, findex, owenable, dindex, nunits, nf, dr, portno, smode),
|
||||
filefd(nullptr),
|
||||
numFramesInFile(0),
|
||||
numActualPacketsInFile(0),
|
||||
maxMasterFileSize(2000)
|
||||
{
|
||||
BinaryFile::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)
|
||||
: File(ind, BINARY, maxf, nd, fname, fpath, findex, owenable, dindex,
|
||||
nunits, nf, dr, portno, smode),
|
||||
filefd(nullptr), numFramesInFile(0), numActualPacketsInFile(0),
|
||||
maxMasterFileSize(2000) {
|
||||
#ifdef VERBOSE
|
||||
PrintMembers();
|
||||
PrintMembers();
|
||||
#endif
|
||||
}
|
||||
|
||||
BinaryFile::~BinaryFile() {
|
||||
CloseAllFiles();
|
||||
}
|
||||
BinaryFile::~BinaryFile() { CloseAllFiles(); }
|
||||
|
||||
void BinaryFile::PrintMembers(TLogLevel level) {
|
||||
File::PrintMembers(level);
|
||||
LOG(logINFO) << "Max Frames Per File: " << *maxFramesPerFile;
|
||||
LOG(logINFO) << "Number of Frames in File: " << numFramesInFile;
|
||||
File::PrintMembers(level);
|
||||
LOG(logINFO) << "Max Frames Per File: " << *maxFramesPerFile;
|
||||
LOG(logINFO) << "Number of Frames in File: " << numFramesInFile;
|
||||
}
|
||||
|
||||
void BinaryFile::CreateFile() {
|
||||
numFramesInFile = 0;
|
||||
numActualPacketsInFile = 0;
|
||||
numFramesInFile = 0;
|
||||
numActualPacketsInFile = 0;
|
||||
|
||||
std::ostringstream os;
|
||||
os << *filePath << "/" << *fileNamePrefix << "_d"
|
||||
<< (*detIndex * (*numUnitsPerDetector) + index) << "_f" << subFileIndex << '_'
|
||||
<< *fileIndex << ".raw";
|
||||
currentFileName = os.str();
|
||||
std::ostringstream os;
|
||||
os << *filePath << "/" << *fileNamePrefix << "_d"
|
||||
<< (*detIndex * (*numUnitsPerDetector) + index) << "_f" << subFileIndex
|
||||
<< '_' << *fileIndex << ".raw";
|
||||
currentFileName = os.str();
|
||||
|
||||
if (!(*overWriteEnable)){
|
||||
if (NULL == (filefd = fopen((const char *) currentFileName.c_str(), "wx"))){
|
||||
filefd = 0;
|
||||
throw sls::RuntimeError("Could not create/overwrite file " + currentFileName);
|
||||
}
|
||||
} else if (NULL == (filefd = fopen((const char *) currentFileName.c_str(), "w"))){
|
||||
filefd = 0;
|
||||
throw sls::RuntimeError("Could not create file " + currentFileName);
|
||||
}
|
||||
//setting to no file buffering
|
||||
setvbuf(filefd, NULL, _IONBF, 0);
|
||||
if (!(*overWriteEnable)) {
|
||||
if (NULL ==
|
||||
(filefd = fopen((const char *)currentFileName.c_str(), "wx"))) {
|
||||
filefd = 0;
|
||||
throw sls::RuntimeError("Could not create/overwrite file " +
|
||||
currentFileName);
|
||||
}
|
||||
} else if (NULL ==
|
||||
(filefd = fopen((const char *)currentFileName.c_str(), "w"))) {
|
||||
filefd = 0;
|
||||
throw sls::RuntimeError("Could not create file " + currentFileName);
|
||||
}
|
||||
// setting to no file buffering
|
||||
setvbuf(filefd, NULL, _IONBF, 0);
|
||||
|
||||
if(!(*silentMode)) {
|
||||
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));
|
||||
if (!(*silentMode)) {
|
||||
LOG(logINFO) << "[" << *udpPortNumber
|
||||
<< "]: Binary File created: " << currentFileName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
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::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
82
slsReceiverSoftware/src/BinaryFile.h
Executable file → Normal file
@ -5,57 +5,55 @@
|
||||
* 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 <string>
|
||||
|
||||
|
||||
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;
|
||||
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;
|
||||
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();
|
||||
|
||||
private:
|
||||
int WriteData(char* buf, int bsize);
|
||||
void PrintMembers(TLogLevel level = logDEBUG1) override;
|
||||
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;
|
||||
static FILE* masterfd;
|
||||
uint32_t numFramesInFile;
|
||||
uint64_t numActualPacketsInFile;
|
||||
const size_t maxMasterFileSize;
|
||||
private:
|
||||
int WriteData(char *buf, int bsize);
|
||||
|
||||
FILE *filefd;
|
||||
static FILE *masterfd;
|
||||
uint32_t numFramesInFile;
|
||||
uint64_t numActualPacketsInFile;
|
||||
const size_t maxMasterFileSize;
|
||||
};
|
||||
|
||||
|
415
slsReceiverSoftware/src/ClientInterface.cpp
Executable file → Normal file
415
slsReceiverSoftware/src/ClientInterface.cpp
Executable file → Normal file
@ -1,28 +1,28 @@
|
||||
#include "ClientInterface.h"
|
||||
#include "FixedCapacityContainer.h"
|
||||
#include "ServerSocket.h"
|
||||
#include "ToString.h"
|
||||
#include "sls_detector_exceptions.h"
|
||||
#include "string_utils.h"
|
||||
#include "versionAPI.h"
|
||||
#include "ToString.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
using sls::RuntimeError;
|
||||
using sls::SocketError;
|
||||
using Interface = sls::ServerInterface;
|
||||
|
||||
ClientInterface::~ClientInterface() {
|
||||
ClientInterface::~ClientInterface() {
|
||||
killTcpThread = true;
|
||||
LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber;
|
||||
server.shutdown();
|
||||
@ -31,25 +31,28 @@ ClientInterface::~ClientInterface() {
|
||||
}
|
||||
|
||||
ClientInterface::ClientInterface(int portNumber)
|
||||
: myDetectorType(GOTTHARD),
|
||||
portNumber(portNumber > 0 ? portNumber : DEFAULT_PORTNO + 2),
|
||||
server(portNumber) {
|
||||
: myDetectorType(GOTTHARD),
|
||||
portNumber(portNumber > 0 ? portNumber : DEFAULT_PORTNO + 2),
|
||||
server(portNumber) {
|
||||
functionTable();
|
||||
// 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; }
|
||||
|
||||
/***callback functions***/
|
||||
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;
|
||||
pStartAcquisition = arg;
|
||||
}
|
||||
|
||||
void ClientInterface::registerCallBackAcquisitionFinished(
|
||||
void (*func)(uint64_t, void *), void *arg) {
|
||||
void ClientInterface::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
|
||||
void *),
|
||||
void *arg) {
|
||||
acquisitionFinishedCallBack = func;
|
||||
pAcquisitionFinished = arg;
|
||||
}
|
||||
@ -67,9 +70,10 @@ void ClientInterface::registerCallBackRawDataModifyReady(
|
||||
}
|
||||
|
||||
void ClientInterface::startTCPServer() {
|
||||
LOG(logINFOBLUE) << "Created [ TCP server Tid: " << syscall(SYS_gettid) << "]";
|
||||
LOG(logINFO) << "SLS Receiver starting TCP Server on port "
|
||||
<< portNumber << '\n';
|
||||
LOG(logINFOBLUE) << "Created [ TCP server Tid: " << syscall(SYS_gettid)
|
||||
<< "]";
|
||||
LOG(logINFO) << "SLS Receiver starting TCP Server on port " << portNumber
|
||||
<< '\n';
|
||||
// server = sls::make_unique<sls::ServerSocket>(portNumber);
|
||||
while (!killTcpThread) {
|
||||
LOG(logDEBUG1) << "Start accept loop";
|
||||
@ -97,7 +101,8 @@ void ClientInterface::startTCPServer() {
|
||||
if (receiver) {
|
||||
receiver->shutDownUDPSockets();
|
||||
}
|
||||
LOG(logINFOBLUE) << "Exiting [ TCP server Tid: " << syscall(SYS_gettid) << "]";
|
||||
LOG(logINFOBLUE) << "Exiting [ TCP server Tid: " << syscall(SYS_gettid)
|
||||
<< "]";
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
@ -208,12 +213,11 @@ int ClientInterface::decodeFunction(Interface &socket) {
|
||||
std::to_string(fnum) + "\n");
|
||||
} else {
|
||||
LOG(logDEBUG1) << "calling function fnum: " << fnum << " ("
|
||||
<< getFunctionNameFromEnum((enum detFuncs)fnum)
|
||||
<< ")";
|
||||
<< getFunctionNameFromEnum((enum detFuncs)fnum) << ")";
|
||||
ret = (this->*flist[fnum])(socket);
|
||||
LOG(logDEBUG1)
|
||||
<< "Function " << getFunctionNameFromEnum((enum detFuncs)fnum)
|
||||
<< " finished";
|
||||
LOG(logDEBUG1) << "Function "
|
||||
<< getFunctionNameFromEnum((enum detFuncs)fnum)
|
||||
<< " finished";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -226,15 +230,15 @@ void ClientInterface::functionNotImplemented() {
|
||||
}
|
||||
|
||||
void ClientInterface::modeNotImplemented(const std::string &modename,
|
||||
int mode) {
|
||||
int mode) {
|
||||
std::ostringstream os;
|
||||
os << modename << " (" << mode << ") is not implemented for this detector";
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ClientInterface::validate(T arg, T retval, const std::string& modename,
|
||||
numberMode hex) {
|
||||
void ClientInterface::validate(T arg, T retval, const std::string &modename,
|
||||
numberMode hex) {
|
||||
if (ret == OK && arg != -1 && retval != arg) {
|
||||
auto format = (hex == HEX) ? std::hex : std::dec;
|
||||
auto prefix = (hex == HEX) ? "0x" : "";
|
||||
@ -254,7 +258,8 @@ void ClientInterface::verifyLock() {
|
||||
void ClientInterface::verifyIdle(Interface &socket) {
|
||||
if (impl()->getStatus() != IDLE) {
|
||||
std::ostringstream oss;
|
||||
oss << "Can not execute " << getFunctionNameFromEnum((enum detFuncs)fnum)
|
||||
oss << "Can not execute "
|
||||
<< getFunctionNameFromEnum((enum detFuncs)fnum)
|
||||
<< " when receiver is not idle";
|
||||
throw sls::SocketError(oss.str());
|
||||
}
|
||||
@ -292,7 +297,8 @@ int ClientInterface::lock_receiver(Interface &socket) {
|
||||
auto lock = socket.Receive<int>();
|
||||
LOG(logDEBUG1) << "Locking Server to " << lock;
|
||||
if (lock >= 0) {
|
||||
if (!lockedByClient || (server.getLockedBy() == server.getThisClient())) {
|
||||
if (!lockedByClient ||
|
||||
(server.getLockedBy() == server.getThisClient())) {
|
||||
lockedByClient = lock;
|
||||
lock ? server.setLockedBy(server.getThisClient())
|
||||
: server.setLockedBy(sls::IpAddr{});
|
||||
@ -328,41 +334,40 @@ int ClientInterface::get_version(Interface &socket) {
|
||||
|
||||
int ClientInterface::setup_receiver(Interface &socket) {
|
||||
auto arg = socket.Receive<rxParameters>();
|
||||
LOG(logDEBUG1)
|
||||
<< "detType:" << arg.detType << std::endl
|
||||
<< "multiSize.x:" << arg.multiSize.x << std::endl
|
||||
<< "multiSize.y:" << arg.multiSize.y << std::endl
|
||||
<< "detId:" << arg.detId << std::endl
|
||||
<< "hostname:" << arg.hostname << std::endl
|
||||
<< "udpInterfaces:" << arg.udpInterfaces << std::endl
|
||||
<< "udp_dstport:" << arg.udp_dstport << std::endl
|
||||
<< "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl
|
||||
<< "udp_dstmac:" << sls::MacAddr(arg.udp_dstmac) << std::endl
|
||||
<< "udp_dstport2:" << arg.udp_dstport2 << std::endl
|
||||
<< "udp_dstip2:" << sls::IpAddr(arg.udp_dstip2) << std::endl
|
||||
<< "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2) << std::endl
|
||||
<< "frames:" << arg.frames << std::endl
|
||||
<< "triggers:" << arg.triggers << std::endl
|
||||
<< "bursts:" << arg.bursts << std::endl
|
||||
<< "analogSamples:" << arg.analogSamples << std::endl
|
||||
<< "digitalSamples:" << arg.digitalSamples << std::endl
|
||||
<< "expTimeNs:" << arg.expTimeNs << std::endl
|
||||
<< "periodNs:" << arg.periodNs << std::endl
|
||||
<< "subExpTimeNs:" << arg.subExpTimeNs << std::endl
|
||||
<< "subDeadTimeNs:" << arg.subDeadTimeNs << std::endl
|
||||
<< "activate:" << arg.activate << std::endl
|
||||
<< "quad:" << arg.quad << std::endl
|
||||
<< "dynamicRange:" << arg.dynamicRange << std::endl
|
||||
<< "timMode:" << arg.timMode << std::endl
|
||||
<< "tenGiga:" << arg.tenGiga << std::endl
|
||||
<< "roMode:" << arg.roMode << std::endl
|
||||
<< "adcMask:" << arg.adcMask << std::endl
|
||||
<< "adc10gMask:" << arg.adc10gMask << std::endl
|
||||
<< "roi.xmin:" << arg.roi.xmin << std::endl
|
||||
<< "roi.xmax:" << arg.roi.xmax << std::endl
|
||||
<< "countermask:" << arg.countermask << std::endl
|
||||
<< "burstType:" << arg.burstType << std::endl;
|
||||
|
||||
LOG(logDEBUG1) << "detType:" << arg.detType << std::endl
|
||||
<< "multiSize.x:" << arg.multiSize.x << std::endl
|
||||
<< "multiSize.y:" << arg.multiSize.y << std::endl
|
||||
<< "detId:" << arg.detId << std::endl
|
||||
<< "hostname:" << arg.hostname << std::endl
|
||||
<< "udpInterfaces:" << arg.udpInterfaces << std::endl
|
||||
<< "udp_dstport:" << arg.udp_dstport << std::endl
|
||||
<< "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl
|
||||
<< "udp_dstmac:" << sls::MacAddr(arg.udp_dstmac) << std::endl
|
||||
<< "udp_dstport2:" << arg.udp_dstport2 << std::endl
|
||||
<< "udp_dstip2:" << sls::IpAddr(arg.udp_dstip2) << std::endl
|
||||
<< "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2)
|
||||
<< std::endl
|
||||
<< "frames:" << arg.frames << std::endl
|
||||
<< "triggers:" << arg.triggers << std::endl
|
||||
<< "bursts:" << arg.bursts << std::endl
|
||||
<< "analogSamples:" << arg.analogSamples << std::endl
|
||||
<< "digitalSamples:" << arg.digitalSamples << std::endl
|
||||
<< "expTimeNs:" << arg.expTimeNs << std::endl
|
||||
<< "periodNs:" << arg.periodNs << std::endl
|
||||
<< "subExpTimeNs:" << arg.subExpTimeNs << std::endl
|
||||
<< "subDeadTimeNs:" << arg.subDeadTimeNs << std::endl
|
||||
<< "activate:" << arg.activate << std::endl
|
||||
<< "quad:" << arg.quad << std::endl
|
||||
<< "dynamicRange:" << arg.dynamicRange << std::endl
|
||||
<< "timMode:" << arg.timMode << std::endl
|
||||
<< "tenGiga:" << arg.tenGiga << std::endl
|
||||
<< "roMode:" << arg.roMode << std::endl
|
||||
<< "adcMask:" << arg.adcMask << std::endl
|
||||
<< "adc10gMask:" << arg.adc10gMask << std::endl
|
||||
<< "roi.xmin:" << arg.roi.xmin << std::endl
|
||||
<< "roi.xmax:" << arg.roi.xmax << std::endl
|
||||
<< "countermask:" << arg.countermask << std::endl
|
||||
<< "burstType:" << arg.burstType << std::endl;
|
||||
|
||||
// if object exists, verify unlocked and idle, else only verify lock
|
||||
// (connecting first time)
|
||||
@ -378,7 +383,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
}
|
||||
impl()->setDetectorPositionId(arg.detId);
|
||||
impl()->setDetectorHostname(arg.hostname);
|
||||
|
||||
|
||||
// udp setup
|
||||
sls::MacAddr retvals[2];
|
||||
if (arg.udp_dstmac == 0 && arg.udp_dstip != 0) {
|
||||
@ -392,9 +397,9 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
if (myDetectorType == JUNGFRAU) {
|
||||
try {
|
||||
impl()->setNumberofUDPInterfaces(arg.udpInterfaces);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Failed to set number of interfaces to " +
|
||||
std::to_string(arg.udpInterfaces));
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Failed to set number of interfaces to " +
|
||||
std::to_string(arg.udpInterfaces));
|
||||
}
|
||||
}
|
||||
impl()->setUDPSocketBufferSize(0);
|
||||
@ -408,19 +413,19 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
if (myDetectorType == MOENCH || myDetectorType == CHIPTESTBOARD) {
|
||||
try {
|
||||
impl()->setNumberofAnalogSamples(arg.analogSamples);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set num analog samples to " +
|
||||
std::to_string(arg.analogSamples) +
|
||||
" due to fifo structure memory allocation.");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set num analog samples to " +
|
||||
std::to_string(arg.analogSamples) +
|
||||
" due to fifo structure memory allocation.");
|
||||
}
|
||||
}
|
||||
if (myDetectorType == CHIPTESTBOARD) {
|
||||
try {
|
||||
impl()->setNumberofDigitalSamples(arg.digitalSamples);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set num digital samples to "
|
||||
+ std::to_string(arg.analogSamples) +
|
||||
" due to fifo structure memory allocation.");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set num digital samples to " +
|
||||
std::to_string(arg.analogSamples) +
|
||||
" due to fifo structure memory allocation.");
|
||||
}
|
||||
}
|
||||
impl()->setAcquisitionTime(arg.expTimeNs);
|
||||
@ -431,55 +436,56 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
impl()->setActivate(static_cast<bool>(arg.activate));
|
||||
try {
|
||||
impl()->setQuad(arg.quad == 0 ? false : true);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set quad to " +
|
||||
std::to_string(arg.quad) +
|
||||
" due to fifo strucutre memory allocation");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set quad to " +
|
||||
std::to_string(arg.quad) +
|
||||
" due to fifo strucutre memory allocation");
|
||||
}
|
||||
}
|
||||
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
|
||||
try {
|
||||
impl()->setDynamicRange(arg.dynamicRange);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set dynamic range. Could not allocate "
|
||||
"memory for fifo or could not start listening/writing threads");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError(
|
||||
"Could not set dynamic range. Could not allocate "
|
||||
"memory for fifo or could not start listening/writing threads");
|
||||
}
|
||||
}
|
||||
impl()->setTimingMode(arg.timMode);
|
||||
if (myDetectorType == EIGER || myDetectorType == MOENCH ||
|
||||
if (myDetectorType == EIGER || myDetectorType == MOENCH ||
|
||||
myDetectorType == CHIPTESTBOARD) {
|
||||
try {
|
||||
impl()->setTenGigaEnable(arg.tenGiga);
|
||||
} catch(const RuntimeError &e) {
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set 10GbE.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myDetectorType == CHIPTESTBOARD) {
|
||||
try {
|
||||
impl()->setReadoutMode(arg.roMode);
|
||||
} catch(const RuntimeError &e) {
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set read out mode "
|
||||
"due to fifo memory allocation.");
|
||||
"due to fifo memory allocation.");
|
||||
}
|
||||
}
|
||||
if (myDetectorType == CHIPTESTBOARD || myDetectorType == MOENCH) {
|
||||
try {
|
||||
impl()->setADCEnableMask(arg.adcMask);
|
||||
} catch(const RuntimeError &e) {
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set adc enable mask "
|
||||
"due to fifo memory allcoation");
|
||||
"due to fifo memory allcoation");
|
||||
}
|
||||
try {
|
||||
impl()->setTenGigaADCEnableMask(arg.adc10gMask);
|
||||
} catch(const RuntimeError &e) {
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set 10Gb adc enable mask "
|
||||
"due to fifo memory allcoation");
|
||||
"due to fifo memory allcoation");
|
||||
}
|
||||
}
|
||||
if (myDetectorType == GOTTHARD) {
|
||||
try {
|
||||
impl()->setROI(arg.roi);
|
||||
} catch(const RuntimeError &e) {
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set ROI");
|
||||
}
|
||||
}
|
||||
@ -520,16 +526,16 @@ void ClientInterface::setDetectorType(detectorType arg) {
|
||||
// callbacks after (in setdetectortype, the object is reinitialized)
|
||||
if (startAcquisitionCallBack != nullptr)
|
||||
impl()->registerCallBackStartAcquisition(startAcquisitionCallBack,
|
||||
pStartAcquisition);
|
||||
pStartAcquisition);
|
||||
if (acquisitionFinishedCallBack != nullptr)
|
||||
impl()->registerCallBackAcquisitionFinished(
|
||||
acquisitionFinishedCallBack, pAcquisitionFinished);
|
||||
impl()->registerCallBackAcquisitionFinished(acquisitionFinishedCallBack,
|
||||
pAcquisitionFinished);
|
||||
if (rawDataReadyCallBack != nullptr)
|
||||
impl()->registerCallBackRawDataReady(rawDataReadyCallBack,
|
||||
pRawDataReady);
|
||||
pRawDataReady);
|
||||
if (rawDataModifyReadyCallBack != nullptr)
|
||||
impl()->registerCallBackRawDataModifyReady(
|
||||
rawDataModifyReadyCallBack, pRawDataReady);
|
||||
impl()->registerCallBackRawDataModifyReady(rawDataModifyReadyCallBack,
|
||||
pRawDataReady);
|
||||
}
|
||||
|
||||
int ClientInterface::set_roi(Interface &socket) {
|
||||
@ -544,7 +550,7 @@ int ClientInterface::set_roi(Interface &socket) {
|
||||
verifyIdle(socket);
|
||||
try {
|
||||
impl()->setROI(arg);
|
||||
} catch(const RuntimeError &e) {
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set ROI");
|
||||
}
|
||||
return socket.Send(OK);
|
||||
@ -553,8 +559,7 @@ int ClientInterface::set_roi(Interface &socket) {
|
||||
int ClientInterface::set_num_frames(Interface &socket) {
|
||||
auto value = socket.Receive<int64_t>();
|
||||
if (value <= 0) {
|
||||
throw RuntimeError("Invalid number of frames " +
|
||||
std::to_string(value));
|
||||
throw RuntimeError("Invalid number of frames " + std::to_string(value));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
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) {
|
||||
auto value = socket.Receive<int64_t>();
|
||||
if (value <= 0) {
|
||||
throw RuntimeError("Invalid number of triggers " +
|
||||
std::to_string(value));
|
||||
throw RuntimeError("Invalid number of triggers " +
|
||||
std::to_string(value));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
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) {
|
||||
auto value = socket.Receive<int64_t>();
|
||||
if (value <= 0) {
|
||||
throw RuntimeError("Invalid number of bursts " +
|
||||
std::to_string(value));
|
||||
throw RuntimeError("Invalid number of bursts " + std::to_string(value));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
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) {
|
||||
auto value = socket.Receive<int>();
|
||||
if (value < 0) {
|
||||
throw RuntimeError("Invalid number of additional storage cells " +
|
||||
std::to_string(value));
|
||||
throw RuntimeError("Invalid number of additional storage cells " +
|
||||
std::to_string(value));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
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) {
|
||||
auto value = socket.Receive<int>();
|
||||
if (value < 0 || value >= NUM_TIMING_MODES) {
|
||||
throw RuntimeError("Invalid timing mode " +
|
||||
std::to_string(value));
|
||||
if (value < 0 || value >= NUM_TIMING_MODES) {
|
||||
throw RuntimeError("Invalid timing mode " + std::to_string(value));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
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) {
|
||||
auto value = socket.Receive<int>();
|
||||
if (value < 0 || value >= NUM_BURST_MODES) {
|
||||
throw RuntimeError("Invalid burst mode " +
|
||||
std::to_string(value));
|
||||
if (value < 0 || value >= NUM_BURST_MODES) {
|
||||
throw RuntimeError("Invalid burst mode " + std::to_string(value));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
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;
|
||||
if (myDetectorType != CHIPTESTBOARD && myDetectorType != MOENCH) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
}
|
||||
try {
|
||||
impl()->setNumberofAnalogSamples(value);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set num analog samples to " + std::to_string(value) + " due to fifo structure memory allocation.");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set num analog samples to " +
|
||||
std::to_string(value) +
|
||||
" due to fifo structure memory allocation.");
|
||||
}
|
||||
return socket.Send(OK);
|
||||
}
|
||||
@ -653,11 +657,13 @@ int ClientInterface::set_num_digital_samples(Interface &socket) {
|
||||
LOG(logDEBUG1) << "Setting num digital samples to " << value;
|
||||
if (myDetectorType != CHIPTESTBOARD) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
}
|
||||
try {
|
||||
impl()->setNumberofDigitalSamples(value);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set num digital samples to " + std::to_string(value) + " due to fifo structure memory allocation.");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set num digital samples to " +
|
||||
std::to_string(value) +
|
||||
" due to fifo structure memory allocation.");
|
||||
}
|
||||
return socket.Send(OK);
|
||||
}
|
||||
@ -689,7 +695,8 @@ int ClientInterface::set_subdeadtime(Interface &socket) {
|
||||
auto value = socket.Receive<int64_t>();
|
||||
LOG(logDEBUG1) << "Setting sub deadtime to " << value << "ns";
|
||||
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);
|
||||
}
|
||||
|
||||
@ -699,7 +706,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting dynamic range: " << dr;
|
||||
bool exists = false;
|
||||
switch(myDetectorType) {
|
||||
switch (myDetectorType) {
|
||||
case EIGER:
|
||||
if (dr == 4 || dr == 8 || dr == 16 || dr == 32) {
|
||||
exists = true;
|
||||
@ -711,7 +718,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (dr == 16) {
|
||||
if (dr == 16) {
|
||||
exists = true;
|
||||
}
|
||||
break;
|
||||
@ -721,7 +728,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
|
||||
} else {
|
||||
try {
|
||||
impl()->setDynamicRange(dr);
|
||||
} catch(const RuntimeError &e) {
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not allocate memory for fifo or "
|
||||
"could not start listening/writing threads");
|
||||
}
|
||||
@ -736,13 +743,13 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
|
||||
int ClientInterface::set_streaming_frequency(Interface &socket) {
|
||||
auto index = socket.Receive<int>();
|
||||
if (index < 0) {
|
||||
throw RuntimeError("Invalid streaming frequency: "
|
||||
+ std::to_string(index));
|
||||
throw RuntimeError("Invalid streaming frequency: " +
|
||||
std::to_string(index));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting streaming frequency: " << index;
|
||||
impl()->setStreamingFrequency(index);
|
||||
|
||||
|
||||
int retval = impl()->getStreamingFrequency();
|
||||
validate(index, retval, "set streaming frequency", DEC);
|
||||
return socket.Send(OK);
|
||||
@ -791,11 +798,11 @@ int ClientInterface::set_file_dir(Interface &socket) {
|
||||
if (strlen(fPath) == 0) {
|
||||
throw RuntimeError("Cannot set empty file path");
|
||||
}
|
||||
if(fPath[0] != '/')
|
||||
if (fPath[0] != '/')
|
||||
throw RuntimeError("Receiver path needs to be absolute path");
|
||||
LOG(logDEBUG1) << "Setting file path: " << fPath;
|
||||
impl()->setFilePath(fPath);
|
||||
|
||||
|
||||
std::string s = impl()->getFilePath();
|
||||
sls::strcpy_safe(retval, s.c_str());
|
||||
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;
|
||||
impl()->setFileName(fName);
|
||||
|
||||
|
||||
std::string s = impl()->getFileName();
|
||||
sls::strcpy_safe(retval, s.c_str());
|
||||
LOG(logDEBUG1) << "file name:" << retval;
|
||||
@ -841,8 +848,7 @@ int ClientInterface::get_file_name(Interface &socket) {
|
||||
int ClientInterface::set_file_index(Interface &socket) {
|
||||
auto index = socket.Receive<int64_t>();
|
||||
if (index < 0) {
|
||||
throw RuntimeError("Invalid file index: "
|
||||
+ std::to_string(index));
|
||||
throw RuntimeError("Invalid file index: " + std::to_string(index));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting file index: " << index;
|
||||
@ -887,7 +893,8 @@ int ClientInterface::get_frames_caught(Interface &socket) {
|
||||
int ClientInterface::set_file_write(Interface &socket) {
|
||||
auto enable = socket.Receive<int>();
|
||||
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);
|
||||
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) {
|
||||
auto enable = socket.Receive<int>();
|
||||
if (enable < 0) {
|
||||
throw RuntimeError("Invalid master file write enable: "
|
||||
+ std::to_string(enable));
|
||||
throw RuntimeError("Invalid master file write enable: " +
|
||||
std::to_string(enable));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting Master File write enable:" << enable;
|
||||
impl()->setMasterFileWriteEnable(enable);
|
||||
|
||||
|
||||
int retval = impl()->getMasterFileWriteEnable();
|
||||
validate(enable, retval, "set master file write enable", DEC);
|
||||
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) {
|
||||
auto index = socket.Receive<int>();
|
||||
if (index < 0) {
|
||||
throw RuntimeError("Invalid over write enable: "
|
||||
+ std::to_string(index));
|
||||
throw RuntimeError("Invalid over write enable: " +
|
||||
std::to_string(index));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting File overwrite enable:" << index;
|
||||
impl()->setOverwriteEnable(index);
|
||||
|
||||
|
||||
int retval = impl()->getOverwriteEnable();
|
||||
validate(index, retval, "set file overwrite enable", DEC);
|
||||
LOG(logDEBUG1) << "file overwrite enable:" << retval;
|
||||
@ -960,8 +967,8 @@ int ClientInterface::enable_tengiga(Interface &socket) {
|
||||
LOG(logDEBUG1) << "Setting 10GbE:" << val;
|
||||
try {
|
||||
impl()->setTenGigaEnable(val);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set 10GbE." );
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set 10GbE.");
|
||||
}
|
||||
}
|
||||
int retval = impl()->getTenGigaEnable();
|
||||
@ -977,8 +984,9 @@ int ClientInterface::set_fifo_depth(Interface &socket) {
|
||||
LOG(logDEBUG1) << "Setting fifo depth:" << value;
|
||||
try {
|
||||
impl()->setFifoDepth(value);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set fifo depth due to fifo structure memory allocation.");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set fifo depth due to fifo structure "
|
||||
"memory allocation.");
|
||||
}
|
||||
}
|
||||
int retval = impl()->getFifoDepth();
|
||||
@ -1006,17 +1014,18 @@ int ClientInterface::set_activate(Interface &socket) {
|
||||
int ClientInterface::set_streaming(Interface &socket) {
|
||||
auto index = socket.Receive<int>();
|
||||
if (index < 0) {
|
||||
throw RuntimeError("Invalid streaming enable: "
|
||||
+ std::to_string(index));
|
||||
throw RuntimeError("Invalid streaming enable: " +
|
||||
std::to_string(index));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting data stream enable:" << index;
|
||||
try {
|
||||
impl()->setDataStreamEnable(index);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set data stream enable to " + std::to_string(index));
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set data stream enable to " +
|
||||
std::to_string(index));
|
||||
}
|
||||
|
||||
|
||||
auto retval = static_cast<int>(impl()->getDataStreamEnable());
|
||||
validate(index, retval, "set data stream enable", DEC);
|
||||
LOG(logDEBUG1) << "data streaming enable:" << retval;
|
||||
@ -1063,13 +1072,12 @@ int ClientInterface::set_file_format(Interface &socket) {
|
||||
fileFormat f = GET_FILE_FORMAT;
|
||||
socket.Receive(f);
|
||||
if (f < 0 || f > NUM_FILE_FORMATS) {
|
||||
throw RuntimeError("Invalid file format: "
|
||||
+ std::to_string(f));
|
||||
throw RuntimeError("Invalid file format: " + std::to_string(f));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting file format:" << f;
|
||||
impl()->setFileFormat(f);
|
||||
|
||||
|
||||
auto retval = impl()->getFileFormat();
|
||||
validate(f, retval, "set file format", DEC);
|
||||
LOG(logDEBUG1) << "File Format: " << retval;
|
||||
@ -1106,19 +1114,19 @@ int ClientInterface::get_streaming_port(Interface &socket) {
|
||||
int ClientInterface::set_streaming_source_ip(Interface &socket) {
|
||||
sls::IpAddr arg;
|
||||
socket.Receive(arg);
|
||||
if (arg == 0) {
|
||||
if (arg == 0) {
|
||||
throw RuntimeError("Invalid zmq ip " + arg.str());
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting streaming source ip:" << arg;
|
||||
impl()->setStreamingSourceIP(arg);
|
||||
|
||||
|
||||
sls::IpAddr retval = impl()->getStreamingSourceIP();
|
||||
LOG(logDEBUG1) << "streaming IP:" << retval;
|
||||
if (retval != arg && arg != 0) {
|
||||
std::ostringstream os;
|
||||
os << "Could not set streaming ip. Set " << arg
|
||||
<< ", but read " << retval << '\n';
|
||||
os << "Could not set streaming ip. Set " << arg << ", but read "
|
||||
<< retval << '\n';
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
return socket.Send(OK);
|
||||
@ -1133,13 +1141,12 @@ int ClientInterface::get_streaming_source_ip(Interface &socket) {
|
||||
int ClientInterface::set_silent_mode(Interface &socket) {
|
||||
auto value = socket.Receive<int>();
|
||||
if (value < 0) {
|
||||
throw RuntimeError("Invalid silent mode: "
|
||||
+ std::to_string(value));
|
||||
throw RuntimeError("Invalid silent mode: " + std::to_string(value));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting silent mode:" << value;
|
||||
impl()->setSilentMode(value);
|
||||
|
||||
|
||||
auto retval = static_cast<int>(impl()->getSilentMode());
|
||||
validate(value, retval, "set silent mode", DEC);
|
||||
LOG(logDEBUG1) << "silent mode:" << retval;
|
||||
@ -1173,7 +1180,7 @@ int ClientInterface::set_additional_json_header(Interface &socket) {
|
||||
socket.Receive(args, sizeof(args));
|
||||
for (int i = 0; i < size; ++i) {
|
||||
json[args[2 * i]] = args[2 * i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
verifyIdle(socket);
|
||||
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];
|
||||
memset(retvals, 0, sizeof(retvals));
|
||||
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 + 1], it.second.c_str());
|
||||
iarg += 2;
|
||||
@ -1216,8 +1223,7 @@ int ClientInterface::set_udp_socket_buffer_size(Interface &socket) {
|
||||
return socket.sendResult(retval);
|
||||
}
|
||||
|
||||
int ClientInterface::get_real_udp_socket_buffer_size(
|
||||
Interface &socket) {
|
||||
int ClientInterface::get_real_udp_socket_buffer_size(Interface &socket) {
|
||||
auto size = impl()->getActualUDPSocketBufferSize();
|
||||
LOG(logDEBUG1) << "Actual UDP socket size :" << 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) {
|
||||
auto index = socket.Receive<int>();
|
||||
if (index < 0) {
|
||||
throw RuntimeError("Invalid frames per file: "
|
||||
+ std::to_string(index));
|
||||
throw RuntimeError("Invalid frames per file: " + std::to_string(index));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting frames per file: " << index;
|
||||
impl()->setFramesPerFile(index);
|
||||
|
||||
|
||||
auto retval = static_cast<int>(impl()->getFramesPerFile());
|
||||
validate(index, retval, "set frames per file", DEC);
|
||||
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) {
|
||||
auto arg = socket.Receive<int64_t>();
|
||||
LOG(logDEBUG1) << "Checking versioning compatibility with value "
|
||||
<< arg;
|
||||
LOG(logDEBUG1) << "Checking versioning compatibility with value " << arg;
|
||||
int64_t client_requiredVersion = arg;
|
||||
int64_t rx_apiVersion = APIRECEIVER;
|
||||
int64_t rx_version = getReceiverVersion();
|
||||
@ -1314,15 +1318,14 @@ int ClientInterface::get_padding_enable(Interface &socket) {
|
||||
return socket.sendResult(retval);
|
||||
}
|
||||
|
||||
int ClientInterface::set_deactivated_padding_enable(
|
||||
Interface &socket) {
|
||||
int ClientInterface::set_deactivated_padding_enable(Interface &socket) {
|
||||
auto enable = socket.Receive<int>();
|
||||
if (myDetectorType != EIGER) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
if (enable < 0) {
|
||||
throw RuntimeError("Invalid Deactivated padding: "
|
||||
+ std::to_string(enable));
|
||||
throw RuntimeError("Invalid Deactivated padding: " +
|
||||
std::to_string(enable));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting deactivated padding enable: " << enable;
|
||||
@ -1334,8 +1337,7 @@ int ClientInterface::set_deactivated_padding_enable(
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
||||
int ClientInterface::get_deactivated_padding_enable(
|
||||
Interface &socket) {
|
||||
int ClientInterface::get_deactivated_padding_enable(Interface &socket) {
|
||||
if (myDetectorType != EIGER)
|
||||
functionNotImplemented();
|
||||
auto retval = static_cast<int>(impl()->getDeactivatedPadding());
|
||||
@ -1354,8 +1356,9 @@ int ClientInterface::set_readout_mode(Interface &socket) {
|
||||
LOG(logDEBUG1) << "Setting readout mode: " << arg;
|
||||
try {
|
||||
impl()->setReadoutMode(arg);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set read out mode due to fifo memory allocation.");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError(
|
||||
"Could not set read out mode due to fifo memory allocation.");
|
||||
}
|
||||
}
|
||||
auto retval = impl()->getReadoutMode();
|
||||
@ -1371,8 +1374,9 @@ int ClientInterface::set_adc_mask(Interface &socket) {
|
||||
LOG(logDEBUG1) << "Setting 1Gb ADC enable mask: " << arg;
|
||||
try {
|
||||
impl()->setADCEnableMask(arg);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set adc enable mask due to fifo memory allcoation");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError(
|
||||
"Could not set adc enable mask due to fifo memory allcoation");
|
||||
}
|
||||
auto retval = impl()->getADCEnableMask();
|
||||
if (retval != arg) {
|
||||
@ -1414,13 +1418,12 @@ int ClientInterface::set_dbit_offset(Interface &socket) {
|
||||
if (myDetectorType != CHIPTESTBOARD)
|
||||
functionNotImplemented();
|
||||
if (arg < 0) {
|
||||
throw RuntimeError("Invalid dbit offset: "
|
||||
+ std::to_string(arg));
|
||||
throw RuntimeError("Invalid dbit offset: " + std::to_string(arg));
|
||||
}
|
||||
verifyIdle(socket);
|
||||
LOG(logDEBUG1) << "Setting Dbit offset: " << arg;
|
||||
impl()->setDbitOffset(arg);
|
||||
|
||||
|
||||
int retval = impl()->getDbitOffset();
|
||||
validate(arg, retval, "set dbit offset", DEC);
|
||||
LOG(logDEBUG1) << "Dbit offset retval: " << retval;
|
||||
@ -1442,8 +1445,10 @@ int ClientInterface::set_quad_type(Interface &socket) {
|
||||
LOG(logDEBUG1) << "Setting quad:" << quadEnable;
|
||||
try {
|
||||
impl()->setQuad(quadEnable == 0 ? false : true);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set quad to " + std::to_string(quadEnable) + " due to fifo strucutre memory allocation");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set quad to " +
|
||||
std::to_string(quadEnable) +
|
||||
" due to fifo strucutre memory allocation");
|
||||
}
|
||||
}
|
||||
int retval = impl()->getQuad() ? 1 : 0;
|
||||
@ -1469,12 +1474,14 @@ sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
|
||||
// getting eth
|
||||
std::string eth = sls::IpToInterfaceName(arg.str());
|
||||
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) {
|
||||
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);
|
||||
if (myDetectorType == EIGER) {
|
||||
impl()->setEthernetInterface2(eth);
|
||||
@ -1482,7 +1489,8 @@ sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
|
||||
// get mac address
|
||||
auto retval = sls::InterfaceNameToMac(eth);
|
||||
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;
|
||||
}
|
||||
@ -1500,18 +1508,22 @@ sls::MacAddr ClientInterface::setUdpIp2(sls::IpAddr arg) {
|
||||
// getting eth
|
||||
std::string eth = sls::IpToInterfaceName(arg.str());
|
||||
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) {
|
||||
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);
|
||||
|
||||
// get mac address
|
||||
auto retval = sls::InterfaceNameToMac(eth);
|
||||
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;
|
||||
}
|
||||
@ -1520,7 +1532,8 @@ int ClientInterface::set_udp_ip2(Interface &socket) {
|
||||
auto arg = socket.Receive<sls::IpAddr>();
|
||||
verifyIdle(socket);
|
||||
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;
|
||||
auto retval = setUdpIp2(arg);
|
||||
@ -1540,8 +1553,9 @@ int ClientInterface::set_udp_port2(Interface &socket) {
|
||||
auto arg = socket.Receive<int>();
|
||||
verifyIdle(socket);
|
||||
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;
|
||||
impl()->setUDPPortNumber2(arg);
|
||||
return socket.Send(OK);
|
||||
@ -1552,13 +1566,15 @@ int ClientInterface::set_num_interfaces(Interface &socket) {
|
||||
arg = (arg > 1 ? 2 : 1);
|
||||
verifyIdle(socket);
|
||||
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;
|
||||
try {
|
||||
impl()->setNumberofUDPInterfaces(arg);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Failed to set number of interfaces to " + std::to_string(arg));
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Failed to set number of interfaces to " +
|
||||
std::to_string(arg));
|
||||
}
|
||||
return socket.Send(OK);
|
||||
}
|
||||
@ -1569,8 +1585,9 @@ int ClientInterface::set_adc_mask_10g(Interface &socket) {
|
||||
LOG(logDEBUG1) << "Setting 10Gb ADC enable mask: " << arg;
|
||||
try {
|
||||
impl()->setTenGigaADCEnableMask(arg);
|
||||
} catch(const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set 10Gb adc enable mask due to fifo memory allcoation");
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError(
|
||||
"Could not set 10Gb adc enable mask due to fifo memory allcoation");
|
||||
}
|
||||
auto retval = impl()->getTenGigaADCEnableMask();
|
||||
if (retval != arg) {
|
||||
@ -1600,12 +1617,12 @@ int ClientInterface::increment_file_index(Interface &socket) {
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
||||
|
||||
int ClientInterface::set_additional_json_parameter(Interface &socket) {
|
||||
char args[2][SHORT_STR_LENGTH]{};
|
||||
socket.Receive(args);
|
||||
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]);
|
||||
return socket.Send(OK);
|
||||
}
|
||||
|
37
slsReceiverSoftware/src/ClientInterface.h
Executable file → Normal file
37
slsReceiverSoftware/src/ClientInterface.h
Executable file → Normal file
@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
#include "receiver_defs.h"
|
||||
#include "sls_detector_defs.h"
|
||||
#include "Implementation.h"
|
||||
#include "ServerSocket.h"
|
||||
class MySocketTCP;
|
||||
#include "receiver_defs.h"
|
||||
#include "sls_detector_defs.h"
|
||||
class ServerInterface;
|
||||
|
||||
#include <atomic>
|
||||
@ -19,9 +18,8 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int ret{OK};
|
||||
int fnum{-1};
|
||||
int lockedByClient{0};
|
||||
|
||||
|
||||
std::atomic<bool> killTcpThread{false};
|
||||
|
||||
|
||||
public:
|
||||
virtual ~ClientInterface();
|
||||
@ -30,8 +28,9 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
|
||||
//***callback functions***
|
||||
/** params: filepath, filename, fileindex, datasize */
|
||||
void registerCallBackStartAcquisition(int (*func)(std::string, std::string, uint64_t,
|
||||
uint32_t, void *),
|
||||
void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
|
||||
uint64_t, uint32_t,
|
||||
void *),
|
||||
void *arg);
|
||||
|
||||
/** params: total frames caught */
|
||||
@ -43,7 +42,8 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
void *),
|
||||
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 *,
|
||||
uint32_t &, void *),
|
||||
void *arg);
|
||||
@ -53,9 +53,9 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int functionTable();
|
||||
int decodeFunction(sls::ServerInterface &socket);
|
||||
void functionNotImplemented();
|
||||
void modeNotImplemented(const std::string& modename, int mode);
|
||||
void modeNotImplemented(const std::string &modename, int mode);
|
||||
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 verifyIdle(sls::ServerInterface &socket);
|
||||
|
||||
@ -146,13 +146,13 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
int set_udp_port(sls::ServerInterface &socket);
|
||||
int set_udp_port2(sls::ServerInterface &socket);
|
||||
int set_num_interfaces(sls::ServerInterface &socket);
|
||||
int set_adc_mask_10g(sls::ServerInterface &socket);
|
||||
int set_num_counters(sls::ServerInterface &socket);
|
||||
int set_adc_mask_10g(sls::ServerInterface &socket);
|
||||
int set_num_counters(sls::ServerInterface &socket);
|
||||
int increment_file_index(sls::ServerInterface &socket);
|
||||
int set_additional_json_parameter(sls::ServerInterface &socket);
|
||||
int get_additional_json_parameter(sls::ServerInterface &socket);
|
||||
int get_progress(sls::ServerInterface &socket);
|
||||
|
||||
|
||||
Implementation *impl() {
|
||||
if (receiver != nullptr) {
|
||||
return receiver.get();
|
||||
@ -164,11 +164,11 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
|
||||
int (ClientInterface::*flist[NUM_REC_FUNCTIONS])(
|
||||
sls::ServerInterface &socket);
|
||||
|
||||
|
||||
//***callback parameters***
|
||||
|
||||
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t, uint32_t,
|
||||
void *) = nullptr;
|
||||
|
||||
int (*startAcquisitionCallBack)(std::string, std::string, uint64_t,
|
||||
uint32_t, void *) = nullptr;
|
||||
void *pStartAcquisition{nullptr};
|
||||
void (*acquisitionFinishedCallBack)(uint64_t, void *) = nullptr;
|
||||
void *pAcquisitionFinished{nullptr};
|
||||
@ -176,7 +176,4 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &,
|
||||
void *) = nullptr;
|
||||
void *pRawDataReady{nullptr};
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
671
slsReceiverSoftware/src/DataProcessor.cpp
Executable file → Normal file
671
slsReceiverSoftware/src/DataProcessor.cpp
Executable file → Normal file
@ -5,7 +5,6 @@
|
||||
* and processes data stored in them & writes them to file
|
||||
***********************************************/
|
||||
|
||||
|
||||
#include "DataProcessor.h"
|
||||
#include "BinaryFile.h"
|
||||
#include "Fifo.h"
|
||||
@ -22,241 +21,218 @@
|
||||
|
||||
const std::string DataProcessor::TypeName = "DataProcessor";
|
||||
|
||||
|
||||
DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
|
||||
fileFormat* ftype, bool fwenable, bool* mfwenable,
|
||||
bool* dsEnable, uint32_t* dr,
|
||||
uint32_t* freq, uint32_t* timer,
|
||||
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
|
||||
std::vector <int> * cdl, int* cdo, int* cad) :
|
||||
ThreadObject(ind, TypeName),
|
||||
fifo(f),
|
||||
myDetectorType(dtype),
|
||||
dataStreamEnable(dsEnable),
|
||||
fileFormatType(ftype),
|
||||
fileWriteEnable(fwenable),
|
||||
masterFileWriteEnable(mfwenable),
|
||||
dynamicRange(dr),
|
||||
streamingFrequency(freq),
|
||||
streamingTimerInMs(timer),
|
||||
activated(act),
|
||||
deactivatedPaddingEnable(depaden),
|
||||
silentMode(sm),
|
||||
quadEnable(qe),
|
||||
framePadding(fp),
|
||||
ctbDbitList(cdl),
|
||||
ctbDbitOffset(cdo),
|
||||
ctbAnalogDataBytes(cad)
|
||||
{
|
||||
DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo *f,
|
||||
fileFormat *ftype, bool fwenable, bool *mfwenable,
|
||||
bool *dsEnable, uint32_t *dr, uint32_t *freq,
|
||||
uint32_t *timer, bool *fp, bool *act,
|
||||
bool *depaden, bool *sm, bool *qe,
|
||||
std::vector<int> *cdl, int *cdo, int *cad)
|
||||
: ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype),
|
||||
dataStreamEnable(dsEnable), fileFormatType(ftype),
|
||||
fileWriteEnable(fwenable), 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";
|
||||
memset((void*)&timerBegin, 0, sizeof(timespec));
|
||||
memset((void *)&timerBegin, 0, sizeof(timespec));
|
||||
}
|
||||
|
||||
|
||||
DataProcessor::~DataProcessor() {
|
||||
delete file;
|
||||
}
|
||||
DataProcessor::~DataProcessor() { delete file; }
|
||||
|
||||
/** getters */
|
||||
|
||||
bool DataProcessor::GetStartedFlag(){
|
||||
return startedFlag;
|
||||
}
|
||||
bool DataProcessor::GetStartedFlag() { return startedFlag; }
|
||||
|
||||
uint64_t DataProcessor::GetNumFramesCaught() {
|
||||
return numFramesCaught;
|
||||
}
|
||||
uint64_t DataProcessor::GetNumFramesCaught() { return numFramesCaught; }
|
||||
|
||||
uint64_t DataProcessor::GetCurrentFrameIndex() {
|
||||
return currentFrameIndex;
|
||||
}
|
||||
uint64_t DataProcessor::GetCurrentFrameIndex() { return currentFrameIndex; }
|
||||
|
||||
uint64_t DataProcessor::GetProcessedIndex() {
|
||||
return currentFrameIndex - firstIndex;
|
||||
return currentFrameIndex - firstIndex;
|
||||
}
|
||||
|
||||
void DataProcessor::SetFifo(Fifo* f) {
|
||||
fifo = f;
|
||||
}
|
||||
void DataProcessor::SetFifo(Fifo *f) { fifo = f; }
|
||||
|
||||
void DataProcessor::ResetParametersforNewAcquisition(){
|
||||
StopRunning();
|
||||
startedFlag = false;
|
||||
numFramesCaught = 0;
|
||||
firstIndex = 0;
|
||||
currentFrameIndex = 0;
|
||||
void DataProcessor::ResetParametersforNewAcquisition() {
|
||||
StopRunning();
|
||||
startedFlag = false;
|
||||
numFramesCaught = 0;
|
||||
firstIndex = 0;
|
||||
currentFrameIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
void DataProcessor::RecordFirstIndex(uint64_t fnum) {
|
||||
//listen to this fnum, later +1
|
||||
currentFrameIndex = fnum;
|
||||
// listen to this fnum, later +1
|
||||
currentFrameIndex = fnum;
|
||||
|
||||
startedFlag = true;
|
||||
firstIndex = fnum;
|
||||
startedFlag = true;
|
||||
firstIndex = fnum;
|
||||
|
||||
LOG(logDEBUG1) << index << " First Index:" << firstIndex;
|
||||
LOG(logDEBUG1) << index << " First Index:" << firstIndex;
|
||||
}
|
||||
|
||||
|
||||
void DataProcessor::SetGeneralData(GeneralData* g) {
|
||||
generalData = g;
|
||||
generalData->Print();
|
||||
if (file != nullptr) {
|
||||
if (file->GetFileType() == HDF5) {
|
||||
file->SetNumberofPixels(generalData->nPixelsX, generalData->nPixelsY);
|
||||
}
|
||||
}
|
||||
void DataProcessor::SetGeneralData(GeneralData *g) {
|
||||
generalData = g;
|
||||
generalData->Print();
|
||||
if (file != nullptr) {
|
||||
if (file->GetFileType() == HDF5) {
|
||||
file->SetNumberofPixels(generalData->nPixelsX,
|
||||
generalData->nPixelsY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DataProcessor::SetFileFormat(const fileFormat f) {
|
||||
if ((file != nullptr) && file->GetFileType() != f) {
|
||||
//remember the pointer values before they are destroyed
|
||||
int nd[MAX_DIMENSIONS];nd[0] = 0; nd[1] = 0;
|
||||
uint32_t* maxf = nullptr;
|
||||
std::string* fname=nullptr; std::string* fpath=nullptr;
|
||||
uint64_t* findex=nullptr; bool* owenable=nullptr; int* dindex=nullptr;
|
||||
int* nunits=nullptr; uint64_t* nf = nullptr;
|
||||
uint32_t* dr = nullptr; uint32_t* port = nullptr;
|
||||
file->GetMemberPointerValues(nd, maxf, fname, fpath, findex,
|
||||
owenable, dindex, nunits, nf, dr, port);
|
||||
//create file writer with same pointers
|
||||
SetupFileWriter(fileWriteEnable, nd, maxf, fname, fpath, findex,
|
||||
owenable, dindex, nunits, nf, dr, port);
|
||||
}
|
||||
if ((file != nullptr) && file->GetFileType() != f) {
|
||||
// remember the pointer values before they are destroyed
|
||||
int nd[MAX_DIMENSIONS];
|
||||
nd[0] = 0;
|
||||
nd[1] = 0;
|
||||
uint32_t *maxf = nullptr;
|
||||
std::string *fname = nullptr;
|
||||
std::string *fpath = nullptr;
|
||||
uint64_t *findex = nullptr;
|
||||
bool *owenable = nullptr;
|
||||
int *dindex = nullptr;
|
||||
int *nunits = nullptr;
|
||||
uint64_t *nf = nullptr;
|
||||
uint32_t *dr = nullptr;
|
||||
uint32_t *port = nullptr;
|
||||
file->GetMemberPointerValues(nd, maxf, fname, fpath, findex, owenable,
|
||||
dindex, nunits, nf, dr, port);
|
||||
// create file writer with same pointers
|
||||
SetupFileWriter(fileWriteEnable, nd, maxf, fname, fpath, findex,
|
||||
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,
|
||||
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;
|
||||
if (file != nullptr) {
|
||||
delete file;
|
||||
file = nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (file != nullptr) {
|
||||
delete file;
|
||||
file = nullptr;
|
||||
}
|
||||
|
||||
if (fileWriteEnable) {
|
||||
switch(*fileFormatType){
|
||||
if (fileWriteEnable) {
|
||||
switch (*fileFormatType) {
|
||||
#ifdef HDF5C
|
||||
case HDF5:
|
||||
file = new HDF5File(index, maxf,
|
||||
nd, fname, fpath, findex, owenable,
|
||||
dindex, nunits, nf, dr, portno,
|
||||
generalData->nPixelsX, generalData->nPixelsY, silentMode);
|
||||
break;
|
||||
case HDF5:
|
||||
file = new HDF5File(index, maxf, nd, fname, fpath, findex, owenable,
|
||||
dindex, nunits, nf, dr, portno,
|
||||
generalData->nPixelsX, generalData->nPixelsY,
|
||||
silentMode);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
file = new BinaryFile(index, maxf,
|
||||
nd, fname, fpath, findex, owenable,
|
||||
dindex, nunits, nf, dr, portno, silentMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
file =
|
||||
new BinaryFile(index, maxf, nd, fname, fpath, findex, owenable,
|
||||
dindex, nunits, nf, dr, portno, silentMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// only the first file
|
||||
void DataProcessor::CreateNewFile(masterAttributes& attr) {
|
||||
if (file == nullptr) {
|
||||
throw sls::RuntimeError("file object not contstructed");
|
||||
}
|
||||
file->CloseAllFiles();
|
||||
file->resetSubFileIndex();
|
||||
file->CreateMasterFile(*masterFileWriteEnable, attr);
|
||||
file->CreateFile();
|
||||
void DataProcessor::CreateNewFile(masterAttributes &attr) {
|
||||
if (file == nullptr) {
|
||||
throw sls::RuntimeError("file object not contstructed");
|
||||
}
|
||||
file->CloseAllFiles();
|
||||
file->resetSubFileIndex();
|
||||
file->CreateMasterFile(*masterFileWriteEnable, attr);
|
||||
file->CreateFile();
|
||||
}
|
||||
|
||||
|
||||
void DataProcessor::CloseFiles() {
|
||||
if (file != nullptr)
|
||||
file->CloseAllFiles();
|
||||
if (file != nullptr)
|
||||
file->CloseAllFiles();
|
||||
}
|
||||
|
||||
void DataProcessor::EndofAcquisition(bool anyPacketsCaught, uint64_t numf) {
|
||||
if ((file != nullptr) && file->GetFileType() == HDF5) {
|
||||
try {
|
||||
file->EndofAcquisition(anyPacketsCaught, numf);
|
||||
} catch (const sls::RuntimeError &e) {
|
||||
;// ignore for now //TODO: send error to client via stop receiver
|
||||
}
|
||||
}
|
||||
if ((file != nullptr) && file->GetFileType() == HDF5) {
|
||||
try {
|
||||
file->EndofAcquisition(anyPacketsCaught, numf);
|
||||
} catch (const sls::RuntimeError &e) {
|
||||
; // ignore for now //TODO: send error to client via stop receiver
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DataProcessor::ThreadExecution() {
|
||||
char* buffer=nullptr;
|
||||
fifo->PopAddress(buffer);
|
||||
LOG(logDEBUG5) << "DataProcessor " << index << ", "
|
||||
"pop 0x" << std::hex << (void*)(buffer) << std::dec << ":" << buffer;
|
||||
char *buffer = nullptr;
|
||||
fifo->PopAddress(buffer);
|
||||
LOG(logDEBUG5) << "DataProcessor " << index
|
||||
<< ", "
|
||||
"pop 0x"
|
||||
<< std::hex << (void *)(buffer) << std::dec << ":" << buffer;
|
||||
|
||||
//check dummy
|
||||
auto numBytes = (uint32_t)(*((uint32_t*)buffer));
|
||||
LOG(logDEBUG1) << "DataProcessor " << index << ", Numbytes:" << numBytes;
|
||||
if (numBytes == DUMMY_PACKET_VALUE) {
|
||||
StopProcessing(buffer);
|
||||
return;
|
||||
}
|
||||
// check dummy
|
||||
auto numBytes = (uint32_t)(*((uint32_t *)buffer));
|
||||
LOG(logDEBUG1) << "DataProcessor " << index << ", Numbytes:" << numBytes;
|
||||
if (numBytes == DUMMY_PACKET_VALUE) {
|
||||
StopProcessing(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessAnImage(buffer);
|
||||
ProcessAnImage(buffer);
|
||||
|
||||
//stream (if time/freq to stream) or free
|
||||
if (*dataStreamEnable && SendToStreamer())
|
||||
fifo->PushAddressToStream(buffer);
|
||||
else
|
||||
fifo->FreeAddress(buffer);
|
||||
// stream (if time/freq to stream) or free
|
||||
if (*dataStreamEnable && SendToStreamer())
|
||||
fifo->PushAddressToStream(buffer);
|
||||
else
|
||||
fifo->FreeAddress(buffer);
|
||||
}
|
||||
|
||||
void DataProcessor::StopProcessing(char *buf) {
|
||||
LOG(logDEBUG1) << "DataProcessing " << index << ": Dummy";
|
||||
|
||||
void DataProcessor::StopProcessing(char* buf) {
|
||||
LOG(logDEBUG1) << "DataProcessing " << index << ": Dummy";
|
||||
// stream or free
|
||||
if (*dataStreamEnable)
|
||||
fifo->PushAddressToStream(buf);
|
||||
else
|
||||
fifo->FreeAddress(buf);
|
||||
|
||||
//stream or free
|
||||
if (*dataStreamEnable)
|
||||
fifo->PushAddressToStream(buf);
|
||||
else
|
||||
fifo->FreeAddress(buf);
|
||||
|
||||
if (file != nullptr)
|
||||
file->CloseCurrentFile();
|
||||
StopRunning();
|
||||
LOG(logDEBUG1) << index << ": Processing Completed";
|
||||
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);
|
||||
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;
|
||||
|
||||
LOG(logDEBUG1) << "DataProcessing " << index << ": fnum:" << fnum;
|
||||
if (!startedFlag) {
|
||||
RecordFirstIndex(fnum);
|
||||
|
||||
if (!startedFlag) {
|
||||
RecordFirstIndex(fnum);
|
||||
if (*dataStreamEnable) {
|
||||
// restart timer
|
||||
clock_gettime(CLOCK_REALTIME, &timerBegin);
|
||||
timerBegin.tv_sec -= (*streamingTimerInMs) / 1000;
|
||||
timerBegin.tv_nsec -= ((*streamingTimerInMs) % 1000) * 1000000;
|
||||
|
||||
if (*dataStreamEnable) {
|
||||
//restart timer
|
||||
clock_gettime(CLOCK_REALTIME, &timerBegin);
|
||||
timerBegin.tv_sec -= (*streamingTimerInMs) / 1000;
|
||||
timerBegin.tv_nsec -= ((*streamingTimerInMs) % 1000) * 1000000;
|
||||
|
||||
//to send first image
|
||||
currentFreqCount = *streamingFrequency;
|
||||
}
|
||||
}
|
||||
// to send first image
|
||||
currentFreqCount = *streamingFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
// frame padding
|
||||
if (*activated && *framePadding && nump < generalData->packetsPerFrame)
|
||||
@ -264,208 +240,213 @@ void DataProcessor::ProcessAnImage(char* buf) {
|
||||
|
||||
// deactivated and padding enabled
|
||||
else if (!(*activated) && *deactivatedPaddingEnable)
|
||||
PadMissingPackets(buf);
|
||||
PadMissingPackets(buf);
|
||||
|
||||
// rearrange ctb digital bits (if ctbDbitlist is not empty)
|
||||
if (!(*ctbDbitList).empty()) {
|
||||
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;
|
||||
// rearrange ctb digital bits (if ctbDbitlist is not empty)
|
||||
if (!(*ctbDbitList).empty()) {
|
||||
RearrangeDbitData(buf);
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
// 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
|
||||
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() {
|
||||
//skip
|
||||
if ((*streamingFrequency) == 0u) {
|
||||
if (!CheckTimer())
|
||||
return false;
|
||||
} else {
|
||||
if (!CheckCount())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
// skip
|
||||
if ((*streamingFrequency) == 0u) {
|
||||
if (!CheckTimer())
|
||||
return false;
|
||||
} else {
|
||||
if (!CheckCount())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DataProcessor::CheckTimer() {
|
||||
struct timespec end;
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
struct timespec end;
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
|
||||
LOG(logDEBUG1) << index << " Timer elapsed time:" <<
|
||||
(( end.tv_sec - timerBegin.tv_sec ) + ( end.tv_nsec - timerBegin.tv_nsec ) / 1000000000.0)
|
||||
<< " seconds";
|
||||
//still less than streaming timer, keep waiting
|
||||
if((( end.tv_sec - timerBegin.tv_sec ) + ( end.tv_nsec - timerBegin.tv_nsec )
|
||||
/ 1000000000.0) < ((double)*streamingTimerInMs/1000.00))
|
||||
return false;
|
||||
LOG(logDEBUG1) << index << " Timer elapsed time:"
|
||||
<< ((end.tv_sec - timerBegin.tv_sec) +
|
||||
(end.tv_nsec - timerBegin.tv_nsec) / 1000000000.0)
|
||||
<< " seconds";
|
||||
// still less than streaming timer, keep waiting
|
||||
if (((end.tv_sec - timerBegin.tv_sec) +
|
||||
(end.tv_nsec - timerBegin.tv_nsec) / 1000000000.0) <
|
||||
((double)*streamingTimerInMs / 1000.00))
|
||||
return false;
|
||||
|
||||
//restart timer
|
||||
clock_gettime(CLOCK_REALTIME, &timerBegin);
|
||||
return true;
|
||||
// restart timer
|
||||
clock_gettime(CLOCK_REALTIME, &timerBegin);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DataProcessor::CheckCount() {
|
||||
if (currentFreqCount == *streamingFrequency ) {
|
||||
currentFreqCount = 1;
|
||||
return true;
|
||||
}
|
||||
currentFreqCount++;
|
||||
return false;
|
||||
if (currentFreqCount == *streamingFrequency) {
|
||||
currentFreqCount = 1;
|
||||
return true;
|
||||
}
|
||||
currentFreqCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void DataProcessor::SetPixelDimension() {
|
||||
if (file != nullptr) {
|
||||
if (file->GetFileType() == HDF5) {
|
||||
file->SetNumberofPixels(generalData->nPixelsX, generalData->nPixelsY);
|
||||
}
|
||||
}
|
||||
if (file != nullptr) {
|
||||
if (file->GetFileType() == HDF5) {
|
||||
file->SetNumberofPixels(generalData->nPixelsX,
|
||||
generalData->nPixelsY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DataProcessor::registerCallBackRawDataReady(void (*func)(char* ,
|
||||
char*, uint32_t, void*),void *arg) {
|
||||
rawDataReadyCallBack=func;
|
||||
pRawDataReady=arg;
|
||||
void DataProcessor::registerCallBackRawDataReady(void (*func)(char *, char *,
|
||||
uint32_t, void *),
|
||||
void *arg) {
|
||||
rawDataReadyCallBack = func;
|
||||
pRawDataReady = arg;
|
||||
}
|
||||
|
||||
void DataProcessor::registerCallBackRawDataModifyReady(void (*func)(char* ,
|
||||
char*, uint32_t&, void*),void *arg) {
|
||||
rawDataModifyReadyCallBack=func;
|
||||
pRawDataReady=arg;
|
||||
void DataProcessor::registerCallBackRawDataModifyReady(
|
||||
void (*func)(char *, char *, uint32_t &, void *), void *arg) {
|
||||
rawDataModifyReadyCallBack = func;
|
||||
pRawDataReady = arg;
|
||||
}
|
||||
|
||||
void DataProcessor::PadMissingPackets(char* buf) {
|
||||
LOG(logDEBUG) << index << ": Padding Missing Packets";
|
||||
void DataProcessor::PadMissingPackets(char *buf) {
|
||||
LOG(logDEBUG) << index << ": Padding Missing Packets";
|
||||
|
||||
uint32_t pperFrame = generalData->packetsPerFrame;
|
||||
auto* header = (sls_receiver_header*) (buf + FIFO_HEADER_NUMBYTES);
|
||||
uint32_t nmissing = pperFrame - header->detHeader.packetNumber;
|
||||
sls_bitset pmask = header->packetsMask;
|
||||
uint32_t pperFrame = generalData->packetsPerFrame;
|
||||
auto *header = (sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
|
||||
uint32_t nmissing = pperFrame - header->detHeader.packetNumber;
|
||||
sls_bitset pmask = header->packetsMask;
|
||||
|
||||
uint32_t dsize = generalData->dataSize;
|
||||
uint32_t fifohsize = generalData->fifoBufferHeaderSize;
|
||||
uint32_t corrected_dsize = dsize - ((pperFrame * dsize) - generalData->imageSize);
|
||||
LOG(logDEBUG1) << "bitmask: " << pmask.to_string();
|
||||
uint32_t dsize = generalData->dataSize;
|
||||
uint32_t fifohsize = generalData->fifoBufferHeaderSize;
|
||||
uint32_t corrected_dsize =
|
||||
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
|
||||
if (pmask[pnum])
|
||||
continue;
|
||||
// not missing packet
|
||||
if (pmask[pnum])
|
||||
continue;
|
||||
|
||||
// done with padding, exit loop earlier
|
||||
if (nmissing == 0u)
|
||||
break;
|
||||
// done with padding, exit loop earlier
|
||||
if (nmissing == 0u)
|
||||
break;
|
||||
|
||||
LOG(logDEBUG) << "padding for " << index << " for pnum: " << pnum << std::endl;
|
||||
LOG(logDEBUG) << "padding for " << index << " for pnum: " << pnum
|
||||
<< std::endl;
|
||||
|
||||
// missing packet
|
||||
switch(myDetectorType) {
|
||||
//for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes data
|
||||
// 2nd packet: 4 bytes fnum, previous 1*2 bytes data + 640*2 bytes data !!
|
||||
case GOTTHARD:
|
||||
if(pnum == 0u)
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize-2);
|
||||
else
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize+2);
|
||||
break;
|
||||
case CHIPTESTBOARD:
|
||||
case MOENCH:
|
||||
if (pnum == (pperFrame-1))
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, corrected_dsize);
|
||||
else
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize);
|
||||
break;
|
||||
default:
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize);
|
||||
break;
|
||||
}
|
||||
--nmissing;
|
||||
}
|
||||
// missing packet
|
||||
switch (myDetectorType) {
|
||||
// for gotthard, 1st packet: 4 bytes fnum, CACA +
|
||||
// CACA, 639*2 bytes data
|
||||
// 2nd packet: 4 bytes fnum, previous 1*2 bytes data +
|
||||
// 640*2 bytes data !!
|
||||
case GOTTHARD:
|
||||
if (pnum == 0u)
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize - 2);
|
||||
else
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize + 2);
|
||||
break;
|
||||
case CHIPTESTBOARD:
|
||||
case MOENCH:
|
||||
if (pnum == (pperFrame - 1))
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, corrected_dsize);
|
||||
else
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize);
|
||||
break;
|
||||
default:
|
||||
memset(buf + fifohsize + (pnum * dsize), 0xFF, dsize);
|
||||
break;
|
||||
}
|
||||
--nmissing;
|
||||
}
|
||||
}
|
||||
|
||||
/** ctb specific */
|
||||
void DataProcessor::RearrangeDbitData(char* buf) {
|
||||
int totalSize = (int)(*((uint32_t*)buf));
|
||||
int ctbDigitalDataBytes = totalSize - (*ctbAnalogDataBytes) - (*ctbDbitOffset);
|
||||
void DataProcessor::RearrangeDbitData(char *buf) {
|
||||
int totalSize = (int)(*((uint32_t *)buf));
|
||||
int ctbDigitalDataBytes =
|
||||
totalSize - (*ctbAnalogDataBytes) - (*ctbDbitOffset);
|
||||
|
||||
// no digital data
|
||||
// no digital data
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
memcpy(buf + digOffset, result, numResult8Bits * sizeof(uint8_t));
|
||||
(*((uint32_t*)buf)) = numResult8Bits * sizeof(uint8_t);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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
569
slsReceiverSoftware/src/DataProcessor.h
Executable file → Normal file
@ -17,308 +17,141 @@ class Fifo;
|
||||
class File;
|
||||
class DataStreamer;
|
||||
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofDataProcessors
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Calls Base Class CreateThread(), sets ErrorMask if error and increments
|
||||
* NumberofDataProcessors
|
||||
* @param ind self index
|
||||
* @param dtype detector type
|
||||
* @param f address of Fifo pointer
|
||||
* @param ftype pointer to file format type
|
||||
* @param fwenable file writer enable
|
||||
* @apram mfwenable pointer to master file write enable
|
||||
* @param dsEnable pointer to data stream enable
|
||||
* @param dr pointer to dynamic range
|
||||
* @param freq pointer to streaming frequency
|
||||
* @param timer pointer to timer if streaming frequency is random
|
||||
* @param fp pointer to frame padding enable
|
||||
* @param act pointer to activated
|
||||
* @param depaden pointer to deactivated padding enable
|
||||
* @param sm pointer to silent mode
|
||||
* @param qe pointer to quad Enable
|
||||
* @param cdl pointer to vector or ctb digital bits enable
|
||||
* @param cdo pointer to digital bits offset
|
||||
* @param cad pointer to ctb analog databytes
|
||||
*/
|
||||
DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat* ftype,
|
||||
bool fwenable, bool* mfwenable, bool* dsEnable, uint32_t* dr,
|
||||
uint32_t* freq, uint32_t* timer,
|
||||
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
|
||||
std::vector <int> * cdl, 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);
|
||||
* @param f address of Fifo pointer
|
||||
* @param ftype pointer to file format type
|
||||
* @param fwenable file writer enable
|
||||
* @apram mfwenable pointer to master file write enable
|
||||
* @param dsEnable pointer to data stream enable
|
||||
* @param dr pointer to dynamic range
|
||||
* @param freq pointer to streaming frequency
|
||||
* @param timer pointer to timer if streaming frequency is random
|
||||
* @param fp pointer to frame padding enable
|
||||
* @param act pointer to activated
|
||||
* @param depaden pointer to deactivated padding enable
|
||||
* @param sm pointer to silent mode
|
||||
* @param qe pointer to quad Enable
|
||||
* @param cdl pointer to vector or ctb digital bits enable
|
||||
* @param cdo pointer to digital bits offset
|
||||
* @param cad pointer to ctb analog databytes
|
||||
*/
|
||||
DataProcessor(int ind, detectorType dtype, Fifo *f, fileFormat *ftype,
|
||||
bool fwenable, bool *mfwenable, bool *dsEnable, uint32_t *dr,
|
||||
uint32_t *freq, uint32_t *timer, bool *fp, bool *act,
|
||||
bool *depaden, bool *sm, bool *qe, std::vector<int> *cdl,
|
||||
int *cdo, int *cad);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* Destructor
|
||||
* Calls Base Class DestroyThread() and decrements NumberofDataProcessors
|
||||
*/
|
||||
void registerCallBackRawDataModifyReady(void (*func)(char* ,
|
||||
char*, uint32_t &, void*),void *arg);
|
||||
~DataProcessor() override;
|
||||
|
||||
//*** 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
|
||||
* @param fnum frame index to record
|
||||
*/
|
||||
void RecordFirstIndex(uint64_t fnum);
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* Thread Exeution for DataProcessor Class
|
||||
* Pop bound addresses, process them,
|
||||
* write to file if needed & free the address
|
||||
*/
|
||||
void ThreadExecution() override;
|
||||
/**
|
||||
* Get Current Frame Index thats been processed
|
||||
* @return -1 if no frames have been caught, else current frame index
|
||||
*/
|
||||
uint64_t GetProcessedIndex();
|
||||
|
||||
/**
|
||||
* Frees dummy buffer,
|
||||
* reset running mask by calling StopRunning()
|
||||
* @param buf address of pointer
|
||||
*/
|
||||
void StopProcessing(char* buf);
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
* @param f address of Fifo pointer
|
||||
*/
|
||||
void SetFifo(Fifo *f);
|
||||
|
||||
/**
|
||||
* Process an image popped from fifo,
|
||||
* write to file if fw enabled & update parameters
|
||||
* @param buffer
|
||||
*/
|
||||
void ProcessAnImage(char* buf);
|
||||
/**
|
||||
* Reset parameters for new acquisition
|
||||
*/
|
||||
void ResetParametersforNewAcquisition();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
/**
|
||||
* Set GeneralData pointer to the one given
|
||||
* @param g address of GeneralData (Detector Data) pointer
|
||||
*/
|
||||
void SetGeneralData(GeneralData *g);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
/**
|
||||
* Set File Format
|
||||
* @param f file format
|
||||
*/
|
||||
void SetFileFormat(const fileFormat fs);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Pad Missing Packets from the bit mask
|
||||
* @param buf buffer
|
||||
*/
|
||||
void PadMissingPackets(char* buf);
|
||||
/**
|
||||
* Create New File
|
||||
* @param attr master file attributes
|
||||
*/
|
||||
void CreateNewFile(masterAttributes &attr);
|
||||
|
||||
/**
|
||||
* Align corresponding digital bits together (CTB only if ctbDbitlist is not empty)
|
||||
*/
|
||||
void RearrangeDbitData(char* buf);
|
||||
/**
|
||||
* Closes files
|
||||
*/
|
||||
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
|
||||
* 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
|
||||
* dataSize in bytes is the size of the data in bytes.
|
||||
*/
|
||||
void (*rawDataReadyCallBack)(char*,
|
||||
char*, uint32_t, void*) = nullptr;
|
||||
void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
|
||||
void *),
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* 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};
|
||||
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
|
||||
uint32_t &, void *),
|
||||
void *arg);
|
||||
|
||||
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
317
slsReceiverSoftware/src/DataStreamer.cpp
Executable file → Normal file
@ -3,7 +3,6 @@
|
||||
* @short streams data from receiver via ZMQ
|
||||
***********************************************/
|
||||
|
||||
|
||||
#include "DataStreamer.h"
|
||||
#include "Fifo.h"
|
||||
#include "GeneralData.h"
|
||||
@ -15,211 +14,210 @@
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
|
||||
DataStreamer::~DataStreamer() {
|
||||
CloseZmqSocket();
|
||||
delete [] completeBuffer;
|
||||
CloseZmqSocket();
|
||||
delete[] completeBuffer;
|
||||
}
|
||||
|
||||
void DataStreamer::SetFifo(Fifo* f) {
|
||||
fifo = f;
|
||||
}
|
||||
void DataStreamer::SetFifo(Fifo *f) { fifo = f; }
|
||||
|
||||
void DataStreamer::ResetParametersforNewAcquisition(const std::string& fname){
|
||||
void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
|
||||
StopRunning();
|
||||
startedFlag = false;
|
||||
firstIndex = 0;
|
||||
startedFlag = false;
|
||||
firstIndex = 0;
|
||||
|
||||
fileNametoStream = fname;
|
||||
if (completeBuffer) {
|
||||
delete[] completeBuffer;
|
||||
completeBuffer = nullptr;
|
||||
}
|
||||
if (roi->xmin != -1) {
|
||||
if (generalData->myDetectorType == GOTTHARD) {
|
||||
adcConfigured = generalData->GetAdcConfigured(index, *roi);
|
||||
}
|
||||
completeBuffer = new char[generalData->imageSizeComplete];
|
||||
memset(completeBuffer, 0, generalData->imageSizeComplete);
|
||||
}
|
||||
delete[] completeBuffer;
|
||||
completeBuffer = nullptr;
|
||||
}
|
||||
if (roi->xmin != -1) {
|
||||
if (generalData->myDetectorType == GOTTHARD) {
|
||||
adcConfigured = generalData->GetAdcConfigured(index, *roi);
|
||||
}
|
||||
completeBuffer = new char[generalData->imageSizeComplete];
|
||||
memset(completeBuffer, 0, generalData->imageSizeComplete);
|
||||
}
|
||||
}
|
||||
|
||||
void DataStreamer::RecordFirstIndex(uint64_t fnum) {
|
||||
startedFlag = true;
|
||||
firstIndex = fnum;
|
||||
startedFlag = true;
|
||||
firstIndex = fnum;
|
||||
|
||||
LOG(logDEBUG1) << index << " First Index: " << firstIndex;
|
||||
LOG(logDEBUG1) << index << " First Index: " << firstIndex;
|
||||
}
|
||||
|
||||
void DataStreamer::SetGeneralData(GeneralData* g) {
|
||||
generalData = g;
|
||||
generalData->Print();
|
||||
void DataStreamer::SetGeneralData(GeneralData *g) {
|
||||
generalData = g;
|
||||
generalData->Print();
|
||||
}
|
||||
|
||||
void DataStreamer::SetNumberofDetectors(int* nd) {
|
||||
numDet[0] = nd[0];
|
||||
numDet[1] = nd[1];
|
||||
void DataStreamer::SetNumberofDetectors(int *nd) {
|
||||
numDet[0] = nd[0];
|
||||
numDet[1] = nd[1];
|
||||
}
|
||||
|
||||
void DataStreamer::SetFlippedDataX(int fd) {
|
||||
flippedDataX = fd;
|
||||
void DataStreamer::SetFlippedDataX(int 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) {
|
||||
additionJsonHeader = json;
|
||||
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::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() {
|
||||
if (zmqSocket) {
|
||||
delete zmqSocket;
|
||||
zmqSocket = nullptr;
|
||||
}
|
||||
if (zmqSocket) {
|
||||
delete zmqSocket;
|
||||
zmqSocket = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DataStreamer::ThreadExecution() {
|
||||
char* buffer=nullptr;
|
||||
fifo->PopAddressToStream(buffer);
|
||||
LOG(logDEBUG5) << "DataStreamer " << index << ", "
|
||||
"pop 0x" << std::hex << (void*)(buffer) << std::dec << ":" << buffer;
|
||||
char *buffer = nullptr;
|
||||
fifo->PopAddressToStream(buffer);
|
||||
LOG(logDEBUG5) << "DataStreamer " << index
|
||||
<< ", "
|
||||
"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
|
||||
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);
|
||||
ProcessAnImage(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) {
|
||||
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;
|
||||
}
|
||||
|
||||
fifo->FreeAddress(buf);
|
||||
StopRunning();
|
||||
LOG(logDEBUG1) << index << ": Streaming Completed";
|
||||
fifo->FreeAddress(buf);
|
||||
StopRunning();
|
||||
LOG(logDEBUG1) << index << ": Streaming Completed";
|
||||
}
|
||||
|
||||
/** 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);
|
||||
uint64_t fnum = header->detHeader.frameNumber;
|
||||
LOG(logDEBUG1) << "DataStreamer " << index << ": fnum:" << fnum;
|
||||
sls_receiver_header *header =
|
||||
(sls_receiver_header *)(buf + FIFO_HEADER_NUMBYTES);
|
||||
uint64_t fnum = header->detHeader.frameNumber;
|
||||
LOG(logDEBUG1) << "DataStreamer " << index << ": fnum:" << fnum;
|
||||
|
||||
if (!startedFlag) {
|
||||
RecordFirstIndex(fnum);
|
||||
}
|
||||
if (!startedFlag) {
|
||||
RecordFirstIndex(fnum);
|
||||
}
|
||||
|
||||
//shortframe gotthard
|
||||
if (completeBuffer) {
|
||||
// shortframe gotthard
|
||||
if (completeBuffer) {
|
||||
|
||||
//disregarding the size modified from callback (always using imageSizeComplete
|
||||
// instead of buf (32 bit) because gui needs imagesizecomplete and listener
|
||||
//write imagesize
|
||||
// disregarding the size modified from callback (always using
|
||||
// imageSizeComplete
|
||||
// instead of buf (32 bit) because gui needs imagesizecomplete and
|
||||
// listener
|
||||
// write imagesize
|
||||
|
||||
if (!SendHeader(header, generalData->imageSizeComplete,
|
||||
generalData->nPixelsXComplete, generalData->nPixelsYComplete, false)) {
|
||||
LOG(logERROR) << "Could not send zmq header for fnum " << fnum << " and streamer " << index;
|
||||
}
|
||||
memcpy(completeBuffer + ((generalData->imageSize) * adcConfigured),
|
||||
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
|
||||
(uint32_t)(*((uint32_t*)buf)) );
|
||||
if (!SendHeader(header, generalData->imageSizeComplete,
|
||||
generalData->nPixelsXComplete,
|
||||
generalData->nPixelsYComplete, false)) {
|
||||
LOG(logERROR) << "Could not send zmq header for fnum " << fnum
|
||||
<< " and streamer " << index;
|
||||
}
|
||||
memcpy(completeBuffer + ((generalData->imageSize) * adcConfigured),
|
||||
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
|
||||
(uint32_t)(*((uint32_t *)buf)));
|
||||
|
||||
if (!zmqSocket->SendData(completeBuffer, generalData->imageSizeComplete)) {
|
||||
LOG(logERROR) << "Could not send zmq data for fnum " << fnum << " and streamer " << index;
|
||||
}
|
||||
}
|
||||
if (!zmqSocket->SendData(completeBuffer,
|
||||
generalData->imageSizeComplete)) {
|
||||
LOG(logERROR) << "Could not send zmq data for fnum " << fnum
|
||||
<< " and streamer " << index;
|
||||
}
|
||||
}
|
||||
|
||||
// normal
|
||||
else {
|
||||
|
||||
//normal
|
||||
else {
|
||||
|
||||
if (!SendHeader(header, (uint32_t)(*((uint32_t*)buf)),
|
||||
generalData->nPixelsX, generalData->nPixelsY, false)) {// new size possibly from callback
|
||||
LOG(logERROR) << "Could not send zmq header for fnum " << fnum << " and streamer " << index;
|
||||
}
|
||||
if (!zmqSocket->SendData(buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
|
||||
(uint32_t)(*((uint32_t*)buf)) )) {// new size possibly from callback
|
||||
LOG(logERROR) << "Could not send zmq data for fnum " << fnum << " and streamer " << index;
|
||||
}
|
||||
}
|
||||
if (!SendHeader(header, (uint32_t)(*((uint32_t *)buf)),
|
||||
generalData->nPixelsX, generalData->nPixelsY,
|
||||
false)) { // new size possibly from callback
|
||||
LOG(logERROR) << "Could not send zmq header for fnum " << fnum
|
||||
<< " and streamer " << index;
|
||||
}
|
||||
if (!zmqSocket->SendData(
|
||||
buf + FIFO_HEADER_NUMBYTES + sizeof(sls_receiver_header),
|
||||
(uint32_t)(
|
||||
*((uint32_t *)buf)))) { // new size possibly from callback
|
||||
LOG(logERROR) << "Could not send zmq data for fnum " << fnum
|
||||
<< " and streamer " << index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int DataStreamer::SendHeader(sls_receiver_header *rheader, uint32_t size,
|
||||
uint32_t nx, uint32_t ny, bool dummy) {
|
||||
|
||||
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;
|
||||
zHeader.data = !dummy;
|
||||
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
|
||||
sls_detector_header header = rheader->detHeader;
|
||||
|
||||
if (dummy) {
|
||||
return zmqSocket->SendHeader(index, zHeader);
|
||||
}
|
||||
uint64_t frameIndex = header.frameNumber - firstIndex;
|
||||
uint64_t acquisitionIndex = header.frameNumber;
|
||||
|
||||
sls_detector_header header = rheader->detHeader;
|
||||
|
||||
uint64_t frameIndex = header.frameNumber - firstIndex;
|
||||
uint64_t acquisitionIndex = header.frameNumber;
|
||||
|
||||
zHeader.dynamicRange = *dynamicRange;
|
||||
zHeader.fileIndex = *fileIndex;
|
||||
zHeader.ndetx = numDet[0];
|
||||
zHeader.ndety = numDet[1];
|
||||
zHeader.dynamicRange = *dynamicRange;
|
||||
zHeader.fileIndex = *fileIndex;
|
||||
zHeader.ndetx = numDet[0];
|
||||
zHeader.ndety = numDet[1];
|
||||
zHeader.npixelsx = nx;
|
||||
zHeader.npixelsy = ny;
|
||||
zHeader.imageSize = size;
|
||||
zHeader.acqIndex = acquisitionIndex;
|
||||
zHeader.frameIndex = frameIndex;
|
||||
zHeader.progress = 100 * ((double)(frameIndex + 1) / (double)(*totalNumFrames));
|
||||
zHeader.fname = fileNametoStream;
|
||||
zHeader.progress =
|
||||
100 * ((double)(frameIndex + 1) / (double)(*totalNumFrames));
|
||||
zHeader.fname = fileNametoStream;
|
||||
zHeader.frameNumber = header.frameNumber;
|
||||
zHeader.expLength = header.expLength;
|
||||
zHeader.packetNumber = header.packetNumber;
|
||||
@ -235,23 +233,22 @@ int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32
|
||||
zHeader.version = header.version;
|
||||
zHeader.flippedDataX = flippedDataX;
|
||||
zHeader.quad = *quadEnable;
|
||||
zHeader.completeImage = (header.packetNumber < generalData->packetsPerFrame ? false : true);
|
||||
zHeader.completeImage =
|
||||
(header.packetNumber < generalData->packetsPerFrame ? false : true);
|
||||
zHeader.addJsonHeader = additionJsonHeader;
|
||||
|
||||
return zmqSocket->SendHeader(index, zHeader);
|
||||
return zmqSocket->SendHeader(index, zHeader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataStreamer::RestreamStop() {
|
||||
//send dummy header
|
||||
zmqHeader zHeader;
|
||||
zHeader.data = false;
|
||||
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
|
||||
int ret = zmqSocket->SendHeader(index, zHeader);
|
||||
if (!ret) {
|
||||
throw sls::RuntimeError("Could not restream Dummy Header via ZMQ for port " + std::to_string(zmqSocket->GetPortNumber()));
|
||||
}
|
||||
// send dummy header
|
||||
zmqHeader zHeader;
|
||||
zHeader.data = false;
|
||||
zHeader.jsonversion = SLS_DETECTOR_JSON_HEADER_VERSION;
|
||||
int ret = zmqSocket->SendHeader(index, zHeader);
|
||||
if (!ret) {
|
||||
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
273
slsReceiverSoftware/src/DataStreamer.h
Executable file → Normal file
@ -18,174 +18,173 @@ class ZmqSocket;
|
||||
#include <map>
|
||||
|
||||
class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofDataStreamers
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Calls Base Class CreateThread(), sets ErrorMask if error and increments
|
||||
* NumberofDataStreamers
|
||||
* @param ind self index
|
||||
* @param f address of Fifo pointer
|
||||
* @param dr pointer to dynamic range
|
||||
* @param r roi
|
||||
* @param fi pointer to file index
|
||||
* @param fd flipped data enable for x dimension
|
||||
* @param nd pointer to number of detectors in each dimension
|
||||
* @param qe pointer to quad Enable
|
||||
* @param tot pointer to total number of frames
|
||||
*/
|
||||
DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
|
||||
uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot);
|
||||
* @param f address of Fifo pointer
|
||||
* @param dr pointer to dynamic range
|
||||
* @param r roi
|
||||
* @param fi pointer to file index
|
||||
* @param fd flipped data enable for x dimension
|
||||
* @param nd pointer to number of detectors in each dimension
|
||||
* @param qe pointer to quad Enable
|
||||
* @param tot pointer to total number of frames
|
||||
*/
|
||||
DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi, int fd,
|
||||
int *nd, bool *qe, uint64_t *tot);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* Calls Base Class DestroyThread() and decrements NumberofDataStreamers
|
||||
*/
|
||||
~DataStreamer();
|
||||
/**
|
||||
* Destructor
|
||||
* Calls Base Class DestroyThread() and decrements NumberofDataStreamers
|
||||
*/
|
||||
~DataStreamer();
|
||||
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
* @param f address of Fifo pointer
|
||||
*/
|
||||
void SetFifo(Fifo* f);
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
* @param f address of Fifo pointer
|
||||
*/
|
||||
void SetFifo(Fifo *f);
|
||||
|
||||
/**
|
||||
* Reset parameters for new acquisition
|
||||
*/
|
||||
void ResetParametersforNewAcquisition(const std::string& fname);
|
||||
/**
|
||||
* Reset parameters for new acquisition
|
||||
*/
|
||||
void ResetParametersforNewAcquisition(const std::string &fname);
|
||||
|
||||
/**
|
||||
* Set GeneralData pointer to the one given
|
||||
* @param g address of GeneralData (Detector Data) pointer
|
||||
*/
|
||||
void SetGeneralData(GeneralData* g);
|
||||
/**
|
||||
* Set GeneralData pointer to the one given
|
||||
* @param g address of GeneralData (Detector Data) pointer
|
||||
*/
|
||||
void SetGeneralData(GeneralData *g);
|
||||
|
||||
/**
|
||||
* Set number of detectors
|
||||
* @param number of detectors in both dimensions
|
||||
*/
|
||||
void SetNumberofDetectors(int* nd);
|
||||
/**
|
||||
* Set number of detectors
|
||||
* @param number of detectors in both dimensions
|
||||
*/
|
||||
void SetNumberofDetectors(int *nd);
|
||||
|
||||
/**
|
||||
* Set Flipped data enable across x dimension
|
||||
* @param flipped data enable in x dimension
|
||||
*/
|
||||
void SetFlippedDataX(int fd);
|
||||
/**
|
||||
* Set Flipped data enable across x dimension
|
||||
* @param flipped data enable in x dimension
|
||||
*/
|
||||
void SetFlippedDataX(int fd);
|
||||
|
||||
/**
|
||||
* Set additional json header
|
||||
* @param json additional json header
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* Set additional json header
|
||||
* @param json additional json header
|
||||
*/
|
||||
void
|
||||
SetAdditionalJsonHeader(const std::map<std::string, std::string> &json);
|
||||
|
||||
/**
|
||||
* Shuts down and deletes Zmq Sockets
|
||||
*/
|
||||
void CloseZmqSocket();
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Restream stop dummy packet
|
||||
*/
|
||||
void RestreamStop();
|
||||
/**
|
||||
* Shuts down and deletes Zmq Sockets
|
||||
*/
|
||||
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
|
||||
* @param fnum frame index to record
|
||||
*/
|
||||
void RecordFirstIndex(uint64_t fnum);
|
||||
/**
|
||||
* Thread Exeution for DataStreamer Class
|
||||
* Stream an image via zmq
|
||||
*/
|
||||
void ThreadExecution();
|
||||
|
||||
/**
|
||||
* Thread Exeution for DataStreamer Class
|
||||
* Stream an image via zmq
|
||||
*/
|
||||
void ThreadExecution();
|
||||
/**
|
||||
* Frees dummy buffer,
|
||||
* reset running mask by calling StopRunning()
|
||||
* @param buf address of pointer
|
||||
*/
|
||||
void StopProcessing(char *buf);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Process an image popped from fifo,
|
||||
* write to file if fw enabled & update parameters
|
||||
* @param buffer
|
||||
*/
|
||||
void ProcessAnImage(char* buf);
|
||||
/**
|
||||
* Create and send Json Header
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Create and send Json Header
|
||||
* @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 */
|
||||
static const std::string TypeName;
|
||||
|
||||
/** type of thread */
|
||||
static const std::string TypeName;
|
||||
/** GeneralData (Detector Data) object */
|
||||
const GeneralData *generalData{nullptr};
|
||||
|
||||
/** GeneralData (Detector Data) object */
|
||||
const GeneralData* generalData{nullptr};
|
||||
/** Fifo structure */
|
||||
Fifo *fifo;
|
||||
|
||||
/** Fifo structure */
|
||||
Fifo* fifo;
|
||||
/** ZMQ Socket - Receiver to Client */
|
||||
ZmqSocket *zmqSocket{nullptr};
|
||||
|
||||
/** ZMQ Socket - Receiver to Client */
|
||||
ZmqSocket* zmqSocket{nullptr};
|
||||
/** Pointer to dynamic range */
|
||||
uint32_t *dynamicRange;
|
||||
|
||||
/** Pointer to dynamic range */
|
||||
uint32_t* dynamicRange;
|
||||
/** ROI */
|
||||
ROI *roi;
|
||||
|
||||
/** ROI */
|
||||
ROI* roi;
|
||||
/** adc Configured */
|
||||
int adcConfigured{-1};
|
||||
|
||||
/** adc Configured */
|
||||
int adcConfigured{-1};
|
||||
/** Pointer to file index */
|
||||
uint64_t *fileIndex;
|
||||
|
||||
/** Pointer to file index */
|
||||
uint64_t* fileIndex;
|
||||
/** flipped data across x axis */
|
||||
int flippedDataX;
|
||||
|
||||
/** flipped data across x axis */
|
||||
int flippedDataX;
|
||||
/** additional json header */
|
||||
std::map<std::string, std::string> additionJsonHeader;
|
||||
|
||||
/** additional json header */
|
||||
std::map<std::string, std::string> additionJsonHeader;
|
||||
/** Aquisition Started flag */
|
||||
bool startedFlag{nullptr};
|
||||
|
||||
/** Aquisition Started flag */
|
||||
bool startedFlag{nullptr};
|
||||
/** Frame Number of First Frame */
|
||||
uint64_t firstIndex{0};
|
||||
|
||||
/** Frame Number of First Frame */
|
||||
uint64_t firstIndex{0};
|
||||
/* File name to stream */
|
||||
std::string fileNametoStream;
|
||||
|
||||
/* File name to stream */
|
||||
std::string fileNametoStream;
|
||||
/** Complete buffer used for roi, eg. shortGotthard */
|
||||
char *completeBuffer{nullptr};
|
||||
|
||||
/** Complete buffer used for roi, eg. shortGotthard */
|
||||
char* completeBuffer{nullptr};
|
||||
/** Number of Detectors in X and Y dimension */
|
||||
int numDet[2];
|
||||
|
||||
/** Number of Detectors in X and Y dimension */
|
||||
int numDet[2];
|
||||
|
||||
/** Quad Enable */
|
||||
bool* quadEnable;
|
||||
|
||||
/** Total number of frames */
|
||||
uint64_t* totalNumFrames;
|
||||
/** Quad Enable */
|
||||
bool *quadEnable;
|
||||
|
||||
/** Total number of frames */
|
||||
uint64_t *totalNumFrames;
|
||||
};
|
||||
|
||||
|
162
slsReceiverSoftware/src/Fifo.cpp
Executable file → Normal file
162
slsReceiverSoftware/src/Fifo.cpp
Executable file → Normal file
@ -13,120 +13,104 @@
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
Fifo::Fifo(int ind, uint32_t fifoItemSize, uint32_t depth):
|
||||
index(ind),
|
||||
memory(nullptr),
|
||||
fifoBound(nullptr),
|
||||
fifoFree(nullptr),
|
||||
fifoStream(nullptr),
|
||||
fifoDepth(depth),
|
||||
status_fifoBound(0),
|
||||
status_fifoFree(depth){
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
CreateFifos(fifoItemSize);
|
||||
Fifo::Fifo(int ind, uint32_t fifoItemSize, uint32_t depth)
|
||||
: index(ind), memory(nullptr), fifoBound(nullptr), fifoFree(nullptr),
|
||||
fifoStream(nullptr), fifoDepth(depth), status_fifoBound(0),
|
||||
status_fifoFree(depth) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
CreateFifos(fifoItemSize);
|
||||
}
|
||||
|
||||
|
||||
Fifo::~Fifo() {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
DestroyFifos();
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
DestroyFifos();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Fifo::CreateFifos(uint32_t fifoItemSize) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
//destroy if not already
|
||||
DestroyFifos();
|
||||
// destroy if not already
|
||||
DestroyFifos();
|
||||
|
||||
//create fifos
|
||||
fifoBound = new CircularFifo<char>(fifoDepth);
|
||||
fifoFree = new CircularFifo<char>(fifoDepth);
|
||||
fifoStream = new CircularFifo<char>(fifoDepth);
|
||||
//allocate memory
|
||||
size_t mem_len = (size_t)fifoItemSize * (size_t)fifoDepth * sizeof(char);
|
||||
memory = (char*) malloc (mem_len);
|
||||
if (memory == nullptr){
|
||||
throw sls::RuntimeError("Could not allocate memory for fifos");
|
||||
}
|
||||
// create fifos
|
||||
fifoBound = new CircularFifo<char>(fifoDepth);
|
||||
fifoFree = new CircularFifo<char>(fifoDepth);
|
||||
fifoStream = new CircularFifo<char>(fifoDepth);
|
||||
// allocate memory
|
||||
size_t mem_len = (size_t)fifoItemSize * (size_t)fifoDepth * sizeof(char);
|
||||
memory = (char *)malloc(mem_len);
|
||||
if (memory == nullptr) {
|
||||
throw sls::RuntimeError("Could not allocate memory for fifos");
|
||||
}
|
||||
memset(memory, 0, mem_len);
|
||||
int pagesize = getpagesize();
|
||||
for (size_t i = 0; i < mem_len; i += pagesize) {
|
||||
strcpy(memory + i, "memory");
|
||||
}
|
||||
LOG(logDEBUG) << "Memory Allocated " << index << ": " << (double)mem_len/(double)(1024 * 1024) << " MB";
|
||||
int pagesize = getpagesize();
|
||||
for (size_t i = 0; i < mem_len; i += pagesize) {
|
||||
strcpy(memory + i, "memory");
|
||||
}
|
||||
LOG(logDEBUG) << "Memory Allocated " << index << ": "
|
||||
<< (double)mem_len / (double)(1024 * 1024) << " MB";
|
||||
|
||||
{ //push free addresses into fifoFree fifo
|
||||
char* buffer = memory;
|
||||
for (int i = 0; i < fifoDepth; ++i) {
|
||||
//sprintf(buffer,"memory");
|
||||
FreeAddress(buffer);
|
||||
buffer += fifoItemSize;
|
||||
}
|
||||
}
|
||||
LOG(logINFO) << "Fifo " << index << " reconstructed Depth (rx_fifodepth): " << fifoFree->getDataValue();
|
||||
{ // push free addresses into fifoFree fifo
|
||||
char *buffer = memory;
|
||||
for (int i = 0; i < fifoDepth; ++i) {
|
||||
// sprintf(buffer,"memory");
|
||||
FreeAddress(buffer);
|
||||
buffer += fifoItemSize;
|
||||
}
|
||||
}
|
||||
LOG(logINFO) << "Fifo " << index << " reconstructed Depth (rx_fifodepth): "
|
||||
<< fifoFree->getDataValue();
|
||||
}
|
||||
|
||||
void Fifo::DestroyFifos() {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
void Fifo::DestroyFifos(){
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
if(memory) {
|
||||
free(memory);
|
||||
memory = nullptr;
|
||||
}
|
||||
delete fifoBound;
|
||||
fifoBound = nullptr;
|
||||
delete fifoFree;
|
||||
fifoFree = nullptr;
|
||||
delete fifoStream;
|
||||
fifoStream = nullptr;
|
||||
if (memory) {
|
||||
free(memory);
|
||||
memory = nullptr;
|
||||
}
|
||||
delete fifoBound;
|
||||
fifoBound = nullptr;
|
||||
delete fifoFree;
|
||||
fifoFree = nullptr;
|
||||
delete fifoStream;
|
||||
fifoStream = nullptr;
|
||||
}
|
||||
|
||||
void Fifo::FreeAddress(char *&address) { fifoFree->push(address); }
|
||||
|
||||
void Fifo::FreeAddress(char*& address) {
|
||||
fifoFree->push(address);
|
||||
void Fifo::GetNewAddress(char *&address) {
|
||||
int temp = fifoFree->getDataValue();
|
||||
if (temp < status_fifoFree)
|
||||
status_fifoFree = temp;
|
||||
fifoFree->pop(address);
|
||||
}
|
||||
|
||||
void Fifo::GetNewAddress(char*& address) {
|
||||
int temp = fifoFree->getDataValue();
|
||||
if (temp < status_fifoFree)
|
||||
status_fifoFree = temp;
|
||||
fifoFree->pop(address);
|
||||
void Fifo::PushAddress(char *&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::PushAddress(char*& 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) { fifoBound->pop(address); }
|
||||
|
||||
void Fifo::PopAddress(char*& address) {
|
||||
fifoBound->pop(address);
|
||||
}
|
||||
void Fifo::PushAddressToStream(char *&address) { fifoStream->push(address); }
|
||||
|
||||
void Fifo::PushAddressToStream(char*& address) {
|
||||
fifoStream->push(address);
|
||||
}
|
||||
|
||||
void Fifo::PopAddressToStream(char*& address) {
|
||||
fifoStream->pop(address);
|
||||
}
|
||||
void Fifo::PopAddressToStream(char *&address) { fifoStream->pop(address); }
|
||||
|
||||
int Fifo::GetMaxLevelForFifoBound() {
|
||||
int temp = status_fifoBound;
|
||||
status_fifoBound = 0;
|
||||
return temp;
|
||||
int temp = status_fifoBound;
|
||||
status_fifoBound = 0;
|
||||
return temp;
|
||||
}
|
||||
|
||||
int Fifo::GetMinLevelForFifoFree() {
|
||||
int temp = status_fifoFree;
|
||||
status_fifoFree = fifoDepth;
|
||||
return temp;
|
||||
int temp = status_fifoFree;
|
||||
status_fifoFree = fifoDepth;
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
146
slsReceiverSoftware/src/Fifo.h
Executable file → Normal file
146
slsReceiverSoftware/src/Fifo.h
Executable file → Normal file
@ -9,102 +9,100 @@
|
||||
*@short constructs the fifo structure
|
||||
*/
|
||||
|
||||
#include "sls_detector_defs.h"
|
||||
#include "logger.h"
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
#include "CircularFifo.h"
|
||||
|
||||
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);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Fifo();
|
||||
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);
|
||||
|
||||
/**
|
||||
* Frees the bound address by pushing into fifoFree
|
||||
*/
|
||||
void FreeAddress(char*& address);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Fifo();
|
||||
|
||||
/**
|
||||
* Pops free address from fifoFree
|
||||
*/
|
||||
void GetNewAddress(char*& address);
|
||||
/**
|
||||
* Frees the bound address by pushing into fifoFree
|
||||
*/
|
||||
void FreeAddress(char *&address);
|
||||
|
||||
/**
|
||||
* Pushes bound address into fifoBound
|
||||
*/
|
||||
void PushAddress(char*& address);
|
||||
/**
|
||||
* Pops free address from fifoFree
|
||||
*/
|
||||
void GetNewAddress(char *&address);
|
||||
|
||||
/**
|
||||
* Pops bound address from fifoBound to process data
|
||||
*/
|
||||
void PopAddress(char*& address);
|
||||
/**
|
||||
* Pushes bound address into fifoBound
|
||||
*/
|
||||
void PushAddress(char *&address);
|
||||
|
||||
/**
|
||||
* Pushes bound address into fifoStream
|
||||
*/
|
||||
void PushAddressToStream(char*& address);
|
||||
/**
|
||||
* Pops bound address from fifoBound to process data
|
||||
*/
|
||||
void PopAddress(char *&address);
|
||||
|
||||
/**
|
||||
* Pops bound address from fifoStream to stream data
|
||||
*/
|
||||
void PopAddressToStream(char*& address);
|
||||
/**
|
||||
* Pushes bound address into fifoStream
|
||||
*/
|
||||
void PushAddressToStream(char *&address);
|
||||
|
||||
/**
|
||||
* Get Maximum Level filled in Fifo Bound
|
||||
* and reset this value for next intake
|
||||
*/
|
||||
int GetMaxLevelForFifoBound();
|
||||
/**
|
||||
* Pops bound address from fifoStream to stream data
|
||||
*/
|
||||
void PopAddressToStream(char *&address);
|
||||
|
||||
/**
|
||||
* Get Minimum Level filled in Fifo Free
|
||||
* and reset this value to max for next intake
|
||||
*/
|
||||
int GetMinLevelForFifoFree();
|
||||
/**
|
||||
* Get Maximum Level filled in Fifo Bound
|
||||
* and reset this value for next intake
|
||||
*/
|
||||
int GetMaxLevelForFifoBound();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Get Minimum Level filled in Fifo Free
|
||||
* and reset this value to max for next intake
|
||||
*/
|
||||
int GetMinLevelForFifoFree();
|
||||
|
||||
/**
|
||||
* Create Fifos, allocate memory & push addresses into fifo
|
||||
* @param fifoItemSize size of each fifo item
|
||||
*/
|
||||
void CreateFifos(uint32_t fifoItemSize);
|
||||
private:
|
||||
/**
|
||||
* Create Fifos, allocate memory & push addresses into fifo
|
||||
* @param fifoItemSize size of each fifo item
|
||||
*/
|
||||
void CreateFifos(uint32_t fifoItemSize);
|
||||
|
||||
/**
|
||||
* Destroy Fifos and deallocate memory
|
||||
*/
|
||||
void DestroyFifos();
|
||||
/**
|
||||
* Destroy Fifos and deallocate memory
|
||||
*/
|
||||
void DestroyFifos();
|
||||
|
||||
/** Self Index */
|
||||
int index;
|
||||
|
||||
/** Self Index */
|
||||
int index;
|
||||
/** Memory allocated, whose addresses are pushed into the fifos */
|
||||
char *memory;
|
||||
|
||||
/** Memory allocated, whose addresses are pushed into the fifos */
|
||||
char* memory;
|
||||
/** Circular Fifo pointing to addresses of bound data in memory */
|
||||
CircularFifo<char> *fifoBound;
|
||||
|
||||
/** Circular Fifo pointing to addresses of bound data in memory */
|
||||
CircularFifo<char>* fifoBound;
|
||||
/** Circular Fifo pointing to addresses of freed data in memory */
|
||||
CircularFifo<char> *fifoFree;
|
||||
|
||||
/** Circular Fifo pointing to addresses of freed data in memory */
|
||||
CircularFifo<char>* fifoFree;
|
||||
/** Circular Fifo pointing to addresses of to be streamed data in memory */
|
||||
CircularFifo<char> *fifoStream;
|
||||
|
||||
/** Circular Fifo pointing to addresses of to be streamed data in memory */
|
||||
CircularFifo<char>* fifoStream;
|
||||
/** Fifo depth set */
|
||||
int fifoDepth;
|
||||
|
||||
/** Fifo depth set */
|
||||
int fifoDepth;
|
||||
|
||||
volatile int status_fifoBound;
|
||||
volatile int status_fifoFree;
|
||||
volatile int status_fifoBound;
|
||||
volatile int status_fifoFree;
|
||||
};
|
||||
|
112
slsReceiverSoftware/src/File.cpp
Executable file → Normal file
112
slsReceiverSoftware/src/File.cpp
Executable file → Normal file
@ -8,82 +8,64 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
File::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):
|
||||
index(ind),
|
||||
formatType(type),
|
||||
maxFramesPerFile(maxf),
|
||||
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)
|
||||
File::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)
|
||||
: index(ind), formatType(type), maxFramesPerFile(maxf), 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() {}
|
||||
|
||||
slsDetectorDefs::fileFormat File::GetFileType() {
|
||||
return formatType;
|
||||
}
|
||||
slsDetectorDefs::fileFormat File::GetFileType() { return formatType; }
|
||||
|
||||
std::string File::GetCurrentFileName() {
|
||||
return currentFileName;
|
||||
}
|
||||
std::string File::GetCurrentFileName() { return currentFileName; }
|
||||
|
||||
void File::resetSubFileIndex(){
|
||||
subFileIndex = 0u;
|
||||
}
|
||||
void File::resetSubFileIndex() { subFileIndex = 0u; }
|
||||
|
||||
void File::PrintMembers(TLogLevel level) {
|
||||
LOG(level) << "\nGeneral Writer Variables:" << std::endl
|
||||
<< "Index: " << index << std::endl
|
||||
<< "Max Frames Per File: " << *maxFramesPerFile << std::endl
|
||||
<< "Number of Detectors in x dir: " << numDetX << std::endl
|
||||
<< "Number of Detectors in y dir: " << numDetY << std::endl
|
||||
<< "File Name Prefix: " << fileNamePrefix << std::endl
|
||||
<< "File Path: " << filePath << std::endl
|
||||
<< "File Index: " << *fileIndex << std::endl
|
||||
<< "Over Write Enable: " << *overWriteEnable << std::endl
|
||||
LOG(level) << "\nGeneral Writer Variables:" << std::endl
|
||||
<< "Index: " << index << std::endl
|
||||
<< "Max Frames Per File: " << *maxFramesPerFile << std::endl
|
||||
<< "Number of Detectors in x dir: " << numDetX << std::endl
|
||||
<< "Number of Detectors in y dir: " << numDetY << std::endl
|
||||
<< "File Name Prefix: " << fileNamePrefix << std::endl
|
||||
<< "File Path: " << filePath << std::endl
|
||||
<< "File Index: " << *fileIndex << std::endl
|
||||
<< "Over Write Enable: " << *overWriteEnable << std::endl
|
||||
|
||||
<< "Detector Index: " << *detIndex << std::endl
|
||||
<< "Number of Units Per Detector: " << *numUnitsPerDetector << std::endl
|
||||
<< "Number of Images in Acquisition: " << *numImages << std::endl
|
||||
<< "Dynamic Range: " << *dynamicRange << std::endl
|
||||
<< "UDP Port number: " << *udpPortNumber << std::endl
|
||||
<< "Master File Name: " << masterFileName << std::endl
|
||||
<< "Current File Name: " << currentFileName << std::endl
|
||||
<< "Silent Mode: " << *silentMode;
|
||||
<< "Detector Index: " << *detIndex << std::endl
|
||||
<< "Number of Units Per Detector: " << *numUnitsPerDetector
|
||||
<< std::endl
|
||||
<< "Number of Images in Acquisition: " << *numImages << std::endl
|
||||
<< "Dynamic Range: " << *dynamicRange << std::endl
|
||||
<< "UDP Port number: " << *udpPortNumber << std::endl
|
||||
<< "Master File Name: " << masterFileName << std::endl
|
||||
<< "Current File Name: " << currentFileName << std::endl
|
||||
<< "Silent Mode: " << *silentMode;
|
||||
}
|
||||
|
||||
|
||||
void File::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)
|
||||
{
|
||||
nd[0] = numDetX;
|
||||
nd[1] = numDetY;
|
||||
maxf = maxFramesPerFile;
|
||||
fname = fileNamePrefix;
|
||||
fpath = filePath;
|
||||
findex = fileIndex;
|
||||
owenable = overWriteEnable;
|
||||
dindex = detIndex;
|
||||
nunits = numUnitsPerDetector;
|
||||
nf = numImages;
|
||||
dr = dynamicRange;
|
||||
portno = udpPortNumber;
|
||||
void File::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) {
|
||||
nd[0] = numDetX;
|
||||
nd[1] = numDetY;
|
||||
maxf = maxFramesPerFile;
|
||||
fname = fileNamePrefix;
|
||||
fpath = filePath;
|
||||
findex = fileIndex;
|
||||
owenable = overWriteEnable;
|
||||
dindex = detIndex;
|
||||
nunits = numUnitsPerDetector;
|
||||
nf = numImages;
|
||||
dr = dynamicRange;
|
||||
portno = udpPortNumber;
|
||||
}
|
||||
|
||||
|
||||
|
214
slsReceiverSoftware/src/File.h
Executable file → Normal file
214
slsReceiverSoftware/src/File.h
Executable file → Normal file
@ -5,125 +5,127 @@
|
||||
* 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 "receiver_defs.h"
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
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();
|
||||
fileFormat GetFileType();
|
||||
std::string GetCurrentFileName();
|
||||
void resetSubFileIndex();
|
||||
virtual void PrintMembers(TLogLevel level = logDEBUG1);
|
||||
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);
|
||||
|
||||
/**
|
||||
* Get Member Pointer Values before the object is destroyed
|
||||
* @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 ~File();
|
||||
fileFormat GetFileType();
|
||||
std::string GetCurrentFileName();
|
||||
void resetSubFileIndex();
|
||||
virtual void PrintMembers(TLogLevel level = logDEBUG1);
|
||||
|
||||
virtual void CreateFile() = 0;
|
||||
virtual void CloseCurrentFile() = 0;
|
||||
virtual void CloseAllFiles() = 0;
|
||||
/**
|
||||
* Get Member Pointer Values before the object is destroyed
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Write data to file
|
||||
* @param buffer buffer to write from
|
||||
* @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;
|
||||
virtual void CreateFile() = 0;
|
||||
virtual void CloseCurrentFile() = 0;
|
||||
virtual void CloseAllFiles() = 0;
|
||||
|
||||
/**
|
||||
* Create master file
|
||||
* @param mfwenable master file write enable
|
||||
* @param attr master file attributes
|
||||
*/
|
||||
virtual void CreateMasterFile(bool mfwenable, masterAttributes& attr) = 0;
|
||||
/**
|
||||
* Write data to file
|
||||
* @param buffer buffer to write from
|
||||
* @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;
|
||||
|
||||
// HDf5 specific
|
||||
/**
|
||||
* Set Number of pixels
|
||||
* @param nx number of pixels in x direction
|
||||
* @param ny number of pixels in y direction
|
||||
*/
|
||||
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";
|
||||
}
|
||||
/**
|
||||
* Create master file
|
||||
* @param mfwenable master file write enable
|
||||
* @param attr master file attributes
|
||||
*/
|
||||
virtual void CreateMasterFile(bool mfwenable, masterAttributes &attr) = 0;
|
||||
|
||||
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;
|
||||
// HDf5 specific
|
||||
/**
|
||||
* Set Number of pixels
|
||||
* @param nx number of pixels in x direction
|
||||
* @param ny number of pixels in y direction
|
||||
*/
|
||||
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:
|
||||
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
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
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
135
slsReceiverSoftware/src/HDF5File.h
Executable file → Normal file
@ -6,90 +6,89 @@
|
||||
* 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 "H5Cpp.h"
|
||||
#ifndef H5_NO_NAMESPACE
|
||||
using namespace H5;
|
||||
using namespace H5;
|
||||
#endif
|
||||
#include <mutex>
|
||||
|
||||
|
||||
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);
|
||||
void WriteDataFile(uint64_t currentFrameNumber, char* buffer);
|
||||
void WriteParameterDatasets(uint64_t currentFrameNumber, sls_receiver_header* rheader);
|
||||
void ExtendDataset();
|
||||
void CreateDataFile();
|
||||
void CreateMasterDataFile(masterAttributes& masterFileAttributes);
|
||||
void CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf);
|
||||
void LinkVirtualInMaster(std::string fname, std::string dsetname);
|
||||
hid_t GetDataTypeinC(DataType dtype);
|
||||
private:
|
||||
void CloseFile(H5File *&fd, bool masterFile);
|
||||
void WriteDataFile(uint64_t currentFrameNumber, char *buffer);
|
||||
void WriteParameterDatasets(uint64_t currentFrameNumber,
|
||||
sls_receiver_header *rheader);
|
||||
void ExtendDataset();
|
||||
void CreateDataFile();
|
||||
void CreateMasterDataFile(masterAttributes &masterFileAttributes);
|
||||
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;
|
||||
/** Virtual File handle ( only file name because
|
||||
code in C as H5Pset_virtual doesnt exist yet in C++) */
|
||||
hid_t virtualfd;
|
||||
H5File* filefd;
|
||||
DataSpace* dataspace;
|
||||
DataSet* dataset;
|
||||
DataType datatype;
|
||||
H5File *masterfd;
|
||||
/** Virtual File handle ( only file name because
|
||||
code in C as H5Pset_virtual doesnt exist yet in C++) */
|
||||
hid_t virtualfd;
|
||||
H5File *filefd;
|
||||
DataSpace *dataspace;
|
||||
DataSet *dataset;
|
||||
DataType datatype;
|
||||
|
||||
uint32_t nPixelsX;
|
||||
uint32_t nPixelsY;
|
||||
uint32_t numFramesInFile;
|
||||
uint64_t numActualPacketsInFile;
|
||||
int numFilesinAcquisition;
|
||||
uint32_t nPixelsX;
|
||||
uint32_t nPixelsY;
|
||||
uint32_t numFramesInFile;
|
||||
uint64_t numActualPacketsInFile;
|
||||
int numFilesinAcquisition;
|
||||
|
||||
std::vector <const char*> parameterNames;
|
||||
std::vector <DataType> parameterDataTypes;
|
||||
DataSpace* dataspace_para;
|
||||
std::vector <DataSet*> dataset_para;
|
||||
|
||||
uint64_t extNumImages;
|
||||
std::vector<const char *> parameterNames;
|
||||
std::vector<DataType> parameterDataTypes;
|
||||
DataSpace *dataspace_para;
|
||||
std::vector<DataSet *> dataset_para;
|
||||
|
||||
uint64_t extNumImages;
|
||||
};
|
||||
#endif
|
||||
|
435
slsReceiverSoftware/src/Implementation.cpp
Executable file → Normal file
435
slsReceiverSoftware/src/Implementation.cpp
Executable file → Normal file
@ -4,9 +4,9 @@
|
||||
#include "Fifo.h"
|
||||
#include "GeneralData.h"
|
||||
#include "Listener.h"
|
||||
#include "ToString.h"
|
||||
#include "ZmqSocket.h" //just for the zmq port define
|
||||
#include "file_utils.h"
|
||||
#include "ToString.h"
|
||||
|
||||
#include <cerrno> //eperm
|
||||
#include <cstdlib> //system
|
||||
@ -82,7 +82,7 @@ void Implementation::InitializeMembers() {
|
||||
udpPortNum.resize(MAX_NUMBER_OF_LISTENING_THREADS);
|
||||
for (int i = 0; i < MAX_NUMBER_OF_LISTENING_THREADS; ++i) {
|
||||
eth[i] = "";
|
||||
udpPortNum[i] = DEFAULT_UDP_PORTNO + i;
|
||||
udpPortNum[i] = DEFAULT_UDP_PORTNO + i;
|
||||
}
|
||||
udpSocketBufferSize = 0;
|
||||
actualUDPSocketBufferSize = 0;
|
||||
@ -188,7 +188,8 @@ void Implementation::SetupFifoStructure() {
|
||||
} catch (...) {
|
||||
fifo.clear();
|
||||
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.");
|
||||
}
|
||||
// set the listener & dataprocessor threads to point to the right fifo
|
||||
@ -201,15 +202,14 @@ void Implementation::SetupFifoStructure() {
|
||||
}
|
||||
|
||||
LOG(logINFO) << "Memory Allocated Per Fifo: "
|
||||
<< (double)(((size_t)(generalData->imageSize) +
|
||||
(size_t)(generalData->fifoBufferHeaderSize)) *
|
||||
(size_t)fifoDepth) / (double)(1024 * 1024)
|
||||
<< " MB";
|
||||
<< (double)(((size_t)(generalData->imageSize) +
|
||||
(size_t)(generalData->fifoBufferHeaderSize)) *
|
||||
(size_t)fifoDepth) /
|
||||
(double)(1024 * 1024)
|
||||
<< " MB";
|
||||
LOG(logINFO) << numThreads << " Fifo structure(s) reconstructed";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Configuration Parameters *
|
||||
@ -227,11 +227,11 @@ void Implementation::setDetectorType(const detectorType d) {
|
||||
case MOENCH:
|
||||
case MYTHEN3:
|
||||
case GOTTHARD2:
|
||||
LOG(logINFO) << " ***** " << sls::ToString(d)
|
||||
<< " Receiver *****";
|
||||
LOG(logINFO) << " ***** " << sls::ToString(d) << " Receiver *****";
|
||||
break;
|
||||
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
|
||||
@ -253,10 +253,10 @@ void Implementation::setDetectorType(const detectorType d) {
|
||||
break;
|
||||
case MYTHEN3:
|
||||
generalData = new Mythen3Data();
|
||||
break;
|
||||
break;
|
||||
case GOTTHARD2:
|
||||
generalData = new Gotthard2Data();
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -280,15 +280,16 @@ void Implementation::setDetectorType(const detectorType d) {
|
||||
&activated, &deactivatedPaddingEnable, &silentMode));
|
||||
dataProcessor.push_back(sls::make_unique<DataProcessor>(
|
||||
i, myDetectorType, fifo_ptr, &fileFormatType, fileWriteEnable,
|
||||
&masterFileWriteEnable, &dataStreamEnable,
|
||||
&dynamicRange, &streamingFrequency, &streamingTimerInMs,
|
||||
&framePadding, &activated, &deactivatedPaddingEnable,
|
||||
&silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset,
|
||||
&ctbAnalogDataBytes));
|
||||
&masterFileWriteEnable, &dataStreamEnable, &dynamicRange,
|
||||
&streamingFrequency, &streamingTimerInMs, &framePadding,
|
||||
&activated, &deactivatedPaddingEnable, &silentMode, &quadEnable,
|
||||
&ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes));
|
||||
} catch (...) {
|
||||
listener.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 += ")";
|
||||
|
||||
int nd[2] = {numDet[0], numDet[1]};
|
||||
if (quadEnable) {
|
||||
nd[0] = 1;
|
||||
nd[1] = 2;
|
||||
}
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(nd);
|
||||
}
|
||||
if (quadEnable) {
|
||||
nd[0] = 1;
|
||||
nd[1] = 2;
|
||||
}
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(nd);
|
||||
}
|
||||
|
||||
LOG(logINFO) << log_message;
|
||||
}
|
||||
@ -349,14 +350,14 @@ void Implementation::setDetectorPositionId(const int id) {
|
||||
LOG(logINFO) << "Detector Position Id:" << detID;
|
||||
|
||||
// update zmq port
|
||||
streamingPort = DEFAULT_ZMQ_RX_PORTNO +
|
||||
(detID * (myDetectorType == EIGER ? 2 : 1));
|
||||
|
||||
streamingPort =
|
||||
DEFAULT_ZMQ_RX_PORTNO + (detID * (myDetectorType == EIGER ? 2 : 1));
|
||||
|
||||
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
|
||||
dataProcessor[i]->SetupFileWriter(
|
||||
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, &filePath,
|
||||
&fileIndex, &overwriteEnable, &detID, &numThreads, &numberOfTotalFrames,
|
||||
&dynamicRange, &udpPortNum[i], generalData);
|
||||
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName,
|
||||
&filePath, &fileIndex, &overwriteEnable, &detID, &numThreads,
|
||||
&numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData);
|
||||
}
|
||||
assert(numDet[1] != 0);
|
||||
for (unsigned int i = 0; i < listener.size(); ++i) {
|
||||
@ -373,7 +374,7 @@ std::string Implementation::getDetectorHostname() const {
|
||||
return detHostname;
|
||||
}
|
||||
|
||||
void Implementation::setDetectorHostname(const std::string& c) {
|
||||
void Implementation::setDetectorHostname(const std::string &c) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
if (!c.empty())
|
||||
@ -412,15 +413,13 @@ Implementation::getFrameDiscardPolicy() const {
|
||||
return frameDiscardMode;
|
||||
}
|
||||
|
||||
void Implementation::setFrameDiscardPolicy(
|
||||
const frameDiscardPolicy i) {
|
||||
void Implementation::setFrameDiscardPolicy(const frameDiscardPolicy i) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
if (i >= 0 && i < NUM_DISCARD_POLICIES)
|
||||
frameDiscardMode = i;
|
||||
|
||||
LOG(logINFO) << "Frame Discard Policy: "
|
||||
<< sls::ToString(frameDiscardMode);
|
||||
LOG(logINFO) << "Frame Discard Policy: " << sls::ToString(frameDiscardMode);
|
||||
}
|
||||
|
||||
bool Implementation::getFramePaddingEnable() const {
|
||||
@ -435,7 +434,6 @@ void Implementation::setFramePaddingEnable(const bool i) {
|
||||
LOG(logINFO) << "Frame Padding: " << framePadding;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* File Parameters *
|
||||
@ -469,11 +467,11 @@ std::string Implementation::getFilePath() const {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
void Implementation::setFilePath(const std::string& c) {
|
||||
void Implementation::setFilePath(const std::string &c) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
if (!c.empty()) {
|
||||
mkdir_p(c); //throws if it can't create
|
||||
mkdir_p(c); // throws if it can't create
|
||||
filePath = c;
|
||||
}
|
||||
LOG(logINFO) << "File path: " << filePath;
|
||||
@ -484,11 +482,11 @@ std::string Implementation::getFileName() const {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
void Implementation::setFileName(const std::string& c) {
|
||||
void Implementation::setFileName(const std::string &c) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
if (!c.empty())
|
||||
fileName = c;
|
||||
fileName = c;
|
||||
LOG(logINFO) << "File name: " << fileName;
|
||||
}
|
||||
|
||||
@ -516,11 +514,13 @@ void Implementation::setFileWriteEnable(const bool b) {
|
||||
dataProcessor[i]->SetupFileWriter(
|
||||
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName,
|
||||
&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 {
|
||||
@ -532,7 +532,7 @@ void Implementation::setMasterFileWriteEnable(const bool b) {
|
||||
masterFileWriteEnable = b;
|
||||
|
||||
LOG(logINFO) << "Master File Write Enable: "
|
||||
<< (masterFileWriteEnable ? "enabled" : "disabled");
|
||||
<< (masterFileWriteEnable ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
bool Implementation::getOverwriteEnable() const {
|
||||
@ -544,7 +544,8 @@ void Implementation::setOverwriteEnable(const bool b) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
overwriteEnable = b;
|
||||
LOG(logINFO) << "Overwrite Enable: " << (overwriteEnable ? "enabled" : "disabled");
|
||||
LOG(logINFO) << "Overwrite Enable: "
|
||||
<< (overwriteEnable ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
uint32_t Implementation::getFramesPerFile() const {
|
||||
@ -559,7 +560,6 @@ void Implementation::setFramesPerFile(const uint32_t i) {
|
||||
LOG(logINFO) << "Frames per file: " << framesPerFile;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Acquisition *
|
||||
@ -577,7 +577,7 @@ uint64_t Implementation::getFramesCaught() const {
|
||||
for (const auto &it : dataProcessor) {
|
||||
flagsum += it->GetStartedFlag();
|
||||
uint64_t curr = it->GetNumFramesCaught();
|
||||
min = curr < min ? curr : min;
|
||||
min = curr < min ? curr : min;
|
||||
}
|
||||
// no data processed
|
||||
if (flagsum != dataProcessor.size())
|
||||
@ -617,7 +617,8 @@ int Implementation::getProgress() const {
|
||||
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 {
|
||||
@ -628,7 +629,7 @@ std::vector<uint64_t> Implementation::getNumMissingPackets() const {
|
||||
// partial readout
|
||||
if (numLinesReadout != MAX_EIGER_ROWS_PER_READOUT) {
|
||||
totnp = ((numLinesReadout * np) / MAX_EIGER_ROWS_PER_READOUT);
|
||||
}
|
||||
}
|
||||
totnp *= numberOfTotalFrames;
|
||||
mp[i] = listener[i]->GetNumMissingPacket(stoppedFlag, totnp);
|
||||
}
|
||||
@ -673,9 +674,7 @@ void Implementation::startReceiver() {
|
||||
LOG(logINFO) << "Status: " << sls::ToString(status);
|
||||
}
|
||||
|
||||
void Implementation::setStoppedFlag(bool stopped) {
|
||||
stoppedFlag = stopped;
|
||||
}
|
||||
void Implementation::setStoppedFlag(bool stopped) { stoppedFlag = stopped; }
|
||||
|
||||
void Implementation::stopReceiver() {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
@ -703,8 +702,7 @@ void Implementation::stopReceiver() {
|
||||
uint64_t maxIndexCaught = 0;
|
||||
bool anycaught = false;
|
||||
for (const auto &it : dataProcessor) {
|
||||
maxIndexCaught =
|
||||
std::max(maxIndexCaught, it->GetProcessedIndex());
|
||||
maxIndexCaught = std::max(maxIndexCaught, it->GetProcessedIndex());
|
||||
if (it->GetStartedFlag())
|
||||
anycaught = true;
|
||||
}
|
||||
@ -733,16 +731,15 @@ void Implementation::stopReceiver() {
|
||||
int nf = dataProcessor[i]->GetNumFramesCaught();
|
||||
tot += nf;
|
||||
|
||||
TLogLevel lev =
|
||||
(((int64_t)mp[i]) > 0) ? logINFORED : logINFOGREEN;
|
||||
TLogLevel lev = (((int64_t)mp[i]) > 0) ? logINFORED : logINFOGREEN;
|
||||
LOG(lev) <<
|
||||
// udp port number could be the second if selected interface is
|
||||
// 2 for jungfrau
|
||||
"Summary of Port " << udpPortNum[i]
|
||||
<< "\n\tMissing Packets\t\t: " << mp[i]
|
||||
<< "\n\tComplete Frames\t\t: " << nf
|
||||
<< "\n\tLast Frame Caught\t: "
|
||||
<< listener[i]->GetLastFrameIndexCaught();
|
||||
<< "\n\tMissing Packets\t\t: " << mp[i]
|
||||
<< "\n\tComplete Frames\t\t: " << nf
|
||||
<< "\n\tLast Frame Caught\t: "
|
||||
<< listener[i]->GetLastFrameIndexCaught();
|
||||
}
|
||||
if (!activated) {
|
||||
LOG(logINFORED) << "Deactivated Receiver";
|
||||
@ -770,8 +767,9 @@ void Implementation::startReadout() {
|
||||
totalPacketsReceived += it->GetPacketsCaught();
|
||||
|
||||
// wait for all packets
|
||||
const int numPacketsToReceive =
|
||||
numberOfTotalFrames * generalData->packetsPerFrame * listener.size();
|
||||
const int numPacketsToReceive = numberOfTotalFrames *
|
||||
generalData->packetsPerFrame *
|
||||
listener.size();
|
||||
if (totalPacketsReceived != numPacketsToReceive) {
|
||||
while (totalPacketsReceived != previousValue) {
|
||||
LOG(logDEBUG3)
|
||||
@ -785,7 +783,7 @@ void Implementation::startReadout() {
|
||||
totalPacketsReceived += it->GetPacketsCaught();
|
||||
|
||||
LOG(logDEBUG3) << "\tupdated: totalPacketsReceived:"
|
||||
<< totalPacketsReceived;
|
||||
<< totalPacketsReceived;
|
||||
}
|
||||
}
|
||||
status = TRANSMITTING;
|
||||
@ -808,8 +806,7 @@ void Implementation::closeFiles() {
|
||||
bool anycaught = false;
|
||||
for (const auto &it : dataProcessor) {
|
||||
it->CloseFiles();
|
||||
maxIndexCaught =
|
||||
std::max(maxIndexCaught, it->GetProcessedIndex());
|
||||
maxIndexCaught = std::max(maxIndexCaught, it->GetProcessedIndex());
|
||||
if (it->GetStartedFlag())
|
||||
anycaught = true;
|
||||
}
|
||||
@ -846,11 +843,11 @@ void Implementation::ResetParametersforNewAcquisition() {
|
||||
void Implementation::CreateUDPSockets() {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
try{
|
||||
try {
|
||||
for (unsigned int i = 0; i < listener.size(); ++i) {
|
||||
listener[i]->CreateUDPSockets();
|
||||
}
|
||||
} catch(const sls::RuntimeError &e) {
|
||||
} catch (const sls::RuntimeError &e) {
|
||||
shutDownUDPSockets();
|
||||
throw sls::RuntimeError("Could not create UDP Socket(s).");
|
||||
}
|
||||
@ -860,22 +857,26 @@ void Implementation::CreateUDPSockets() {
|
||||
|
||||
void Implementation::SetupWriter() {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
masterAttributes attr;
|
||||
attr.detectorType = myDetectorType;
|
||||
attr.dynamicRange = dynamicRange;
|
||||
attr.tenGiga = tengigaEnable;
|
||||
attr.imageSize = generalData->imageSize;
|
||||
attr.nPixelsX = generalData->nPixelsX;
|
||||
attr.nPixelsY = generalData->nPixelsY;
|
||||
attr.maxFramesPerFile = framesPerFile;
|
||||
attr.totalFrames = numberOfTotalFrames;
|
||||
attr.exptimeNs = acquisitionTime;
|
||||
attr.subExptimeNs = subExpTime;
|
||||
attr.subPeriodNs = subPeriod;
|
||||
attr.periodNs = acquisitionPeriod;
|
||||
masterAttributes attr;
|
||||
attr.detectorType = myDetectorType;
|
||||
attr.dynamicRange = dynamicRange;
|
||||
attr.tenGiga = tengigaEnable;
|
||||
attr.imageSize = generalData->imageSize;
|
||||
attr.nPixelsX = generalData->nPixelsX;
|
||||
attr.nPixelsY = generalData->nPixelsY;
|
||||
attr.maxFramesPerFile = framesPerFile;
|
||||
attr.totalFrames = numberOfTotalFrames;
|
||||
attr.exptimeNs = acquisitionTime;
|
||||
attr.subExptimeNs = subExpTime;
|
||||
attr.subPeriodNs = subPeriod;
|
||||
attr.periodNs = acquisitionPeriod;
|
||||
attr.quadEnable = quadEnable;
|
||||
attr.analogFlag = (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0;
|
||||
attr.digitalFlag = (readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) ? 1 : 0;
|
||||
attr.analogFlag =
|
||||
(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.dbitoffset = ctbDbitOffset;
|
||||
attr.dbitlist = 0;
|
||||
@ -889,7 +890,7 @@ void Implementation::SetupWriter() {
|
||||
for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
|
||||
dataProcessor[i]->CreateNewFile(attr);
|
||||
}
|
||||
} catch(const sls::RuntimeError &e) {
|
||||
} catch (const sls::RuntimeError &e) {
|
||||
shutDownUDPSockets();
|
||||
closeFiles();
|
||||
throw sls::RuntimeError("Could not create file.");
|
||||
@ -914,7 +915,6 @@ void Implementation::StartRunning() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Network Configuration (UDP) *
|
||||
@ -967,15 +967,17 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
|
||||
dataProcessor.push_back(sls::make_unique<DataProcessor>(
|
||||
i, myDetectorType, fifo_ptr, &fileFormatType,
|
||||
fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable,
|
||||
&dynamicRange, &streamingFrequency,
|
||||
&streamingTimerInMs, &framePadding, &activated,
|
||||
&deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList,
|
||||
&ctbDbitOffset, &ctbAnalogDataBytes));
|
||||
&dynamicRange, &streamingFrequency, &streamingTimerInMs,
|
||||
&framePadding, &activated, &deactivatedPaddingEnable,
|
||||
&silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset,
|
||||
&ctbAnalogDataBytes));
|
||||
dataProcessor[i]->SetGeneralData(generalData);
|
||||
} catch (...) {
|
||||
listener.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
|
||||
if (dataStreamEnable) {
|
||||
@ -988,19 +990,22 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
|
||||
nd[1] = 2;
|
||||
}
|
||||
dataStreamer.push_back(sls::make_unique<DataStreamer>(
|
||||
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
|
||||
fd, (int*)nd, &quadEnable, &numberOfTotalFrames));
|
||||
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, fd,
|
||||
(int *)nd, &quadEnable, &numberOfTotalFrames));
|
||||
dataStreamer[i]->SetGeneralData(generalData);
|
||||
dataStreamer[i]->CreateZmqSockets(
|
||||
&numThreads, streamingPort, streamingSrcIP);
|
||||
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader);
|
||||
dataStreamer[i]->SetAdditionalJsonHeader(
|
||||
additionalJsonHeader);
|
||||
|
||||
} catch (...) {
|
||||
if (dataStreamEnable) {
|
||||
dataStreamer.clear();
|
||||
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();
|
||||
|
||||
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) {
|
||||
@ -1102,7 +1109,6 @@ int64_t Implementation::getActualUDPSocketBufferSize() const {
|
||||
return actualUDPSocketBufferSize;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* ZMQ Streaming Parameters (ZMQ) *
|
||||
@ -1132,16 +1138,18 @@ void Implementation::setDataStreamEnable(const bool enable) {
|
||||
nd[1] = 2;
|
||||
}
|
||||
dataStreamer.push_back(sls::make_unique<DataStreamer>(
|
||||
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
|
||||
fd, (int*)nd, &quadEnable, &numberOfTotalFrames));
|
||||
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, fd,
|
||||
(int *)nd, &quadEnable, &numberOfTotalFrames));
|
||||
dataStreamer[i]->SetGeneralData(generalData);
|
||||
dataStreamer[i]->CreateZmqSockets(
|
||||
&numThreads, streamingPort, streamingSrcIP);
|
||||
dataStreamer[i]->SetAdditionalJsonHeader(additionalJsonHeader);
|
||||
dataStreamer[i]->SetAdditionalJsonHeader(
|
||||
additionalJsonHeader);
|
||||
} catch (...) {
|
||||
dataStreamer.clear();
|
||||
dataStreamEnable = false;
|
||||
throw sls::RuntimeError("Could not set data stream enable.");
|
||||
throw sls::RuntimeError(
|
||||
"Could not set data stream enable.");
|
||||
}
|
||||
}
|
||||
SetThreadPriorities();
|
||||
@ -1196,54 +1204,65 @@ void Implementation::setStreamingSourceIP(const sls::IpAddr ip) {
|
||||
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";
|
||||
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";
|
||||
additionalJsonHeader = c;
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetAdditionalJsonHeader(c);
|
||||
}
|
||||
LOG(logINFO) << "Additional JSON Header: " << sls::ToString(additionalJsonHeader);
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetAdditionalJsonHeader(c);
|
||||
}
|
||||
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()) {
|
||||
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);
|
||||
|
||||
// if value is empty, delete
|
||||
if (value.empty()) {
|
||||
// doesnt exist
|
||||
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 {
|
||||
LOG(logINFO) << "Deleting additional json parameter (" << key << ")";
|
||||
LOG(logINFO) << "Deleting additional json parameter (" << key
|
||||
<< ")";
|
||||
additionalJsonHeader.erase(pos);
|
||||
}
|
||||
}
|
||||
// if found, set it
|
||||
else if (pos != additionalJsonHeader.end()) {
|
||||
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
|
||||
else {
|
||||
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) {
|
||||
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() {
|
||||
int64_t repeats = numberOfTriggers;
|
||||
// gotthard2: auto mode
|
||||
// gotthard2: auto mode
|
||||
// burst mode: (bursts instead of triggers)
|
||||
// non burst mode: no bursts or triggers
|
||||
if (myDetectorType == GOTTHARD2 &&timingMode == AUTO_TIMING) {
|
||||
if (myDetectorType == GOTTHARD2 && timingMode == AUTO_TIMING) {
|
||||
if (burstMode == BURST_OFF) {
|
||||
repeats = numberOfBursts;
|
||||
} else {
|
||||
repeats = 1;
|
||||
}
|
||||
}
|
||||
numberOfTotalFrames = numberOfFrames * repeats *
|
||||
(int64_t)(numberOfAdditionalStorageCells + 1);
|
||||
numberOfTotalFrames = numberOfFrames * repeats *
|
||||
(int64_t)(numberOfAdditionalStorageCells + 1);
|
||||
if (numberOfTotalFrames == 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) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
numberOfAdditionalStorageCells = i;
|
||||
LOG(logINFO) << "Number of Additional Storage Cells: " << numberOfAdditionalStorageCells;
|
||||
LOG(logINFO) << "Number of Additional Storage Cells: "
|
||||
<< numberOfAdditionalStorageCells;
|
||||
updateTotalNumberOfFrames();
|
||||
}
|
||||
|
||||
@ -1352,8 +1372,8 @@ void Implementation::setAcquisitionPeriod(const uint64_t i) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
acquisitionPeriod = i;
|
||||
LOG(logINFO) << "Acquisition Period: "
|
||||
<< (double)acquisitionPeriod / (1E9) << "s";
|
||||
LOG(logINFO) << "Acquisition Period: " << (double)acquisitionPeriod / (1E9)
|
||||
<< "s";
|
||||
}
|
||||
|
||||
uint64_t Implementation::getAcquisitionTime() const {
|
||||
@ -1366,7 +1386,7 @@ void Implementation::setAcquisitionTime(const uint64_t i) {
|
||||
|
||||
acquisitionTime = i;
|
||||
LOG(logINFO) << "Acquisition Time: " << (double)acquisitionTime / (1E9)
|
||||
<< "s";
|
||||
<< "s";
|
||||
}
|
||||
|
||||
uint64_t Implementation::getSubExpTime() const {
|
||||
@ -1378,8 +1398,7 @@ void Implementation::setSubExpTime(const uint64_t i) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
subExpTime = i;
|
||||
LOG(logINFO) << "Sub Exposure Time: " << (double)subExpTime / (1E9)
|
||||
<< "s";
|
||||
LOG(logINFO) << "Sub Exposure Time: " << (double)subExpTime / (1E9) << "s";
|
||||
}
|
||||
|
||||
uint64_t Implementation::getSubPeriod() const {
|
||||
@ -1391,8 +1410,7 @@ void Implementation::setSubPeriod(const uint64_t i) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
|
||||
subPeriod = i;
|
||||
LOG(logINFO) << "Sub Period: " << (double)subPeriod / (1E9)
|
||||
<< "s";
|
||||
LOG(logINFO) << "Sub Period: " << (double)subPeriod / (1E9) << "s";
|
||||
}
|
||||
|
||||
uint32_t Implementation::getNumberofAnalogSamples() const {
|
||||
@ -1405,17 +1423,16 @@ void Implementation::setNumberofAnalogSamples(const uint32_t i) {
|
||||
numberOfAnalogSamples = i;
|
||||
|
||||
ctbAnalogDataBytes = generalData->setImageSize(
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples,
|
||||
tengigaEnable, readoutType);
|
||||
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "Number of Analog Samples: " << numberOfAnalogSamples;
|
||||
LOG(logINFO) << "Packets per Frame: "
|
||||
<< (generalData->packetsPerFrame);
|
||||
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
|
||||
}
|
||||
|
||||
uint32_t Implementation::getNumberofDigitalSamples() const {
|
||||
@ -1428,18 +1445,16 @@ void Implementation::setNumberofDigitalSamples(const uint32_t i) {
|
||||
numberOfDigitalSamples = i;
|
||||
|
||||
ctbAnalogDataBytes = generalData->setImageSize(
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples,
|
||||
tengigaEnable, readoutType);
|
||||
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "Number of Digital Samples: "
|
||||
<< numberOfDigitalSamples;
|
||||
LOG(logINFO) << "Packets per Frame: "
|
||||
<< (generalData->packetsPerFrame);
|
||||
LOG(logINFO) << "Number of Digital Samples: " << numberOfDigitalSamples;
|
||||
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
|
||||
}
|
||||
|
||||
int Implementation::getNumberofCounters() const {
|
||||
@ -1502,9 +1517,9 @@ void Implementation::setROI(slsDetectorDefs::ROI arg) {
|
||||
SetupFifoStructure();
|
||||
}
|
||||
|
||||
LOG(logINFO) << "ROI: [" << roi.xmin << ", " << roi.xmax << "]";;
|
||||
LOG(logINFO) << "Packets per Frame: "
|
||||
<< (generalData->packetsPerFrame);
|
||||
LOG(logINFO) << "ROI: [" << roi.xmin << ", " << roi.xmax << "]";
|
||||
;
|
||||
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
|
||||
}
|
||||
|
||||
bool Implementation::getTenGigaEnable() const {
|
||||
@ -1523,9 +1538,9 @@ void Implementation::setTenGigaEnable(const bool b) {
|
||||
case MOENCH:
|
||||
case CHIPTESTBOARD:
|
||||
ctbAnalogDataBytes = generalData->setImageSize(
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples,
|
||||
tengigaEnable, readoutType);
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1534,8 +1549,7 @@ void Implementation::setTenGigaEnable(const bool b) {
|
||||
SetupFifoStructure();
|
||||
}
|
||||
LOG(logINFO) << "Ten Giga: " << (tengigaEnable ? "enabled" : "disabled");
|
||||
LOG(logINFO) << "Packets per Frame: "
|
||||
<< (generalData->packetsPerFrame);
|
||||
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
|
||||
}
|
||||
|
||||
int Implementation::getFlippedDataX() const {
|
||||
@ -1547,47 +1561,46 @@ void Implementation::setFlippedDataX(int enable) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
flippedDataX = (enable == 0) ? 0 : 1;
|
||||
|
||||
if (!quadEnable) {
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetFlippedDataX(flippedDataX);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dataStreamer.size() == 2) {
|
||||
dataStreamer[0]->SetFlippedDataX(0);
|
||||
dataStreamer[1]->SetFlippedDataX(1);
|
||||
}
|
||||
}
|
||||
if (!quadEnable) {
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetFlippedDataX(flippedDataX);
|
||||
}
|
||||
} else {
|
||||
if (dataStreamer.size() == 2) {
|
||||
dataStreamer[0]->SetFlippedDataX(0);
|
||||
dataStreamer[1]->SetFlippedDataX(1);
|
||||
}
|
||||
}
|
||||
|
||||
LOG(logINFO) << "Flipped Data X: " << flippedDataX;
|
||||
}
|
||||
|
||||
bool Implementation::getQuad() const {
|
||||
LOG(logDEBUG) << __AT__ << " starting";
|
||||
return quadEnable;
|
||||
LOG(logDEBUG) << __AT__ << " starting";
|
||||
return quadEnable;
|
||||
}
|
||||
|
||||
void Implementation::setQuad(const bool b) {
|
||||
if (quadEnable != b) {
|
||||
quadEnable = b;
|
||||
if (quadEnable != b) {
|
||||
quadEnable = b;
|
||||
|
||||
if (!quadEnable) {
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(numDet);
|
||||
it->SetFlippedDataX(flippedDataX);
|
||||
}
|
||||
} else {
|
||||
int size[2] = {1, 2};
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(size);
|
||||
}
|
||||
if (dataStreamer.size() == 2) {
|
||||
dataStreamer[0]->SetFlippedDataX(0);
|
||||
dataStreamer[1]->SetFlippedDataX(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG(logINFO) << "Quad Enable: " << quadEnable;
|
||||
if (!quadEnable) {
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(numDet);
|
||||
it->SetFlippedDataX(flippedDataX);
|
||||
}
|
||||
} else {
|
||||
int size[2] = {1, 2};
|
||||
for (const auto &it : dataStreamer) {
|
||||
it->SetNumberofDetectors(size);
|
||||
}
|
||||
if (dataStreamer.size() == 2) {
|
||||
dataStreamer[0]->SetFlippedDataX(0);
|
||||
dataStreamer[1]->SetFlippedDataX(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG(logINFO) << "Quad Enable: " << quadEnable;
|
||||
}
|
||||
|
||||
bool Implementation::getActivate() const {
|
||||
@ -1611,22 +1624,21 @@ bool Implementation::setDeactivatedPadding(bool enable) {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
deactivatedPaddingEnable = enable;
|
||||
LOG(logINFO) << "Deactivated Padding Enable: "
|
||||
<< (deactivatedPaddingEnable ? "enabled" : "disabled");
|
||||
<< (deactivatedPaddingEnable ? "enabled" : "disabled");
|
||||
return deactivatedPaddingEnable;
|
||||
}
|
||||
|
||||
int Implementation::getReadNLines() const {
|
||||
LOG(logDEBUG) << __AT__ << " starting";
|
||||
return numLinesReadout;
|
||||
LOG(logDEBUG) << __AT__ << " starting";
|
||||
return numLinesReadout;
|
||||
}
|
||||
|
||||
void Implementation::setReadNLines(const int value) {
|
||||
numLinesReadout = value;
|
||||
LOG(logINFO) << "Number of Lines to readout: " << numLinesReadout;
|
||||
LOG(logINFO) << "Number of Lines to readout: " << numLinesReadout;
|
||||
}
|
||||
|
||||
slsDetectorDefs::readoutMode
|
||||
Implementation::getReadoutMode() const {
|
||||
slsDetectorDefs::readoutMode Implementation::getReadoutMode() const {
|
||||
LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
return readoutType;
|
||||
}
|
||||
@ -1637,17 +1649,16 @@ void Implementation::setReadoutMode(const readoutMode f) {
|
||||
|
||||
// side effects
|
||||
ctbAnalogDataBytes = generalData->setImageSize(
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples,
|
||||
tengigaEnable, readoutType);
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
|
||||
LOG(logINFO) << "Readout Mode: " << sls::ToString(f);
|
||||
LOG(logINFO) << "Packets per Frame: "
|
||||
<< (generalData->packetsPerFrame);
|
||||
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
|
||||
}
|
||||
|
||||
uint32_t Implementation::getADCEnableMask() const {
|
||||
@ -1660,19 +1671,18 @@ void Implementation::setADCEnableMask(uint32_t mask) {
|
||||
adcEnableMaskOneGiga = mask;
|
||||
|
||||
ctbAnalogDataBytes = generalData->setImageSize(
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples,
|
||||
tengigaEnable, readoutType);
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
|
||||
LOG(logINFO) << "ADC Enable Mask for 1Gb mode: 0x" << std::hex << adcEnableMaskOneGiga
|
||||
<< std::dec;
|
||||
LOG(logINFO) << "Packets per Frame: "
|
||||
<< (generalData->packetsPerFrame);
|
||||
LOG(logINFO) << "ADC Enable Mask for 1Gb mode: 0x" << std::hex
|
||||
<< adcEnableMaskOneGiga << std::dec;
|
||||
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
|
||||
}
|
||||
|
||||
uint32_t Implementation::getTenGigaADCEnableMask() const {
|
||||
@ -1685,19 +1695,18 @@ void Implementation::setTenGigaADCEnableMask(uint32_t mask) {
|
||||
adcEnableMaskTenGiga = mask;
|
||||
|
||||
ctbAnalogDataBytes = generalData->setImageSize(
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples,
|
||||
tengigaEnable, readoutType);
|
||||
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga,
|
||||
numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable,
|
||||
readoutType);
|
||||
|
||||
for (const auto &it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
SetupFifoStructure();
|
||||
}
|
||||
|
||||
LOG(logINFO) << "ADC Enable Mask for 10Gb mode: 0x" << std::hex << adcEnableMaskTenGiga
|
||||
<< std::dec;
|
||||
LOG(logINFO) << "Packets per Frame: "
|
||||
<< (generalData->packetsPerFrame);
|
||||
LOG(logINFO) << "ADC Enable Mask for 10Gb mode: 0x" << std::hex
|
||||
<< adcEnableMaskTenGiga << std::dec;
|
||||
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
|
||||
}
|
||||
|
||||
std::vector<int> Implementation::getDbitList() const {
|
||||
@ -1720,20 +1729,21 @@ void Implementation::setDbitOffset(const int s) {
|
||||
ctbDbitOffset = s;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Callbacks *
|
||||
* *
|
||||
* ************************************************/
|
||||
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;
|
||||
pStartAcquisition = arg;
|
||||
}
|
||||
|
||||
void Implementation::registerCallBackAcquisitionFinished(
|
||||
void (*func)(uint64_t, void *), void *arg) {
|
||||
void Implementation::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
|
||||
void *),
|
||||
void *arg) {
|
||||
acquisitionFinishedCallBack = func;
|
||||
pAcquisitionFinished = arg;
|
||||
}
|
||||
@ -1754,4 +1764,3 @@ void Implementation::registerCallBackRawDataModifyReady(
|
||||
it->registerCallBackRawDataModifyReady(rawDataModifyReadyCallBack,
|
||||
pRawDataReady);
|
||||
}
|
||||
|
||||
|
64
slsReceiverSoftware/src/Implementation.h
Executable file → Normal file
64
slsReceiverSoftware/src/Implementation.h
Executable file → Normal file
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include "container_utils.h"
|
||||
#include "logger.h"
|
||||
#include "receiver_defs.h"
|
||||
#include "network_utils.h"
|
||||
#include "receiver_defs.h"
|
||||
class GeneralData;
|
||||
class Listener;
|
||||
class DataProcessor;
|
||||
@ -12,9 +12,9 @@ class slsDetectorDefs;
|
||||
|
||||
#include <atomic>
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class Implementation : private virtual slsDetectorDefs {
|
||||
public:
|
||||
@ -33,7 +33,7 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
int getDetectorPositionId() const;
|
||||
void setDetectorPositionId(const int id);
|
||||
std::string getDetectorHostname() const;
|
||||
void setDetectorHostname(const std::string& c);
|
||||
void setDetectorHostname(const std::string &c);
|
||||
bool getSilentMode() const;
|
||||
void setSilentMode(const bool i);
|
||||
uint32_t getFifoDepth() const;
|
||||
@ -52,9 +52,9 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
void setFileFormat(slsDetectorDefs::fileFormat f);
|
||||
std::string getFilePath() const;
|
||||
/* check for existence */
|
||||
void setFilePath(const std::string& c);
|
||||
void setFilePath(const std::string &c);
|
||||
std::string getFileName() const;
|
||||
void setFileName(const std::string& c);
|
||||
void setFileName(const std::string &c);
|
||||
uint64_t getFileIndex() const;
|
||||
void setFileIndex(const uint64_t i);
|
||||
bool getFileWriteEnable() const;
|
||||
@ -85,7 +85,6 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
void closeFiles();
|
||||
void restreamStop();
|
||||
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Network Configuration (UDP) *
|
||||
@ -106,8 +105,7 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
void setUDPPortNumber2(const uint32_t i);
|
||||
int64_t getUDPSocketBufferSize() const;
|
||||
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;
|
||||
void setDataStreamEnable(const bool enable);
|
||||
uint32_t getStreamingFrequency() const;
|
||||
/* 0 for timer */
|
||||
/* 0 for timer */
|
||||
void setStreamingFrequency(const uint32_t freq);
|
||||
uint32_t getStreamingTimer() const;
|
||||
void setStreamingTimer(const uint32_t time_in_ms);
|
||||
uint32_t getStreamingPort() const;
|
||||
void setStreamingPort(const uint32_t i);
|
||||
sls::IpAddr getStreamingSourceIP() const;
|
||||
void setStreamingSourceIP(const sls::IpAddr ip);
|
||||
void setStreamingSourceIP(const sls::IpAddr ip);
|
||||
std::map<std::string, std::string> getAdditionalJsonHeader() const;
|
||||
void setAdditionalJsonHeader(const std::map<std::string, std::string> &c);
|
||||
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] */
|
||||
void setROI(ROI arg);
|
||||
bool getTenGigaEnable() const;
|
||||
/* [Eiger][Ctb] */
|
||||
/* [Eiger][Ctb] */
|
||||
void setTenGigaEnable(const bool b);
|
||||
int getFlippedDataX() const;
|
||||
void setFlippedDataX(int enable = -1);
|
||||
@ -180,7 +179,8 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
/* [Eiger] */
|
||||
void setQuad(const bool b);
|
||||
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 getDeactivatedPadding() const;
|
||||
/* [Eiger] */
|
||||
@ -196,7 +196,7 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
void setADCEnableMask(const uint32_t mask);
|
||||
uint32_t getTenGigaADCEnableMask() const;
|
||||
/* [Ctb][Moench] */
|
||||
void setTenGigaADCEnableMask(const uint32_t mask);
|
||||
void setTenGigaADCEnableMask(const uint32_t mask);
|
||||
std::vector<int> getDbitList() const;
|
||||
/* [Ctb] */
|
||||
void setDbitList(const std::vector<int> v);
|
||||
@ -209,14 +209,18 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
* Callbacks *
|
||||
* *
|
||||
* ************************************************/
|
||||
void registerCallBackStartAcquisition(
|
||||
int (*func)(std::string, std::string, uint64_t, uint32_t, void *), void *arg);
|
||||
void registerCallBackAcquisitionFinished(
|
||||
void (*func)(uint64_t, void *), void *arg);
|
||||
void registerCallBackRawDataReady(
|
||||
void (*func)(char *, char *, uint32_t, void *), void *arg);
|
||||
void registerCallBackRawDataModifyReady(
|
||||
void (*func)(char *, char *, uint32_t &, void *), void *arg);
|
||||
void registerCallBackStartAcquisition(int (*func)(std::string, std::string,
|
||||
uint64_t, uint32_t,
|
||||
void *),
|
||||
void *arg);
|
||||
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *),
|
||||
void *arg);
|
||||
void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
|
||||
void *),
|
||||
void *arg);
|
||||
void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
|
||||
uint32_t &, void *),
|
||||
void *arg);
|
||||
|
||||
private:
|
||||
void DeleteMembers();
|
||||
@ -224,19 +228,18 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
void SetLocalNetworkParameters();
|
||||
void SetThreadPriorities();
|
||||
void SetupFifoStructure();
|
||||
|
||||
|
||||
void ResetParametersforNewAcquisition();
|
||||
void CreateUDPSockets();
|
||||
void SetupWriter();
|
||||
void StartRunning();
|
||||
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* Class Members *
|
||||
* *
|
||||
* ************************************************/
|
||||
|
||||
|
||||
// config parameters
|
||||
int numThreads;
|
||||
detectorType myDetectorType;
|
||||
@ -264,8 +267,8 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
|
||||
// network configuration (UDP)
|
||||
int numUDPInterfaces;
|
||||
std::vector <std::string> eth;
|
||||
std::vector <uint32_t> udpPortNum;
|
||||
std::vector<std::string> eth;
|
||||
std::vector<uint32_t> udpPortNum;
|
||||
int64_t udpSocketBufferSize;
|
||||
int64_t actualUDPSocketBufferSize;
|
||||
|
||||
@ -296,19 +299,20 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
ROI roi;
|
||||
bool tengigaEnable;
|
||||
int flippedDataX;
|
||||
bool quadEnable;
|
||||
bool quadEnable;
|
||||
bool activated;
|
||||
bool deactivatedPaddingEnable;
|
||||
int numLinesReadout;
|
||||
readoutMode readoutType;
|
||||
uint32_t adcEnableMaskOneGiga;
|
||||
uint32_t adcEnableMaskTenGiga;
|
||||
uint32_t adcEnableMaskTenGiga;
|
||||
std::vector<int> ctbDbitList;
|
||||
int ctbDbitOffset;
|
||||
int ctbAnalogDataBytes;
|
||||
|
||||
// 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 (*acquisitionFinishedCallBack)(uint64_t, void *);
|
||||
void *pAcquisitionFinished;
|
||||
|
933
slsReceiverSoftware/src/Listener.cpp
Executable file → Normal file
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
341
slsReceiverSoftware/src/Listener.h
Executable file → Normal file
@ -9,88 +9,89 @@
|
||||
*@short creates & manages a listener thread each
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include "ThreadObject.h"
|
||||
#include "UdpRxSocket.h"
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
class GeneralData;
|
||||
class Fifo;
|
||||
|
||||
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);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* Calls Base Class DestroyThread() and decrements NumberofListerners
|
||||
*/
|
||||
~Listener();
|
||||
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);
|
||||
|
||||
/**
|
||||
* Get Packets caught
|
||||
* @return Packets caught
|
||||
*/
|
||||
uint64_t GetPacketsCaught() const;
|
||||
/**
|
||||
* Destructor
|
||||
* Calls Base Class DestroyThread() and decrements NumberofListerners
|
||||
*/
|
||||
~Listener();
|
||||
|
||||
/**
|
||||
* Get Last Frame index caught
|
||||
* @return last frame index caught
|
||||
*/
|
||||
uint64_t GetLastFrameIndexCaught() const;
|
||||
/**
|
||||
* Get Packets caught
|
||||
* @return Packets caught
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
* @param f address of Fifo pointer
|
||||
*/
|
||||
void SetFifo(Fifo* f);
|
||||
/** Get number of missing packets */
|
||||
uint64_t GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const;
|
||||
|
||||
/**
|
||||
* Reset parameters for new acquisition
|
||||
*/
|
||||
void ResetParametersforNewAcquisition();
|
||||
/**
|
||||
* Set Fifo pointer to the one given
|
||||
* @param f address of Fifo pointer
|
||||
*/
|
||||
void SetFifo(Fifo *f);
|
||||
|
||||
/**
|
||||
* Set GeneralData pointer to the one given
|
||||
* @param g address of GeneralData (Detector Data) pointer
|
||||
*/
|
||||
void SetGeneralData(GeneralData* g);
|
||||
/**
|
||||
* Reset parameters for new acquisition
|
||||
*/
|
||||
void ResetParametersforNewAcquisition();
|
||||
|
||||
/**
|
||||
* Creates UDP Sockets
|
||||
*/
|
||||
void CreateUDPSockets();
|
||||
/**
|
||||
* Set GeneralData pointer to the one given
|
||||
* @param g address of GeneralData (Detector Data) pointer
|
||||
*/
|
||||
void SetGeneralData(GeneralData *g);
|
||||
|
||||
/**
|
||||
* Shuts down and deletes UDP Sockets
|
||||
*/
|
||||
void ShutDownUDPSocket();
|
||||
/**
|
||||
* Creates UDP Sockets
|
||||
*/
|
||||
void CreateUDPSockets();
|
||||
|
||||
/**
|
||||
* Shuts down and deletes UDP Sockets
|
||||
*/
|
||||
void ShutDownUDPSocket();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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 when used is in 2d
|
||||
* c is in col index for jungfrau and eiger (for missing packets/deactivated
|
||||
* eiger) c when used is in 2d
|
||||
*/
|
||||
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
|
||||
* @param fnum frame index to record
|
||||
*/
|
||||
void RecordFirstIndex(uint64_t fnum);
|
||||
/**
|
||||
* Pushes non empty buffers into fifo/ frees empty buffer,
|
||||
* pushes dummy buffer into fifo
|
||||
* and reset running mask by calling StopRunning()
|
||||
* @param buf address of buffer
|
||||
*/
|
||||
void StopListening(char *buf);
|
||||
|
||||
/**
|
||||
* Thread Execution for Listener Class
|
||||
* Pop free addresses, listen to udp socket,
|
||||
* write to memory & push the address into fifo
|
||||
*/
|
||||
void ThreadExecution() override;
|
||||
/**
|
||||
* Listen to the UDP Socket for an image,
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Pushes non empty buffers into fifo/ frees empty buffer,
|
||||
* pushes dummy buffer into fifo
|
||||
* and reset running mask by calling StopRunning()
|
||||
* @param buf address of buffer
|
||||
*/
|
||||
void StopListening(char* buf);
|
||||
/**
|
||||
* Print Fifo Statistics
|
||||
*/
|
||||
void PrintFifoStatistics();
|
||||
|
||||
/**
|
||||
* Listen to the UDP Socket for an image,
|
||||
* 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);
|
||||
/** type of thread */
|
||||
static const std::string TypeName;
|
||||
|
||||
/**
|
||||
* Print Fifo Statistics
|
||||
*/
|
||||
void PrintFifoStatistics();
|
||||
/** GeneralData (Detector Data) object */
|
||||
GeneralData *generalData{nullptr};
|
||||
|
||||
/** type of thread */
|
||||
static const std::string TypeName;
|
||||
/** Fifo structure */
|
||||
Fifo *fifo;
|
||||
|
||||
/** GeneralData (Detector Data) object */
|
||||
GeneralData* generalData{nullptr};
|
||||
// individual members
|
||||
/** Detector Type */
|
||||
detectorType myDetectorType;
|
||||
|
||||
/** Fifo structure */
|
||||
Fifo* fifo;
|
||||
/** Receiver Status */
|
||||
std::atomic<runStatus> *status;
|
||||
|
||||
// individual members
|
||||
/** Detector Type */
|
||||
detectorType myDetectorType;
|
||||
/** UDP Socket - Detector to Receiver */
|
||||
std::unique_ptr<sls::UdpRxSocket> udpSocket{nullptr};
|
||||
|
||||
/** Receiver Status */
|
||||
std::atomic<runStatus>* status;
|
||||
/** UDP Port Number */
|
||||
uint32_t *udpPortNumber;
|
||||
|
||||
/** UDP Socket - Detector to Receiver */
|
||||
std::unique_ptr<sls::UdpRxSocket> udpSocket{nullptr};
|
||||
/** ethernet interface */
|
||||
std::string *eth;
|
||||
|
||||
/** UDP Port Number */
|
||||
uint32_t* udpPortNumber;
|
||||
/** Number of Images to catch */
|
||||
uint64_t *numImages;
|
||||
|
||||
/** ethernet interface */
|
||||
std::string* eth;
|
||||
/** Dynamic Range */
|
||||
uint32_t *dynamicRange;
|
||||
|
||||
/** Number of Images to catch */
|
||||
uint64_t* numImages;
|
||||
/** UDP Socket Buffer Size */
|
||||
int64_t *udpSocketBufferSize;
|
||||
|
||||
/** Dynamic Range */
|
||||
uint32_t* dynamicRange;
|
||||
/** actual UDP Socket Buffer Size (double due to kernel bookkeeping) */
|
||||
int64_t *actualUDPSocketBufferSize;
|
||||
|
||||
/** UDP Socket Buffer Size */
|
||||
int64_t* udpSocketBufferSize;
|
||||
/** frames per file */
|
||||
uint32_t *framesPerFile;
|
||||
|
||||
/** actual UDP Socket Buffer Size (double due to kernel bookkeeping) */
|
||||
int64_t* actualUDPSocketBufferSize;
|
||||
/** frame discard policy */
|
||||
frameDiscardPolicy *frameDiscardMode;
|
||||
|
||||
/** frames per file */
|
||||
uint32_t* framesPerFile;
|
||||
/** Activated/Deactivated */
|
||||
bool *activated;
|
||||
|
||||
/** frame discard policy */
|
||||
frameDiscardPolicy* frameDiscardMode;
|
||||
|
||||
/** Activated/Deactivated */
|
||||
bool* activated;
|
||||
|
||||
/** Deactivated padding enable */
|
||||
bool* deactivatedPaddingEnable;
|
||||
/** Deactivated padding enable */
|
||||
bool *deactivatedPaddingEnable;
|
||||
|
||||
/** Silent Mode */
|
||||
bool* silentMode;
|
||||
bool *silentMode;
|
||||
|
||||
/** row hardcoded as 1D or 2d,
|
||||
* if detector does not send them yet or
|
||||
* missing packets/deactivated (eiger/jungfrau sends 2d pos) **/
|
||||
uint16_t row{0};
|
||||
/** row hardcoded as 1D or 2d,
|
||||
* if detector does not send them yet or
|
||||
* missing packets/deactivated (eiger/jungfrau sends 2d pos) **/
|
||||
uint16_t row{0};
|
||||
|
||||
/** column hardcoded as 2D,
|
||||
* deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/
|
||||
uint16_t column{0};
|
||||
/** column hardcoded as 2D,
|
||||
* deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/
|
||||
uint16_t column{0};
|
||||
|
||||
// acquisition start
|
||||
/** Aquisition Started flag */
|
||||
std::atomic<bool> startedFlag{false};
|
||||
// acquisition start
|
||||
/** Aquisition Started flag */
|
||||
std::atomic<bool> startedFlag{false};
|
||||
|
||||
/** Frame Number of First Frame */
|
||||
uint64_t firstIndex{0};
|
||||
/** Frame Number of First Frame */
|
||||
uint64_t firstIndex{0};
|
||||
|
||||
// for acquisition summary
|
||||
/** Number of complete Packets caught */
|
||||
std::atomic<uint64_t> numPacketsCaught{0};
|
||||
// for acquisition summary
|
||||
/** Number of complete Packets caught */
|
||||
std::atomic<uint64_t> numPacketsCaught{0};
|
||||
|
||||
/** Last Frame Index caught from udp network */
|
||||
std::atomic<uint64_t> lastCaughtFrameIndex{0};
|
||||
/** Last Frame Index caught from udp network */
|
||||
std::atomic<uint64_t> lastCaughtFrameIndex{0};
|
||||
|
||||
// parameters to acquire image
|
||||
/** Current Frame Index, default value is 0
|
||||
* ( always check startedFlag for validity first)
|
||||
*/
|
||||
uint64_t currentFrameIndex{0};
|
||||
// parameters to acquire image
|
||||
/** Current Frame Index, default value is 0
|
||||
* ( always check startedFlag for validity first)
|
||||
*/
|
||||
uint64_t currentFrameIndex{0};
|
||||
|
||||
/** True if there is a packet carry over from previous Image */
|
||||
bool carryOverFlag{false};
|
||||
/** True if there is a packet carry over from previous Image */
|
||||
bool carryOverFlag{false};
|
||||
|
||||
/** Carry over packet buffer */
|
||||
std::unique_ptr<char []> carryOverPacket;
|
||||
/** Carry over packet buffer */
|
||||
std::unique_ptr<char[]> carryOverPacket;
|
||||
|
||||
/** Listening buffer for one packet - might be removed when we can peek and eiger fnum is in header */
|
||||
std::unique_ptr<char []> listeningPacket;
|
||||
/** Listening buffer for one packet - might be removed when we can peek and
|
||||
* eiger fnum is in header */
|
||||
std::unique_ptr<char[]> listeningPacket;
|
||||
|
||||
/** if the udp socket is connected */
|
||||
std::atomic<bool> udpSocketAlive{false};
|
||||
/** if the udp socket is connected */
|
||||
std::atomic<bool> udpSocketAlive{false};
|
||||
|
||||
// for print progress during acquisition
|
||||
/** number of packets for statistic */
|
||||
uint32_t numPacketsStatistic{0};
|
||||
// for print progress during acquisition
|
||||
/** number of packets for statistic */
|
||||
uint32_t numPacketsStatistic{0};
|
||||
|
||||
/** number of images for statistic */
|
||||
uint32_t numFramesStatistic{0};
|
||||
/** number of images for statistic */
|
||||
uint32_t numFramesStatistic{0};
|
||||
|
||||
/**
|
||||
* 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) */
|
||||
bool oddStartingPacket{true};
|
||||
};
|
||||
|
||||
|
370
slsReceiverSoftware/src/MultiReceiverApp.cpp
Executable file → Normal file
370
slsReceiverSoftware/src/MultiReceiverApp.cpp
Executable file → Normal file
@ -1,19 +1,21 @@
|
||||
/* Creates the slsMultiReceiver for running multiple receivers form a single binary */
|
||||
#include "sls_detector_defs.h"
|
||||
/* Creates the slsMultiReceiver for running multiple receivers form a single
|
||||
* binary */
|
||||
#include "Receiver.h"
|
||||
#include "container_utils.h"
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
#include <csignal> //SIGINT
|
||||
#include <csignal> //SIGINT
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sys/wait.h> //wait
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.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 PRINT_IN_COLOR(c,f, ...) printf ("\033[%dm" f RESET, 30 + c+1, ##__VA_ARGS__)
|
||||
|
||||
/** Define Colors to print data call back in different colors for different
|
||||
* recievers */
|
||||
#define PRINT_IN_COLOR(c, f, ...) \
|
||||
printf("\033[%dm" f RESET, 30 + c + 1, ##__VA_ARGS__)
|
||||
|
||||
sem_t semaphore;
|
||||
|
||||
@ -21,23 +23,23 @@ sem_t semaphore;
|
||||
* Control+C Interrupt Handler
|
||||
* to let all the processes know to exit properly
|
||||
*/
|
||||
void sigInterruptHandler(int p){
|
||||
sem_post(&semaphore);
|
||||
}
|
||||
void sigInterruptHandler(int p) { sem_post(&semaphore); }
|
||||
|
||||
/**
|
||||
* prints usage of this example program
|
||||
*/
|
||||
void printHelp() {
|
||||
cprintf(RESET, "Usage:\n"
|
||||
"./slsMultiReceiver(detReceiver) [start_tcp_port] [num_receivers] [1 for call back, 0 for none]\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
cprintf(RESET, "Usage:\n"
|
||||
"./slsMultiReceiver(detReceiver) [start_tcp_port] "
|
||||
"[num_receivers] [1 for call back, 0 for none]\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Acquisition Call back
|
||||
* 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 filename file name
|
||||
* @param fileindex file index
|
||||
@ -45,9 +47,12 @@ void printHelp() {
|
||||
* @param p pointer to object
|
||||
* \returns ignored
|
||||
*/
|
||||
int StartAcq(std::string filepath, std::string filename, uint64_t fileindex, uint32_t datasize, void*p){
|
||||
LOG(logINFOBLUE) << "#### StartAcq: filepath:" << filepath << " filename:" << filename << " fileindex:" << fileindex << " datasize:" << datasize << " ####";
|
||||
return 0;
|
||||
int StartAcq(std::string filepath, std::string filename, uint64_t fileindex,
|
||||
uint32_t datasize, void *p) {
|
||||
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 p pointer to object
|
||||
*/
|
||||
void AcquisitionFinished(uint64_t frames, void*p){
|
||||
LOG(logINFOBLUE) << "#### AcquisitionFinished: frames:" << frames << " ####";
|
||||
void AcquisitionFinished(uint64_t frames, void *p) {
|
||||
LOG(logINFOBLUE) << "#### AcquisitionFinished: frames:" << frames
|
||||
<< " ####";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 datapointer pointer to data
|
||||
* @param datasize data size in bytes.
|
||||
* @param p pointer to object
|
||||
*/
|
||||
void GetData(char* metadata, char* datapointer, uint32_t datasize, void* p){
|
||||
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata;
|
||||
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
|
||||
void GetData(char *metadata, char *datapointer, uint32_t datasize, void *p) {
|
||||
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,
|
||||
"#### %d GetData: ####\n"
|
||||
"frameNumber: %lu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %lu"
|
||||
"\t\ttimestamp: %lu\t\tmodId: %u\t\t"
|
||||
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
|
||||
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
|
||||
//"\t\tpacketsMask:%s"
|
||||
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
|
||||
detectorHeader.row, (long unsigned int)detectorHeader.frameNumber,
|
||||
detectorHeader.expLength, detectorHeader.packetNumber, (long unsigned int)detectorHeader.bunchId,
|
||||
(long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
|
||||
detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
|
||||
detectorHeader.debug, detectorHeader.roundRNumber,
|
||||
detectorHeader.detType, detectorHeader.version,
|
||||
//header->packetsMask.to_string().c_str(),
|
||||
((uint8_t)(*((uint8_t*)(datapointer)))), datasize);
|
||||
PRINT_IN_COLOR(
|
||||
detectorHeader.modId ? detectorHeader.modId : detectorHeader.row,
|
||||
"#### %d GetData: ####\n"
|
||||
"frameNumber: %lu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %lu"
|
||||
"\t\ttimestamp: %lu\t\tmodId: %u\t\t"
|
||||
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
|
||||
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
|
||||
//"\t\tpacketsMask:%s"
|
||||
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
|
||||
detectorHeader.row, (long unsigned int)detectorHeader.frameNumber,
|
||||
detectorHeader.expLength, detectorHeader.packetNumber,
|
||||
(long unsigned int)detectorHeader.bunchId,
|
||||
(long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
|
||||
detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
|
||||
detectorHeader.debug, detectorHeader.roundRNumber,
|
||||
detectorHeader.detType, detectorHeader.version,
|
||||
// header->packetsMask.to_string().c_str(),
|
||||
((uint8_t)(*((uint8_t *)(datapointer)))), datasize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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 datapointer pointer to data
|
||||
* @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).
|
||||
* @param p pointer to object
|
||||
*/
|
||||
void GetData(char* metadata, char* datapointer, uint32_t &revDatasize, void* p){
|
||||
slsDetectorDefs::sls_receiver_header* header = (slsDetectorDefs::sls_receiver_header*)metadata;
|
||||
slsDetectorDefs::sls_detector_header detectorHeader = header->detHeader;
|
||||
void GetData(char *metadata, char *datapointer, uint32_t &revDatasize,
|
||||
void *p) {
|
||||
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,
|
||||
"#### %d GetData: ####\n"
|
||||
"frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: %llu"
|
||||
"\t\ttimestamp: %llu\t\tmodId: %u\t\t"
|
||||
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
|
||||
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
|
||||
//"\t\tpacketsMask:%s"
|
||||
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
|
||||
detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber,
|
||||
detectorHeader.expLength, detectorHeader.packetNumber, (long long unsigned int)detectorHeader.bunchId,
|
||||
(long long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
|
||||
detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
|
||||
detectorHeader.debug, detectorHeader.roundRNumber,
|
||||
detectorHeader.detType, detectorHeader.version,
|
||||
//header->packetsMask.to_string().c_str(),
|
||||
((uint8_t)(*((uint8_t*)(datapointer)))), revDatasize);
|
||||
PRINT_IN_COLOR(
|
||||
detectorHeader.modId ? detectorHeader.modId : detectorHeader.row,
|
||||
"#### %d GetData: ####\n"
|
||||
"frameNumber: %llu\t\texpLength: %u\t\tpacketNumber: %u\t\tbunchId: "
|
||||
"%llu"
|
||||
"\t\ttimestamp: %llu\t\tmodId: %u\t\t"
|
||||
"row: %u\t\tcolumn: %u\t\treserved: %u\t\tdebug: %u"
|
||||
"\t\troundRNumber: %u\t\tdetType: %u\t\tversion: %u"
|
||||
//"\t\tpacketsMask:%s"
|
||||
"\t\tfirstbytedata: 0x%x\t\tdatsize: %u\n\n",
|
||||
detectorHeader.row, (long long unsigned int)detectorHeader.frameNumber,
|
||||
detectorHeader.expLength, detectorHeader.packetNumber,
|
||||
(long long unsigned int)detectorHeader.bunchId,
|
||||
(long long unsigned int)detectorHeader.timestamp, detectorHeader.modId,
|
||||
detectorHeader.row, detectorHeader.column, detectorHeader.reserved,
|
||||
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
|
||||
revDatasize = 26000;
|
||||
// if data is modified, eg ROI and size is reduced
|
||||
revDatasize = 26000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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[]) {
|
||||
|
||||
/** - set default values */
|
||||
int numReceivers = 1;
|
||||
int startTCPPort = 1954;
|
||||
int withCallback = 0;
|
||||
sem_init(&semaphore,1,0);
|
||||
/** - set default values */
|
||||
int numReceivers = 1;
|
||||
int startTCPPort = 1954;
|
||||
int withCallback = 0;
|
||||
sem_init(&semaphore, 1, 0);
|
||||
|
||||
/** - get number of receivers and start tcp port from command line arguments */
|
||||
if ( (argc != 4) || (!sscanf(argv[1],"%d", &startTCPPort)) || (!sscanf(argv[2],"%d", &numReceivers)) || (!sscanf(argv[3],"%d", &withCallback)) )
|
||||
printHelp();
|
||||
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);
|
||||
/** - get number of receivers and start tcp port from command line
|
||||
* arguments */
|
||||
if ((argc != 4) || (!sscanf(argv[1], "%d", &startTCPPort)) ||
|
||||
(!sscanf(argv[2], "%d", &numReceivers)) ||
|
||||
(!sscanf(argv[3], "%d", &withCallback)))
|
||||
printHelp();
|
||||
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 */
|
||||
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");
|
||||
}
|
||||
/** - loop over number of receivers */
|
||||
for (int i = 0; i < numReceivers; ++i) {
|
||||
|
||||
/** - 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");
|
||||
}
|
||||
/** - fork process to create child process */
|
||||
pid_t pid = fork();
|
||||
|
||||
/** - 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 */
|
||||
for (int i = 0; i < numReceivers; ++i) {
|
||||
/** - if child process */
|
||||
else if (pid == 0) {
|
||||
cprintf(BLUE, "Child process %d [ Tid: %ld ]\n", i,
|
||||
(long)syscall(SYS_gettid));
|
||||
|
||||
/** - fork process to create child process */
|
||||
pid_t pid = fork();
|
||||
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) {
|
||||
|
||||
/** - 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);
|
||||
}
|
||||
/** - Call back for start acquisition */
|
||||
cprintf(BLUE, "Registering StartAcq()\n");
|
||||
receiver->registerCallBackStartAcquisition(StartAcq, nullptr);
|
||||
|
||||
/** - if child process */
|
||||
else if (pid == 0) {
|
||||
cprintf(BLUE,"Child process %d [ Tid: %ld ]\n", i, (long)syscall(SYS_gettid));
|
||||
|
||||
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 acquisition finished */
|
||||
cprintf(BLUE, "Registering AcquisitionFinished()\n");
|
||||
receiver->registerCallBackAcquisitionFinished(
|
||||
AcquisitionFinished, nullptr);
|
||||
|
||||
/** - Call back for start acquisition */
|
||||
cprintf(BLUE, "Registering StartAcq()\n");
|
||||
receiver->registerCallBackStartAcquisition(StartAcq, nullptr);
|
||||
/* - Call back for raw data */
|
||||
cprintf(BLUE, "Registering GetData() \n");
|
||||
if (withCallback == 1)
|
||||
receiver->registerCallBackRawDataReady(GetData, nullptr);
|
||||
else if (withCallback == 2)
|
||||
receiver->registerCallBackRawDataModifyReady(GetData,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
/** - Call back for acquisition finished */
|
||||
cprintf(BLUE, "Registering AcquisitionFinished()\n");
|
||||
receiver->registerCallBackAcquisitionFinished(AcquisitionFinished, nullptr);
|
||||
/** - as long as no Ctrl+C */
|
||||
sem_wait(&semaphore);
|
||||
sem_destroy(&semaphore);
|
||||
cprintf(BLUE, "Exiting Child Process [ Tid: %ld ]\n",
|
||||
(long)syscall(SYS_gettid));
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* - Call back for raw data */
|
||||
cprintf(BLUE, "Registering GetData() \n");
|
||||
if (withCallback == 1) receiver->registerCallBackRawDataReady(GetData,nullptr);
|
||||
else if (withCallback == 2) receiver->registerCallBackRawDataModifyReady(GetData,nullptr);
|
||||
}
|
||||
/** - Parent process ignores SIGINT (exits only when all child process
|
||||
* exits) */
|
||||
sa.sa_flags = 0; // no flags
|
||||
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 */
|
||||
sem_wait(&semaphore);
|
||||
sem_destroy(&semaphore);
|
||||
cprintf(BLUE,"Exiting Child Process [ Tid: %ld ]\n", (long)syscall(SYS_gettid));
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/** - Print Ready and Instructions how to exit */
|
||||
std::cout << "Ready ... \n";
|
||||
cprintf(RESET, "\n[ Press \'Ctrl+c\' to exit ]\n");
|
||||
|
||||
/** - Parent process ignores SIGINT (exits only when all child process exits) */
|
||||
sa.sa_flags=0; // no flags
|
||||
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");
|
||||
}
|
||||
/** - Parent process waits for all child processes to exit */
|
||||
for (;;) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/** - Print Ready and Instructions how to exit */
|
||||
std::cout << "Ready ... \n";
|
||||
cprintf(RESET, "\n[ Press \'Ctrl+c\' to exit ]\n");
|
||||
// child closed
|
||||
cprintf(BLUE, "Exiting Child Process [ Tid: %ld ]\n",
|
||||
(long int)childPid);
|
||||
}
|
||||
|
||||
/** - Parent process waits for all child processes to exit */
|
||||
for(;;) {
|
||||
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;
|
||||
std::cout << "Goodbye!\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
201
slsReceiverSoftware/src/Receiver.cpp
Executable file → Normal file
201
slsReceiverSoftware/src/Receiver.cpp
Executable file → Normal file
@ -1,9 +1,9 @@
|
||||
#include "Receiver.h"
|
||||
#include "ClientInterface.h"
|
||||
#include "container_utils.h"
|
||||
#include "logger.h"
|
||||
#include "sls_detector_exceptions.h"
|
||||
#include "versionAPI.h"
|
||||
#include "container_utils.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
@ -17,126 +17,129 @@
|
||||
|
||||
Receiver::~Receiver() = default;
|
||||
|
||||
Receiver::Receiver(int argc, char *argv[]):
|
||||
tcpipInterface (nullptr) {
|
||||
Receiver::Receiver(int argc, char *argv[]) : tcpipInterface(nullptr) {
|
||||
|
||||
// options
|
||||
std::map<std::string, std::string> configuration_map;
|
||||
int tcpip_port_no = 1954;
|
||||
uid_t userid = -1;
|
||||
// options
|
||||
std::map<std::string, std::string> configuration_map;
|
||||
int tcpip_port_no = 1954;
|
||||
uid_t userid = -1;
|
||||
|
||||
//parse command line for config
|
||||
static struct option long_options[] = {
|
||||
// These options set a flag.
|
||||
//{"verbose", no_argument, &verbose_flag, 1},
|
||||
// These options don’t set a flag. We distinguish them by their indices.
|
||||
{"rx_tcpport", required_argument, nullptr, 't'}, //TODO change or backward compatible to "port, p"?
|
||||
{"uid", required_argument, nullptr, 'u'},
|
||||
{"version", no_argument, nullptr, 'v'},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
// parse command line for config
|
||||
static struct option long_options[] = {
|
||||
// These options set a flag.
|
||||
//{"verbose", no_argument, &verbose_flag, 1},
|
||||
// These options don’t set a flag. We distinguish them by their indices.
|
||||
{"rx_tcpport", required_argument, nullptr,
|
||||
't'}, // TODO change or backward compatible to "port, p"?
|
||||
{"uid", required_argument, nullptr, 'u'},
|
||||
{"version", no_argument, nullptr, 'v'},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{nullptr, 0, nullptr, 0}};
|
||||
|
||||
//initialize global optind variable (required when instantiating multiple receivers in the same process)
|
||||
optind = 1;
|
||||
// getopt_long stores the option index here.
|
||||
int option_index = 0;
|
||||
int c = 0;
|
||||
// initialize global optind variable (required when instantiating multiple
|
||||
// receivers in the same process)
|
||||
optind = 1;
|
||||
// getopt_long stores the option index here.
|
||||
int option_index = 0;
|
||||
int c = 0;
|
||||
|
||||
while ( c != -1 ){
|
||||
c = getopt_long (argc, argv, "hvf:t:u:", long_options, &option_index);
|
||||
while (c != -1) {
|
||||
c = getopt_long(argc, argv, "hvf:t:u:", long_options, &option_index);
|
||||
|
||||
// Detect the end of the options.
|
||||
if (c == -1)
|
||||
break;
|
||||
// Detect the end of the options.
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch(c){
|
||||
switch (c) {
|
||||
|
||||
case 't':
|
||||
sscanf(optarg, "%d", &tcpip_port_no);
|
||||
break;
|
||||
case 't':
|
||||
sscanf(optarg, "%d", &tcpip_port_no);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if (sscanf(optarg, "%u", &userid) != 1) {
|
||||
throw sls::RuntimeError("Could not scan uid");
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
if (sscanf(optarg, "%u", &userid) != 1) {
|
||||
throw sls::RuntimeError("Could not scan uid");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
std::cout << "SLS Receiver Version: " << GITBRANCH << " (0x" << std::hex << APIRECEIVER << ")" << std::endl;
|
||||
LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]";
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'v':
|
||||
std::cout << "SLS Receiver Version: " << GITBRANCH << " (0x"
|
||||
<< std::hex << APIRECEIVER << ")" << std::endl;
|
||||
LOG(logINFOBLUE)
|
||||
<< "Exiting [ Tid: " << syscall(SYS_gettid) << " ]";
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
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";
|
||||
case 'h':
|
||||
default:
|
||||
std::cout << std::endl;
|
||||
|
||||
//std::cout << help_message << std::endl;
|
||||
throw sls::RuntimeError(help_message);
|
||||
}
|
||||
}
|
||||
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";
|
||||
|
||||
// set effective id if provided
|
||||
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;
|
||||
}
|
||||
}
|
||||
// std::cout << help_message << std::endl;
|
||||
throw sls::RuntimeError(help_message);
|
||||
}
|
||||
}
|
||||
|
||||
// might throw an exception
|
||||
tcpipInterface = sls::make_unique<ClientInterface>(tcpip_port_no);
|
||||
// set effective id if provided
|
||||
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)
|
||||
{
|
||||
// might throw an exception
|
||||
tcpipInterface = sls::make_unique<ClientInterface>(tcpip_port_no);
|
||||
Receiver::Receiver(int tcpip_port_no) {
|
||||
// might throw an exception
|
||||
tcpipInterface = sls::make_unique<ClientInterface>(tcpip_port_no);
|
||||
}
|
||||
|
||||
int64_t Receiver::getReceiverVersion(){
|
||||
return tcpipInterface->getReceiverVersion();
|
||||
int64_t Receiver::getReceiverVersion() {
|
||||
return tcpipInterface->getReceiverVersion();
|
||||
}
|
||||
|
||||
|
||||
void Receiver::registerCallBackStartAcquisition(int (*func)(
|
||||
std::string, std::string, uint64_t, uint32_t, void*),void *arg){
|
||||
tcpipInterface->registerCallBackStartAcquisition(func,arg);
|
||||
void Receiver::registerCallBackStartAcquisition(
|
||||
int (*func)(std::string, std::string, uint64_t, uint32_t, void *),
|
||||
void *arg) {
|
||||
tcpipInterface->registerCallBackStartAcquisition(func, arg);
|
||||
}
|
||||
|
||||
|
||||
void Receiver::registerCallBackAcquisitionFinished(
|
||||
void (*func)(uint64_t, void*),void *arg){
|
||||
tcpipInterface->registerCallBackAcquisitionFinished(func,arg);
|
||||
void Receiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t,
|
||||
void *),
|
||||
void *arg) {
|
||||
tcpipInterface->registerCallBackAcquisitionFinished(func, arg);
|
||||
}
|
||||
|
||||
|
||||
void Receiver::registerCallBackRawDataReady(void (*func)(char*,
|
||||
char*, uint32_t, void*),void *arg){
|
||||
tcpipInterface->registerCallBackRawDataReady(func,arg);
|
||||
void Receiver::registerCallBackRawDataReady(void (*func)(char *, char *,
|
||||
uint32_t, void *),
|
||||
void *arg) {
|
||||
tcpipInterface->registerCallBackRawDataReady(func, arg);
|
||||
}
|
||||
|
||||
|
||||
void Receiver::registerCallBackRawDataModifyReady(void (*func)(char*,
|
||||
char*, uint32_t &, void*),void *arg){
|
||||
tcpipInterface->registerCallBackRawDataModifyReady(func,arg);
|
||||
void Receiver::registerCallBackRawDataModifyReady(
|
||||
void (*func)(char *, char *, uint32_t &, void *), void *arg) {
|
||||
tcpipInterface->registerCallBackRawDataModifyReady(func, arg);
|
||||
}
|
||||
|
||||
|
77
slsReceiverSoftware/src/ReceiverApp.cpp
Executable file → Normal file
77
slsReceiverSoftware/src/ReceiverApp.cpp
Executable file → Normal file
@ -1,57 +1,54 @@
|
||||
/* slsReceiver */
|
||||
#include "logger.h"
|
||||
#include "Receiver.h"
|
||||
#include "sls_detector_defs.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 <unistd.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
sem_t semaphore;
|
||||
|
||||
void sigInterruptHandler(int p){
|
||||
sem_post(&semaphore);
|
||||
}
|
||||
|
||||
void sigInterruptHandler(int p) { sem_post(&semaphore); }
|
||||
|
||||
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
|
||||
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) {
|
||||
LOG(logERROR) << "Could not set handler function for SIGINT";
|
||||
}
|
||||
// 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) {
|
||||
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
|
||||
// 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";
|
||||
}
|
||||
|
||||
try {
|
||||
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;
|
||||
try {
|
||||
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
84
slsReceiverSoftware/src/ThreadObject.cpp
Executable file → Normal file
@ -10,61 +10,57 @@
|
||||
#include <unistd.h>
|
||||
|
||||
ThreadObject::ThreadObject(int threadIndex, std::string threadType)
|
||||
: index(threadIndex), type(threadType) {
|
||||
LOG(logDEBUG) << type << " thread created: " << index;
|
||||
sem_init(&semaphore,1,0);
|
||||
try {
|
||||
threadObject = std::thread(&ThreadObject::RunningThread, this);
|
||||
} catch (...) {
|
||||
throw sls::RuntimeError("Could not create " + type + " thread with index " + std::to_string(index));
|
||||
}
|
||||
: index(threadIndex), type(threadType) {
|
||||
LOG(logDEBUG) << type << " thread created: " << index;
|
||||
sem_init(&semaphore, 1, 0);
|
||||
try {
|
||||
threadObject = std::thread(&ThreadObject::RunningThread, this);
|
||||
} catch (...) {
|
||||
throw sls::RuntimeError("Could not create " + type +
|
||||
" thread with index " + std::to_string(index));
|
||||
}
|
||||
}
|
||||
|
||||
ThreadObject::~ThreadObject() {
|
||||
killThread = true;
|
||||
sem_post(&semaphore);
|
||||
threadObject.join();
|
||||
sem_destroy(&semaphore);
|
||||
killThread = true;
|
||||
sem_post(&semaphore);
|
||||
threadObject.join();
|
||||
sem_destroy(&semaphore);
|
||||
}
|
||||
|
||||
bool ThreadObject::IsRunning() const{
|
||||
return runningFlag;
|
||||
}
|
||||
bool ThreadObject::IsRunning() const { return runningFlag; }
|
||||
|
||||
void ThreadObject::StartRunning() {
|
||||
runningFlag = true;
|
||||
}
|
||||
void ThreadObject::StartRunning() { runningFlag = true; }
|
||||
|
||||
void ThreadObject::StopRunning() {
|
||||
runningFlag = false;
|
||||
}
|
||||
void ThreadObject::StopRunning() { runningFlag = false; }
|
||||
|
||||
void ThreadObject::RunningThread() {
|
||||
LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]";
|
||||
while(!killThread) {
|
||||
while(IsRunning()) {
|
||||
ThreadExecution();
|
||||
}
|
||||
//wait till the next acquisition
|
||||
sem_wait(&semaphore);
|
||||
}
|
||||
LOG(logINFOBLUE) << "Exiting [ " << type << " Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]";
|
||||
LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index
|
||||
<< ", Tid: " << syscall(SYS_gettid) << "]";
|
||||
while (!killThread) {
|
||||
while (IsRunning()) {
|
||||
ThreadExecution();
|
||||
}
|
||||
// wait till the next acquisition
|
||||
sem_wait(&semaphore);
|
||||
}
|
||||
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) {
|
||||
struct sched_param param;
|
||||
param.sched_priority = priority;
|
||||
if (pthread_setschedparam(threadObject.native_handle(), SCHED_FIFO, ¶m) == EPERM) {
|
||||
if (index == 0) {
|
||||
LOG(logWARNING) << "Could not prioritize " << type << " thread. "
|
||||
"(No Root Privileges?)";
|
||||
}
|
||||
} else {
|
||||
LOG(logINFO) << "Priorities set - " << type << ": " << priority;
|
||||
}
|
||||
struct sched_param param;
|
||||
param.sched_priority = priority;
|
||||
if (pthread_setschedparam(threadObject.native_handle(), SCHED_FIFO,
|
||||
¶m) == EPERM) {
|
||||
if (index == 0) {
|
||||
LOG(logWARNING) << "Could not prioritize " << type
|
||||
<< " thread. "
|
||||
"(No Root Privileges?)";
|
||||
}
|
||||
} else {
|
||||
LOG(logINFO) << "Priorities set - " << type << ": " << priority;
|
||||
}
|
||||
}
|
||||
|
4
slsReceiverSoftware/src/ThreadObject.h
Executable file → Normal file
4
slsReceiverSoftware/src/ThreadObject.h
Executable file → Normal file
@ -11,9 +11,9 @@
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <semaphore.h>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
class ThreadObject : private virtual slsDetectorDefs {
|
||||
protected:
|
||||
@ -22,7 +22,7 @@ class ThreadObject : private virtual slsDetectorDefs {
|
||||
private:
|
||||
std::atomic<bool> killThread{false};
|
||||
std::atomic<bool> runningFlag{false};
|
||||
std::thread threadObject;
|
||||
std::thread threadObject;
|
||||
sem_t semaphore;
|
||||
const std::string type;
|
||||
|
||||
|
@ -1,64 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include "sls_detector_defs.h"
|
||||
#include <cstdint>
|
||||
#include <cstdint>
|
||||
|
||||
#define MAX_DIMENSIONS (2)
|
||||
#define MAX_DIMENSIONS (2)
|
||||
#define MAX_NUMBER_OF_LISTENING_THREADS (2)
|
||||
|
||||
//socket
|
||||
#define GOODBYE (-200)
|
||||
#define RECEIVE_SOCKET_BUFFER_SIZE (100*1024*1024)
|
||||
// socket
|
||||
#define GOODBYE (-200)
|
||||
#define RECEIVE_SOCKET_BUFFER_SIZE (100 * 1024 * 1024)
|
||||
|
||||
#define MAX_SOCKET_INPUT_PACKET_QUEUE (250000)
|
||||
#define MAX_SOCKET_INPUT_PACKET_QUEUE (250000)
|
||||
|
||||
|
||||
//files
|
||||
#define MAX_FRAMES_PER_FILE 20000
|
||||
#define SHORT_MAX_FRAMES_PER_FILE 100000
|
||||
#define MOENCH_MAX_FRAMES_PER_FILE 100000
|
||||
#define EIGER_MAX_FRAMES_PER_FILE 10000
|
||||
#define JFRAU_MAX_FRAMES_PER_FILE 10000
|
||||
#define CTB_MAX_FRAMES_PER_FILE 20000
|
||||
#define MYTHEN3_MAX_FRAMES_PER_FILE 10000
|
||||
// files
|
||||
#define MAX_FRAMES_PER_FILE 20000
|
||||
#define SHORT_MAX_FRAMES_PER_FILE 100000
|
||||
#define MOENCH_MAX_FRAMES_PER_FILE 100000
|
||||
#define EIGER_MAX_FRAMES_PER_FILE 10000
|
||||
#define JFRAU_MAX_FRAMES_PER_FILE 10000
|
||||
#define CTB_MAX_FRAMES_PER_FILE 20000
|
||||
#define MYTHEN3_MAX_FRAMES_PER_FILE 10000
|
||||
#define GOTTHARD2_MAX_FRAMES_PER_FILE 20000
|
||||
|
||||
#define DO_NOTHING (0)
|
||||
#define DO_EVERYTHING (1)
|
||||
#define DO_NOTHING (0)
|
||||
#define DO_EVERYTHING (1)
|
||||
|
||||
#define STATISTIC_FRAMENUMBER_INFINITE (20000)
|
||||
#define STATISTIC_FRAMENUMBER_INFINITE (20000)
|
||||
|
||||
//binary
|
||||
#define FILE_BUFFER_SIZE (16*1024*1024) //16mb
|
||||
// binary
|
||||
#define FILE_BUFFER_SIZE (16 * 1024 * 1024) // 16mb
|
||||
|
||||
//fifo
|
||||
#define FIFO_HEADER_NUMBYTES (8)
|
||||
#define FIFO_DATASIZE_NUMBYTES (4)
|
||||
#define FIFO_PADDING_NUMBYTES (4) // for 8 byte alignment due to sls_receiver_header structure
|
||||
// fifo
|
||||
#define FIFO_HEADER_NUMBYTES (8)
|
||||
#define FIFO_DATASIZE_NUMBYTES (4)
|
||||
#define FIFO_PADDING_NUMBYTES \
|
||||
(4) // for 8 byte alignment due to sls_receiver_header structure
|
||||
|
||||
// hdf5
|
||||
#define MAX_CHUNKED_IMAGES (1)
|
||||
|
||||
//hdf5
|
||||
#define MAX_CHUNKED_IMAGES (1)
|
||||
// versions
|
||||
#define HDF5_WRITER_VERSION (5.0) // 1 decimal places
|
||||
#define BINARY_WRITER_VERSION (5.0) // 1 decimal places
|
||||
|
||||
//versions
|
||||
#define HDF5_WRITER_VERSION (5.0) //1 decimal places
|
||||
#define BINARY_WRITER_VERSION (5.0) //1 decimal places
|
||||
// parameters to calculate fifo depth
|
||||
#define SAMPLE_TIME_IN_NS (100000000) // 100ms
|
||||
#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 SAMPLE_TIME_IN_NS (100000000)//100ms
|
||||
#define MAX_EIGER_ROWS_PER_READOUT (256)
|
||||
#define DUMMY_PACKET_VALUE (0xFFFFFFFF)
|
||||
|
||||
//to differentiate between gotthard and short gotthard
|
||||
#define GOTTHARD_PACKET_SIZE (1286)
|
||||
|
||||
|
||||
#define DUMMY_PACKET_VALUE (0xFFFFFFFF)
|
||||
|
||||
#define LISTENER_PRIORITY (90)
|
||||
#define PROCESSOR_PRIORITY (70)
|
||||
#define STREAMER_PRIORITY (10)
|
||||
#define TCP_PRIORITY (10)
|
||||
#define LISTENER_PRIORITY (90)
|
||||
#define PROCESSOR_PRIORITY (70)
|
||||
#define STREAMER_PRIORITY (10)
|
||||
#define TCP_PRIORITY (10)
|
||||
|
||||
struct masterAttributes {
|
||||
double version;
|
||||
@ -82,4 +79,4 @@ struct masterAttributes {
|
||||
uint64_t dbitlist;
|
||||
uint32_t roiXmin;
|
||||
uint32_t roiXmax;
|
||||
};
|
||||
};
|
||||
|
@ -1,52 +1,49 @@
|
||||
#include "catch.hpp"
|
||||
#include "CircularFifo.h"
|
||||
#include "catch.hpp"
|
||||
#include <vector>
|
||||
|
||||
TEST_CASE("Empty buffer"){
|
||||
TEST_CASE("Empty buffer") {
|
||||
CircularFifo<char> fifo(0);
|
||||
|
||||
//Since the fifo can hold zero elements
|
||||
//its both empty and full
|
||||
CHECK(fifo.isEmpty()== true);
|
||||
CHECK(fifo.isFull()== true);
|
||||
// Since the fifo can hold zero elements
|
||||
// its both empty and full
|
||||
CHECK(fifo.isEmpty() == true);
|
||||
CHECK(fifo.isFull() == true);
|
||||
|
||||
|
||||
//push fails
|
||||
char* c = new char;
|
||||
// push fails
|
||||
char *c = new char;
|
||||
*c = 'h';
|
||||
CHECK(fifo.push(c, true) == false);
|
||||
|
||||
//pop fails
|
||||
// pop fails
|
||||
CHECK(fifo.pop(c, true) == false);
|
||||
|
||||
delete c;
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Push pop"){
|
||||
TEST_CASE("Push pop") {
|
||||
CircularFifo<int> fifo(5);
|
||||
|
||||
std::vector<int> vec{3,7,12,3,4};
|
||||
int* p = &vec[0];
|
||||
std::vector<int> vec{3, 7, 12, 3, 4};
|
||||
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);
|
||||
++p;
|
||||
CHECK(fifo.getDataValue() == i+1);
|
||||
CHECK(fifo.getFreeValue() == 4-i);
|
||||
CHECK(fifo.getDataValue() == i + 1);
|
||||
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);
|
||||
CHECK(*p == vec[i]);
|
||||
CHECK(fifo.getDataValue() == 4-i);
|
||||
CHECK(fifo.getFreeValue() == i+1);
|
||||
CHECK(fifo.getDataValue() == 4 - i);
|
||||
CHECK(fifo.getFreeValue() == i + 1);
|
||||
}
|
||||
|
||||
CHECK(fifo.isEmpty()== true);
|
||||
CHECK(fifo.isFull()== false);
|
||||
|
||||
CHECK(fifo.isEmpty() == true);
|
||||
CHECK(fifo.isFull() == false);
|
||||
}
|
5
slsReceiverSoftware/tests/test-GeneralData.cpp
Executable file → Normal file
5
slsReceiverSoftware/tests/test-GeneralData.cpp
Executable file → Normal file
@ -2,11 +2,8 @@
|
||||
#include "GeneralData.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
// using namespace sls;
|
||||
|
||||
// TEST_CASE("Parse jungfrauctb header", "[receiver]") {
|
||||
@ -55,7 +52,7 @@
|
||||
// CHECK(subFrameNumber == -1);
|
||||
// }
|
||||
|
||||
// TEST_CASE("Parse header gotthard data", "[receiver]") {
|
||||
// TEST_CASE("Parse header gotthard data", "[receiver]") {
|
||||
// GotthardData data;
|
||||
// struct packet {
|
||||
// uint32_t frameNumber;
|
||||
|
Loading…
x
Reference in New Issue
Block a user