Rxclassmembers (#503)

* gui message doesnt show if it has a '>' symbol in error msg

* minor refactoring for readability (size_t calc fifo size)

* refactoring listening udp socket code: activated and datastream dont create udp sockets anyway, rc<=- should be discarded in any case

* wip

* refactoring memory structure access

* wip: bugfix write header + data to binary

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* portRoi no roi effecto on progress

* fail at receiver progress, wip

* segfaults for char pointer in struct

* reference to header to get header and data

* refactoring

* use const defined for size of header of fifo

* updated release notes

* remove pointer in callback for sls_receiver_header pointer

* rx same name arguments in constructors

* rx: same name arguments in constructor

* rx: removing the '_' suffix in class data members

* merge fix

* merge fix

* review fix refactoring
This commit is contained in:
Dhanya Thattil 2022-07-25 14:02:11 +02:00 committed by GitHub
parent d132ad8d02
commit 9ac8dab8af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 349 additions and 493 deletions

View File

@ -84,6 +84,7 @@ This document describes the differences between v7.0.0 and v6.x.x
- set dataset name for all hdf5 files to "data" only - set dataset name for all hdf5 files to "data" only
- number of storage cells is not updated in teh receiver. done. and also allowing it to be modified in running status - number of storage cells is not updated in teh receiver. done. and also allowing it to be modified in running status
- refactored memory structure in receiver and listener code (maybe resolves stuck issue, need to check) - refactored memory structure in receiver and listener code (maybe resolves stuck issue, need to check)
- callback modified to have rx header and not rx header pointer
2. Resolved Issues 2. Resolved Issues
================== ==================

@ -1 +1 @@
Subproject commit 8de7772cc72daca8e947b79b83fea46214931604 Subproject commit 914c06fb252b6cc3727d0eedab6736e88a3fcb01

View File

@ -4,7 +4,6 @@ set(SOURCES
src/Implementation.cpp src/Implementation.cpp
src/ClientInterface.cpp src/ClientInterface.cpp
src/Receiver.cpp src/Receiver.cpp
src/File.cpp
src/BinaryDataFile.cpp src/BinaryDataFile.cpp
src/ThreadObject.cpp src/ThreadObject.cpp
src/Listener.cpp src/Listener.cpp

View File

@ -4,88 +4,93 @@
namespace sls { namespace sls {
BinaryDataFile::BinaryDataFile(const int index) : File(BINARY), index_(index) {} BinaryDataFile::BinaryDataFile(const int index) : index(index) {}
BinaryDataFile::~BinaryDataFile() { CloseFile(); } BinaryDataFile::~BinaryDataFile() { CloseFile(); }
void BinaryDataFile::CloseFile() { slsDetectorDefs::fileFormat BinaryDataFile::GetFileFormat() const {
if (fd_) { return BINARY;
fclose(fd_);
} }
fd_ = nullptr;
void BinaryDataFile::CloseFile() {
if (fd) {
fclose(fd);
}
fd = nullptr;
} }
void BinaryDataFile::CreateFirstBinaryDataFile( void BinaryDataFile::CreateFirstBinaryDataFile(
const std::string filePath, const std::string fileNamePrefix, const std::string fPath, const std::string fNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, const uint64_t fIndex, const bool ovEnable, const bool sMode,
const int modulePos, const int numUnitsPerReadout, const int modulePos, const int nUnitsPerReadout,
const uint32_t udpPortNumber, const uint32_t maxFramesPerFile) { const uint32_t uPortNumber, const uint32_t mFramesPerFile) {
subFileIndex_ = 0; subFileIndex = 0;
numFramesInFile_ = 0; numFramesInFile = 0;
filePath_ = filePath; filePath = fPath;
fileNamePrefix_ = fileNamePrefix; fileNamePrefix = fNamePrefix;
fileIndex_ = fileIndex; fileIndex = fIndex;
overWriteEnable_ = overWriteEnable; overWriteEnable = ovEnable;
silentMode_ = silentMode;
detIndex_ = modulePos; silentMode = sMode;
numUnitsPerReadout_ = numUnitsPerReadout; detIndex = modulePos;
udpPortNumber_ = udpPortNumber; numUnitsPerReadout = nUnitsPerReadout;
maxFramesPerFile_ = maxFramesPerFile; udpPortNumber = uPortNumber;
maxFramesPerFile = mFramesPerFile;
CreateFile(); CreateFile();
} }
void BinaryDataFile::CreateFile() { void BinaryDataFile::CreateFile() {
numFramesInFile_ = 0; numFramesInFile = 0;
std::ostringstream os; std::ostringstream os;
os << filePath_ << "/" << fileNamePrefix_ << "_d" os << filePath << "/" << fileNamePrefix << "_d"
<< (detIndex_ * numUnitsPerReadout_ + index_) << "_f" << subFileIndex_ << (detIndex * numUnitsPerReadout + index) << "_f" << subFileIndex
<< '_' << fileIndex_ << ".raw"; << '_' << fileIndex << ".raw";
fileName_ = os.str(); fileName = os.str();
if (!overWriteEnable_) { if (!overWriteEnable) {
if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "wx"))) { if (nullptr == (fd = fopen(fileName.c_str(), "wx"))) {
fd_ = nullptr; fd = nullptr;
throw RuntimeError("Could not create/overwrite file " + throw RuntimeError("Could not create/overwrite file " +
fileName_); fileName);
} }
} else if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "w"))) { } else if (nullptr == (fd = fopen(fileName.c_str(), "w"))) {
fd_ = nullptr; fd = nullptr;
throw RuntimeError("Could not create file " + fileName_); throw RuntimeError("Could not create file " + fileName);
} }
// setting to no file buffering // setting to no file buffering
setvbuf(fd_, nullptr, _IONBF, 0); setvbuf(fd, nullptr, _IONBF, 0);
if (!silentMode_) { if (!silentMode) {
LOG(logINFO) << "[" << udpPortNumber_ LOG(logINFO) << "[" << udpPortNumber
<< "]: Binary File created: " << fileName_; << "]: Binary File created: " << fileName;
} }
} }
void BinaryDataFile::WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber, const uint32_t numPacketsCaught) { void BinaryDataFile::WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber, const uint32_t numPacketsCaught) {
// check if maxframesperfile = 0 for infinite // check if maxframesperfile = 0 for infinite
if (maxFramesPerFile_ && (numFramesInFile_ >= maxFramesPerFile_)) { if (maxFramesPerFile && (numFramesInFile >= maxFramesPerFile)) {
CloseFile(); CloseFile();
++subFileIndex_; ++subFileIndex;
CreateFile(); CreateFile();
} }
++numFramesInFile_; ++numFramesInFile;
// write to file // write to file
size_t ret = 0; size_t ret = 0;
// contiguous bitset (write header + image) // contiguous bitset (write header + image)
if (sizeof(sls_bitset) == sizeof(bitset_storage)) { if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
ret = fwrite(&header, sizeof(sls_receiver_header) + imageSize, 1, fd_); ret = fwrite(&header, sizeof(sls_receiver_header) + imageSize, 1, fd);
} }
// not contiguous bitset // not contiguous bitset
else { else {
// write detector header // write detector header
ret = fwrite(&header, sizeof(sls_detector_header), 1, fd_); ret = fwrite(&header, sizeof(sls_detector_header), 1, fd);
// get contiguous representation of bit mask // get contiguous representation of bit mask
bitset_storage storage; bitset_storage storage;
@ -94,15 +99,15 @@ void BinaryDataFile::WriteToFile(char *imageData, sls_receiver_header& header, c
for (int i = 0; i < MAX_NUM_PACKETS; ++i) for (int i = 0; i < MAX_NUM_PACKETS; ++i)
storage[i >> 3] |= (bits[i] << (i & 7)); storage[i >> 3] |= (bits[i] << (i & 7));
// write bitmask // write bitmask
ret += fwrite(storage, sizeof(bitset_storage), 1, fd_); ret += fwrite(storage, sizeof(bitset_storage), 1, fd);
// write data // write data
ret += fwrite(imageData, imageSize, 1, fd_); ret += fwrite(imageData, imageSize, 1, fd);
} }
// if write error // if write error
if (ret != imageSize + sizeof(sls_receiver_header)) { if (ret != imageSize + sizeof(sls_receiver_header)) {
throw RuntimeError(std::to_string(index_) + " : Write to file failed for image number " + std::to_string(currentFrameNumber) + ". Wrote " + std::to_string(ret) + " bytes instead of " + std::to_string(imageSize + sizeof(sls_receiver_header))); throw RuntimeError(std::to_string(index) + " : Write to file failed for image number " + std::to_string(currentFrameNumber) + ". Wrote " + std::to_string(ret) + " bytes instead of " + std::to_string(imageSize + sizeof(sls_receiver_header)));
} }
} }

View File

@ -12,36 +12,37 @@ class BinaryDataFile : private virtual slsDetectorDefs, public File {
BinaryDataFile(const int index); BinaryDataFile(const int index);
~BinaryDataFile(); ~BinaryDataFile();
fileFormat GetFileFormat() const override;
void CloseFile() override; void CloseFile() override;
void CreateFirstBinaryDataFile(const std::string filePath, void CreateFirstBinaryDataFile(const std::string fPath,
const std::string fileNamePrefix, const std::string fNamePrefix,
const uint64_t fileIndex, const uint64_t fIndex,
const bool overWriteEnable, const bool ovEnable,
const bool silentMode, const int modulePos, const bool sMode, const int modulePos,
const int numUnitsPerReadout, const int nUnitsPerReadout,
const uint32_t udpPortNumber, const uint32_t uPortNumber,
const uint32_t maxFramesPerFile) override; const uint32_t mFramesPerFile) override;
void WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber, const uint32_t numPacketsCaught) override; void WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber, const uint32_t numPacketsCaught) override;
private: private:
void CreateFile(); void CreateFile();
uint32_t index_; uint32_t index;
FILE *fd_{nullptr}; FILE *fd{nullptr};
std::string fileName_; std::string fileName;
uint32_t numFramesInFile_{0}; uint32_t numFramesInFile{0};
uint32_t subFileIndex_{0}; uint32_t subFileIndex{0};
std::string filePath_; std::string filePath;
std::string fileNamePrefix_; std::string fileNamePrefix;
uint64_t fileIndex_{0}; uint64_t fileIndex{0};
bool overWriteEnable_{false}; bool overWriteEnable{false};
bool silentMode_{false}; bool silentMode{false};
int detIndex_{0}; int detIndex{0};
int numUnitsPerReadout_{0}; int numUnitsPerReadout{0};
uint32_t udpPortNumber_{0}; uint32_t udpPortNumber{0};
uint32_t maxFramesPerFile_{0}; uint32_t maxFramesPerFile{0};
}; };
} // namespace sls } // namespace sls

View File

@ -28,20 +28,8 @@ namespace sls {
const std::string DataProcessor::typeName = "DataProcessor"; const std::string DataProcessor::typeName = "DataProcessor";
DataProcessor::DataProcessor(int index, detectorType dType, Fifo *f, DataProcessor::DataProcessor(int index, detectorType detType, Fifo *fifo, bool *dataStreamEnable, uint32_t *streamingFrequency, uint32_t *streamingTimerInMs, uint32_t *streamingStartFnum, bool *framePadding, std::vector<int> *ctbDbitList, int *ctbDbitOffset, int *ctbAnalogDataBytes)
bool *dse, : ThreadObject(index, typeName), fifo(fifo), detType(detType), dataStreamEnable(dataStreamEnable), streamingFrequency(streamingFrequency), streamingTimerInMs(streamingTimerInMs), streamingStartFnum(streamingStartFnum), framePadding(framePadding), ctbDbitList(ctbDbitList), ctbDbitOffset(ctbDbitOffset), ctbAnalogDataBytes(ctbAnalogDataBytes) {
uint32_t *sf,
uint32_t *st,
uint32_t *sfnum, bool *fp,
std::vector<int> *ctblist, int *ctboff,
int *ctbad)
: ThreadObject(index, typeName), fifo(f), detType(dType),
dataStreamEnable(dse),
streamingFrequency(sf),
streamingTimerInMs(st),
streamingStartFnum(sfnum), framePadding(fp),
ctbDbitList(ctblist), ctbDbitOffset(ctboff),
ctbAnalogDataBytes(ctbad) {
LOG(logDEBUG) << "DataProcessor " << index << " created"; LOG(logDEBUG) << "DataProcessor " << index << " created";
} }

View File

@ -29,12 +29,7 @@ struct MasterAttributes;
class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
public: public:
DataProcessor(int index, detectorType dType, Fifo *f, DataProcessor(int index, detectorType detType, Fifo *fifo, bool *dataStreamEnable, uint32_t *streamingFrequency, uint32_t *streamingTimerInMs, uint32_t *streamingStartFnum, bool *framePadding, std::vector<int> *ctbDbitList, int *ctbDbitOffset, int *ctbAnalogDataBytes);
bool *dse, uint32_t *sf,
uint32_t *st, uint32_t *sfnum,
bool *fp, std::vector<int> *ctblist,
int *ctboff, int *ctbad);
~DataProcessor() override; ~DataProcessor() override;
bool GetStartedFlag() const; bool GetStartedFlag() const;
@ -83,17 +78,10 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
std::mutex *hdf5LibMutex); std::mutex *hdf5LibMutex);
/** params: sls_receiver_header, pointer to data, image size */ /** params: sls_receiver_header, pointer to data, image size */
void registerCallBackRawDataReady(void (*func)(sls_receiver_header&, void registerCallBackRawDataReady(void (*func)(sls_receiver_header&, char *, size_t, void *), void *arg);
char *, size_t, void *),
void *arg);
/** params: sls_receiver_header, pointer to data, reference to image
* size */
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header&,
char *, size_t &,
void *),
void *arg);
/** params: sls_receiver_header, pointer to data, reference to image size */
void registerCallBackRawDataModifyReady(void (*func)(sls_receiver_header&, char *, size_t &, void *), void *arg);
private: private:
void RecordFirstIndex(uint64_t fnum); void RecordFirstIndex(uint64_t fnum);

View File

@ -18,14 +18,10 @@ namespace sls {
const std::string DataStreamer::TypeName = "DataStreamer"; const std::string DataStreamer::TypeName = "DataStreamer";
DataStreamer::DataStreamer(int ind, Fifo *f, uint32_t *dr, ROI *r, uint64_t *fi, DataStreamer::DataStreamer(int index, Fifo *fifo, uint32_t *dynamicRange, ROI *detectorRoi, uint64_t *fileIndex, bool flipRows, slsDetectorDefs::xy numPorts, bool *quadEnable, uint64_t *totalNumFrames)
bool fr, slsDetectorDefs::xy np, bool *qe, : ThreadObject(index, TypeName), fifo(fifo), dynamicRange(dynamicRange), detectorRoi(detectorRoi), fileIndex(fileIndex), flipRows(flipRows), numPorts(numPorts), quadEnable(quadEnable), totalNumFrames(totalNumFrames) {
uint64_t *tot)
: ThreadObject(ind, TypeName), fifo(f), dynamicRange(dr), detectorRoi(r),
fileIndex(fi), flipRows(fr), numPorts(np), quadEnable(qe),
totalNumFrames(tot) {
LOG(logDEBUG) << "DataStreamer " << ind << " created"; LOG(logDEBUG) << "DataStreamer " << index << " created";
} }
DataStreamer::~DataStreamer() { DataStreamer::~DataStreamer() {
@ -45,7 +41,7 @@ void DataStreamer::ResetParametersforNewAcquisition(const std::string &fname) {
delete[] completeBuffer; delete[] completeBuffer;
completeBuffer = nullptr; completeBuffer = nullptr;
} }
if (generalData->myDetectorType == GOTTHARD && detectorRoi->xmin != -1) { if (generalData->detType == GOTTHARD && detectorRoi->xmin != -1) {
adcConfigured = generalData->GetAdcConfigured(index, *detectorRoi); adcConfigured = generalData->GetAdcConfigured(index, *detectorRoi);
completeBuffer = new char[generalData->imageSizeComplete]; completeBuffer = new char[generalData->imageSizeComplete];
memset(completeBuffer, 0, generalData->imageSizeComplete); memset(completeBuffer, 0, generalData->imageSizeComplete);

View File

@ -25,27 +25,7 @@ class ZmqSocket;
class DataStreamer : private virtual slsDetectorDefs, public ThreadObject { class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
public: public:
/** DataStreamer(int index, Fifo *fifo, uint32_t *dynamicRange, ROI *detectorRoi, uint64_t *fileIndex, bool flipRows, slsDetectorDefs::xy numPorts, bool *quadEnable, uint64_t *totalNumFrames);
* 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 detectorRoi
* @param fi pointer to file index
* @param fr flip rows
* @param nm number of ports 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, bool fr,
xy np, bool *qe, uint64_t *tot);
/**
* Destructor
* Calls Base Class DestroyThread() and decrements NumberofDataStreamers
*/
~DataStreamer(); ~DataStreamer();
void SetFifo(Fifo *f); void SetFifo(Fifo *f);

View File

@ -17,10 +17,10 @@
namespace sls { namespace sls {
Fifo::Fifo(int ind, size_t fifoItemSize, uint32_t depth) Fifo::Fifo(int index, size_t fifoItemSize, uint32_t fifoDepth)
: index(ind), memory(nullptr), fifoBound(nullptr), fifoFree(nullptr), : index(index), memory(nullptr), fifoBound(nullptr), fifoFree(nullptr),
fifoStream(nullptr), fifoDepth(depth), status_fifoBound(0), fifoStream(nullptr), fifoDepth(fifoDepth), status_fifoBound(0),
status_fifoFree(depth) { status_fifoFree(fifoDepth) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
CreateFifos(fifoItemSize); CreateFifos(fifoItemSize);
} }

View File

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

View File

@ -1,15 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "File.h"
#include <iostream>
namespace sls {
File::File(const slsDetectorDefs::fileFormat format) : format_(format) {}
File::~File() {}
slsDetectorDefs::fileFormat File::GetFileFormat() const { return format_; }
} // namespace sls

View File

@ -18,10 +18,10 @@ struct MasterAttributes;
class File : private virtual slsDetectorDefs { class File : private virtual slsDetectorDefs {
public: public:
File(const slsDetectorDefs::fileFormat format); File(){};
virtual ~File(); virtual ~File(){};
fileFormat GetFileFormat() const; virtual fileFormat GetFileFormat() const = 0;
virtual void CloseFile() = 0; virtual void CloseFile() = 0;
#ifdef HDF5C #ifdef HDF5C
@ -82,9 +82,6 @@ class File : private virtual slsDetectorDefs {
}; };
virtual void WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber,const uint32_t numPacketsCaught) = 0; virtual void WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber,const uint32_t numPacketsCaught) = 0;
protected:
slsDetectorDefs::fileFormat format_;
}; };
} // namespace sls } // namespace sls

View File

@ -21,7 +21,7 @@ namespace sls {
class GeneralData { class GeneralData {
public: public:
slsDetectorDefs::detectorType myDetectorType{slsDetectorDefs::GENERIC}; slsDetectorDefs::detectorType detType{slsDetectorDefs::GENERIC};
uint32_t nPixelsX{0}; uint32_t nPixelsX{0};
uint32_t nPixelsY{0}; uint32_t nPixelsY{0};
uint32_t headerSizeinPacket{0}; uint32_t headerSizeinPacket{0};
@ -161,7 +161,7 @@ class GotthardData : public GeneralData {
public: public:
GotthardData() { GotthardData() {
myDetectorType = slsDetectorDefs::GOTTHARD; detType = slsDetectorDefs::GOTTHARD;
nPixelsY = 1; nPixelsY = 1;
headerSizeinPacket = 6; headerSizeinPacket = 6;
maxFramesPerFile = MAX_FRAMES_PER_FILE; maxFramesPerFile = MAX_FRAMES_PER_FILE;
@ -290,7 +290,7 @@ class EigerData : public GeneralData {
public: public:
EigerData() { EigerData() {
myDetectorType = slsDetectorDefs::EIGER; detType = slsDetectorDefs::EIGER;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE; maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE;
numUDPInterfaces = 2; numUDPInterfaces = 2;
@ -326,7 +326,7 @@ class JungfrauData : public GeneralData {
public: public:
JungfrauData() { JungfrauData() {
myDetectorType = slsDetectorDefs::JUNGFRAU; detType = slsDetectorDefs::JUNGFRAU;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
dataSize = 8192; dataSize = 8192;
packetSize = headerSizeinPacket + dataSize; packetSize = headerSizeinPacket + dataSize;
@ -359,7 +359,7 @@ class Mythen3Data : public GeneralData {
public: public:
Mythen3Data() { Mythen3Data() {
myDetectorType = slsDetectorDefs::MYTHEN3; detType = slsDetectorDefs::MYTHEN3;
nPixelsY = 1; nPixelsY = 1;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
maxFramesPerFile = MYTHEN3_MAX_FRAMES_PER_FILE; maxFramesPerFile = MYTHEN3_MAX_FRAMES_PER_FILE;
@ -427,7 +427,7 @@ class Mythen3Data : public GeneralData {
class Gotthard2Data : public GeneralData { class Gotthard2Data : public GeneralData {
public: public:
Gotthard2Data() { Gotthard2Data() {
myDetectorType = slsDetectorDefs::GOTTHARD2; detType = slsDetectorDefs::GOTTHARD2;
nPixelsX = 128 * 10; nPixelsX = 128 * 10;
nPixelsY = 1; nPixelsY = 1;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
@ -482,7 +482,7 @@ class ChipTestBoardData : public GeneralData {
public: public:
/** Constructor */ /** Constructor */
ChipTestBoardData() { ChipTestBoardData() {
myDetectorType = slsDetectorDefs::CHIPTESTBOARD; detType = slsDetectorDefs::CHIPTESTBOARD;
nPixelsY = 1; // number of samples nPixelsY = 1; // number of samples
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
frameIndexMask = 0xFFFFFF; // 10g frameIndexMask = 0xFFFFFF; // 10g
@ -572,7 +572,7 @@ class MoenchData : public GeneralData {
public: public:
MoenchData() { MoenchData() {
myDetectorType = slsDetectorDefs::MOENCH; detType = slsDetectorDefs::MOENCH;
headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header);
frameIndexMask = 0xFFFFFF; frameIndexMask = 0xFFFFFF;
maxFramesPerFile = MOENCH_MAX_FRAMES_PER_FILE; maxFramesPerFile = MOENCH_MAX_FRAMES_PER_FILE;

View File

@ -8,9 +8,9 @@
namespace sls { namespace sls {
HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib) HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib)
: File(HDF5), index_(index), hdf5Lib_(hdf5Lib) { : index(index), hdf5Lib(hdf5Lib) {
parameterNames_ = std::vector<std::string>{ parameterNames = std::vector<std::string>{
"frame number", "frame number",
"exp length or sub exposure time", "exp length or sub exposure time",
"packets caught", "packets caught",
@ -27,7 +27,7 @@ HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib)
"packets caught bit mask", "packets caught bit mask",
}; };
H5::StrType strdatatype(H5::PredType::C_S1, sizeof(bitset_storage)); H5::StrType strdatatype(H5::PredType::C_S1, sizeof(bitset_storage));
parameterDataTypes_ = std::vector<H5::DataType>{ parameterDataTypes = std::vector<H5::DataType>{
H5::PredType::STD_U64LE, H5::PredType::STD_U32LE, H5::PredType::STD_U32LE, H5::PredType::STD_U64LE, H5::PredType::STD_U32LE, H5::PredType::STD_U32LE,
H5::PredType::STD_U64LE, H5::PredType::STD_U64LE, H5::PredType::STD_U16LE, H5::PredType::STD_U64LE, H5::PredType::STD_U64LE, H5::PredType::STD_U16LE,
H5::PredType::STD_U16LE, H5::PredType::STD_U16LE, H5::PredType::STD_U16LE, H5::PredType::STD_U16LE, H5::PredType::STD_U16LE, H5::PredType::STD_U16LE,
@ -38,91 +38,95 @@ HDF5DataFile::HDF5DataFile(int index, std::mutex *hdf5Lib)
HDF5DataFile::~HDF5DataFile() { CloseFile(); } HDF5DataFile::~HDF5DataFile() { CloseFile(); }
std::string HDF5DataFile::GetFileName() const { std::string HDF5DataFile::GetFileName() const {
return fileName_; return fileName;
} }
uint32_t HDF5DataFile::GetFilesInAcquisition() const { uint32_t HDF5DataFile::GetFilesInAcquisition() const {
return numFilesInAcquisition_; return numFilesInAcquisition;
} }
H5::DataType HDF5DataFile::GetPDataType() const { return dataType_; } H5::DataType HDF5DataFile::GetPDataType() const { return dataType; }
std::vector<std::string> HDF5DataFile::GetParameterNames() const { std::vector<std::string> HDF5DataFile::GetParameterNames() const {
return parameterNames_; return parameterNames;
} }
std::vector<H5::DataType> HDF5DataFile::GetParameterDataTypes() const { std::vector<H5::DataType> HDF5DataFile::GetParameterDataTypes() const {
return parameterDataTypes_; return parameterDataTypes;
}
slsDetectorDefs::fileFormat HDF5DataFile::GetFileFormat() const {
return HDF5;
} }
void HDF5DataFile::CloseFile() { void HDF5DataFile::CloseFile() {
std::lock_guard<std::mutex> lock(*hdf5Lib_); std::lock_guard<std::mutex> lock(*hdf5Lib);
try { try {
H5::Exception::dontPrint(); // to handle errors H5::Exception::dontPrint(); // to handle errors
if (fd_) { if (fd) {
fd_->close(); fd->close();
delete fd_; delete fd;
fd_ = nullptr; fd = nullptr;
} }
} catch (const H5::Exception &error) { } catch (const H5::Exception &error) {
LOG(logERROR) << "Could not close data HDF5 handles of index " LOG(logERROR) << "Could not close data HDF5 handles of index "
<< index_; << index;
error.printErrorStack(); error.printErrorStack();
} }
if (dataSpace_) { if (dataSpace) {
delete dataSpace_; delete dataSpace;
dataSpace_ = nullptr; dataSpace = nullptr;
} }
if (dataSet_) { if (dataSet) {
delete dataSet_; delete dataSet;
dataSet_ = nullptr; dataSet = nullptr;
} }
if (dataSpacePara_) { if (dataSpacePara) {
delete dataSpacePara_; delete dataSpacePara;
dataSpacePara_ = nullptr; dataSpacePara = nullptr;
} }
for (auto it : dataSetPara_) for (auto it : dataSetPara)
delete it; delete it;
dataSetPara_.clear(); dataSetPara.clear();
} }
void HDF5DataFile::CreateFirstHDF5DataFile( void HDF5DataFile::CreateFirstHDF5DataFile(
const std::string filePath, const std::string fileNamePrefix, const std::string fPath, const std::string fNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, const uint64_t fIndex, const bool owEnable, const bool sMode,
const int modulePos, const int numUnitsPerReadout, const int modulePos, const int nUnitsPerReadout,
const uint32_t udpPortNumber, const uint32_t maxFramesPerFile, const uint32_t uPortNumber, const uint32_t mFramesPerFile,
const uint64_t numImages, const uint32_t nPixelsX, const uint32_t nPixelsY, const uint64_t nImages, const uint32_t nX, const uint32_t nY,
const uint32_t dynamicRange) { const uint32_t dr) {
subFileIndex_ = 0; subFileIndex = 0;
numFramesInFile_ = 0; numFramesInFile = 0;
extNumImages_ = numImages; extNumImages = nImages;
numFilesInAcquisition_ = 0; numFilesInAcquisition = 0;
maxFramesPerFile_ = maxFramesPerFile; maxFramesPerFile = mFramesPerFile;
numImages_ = numImages; numImages = nImages;
nPixelsX_ = nPixelsX; nPixelsX = nX;
nPixelsY_ = nPixelsY; nPixelsY = nY;
dynamicRange_ = dynamicRange; dynamicRange = dr;
filePath_ = filePath; filePath = fPath;
fileNamePrefix_ = fileNamePrefix; fileNamePrefix = fNamePrefix;
fileIndex_ = fileIndex; fileIndex = fIndex;
overWriteEnable_ = overWriteEnable; overWriteEnable = owEnable;
silentMode_ = silentMode; silentMode = sMode;
detIndex_ = modulePos; detIndex = modulePos;
numUnitsPerReadout_ = numUnitsPerReadout; numUnitsPerReadout = nUnitsPerReadout;
udpPortNumber_ = udpPortNumber; udpPortNumber = uPortNumber;
switch (dynamicRange_) { switch (dynamicRange) {
case 12: case 12:
case 16: case 16:
dataType_ = H5::PredType::STD_U16LE; dataType = H5::PredType::STD_U16LE;
break; break;
case 32: case 32:
dataType_ = H5::PredType::STD_U32LE; dataType = H5::PredType::STD_U32LE;
break; break;
default: default:
dataType_ = H5::PredType::STD_U8LE; dataType = H5::PredType::STD_U8LE;
break; break;
} }
@ -130,27 +134,27 @@ void HDF5DataFile::CreateFirstHDF5DataFile(
} }
void HDF5DataFile::CreateFile() { void HDF5DataFile::CreateFile() {
numFramesInFile_ = 0; numFramesInFile = 0;
numFilesInAcquisition_++; numFilesInAcquisition++;
std::ostringstream os; std::ostringstream os;
os << filePath_ << "/" << fileNamePrefix_ << "_d" os << filePath << "/" << fileNamePrefix << "_d"
<< (detIndex_ * numUnitsPerReadout_ + index_) << "_f" << subFileIndex_ << (detIndex * numUnitsPerReadout + index) << "_f" << subFileIndex
<< '_' << fileIndex_ << ".h5"; << '_' << fileIndex << ".h5";
fileName_ = os.str(); fileName = os.str();
std::lock_guard<std::mutex> lock(*hdf5Lib_); std::lock_guard<std::mutex> lock(*hdf5Lib);
uint64_t framestosave = uint64_t framestosave =
((maxFramesPerFile_ == 0) ? numImages_ : // infinite images ((maxFramesPerFile == 0) ? numImages : // infinite images
(((extNumImages_ - subFileIndex_) > maxFramesPerFile_) (((extNumImages - subFileIndex) > maxFramesPerFile)
? // save up to maximum at a time ? // save up to maximum at a time
maxFramesPerFile_ maxFramesPerFile
: (extNumImages_ - subFileIndex_))); : (extNumImages - subFileIndex)));
uint64_t nDimx = framestosave; uint64_t nDimx = framestosave;
uint32_t nDimy = nPixelsY_; uint32_t nDimy = nPixelsY;
uint32_t nDimz = ((dynamicRange_ == 4) ? (nPixelsX_ / 2) : nPixelsX_); uint32_t nDimz = ((dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX);
try { try {
H5::Exception::dontPrint(); // to handle errors H5::Exception::dontPrint(); // to handle errors
@ -158,45 +162,45 @@ void HDF5DataFile::CreateFile() {
// file // file
H5::FileAccPropList fapl; H5::FileAccPropList fapl;
fapl.setFcloseDegree(H5F_CLOSE_STRONG); fapl.setFcloseDegree(H5F_CLOSE_STRONG);
fd_ = nullptr; fd = nullptr;
if (!overWriteEnable_) if (!overWriteEnable)
fd_ = new H5::H5File(fileName_.c_str(), H5F_ACC_EXCL, fd = new H5::H5File(fileName.c_str(), H5F_ACC_EXCL,
H5::FileCreatPropList::DEFAULT, fapl); H5::FileCreatPropList::DEFAULT, fapl);
else else
fd_ = new H5::H5File(fileName_.c_str(), H5F_ACC_TRUNC, fd = new H5::H5File(fileName.c_str(), H5F_ACC_TRUNC,
H5::FileCreatPropList::DEFAULT, fapl); H5::FileCreatPropList::DEFAULT, fapl);
// attributes - version // attributes - version
double dValue = HDF5_WRITER_VERSION; double dValue = HDF5_WRITER_VERSION;
H5::DataSpace dataspace_attr = H5::DataSpace(H5S_SCALAR); H5::DataSpace dataspace_attr = H5::DataSpace(H5S_SCALAR);
H5::Attribute attribute = fd_->createAttribute( H5::Attribute attribute = fd->createAttribute(
"version", H5::PredType::NATIVE_DOUBLE, dataspace_attr); "version", H5::PredType::NATIVE_DOUBLE, dataspace_attr);
attribute.write(H5::PredType::NATIVE_DOUBLE, &dValue); attribute.write(H5::PredType::NATIVE_DOUBLE, &dValue);
// dataspace // dataspace
hsize_t srcdims[3] = {nDimx, nDimy, nDimz}; hsize_t srcdims[3] = {nDimx, nDimy, nDimz};
hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz}; hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz};
dataSpace_ = nullptr; dataSpace = nullptr;
dataSpace_ = new H5::DataSpace(3, srcdims, srcdimsmax); dataSpace = new H5::DataSpace(3, srcdims, srcdimsmax);
// dataset // dataset
// fill value // fill value
H5::DSetCreatPropList plist; H5::DSetCreatPropList plist;
int fill_value = -1; int fill_value = -1;
plist.setFillValue(dataType_, &fill_value); plist.setFillValue(dataType, &fill_value);
// always create chunked dataset as unlimited is only // always create chunked dataset as unlimited is only
// supported with chunked layout // supported with chunked layout
hsize_t chunk_dims[3] = {MAX_CHUNKED_IMAGES, nDimy, nDimz}; hsize_t chunk_dims[3] = {MAX_CHUNKED_IMAGES, nDimy, nDimz};
plist.setChunk(3, chunk_dims); plist.setChunk(3, chunk_dims);
dataSet_ = nullptr; dataSet = nullptr;
dataSet_ = new H5::DataSet(fd_->createDataSet( dataSet = new H5::DataSet(fd->createDataSet(
DATASET_NAME, dataType_, *dataSpace_, plist)); DATASET_NAME, dataType, *dataSpace, plist));
// create parameter datasets // create parameter datasets
hsize_t dims[1] = {nDimx}; hsize_t dims[1] = {nDimx};
hsize_t dimsmax[1] = {H5S_UNLIMITED}; hsize_t dimsmax[1] = {H5S_UNLIMITED};
dataSpacePara_ = nullptr; dataSpacePara = nullptr;
dataSpacePara_ = new H5::DataSpace(1, dims, dimsmax); dataSpacePara = new H5::DataSpace(1, dims, dimsmax);
// always create chunked dataset as unlimited is only // always create chunked dataset as unlimited is only
// supported with chunked layout // supported with chunked layout
@ -204,37 +208,37 @@ void HDF5DataFile::CreateFile() {
hsize_t chunkpara_dims[3] = {MAX_CHUNKED_IMAGES}; hsize_t chunkpara_dims[3] = {MAX_CHUNKED_IMAGES};
paralist.setChunk(1, chunkpara_dims); paralist.setChunk(1, chunkpara_dims);
for (unsigned int i = 0; i < parameterNames_.size(); ++i) { for (unsigned int i = 0; i < parameterNames.size(); ++i) {
H5::DataSet *ds = new H5::DataSet(fd_->createDataSet( H5::DataSet *ds = new H5::DataSet(fd->createDataSet(
parameterNames_[i].c_str(), parameterDataTypes_[i], parameterNames[i].c_str(), parameterDataTypes[i],
*dataSpacePara_, paralist)); *dataSpacePara, paralist));
dataSetPara_.push_back(ds); dataSetPara.push_back(ds);
} }
} catch (const H5::Exception &error) { } catch (const H5::Exception &error) {
error.printErrorStack(); error.printErrorStack();
CloseFile(); CloseFile();
throw RuntimeError("Could not create HDF5 handles in object " + throw RuntimeError("Could not create HDF5 handles in object " +
index_); index);
} }
if (!silentMode_) { if (!silentMode) {
LOG(logINFO) << "[" << udpPortNumber_ LOG(logINFO) << "[" << udpPortNumber
<< "]: HDF5 File created: " << fileName_; << "]: HDF5 File created: " << fileName;
} }
} }
void HDF5DataFile::WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber, const uint32_t numPacketsCaught) { void HDF5DataFile::WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber, const uint32_t numPacketsCaught) {
// check if maxframesperfile = 0 for infinite // check if maxframesperfile = 0 for infinite
if (maxFramesPerFile_ && (numFramesInFile_ >= maxFramesPerFile_)) { if (maxFramesPerFile && (numFramesInFile >= maxFramesPerFile)) {
CloseFile(); CloseFile();
++subFileIndex_; ++subFileIndex;
CreateFile(); CreateFile();
} }
++numFramesInFile_; ++numFramesInFile;
// extend dataset (when receiver start followed by many status starts // extend dataset (when receiver start followed by many status starts
// (jungfrau))) // (jungfrau)))
if (currentFrameNumber >= extNumImages_) { if (currentFrameNumber >= extNumImages) {
ExtendDataset(); ExtendDataset();
} }
@ -256,23 +260,23 @@ void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber,
char *buffer) { char *buffer) {
// expand 12 bit to 16 bits // expand 12 bit to 16 bits
char *revBuffer = buffer; char *revBuffer = buffer;
if (dynamicRange_ == 12) { if (dynamicRange == 12) {
revBuffer = (char *)malloc(EIGER_16_BIT_IMAGE_SIZE); revBuffer = (char *)malloc(EIGER_16_BIT_IMAGE_SIZE);
if (revBuffer == nullptr) { if (revBuffer == nullptr) {
throw RuntimeError("Could not allocate memory for 12 bit to " throw RuntimeError("Could not allocate memory for 12 bit to "
"16 bit conversion in object " + "16 bit conversion in object " +
std::to_string(index_)); std::to_string(index));
} }
Convert12to16Bit((uint16_t *)revBuffer, (uint8_t *)buffer); Convert12to16Bit((uint16_t *)revBuffer, (uint8_t *)buffer);
} }
std::lock_guard<std::mutex> lock(*hdf5Lib_); std::lock_guard<std::mutex> lock(*hdf5Lib);
uint64_t nDimx = uint64_t nDimx =
((maxFramesPerFile_ == 0) ? currentFrameNumber ((maxFramesPerFile == 0) ? currentFrameNumber
: currentFrameNumber % maxFramesPerFile_); : currentFrameNumber % maxFramesPerFile);
uint32_t nDimy = nPixelsY_; uint32_t nDimy = nPixelsY;
uint32_t nDimz = ((dynamicRange_ == 4) ? (nPixelsX_ / 2) : nPixelsX_); uint32_t nDimz = ((dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX);
hsize_t count[3] = {1, nDimy, nDimz}; hsize_t count[3] = {1, nDimy, nDimz};
hsize_t start[3] = {nDimx, 0, 0}; hsize_t start[3] = {nDimx, 0, 0};
@ -280,31 +284,31 @@ void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber,
try { try {
H5::Exception::dontPrint(); // to handle errors H5::Exception::dontPrint(); // to handle errors
dataSpace_->selectHyperslab(H5S_SELECT_SET, count, start); dataSpace->selectHyperslab(H5S_SELECT_SET, count, start);
H5::DataSpace memspace(2, dims2); H5::DataSpace memspace(2, dims2);
dataSet_->write(revBuffer, dataType_, memspace, *dataSpace_); dataSet->write(revBuffer, dataType, memspace, *dataSpace);
memspace.close(); memspace.close();
if (dynamicRange_ == 12) { if (dynamicRange == 12) {
free(revBuffer); free(revBuffer);
} }
} catch (const H5::Exception &error) { } catch (const H5::Exception &error) {
if (dynamicRange_ == 12) { if (dynamicRange == 12) {
free(revBuffer); free(revBuffer);
} }
LOG(logERROR) << "Could not write to file in object " << index_; LOG(logERROR) << "Could not write to file in object " << index;
error.printErrorStack(); error.printErrorStack();
throw RuntimeError("Could not write to file in object " + throw RuntimeError("Could not write to file in object " +
std::to_string(index_)); std::to_string(index));
} }
} }
void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber, void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
sls_receiver_header rheader) { sls_receiver_header rheader) {
std::lock_guard<std::mutex> lock(*hdf5Lib_); std::lock_guard<std::mutex> lock(*hdf5Lib);
uint64_t fnum = uint64_t fnum =
((maxFramesPerFile_ == 0) ? currentFrameNumber ((maxFramesPerFile == 0) ? currentFrameNumber
: currentFrameNumber % maxFramesPerFile_); : currentFrameNumber % maxFramesPerFile);
sls_detector_header header = rheader.detHeader; sls_detector_header header = rheader.detHeader;
hsize_t count[1] = {1}; hsize_t count[1] = {1};
@ -312,53 +316,53 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
int i = 0; int i = 0;
try { try {
H5::Exception::dontPrint(); // to handle errors H5::Exception::dontPrint(); // to handle errors
dataSpacePara_->selectHyperslab(H5S_SELECT_SET, count, start); dataSpacePara->selectHyperslab(H5S_SELECT_SET, count, start);
H5::DataSpace memspace(H5S_SCALAR); H5::DataSpace memspace(H5S_SCALAR);
dataSetPara_[0]->write(&header.frameNumber, parameterDataTypes_[0], dataSetPara[0]->write(&header.frameNumber, parameterDataTypes[0],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
i = 1; i = 1;
dataSetPara_[1]->write(&header.expLength, parameterDataTypes_[1], dataSetPara[1]->write(&header.expLength, parameterDataTypes[1],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
i = 2; i = 2;
dataSetPara_[2]->write(&header.packetNumber, parameterDataTypes_[2], dataSetPara[2]->write(&header.packetNumber, parameterDataTypes[2],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
i = 3; i = 3;
dataSetPara_[3]->write(&header.bunchId, parameterDataTypes_[3], dataSetPara[3]->write(&header.bunchId, parameterDataTypes[3],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
i = 4; i = 4;
dataSetPara_[4]->write(&header.timestamp, parameterDataTypes_[4], dataSetPara[4]->write(&header.timestamp, parameterDataTypes[4],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
i = 5; i = 5;
dataSetPara_[5]->write(&header.modId, parameterDataTypes_[5], memspace, dataSetPara[5]->write(&header.modId, parameterDataTypes[5], memspace,
*dataSpacePara_); *dataSpacePara);
i = 6; i = 6;
dataSetPara_[6]->write(&header.row, parameterDataTypes_[6], memspace, dataSetPara[6]->write(&header.row, parameterDataTypes[6], memspace,
*dataSpacePara_); *dataSpacePara);
i = 7; i = 7;
dataSetPara_[7]->write(&header.column, parameterDataTypes_[7], memspace, dataSetPara[7]->write(&header.column, parameterDataTypes[7], memspace,
*dataSpacePara_); *dataSpacePara);
i = 8; i = 8;
dataSetPara_[8]->write(&header.reserved, parameterDataTypes_[8], dataSetPara[8]->write(&header.reserved, parameterDataTypes[8],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
i = 9; i = 9;
dataSetPara_[9]->write(&header.debug, parameterDataTypes_[9], memspace, dataSetPara[9]->write(&header.debug, parameterDataTypes[9], memspace,
*dataSpacePara_); *dataSpacePara);
i = 10; i = 10;
dataSetPara_[10]->write(&header.roundRNumber, parameterDataTypes_[10], dataSetPara[10]->write(&header.roundRNumber, parameterDataTypes[10],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
i = 11; i = 11;
dataSetPara_[11]->write(&header.detType, parameterDataTypes_[11], dataSetPara[11]->write(&header.detType, parameterDataTypes[11],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
i = 12; i = 12;
dataSetPara_[12]->write(&header.version, parameterDataTypes_[12], dataSetPara[12]->write(&header.version, parameterDataTypes[12],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
i = 13; i = 13;
// contiguous bitset // contiguous bitset
if (sizeof(sls_bitset) == sizeof(bitset_storage)) { if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
dataSetPara_[13]->write((char *)&(rheader.packetsMask), dataSetPara[13]->write((char *)&(rheader.packetsMask),
parameterDataTypes_[13], memspace, parameterDataTypes[13], memspace,
*dataSpacePara_); *dataSpacePara);
} }
// not contiguous bitset // not contiguous bitset
@ -370,50 +374,50 @@ void HDF5DataFile::WriteParameterDatasets(const uint64_t currentFrameNumber,
for (int i = 0; i < MAX_NUM_PACKETS; ++i) for (int i = 0; i < MAX_NUM_PACKETS; ++i)
storage[i >> 3] |= (bits[i] << (i & 7)); storage[i >> 3] |= (bits[i] << (i & 7));
// write bitmask // write bitmask
dataSetPara_[13]->write((char *)storage, parameterDataTypes_[13], dataSetPara[13]->write((char *)storage, parameterDataTypes[13],
memspace, *dataSpacePara_); memspace, *dataSpacePara);
} }
i = 14; i = 14;
} catch (const H5::Exception &error) { } catch (const H5::Exception &error) {
error.printErrorStack(); error.printErrorStack();
throw RuntimeError( throw RuntimeError(
"Could not write parameters (index:" + std::to_string(i) + "Could not write parameters (index:" + std::to_string(i) +
") to file in object " + std::to_string(index_)); ") to file in object " + std::to_string(index));
} }
} }
void HDF5DataFile::ExtendDataset() { void HDF5DataFile::ExtendDataset() {
std::lock_guard<std::mutex> lock(*hdf5Lib_); std::lock_guard<std::mutex> lock(*hdf5Lib);
try { try {
H5::Exception::dontPrint(); // to handle errors H5::Exception::dontPrint(); // to handle errors
hsize_t dims[3]; hsize_t dims[3];
dataSpace_->getSimpleExtentDims(dims); dataSpace->getSimpleExtentDims(dims);
dims[0] += numImages_; dims[0] += numImages;
dataSet_->extend(dims); dataSet->extend(dims);
delete dataSpace_; delete dataSpace;
dataSpace_ = nullptr; dataSpace = nullptr;
dataSpace_ = new H5::DataSpace(dataSet_->getSpace()); dataSpace = new H5::DataSpace(dataSet->getSpace());
hsize_t dims_para[1] = {dims[0]}; hsize_t dims_para[1] = {dims[0]};
for (unsigned int i = 0; i < dataSetPara_.size(); ++i) for (unsigned int i = 0; i < dataSetPara.size(); ++i)
dataSetPara_[i]->extend(dims_para); dataSetPara[i]->extend(dims_para);
delete dataSpacePara_; delete dataSpacePara;
dataSpacePara_ = nullptr; dataSpacePara = nullptr;
dataSpacePara_ = new H5::DataSpace(dataSetPara_[0]->getSpace()); dataSpacePara = new H5::DataSpace(dataSetPara[0]->getSpace());
} catch (const H5::Exception &error) { } catch (const H5::Exception &error) {
error.printErrorStack(); error.printErrorStack();
throw RuntimeError("Could not extend dataset in object " + throw RuntimeError("Could not extend dataset in object " +
std::to_string(index_)); std::to_string(index));
} }
if (!silentMode_) { if (!silentMode) {
LOG(logINFO) << index_ << " Extending HDF5 dataset by " << extNumImages_ LOG(logINFO) << index << " Extending HDF5 dataset by " << extNumImages
<< ", Total x Dimension: " << (extNumImages_ + numImages_); << ", Total x Dimension: " << (extNumImages + numImages);
} }
extNumImages_ += numImages_; extNumImages += numImages;
} }
} // namespace sls } // namespace sls

View File

@ -14,6 +14,7 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File {
HDF5DataFile(const int index, std::mutex *hdf5Lib); HDF5DataFile(const int index, std::mutex *hdf5Lib);
~HDF5DataFile(); ~HDF5DataFile();
fileFormat GetFileFormat() const override;
std::string GetFileName() const override; std::string GetFileName() const override;
uint32_t GetFilesInAcquisition() const override; uint32_t GetFilesInAcquisition() const override;
H5::DataType GetPDataType() const override; H5::DataType GetPDataType() const override;
@ -23,13 +24,13 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File {
void CloseFile() override; void CloseFile() override;
void CreateFirstHDF5DataFile( void CreateFirstHDF5DataFile(
const std::string filePath, const std::string fileNamePrefix, const std::string fPath, const std::string fNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const uint64_t fIndex, const bool owEnable,
const bool silentMode, const int modulePos, const bool sMode, const int modulePos,
const int numUnitsPerReadout, const uint32_t udpPortNumber, const int nUnitsPerReadout, const uint32_t uPortNumber,
const uint32_t maxFramesPerFile, const uint64_t numImages, const uint32_t mFramesPerFile, const uint64_t nImages,
const uint32_t nPixelsX, const uint32_t nPixelsY, const uint32_t nX, const uint32_t nY,
const uint32_t dynamicRange) override; const uint32_t dr) override;
void WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber, const uint32_t numPacketsCaught) override; void WriteToFile(char *imageData, sls_receiver_header& header, const int imageSize, const uint64_t currentFrameNumber, const uint32_t numPacketsCaught) override;
@ -41,38 +42,37 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File {
sls_receiver_header rheader); sls_receiver_header rheader);
void ExtendDataset(); void ExtendDataset();
int index_; int index;
std::mutex *hdf5Lib_; std::mutex *hdf5Lib;
H5::H5File *fd_{nullptr}; H5::H5File *fd{nullptr};
std::string fileName_; std::string fileName;
std::string dataSetName_; H5::DataSpace *dataSpace{nullptr};
H5::DataSpace *dataSpace_{nullptr}; H5::DataSet *dataSet{nullptr};
H5::DataSet *dataSet_{nullptr}; H5::DataType dataType{H5::PredType::STD_U16LE};
H5::DataType dataType_{H5::PredType::STD_U16LE};
H5::DataSpace *dataSpacePara_{nullptr}; H5::DataSpace *dataSpacePara{nullptr};
std::vector<H5::DataSet *> dataSetPara_{nullptr}; std::vector<H5::DataSet *> dataSetPara{nullptr};
std::vector<std::string> parameterNames_; std::vector<std::string> parameterNames;
std::vector<H5::DataType> parameterDataTypes_; std::vector<H5::DataType> parameterDataTypes;
uint32_t subFileIndex_{0}; uint32_t subFileIndex{0};
uint32_t numFramesInFile_{0}; uint32_t numFramesInFile{0};
uint32_t numFilesInAcquisition_{0}; uint32_t numFilesInAcquisition{0};
uint32_t maxFramesPerFile_{0}; uint32_t maxFramesPerFile{0};
uint64_t numImages_{0}; uint64_t numImages{0};
uint64_t extNumImages_{0}; uint64_t extNumImages{0};
uint32_t nPixelsX_{0}; uint32_t nPixelsX{0};
uint32_t nPixelsY_{0}; uint32_t nPixelsY{0};
uint32_t dynamicRange_{0}; uint32_t dynamicRange{0};
std::string filePath_; std::string filePath;
std::string fileNamePrefix_; std::string fileNamePrefix;
uint64_t fileIndex_{0}; uint64_t fileIndex{0};
bool overWriteEnable_{false}; bool overWriteEnable{false};
bool silentMode_{false}; bool silentMode{false};
int detIndex_{0}; int detIndex{0};
int numUnitsPerReadout_{0}; int numUnitsPerReadout{0};
uint32_t udpPortNumber_{0}; uint32_t udpPortNumber{0};
static const int EIGER_NUM_PIXELS{256 * 2 * 256}; static const int EIGER_NUM_PIXELS{256 * 2 * 256};
static const int EIGER_16_BIT_IMAGE_SIZE{EIGER_NUM_PIXELS * 2}; static const int EIGER_16_BIT_IMAGE_SIZE{EIGER_NUM_PIXELS * 2};

View File

@ -177,7 +177,7 @@ void Implementation::setDetectorType(const detectorType d) {
try { try {
auto fifo_ptr = fifo[i].get(); auto fifo_ptr = fifo[i].get();
listener.push_back(sls::make_unique<Listener>( listener.push_back(sls::make_unique<Listener>(
i, detType, fifo_ptr, &status, &udpPortNum[i], &eth[i], i, fifo_ptr, &status, &udpPortNum[i], &eth[i],
&udpSocketBufferSize, &actualUDPSocketBufferSize, &udpSocketBufferSize, &actualUDPSocketBufferSize,
&framesPerFile, &frameDiscardMode, &silentMode)); &framesPerFile, &frameDiscardMode, &silentMode));
int ctbAnalogDataBytes = 0; int ctbAnalogDataBytes = 0;
@ -1009,7 +1009,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
try { try {
auto fifo_ptr = fifo[i].get(); auto fifo_ptr = fifo[i].get();
listener.push_back(sls::make_unique<Listener>( listener.push_back(sls::make_unique<Listener>(
i, detType, fifo_ptr, &status, &udpPortNum[i], &eth[i], i, fifo_ptr, &status, &udpPortNum[i], &eth[i],
&udpSocketBufferSize, &actualUDPSocketBufferSize, &udpSocketBufferSize, &actualUDPSocketBufferSize,
&framesPerFile, &frameDiscardMode, &silentMode)); &framesPerFile, &frameDiscardMode, &silentMode));
listener[i]->SetGeneralData(generalData); listener[i]->SetGeneralData(generalData);

View File

@ -24,14 +24,10 @@ namespace sls {
const std::string Listener::TypeName = "Listener"; const std::string Listener::TypeName = "Listener";
Listener::Listener(int ind, detectorType dtype, Fifo *f, Listener::Listener(int index, Fifo *fifo, std::atomic<runStatus> *status, uint32_t *udpPortNumber, std::string *eth, int *udpSocketBufferSize, int *actualUDPSocketBufferSize, uint32_t *framesPerFile, frameDiscardPolicy *frameDiscardMode, bool *silentMode)
std::atomic<runStatus> *s, uint32_t *portno, std::string *e, : ThreadObject(index, TypeName), fifo(fifo), status(status),
int *us, int *as, uint32_t *fpf, frameDiscardPolicy *fdp, udpPortNumber(udpPortNumber), eth(eth), udpSocketBufferSize(udpSocketBufferSize), actualUDPSocketBufferSize(actualUDPSocketBufferSize), framesPerFile(framesPerFile), frameDiscardMode(frameDiscardMode), silentMode(silentMode) {
bool *sm) LOG(logDEBUG) << "Listener " << index << " created";
: ThreadObject(ind, TypeName), fifo(f), myDetectorType(dtype), status(s),
udpPortNumber(portno), eth(e), udpSocketBufferSize(us),
actualUDPSocketBufferSize(as), framesPerFile(fpf), frameDiscardMode(fdp), silentMode(sm) {
LOG(logDEBUG) << "Listener " << ind << " created";
} }
Listener::~Listener() = default; Listener::~Listener() = default;
@ -40,7 +36,6 @@ bool Listener::isPortDisabled() const {
return disabledPort; return disabledPort;
} }
uint64_t Listener::GetPacketsCaught() const { return numPacketsCaught; } uint64_t Listener::GetPacketsCaught() const { return numPacketsCaught; }
uint64_t Listener::GetNumCompleteFramesCaught() const { uint64_t Listener::GetNumCompleteFramesCaught() const {
@ -87,7 +82,7 @@ void Listener::ResetParametersforNewAcquisition() {
lastCaughtFrameIndex = 0; lastCaughtFrameIndex = 0;
carryOverFlag = false; carryOverFlag = false;
uint32_t packetSize = generalData->packetSize; uint32_t packetSize = generalData->packetSize;
if (myDetectorType == GOTTHARD2 && index != 0) { if (generalData->detType == GOTTHARD2 && index != 0) {
packetSize = generalData->vetoPacketSize; packetSize = generalData->vetoPacketSize;
} }
carryOverPacket = make_unique<char[]>(packetSize); carryOverPacket = make_unique<char[]>(packetSize);
@ -149,7 +144,7 @@ void Listener::CreateUDPSockets() {
ShutDownUDPSocket(); ShutDownUDPSocket();
uint32_t packetSize = generalData->packetSize; uint32_t packetSize = generalData->packetSize;
if (myDetectorType == GOTTHARD2 && index != 0) { if (generalData->detType == GOTTHARD2 && index != 0) {
packetSize = generalData->vetoPacketSize; packetSize = generalData->vetoPacketSize;
} }
@ -200,7 +195,7 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int s) {
} }
uint32_t packetSize = generalData->packetSize; uint32_t packetSize = generalData->packetSize;
if (myDetectorType == GOTTHARD2 && index != 0) { if (generalData->detType == GOTTHARD2 && index != 0) {
packetSize = generalData->vetoPacketSize; packetSize = generalData->vetoPacketSize;
} }
@ -293,7 +288,7 @@ uint32_t Listener::ListenToAnImage(sls_receiver_header & dstHeader, char *dstDat
uint32_t packetSize = generalData->packetSize; uint32_t packetSize = generalData->packetSize;
uint32_t hsize = generalData->headerSizeinPacket; uint32_t hsize = generalData->headerSizeinPacket;
bool standardHeader = generalData->standardheader; bool standardHeader = generalData->standardheader;
if (myDetectorType == GOTTHARD2 && index != 0) { if (generalData->detType == GOTTHARD2 && index != 0) {
dsize = generalData->vetoDataSize; dsize = generalData->vetoDataSize;
imageSize = generalData->vetoImageSize; imageSize = generalData->vetoImageSize;
packetSize = generalData->vetoPacketSize; packetSize = generalData->vetoPacketSize;
@ -346,7 +341,7 @@ uint32_t Listener::ListenToAnImage(sls_receiver_header & dstHeader, char *dstDat
GetPacketIndices(fnum, pnum, bnum, standardHeader, listeningPacket.get(), srcDetHeader); GetPacketIndices(fnum, pnum, bnum, standardHeader, listeningPacket.get(), srcDetHeader);
// Eiger Firmware in a weird state // Eiger Firmware in a weird state
if (myDetectorType == EIGER && fnum == 0) { if (generalData->detType == EIGER && fnum == 0) {
LOG(logERROR) << "[" << *udpPortNumber LOG(logERROR) << "[" << *udpPortNumber
<< "]: Got Frame Number " << "]: Got Frame Number "
"Zero from Firmware. Discarding Packet"; "Zero from Firmware. Discarding Packet";
@ -416,7 +411,7 @@ size_t Listener::HandleFuturePacket(bool EOA, uint32_t numpackets, uint64_t fnum
// no packet to get bnum // no packet to get bnum
dstHeader.detHeader.row = row; dstHeader.detHeader.row = row;
dstHeader.detHeader.column = column; dstHeader.detHeader.column = column;
dstHeader.detHeader.detType = static_cast<uint8_t>(generalData->myDetectorType); dstHeader.detHeader.detType = static_cast<uint8_t>(generalData->detType);
dstHeader.detHeader.version = static_cast<uint8_t>(SLS_DETECTOR_HEADER_VERSION); dstHeader.detHeader.version = static_cast<uint8_t>(SLS_DETECTOR_HEADER_VERSION);
} }
if (!EOA) { if (!EOA) {
@ -428,7 +423,7 @@ size_t Listener::HandleFuturePacket(bool EOA, uint32_t numpackets, uint64_t fnum
void Listener::CopyPacket(char* dst, char* src, uint32_t dataSize, uint32_t detHeaderSize, uint32_t correctedDataSize, uint32_t &numpackets, bool &isHeaderEmpty, bool standardHeader, sls_receiver_header& dstHeader, sls_detector_header * srcDetHeader, uint32_t pnum, uint64_t bnum) { void Listener::CopyPacket(char* dst, char* src, uint32_t dataSize, uint32_t detHeaderSize, uint32_t correctedDataSize, uint32_t &numpackets, bool &isHeaderEmpty, bool standardHeader, sls_receiver_header& dstHeader, sls_detector_header * srcDetHeader, uint32_t pnum, uint64_t bnum) {
// copy packet data // copy packet data
switch (myDetectorType) { switch (generalData->detType) {
// for gotthard, 1st packet: 4 bytes fnum, CACA // for gotthard, 1st packet: 4 bytes fnum, CACA
// + CACA, 639*2 bytes data 2nd packet: 4 // + CACA, 639*2 bytes data 2nd packet: 4
// bytes fnum, previous 1*2 bytes data + 640*2 bytes data !! // bytes fnum, previous 1*2 bytes data + 640*2 bytes data !!
@ -463,7 +458,7 @@ void Listener::CopyPacket(char* dst, char* src, uint32_t dataSize, uint32_t detH
dstHeader.detHeader.bunchId = bnum; dstHeader.detHeader.bunchId = bnum;
dstHeader.detHeader.row = row; dstHeader.detHeader.row = row;
dstHeader.detHeader.column = column; dstHeader.detHeader.column = column;
dstHeader.detHeader.detType = static_cast<uint8_t>(generalData->myDetectorType); dstHeader.detHeader.detType = static_cast<uint8_t>(generalData->detType);
dstHeader.detHeader.version = static_cast<uint8_t>(SLS_DETECTOR_HEADER_VERSION); dstHeader.detHeader.version = static_cast<uint8_t>(SLS_DETECTOR_HEADER_VERSION);
} }
isHeaderEmpty = false; isHeaderEmpty = false;
@ -478,7 +473,7 @@ void Listener::GetPacketIndices(uint64_t &fnum, uint32_t &pnum, uint64_t &bnum,
} else { } else {
// set first packet to be odd or even (check required when switching // set first packet to be odd or even (check required when switching
// from roi to no roi) // from roi to no roi)
if (myDetectorType == GOTTHARD && !startedFlag) { if (generalData->detType == GOTTHARD && !startedFlag) {
oddStartingPacket = generalData->SetOddStartingPacket(index, &packet[0]); oddStartingPacket = generalData->SetOddStartingPacket(index, &packet[0]);
} }
generalData->GetHeaderInfo(index, &packet[0], oddStartingPacket, fnum, pnum, bnum); generalData->GetHeaderInfo(index, &packet[0], oddStartingPacket, fnum, pnum, bnum);

View File

@ -24,31 +24,8 @@ class Fifo;
class Listener : private virtual slsDetectorDefs, public ThreadObject { class Listener : private virtual slsDetectorDefs, public ThreadObject {
public: 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 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 sm pointer to silent mode
*/
Listener(int ind, detectorType dtype, Fifo *f, std::atomic<runStatus> *s,
uint32_t *portno, std::string *e, int *us, int *as, uint32_t *fpf,
frameDiscardPolicy *fdp, bool *sm);
/** Listener(int index, Fifo *fifo, std::atomic<runStatus> *status, uint32_t *udpPortNumber, std::string *eth, int *udpSocketBufferSize, int *actualUDPSocketBufferSize, uint32_t *framesPerFile, frameDiscardPolicy *frameDiscardMode, bool *silentMode);
* Destructor
* Calls Base Class DestroyThread() and decrements NumberofListerners
*/
~Listener(); ~Listener();
bool isPortDisabled() const; bool isPortDisabled() const;
@ -123,7 +100,6 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
Fifo *fifo; Fifo *fifo;
// individual members // individual members
detectorType myDetectorType;
std::atomic<runStatus> *status; std::atomic<runStatus> *status;
std::unique_ptr<UdpRxSocket> udpSocket{nullptr}; std::unique_ptr<UdpRxSocket> udpSocket{nullptr};
uint32_t *udpPortNumber; uint32_t *udpPortNumber;

View File

@ -101,8 +101,7 @@ void GetData(slsDetectorDefs::sls_receiver_header& header, char *dataPointer,
* @param modifiedImageSize new data size in bytes after the callback. * @param modifiedImageSize new data size in bytes after the callback.
* This will be the size written/streamed. (only smaller value is allowed). * This will be the size written/streamed. (only smaller value is allowed).
*/ */
void GetData(slsDetectorDefs::sls_receiver_header& header, char *dataPointer, void GetData(slsDetectorDefs::sls_receiver_header& header, char *dataPointer, size_t &modifiedImageSize, void *objectPointer) {
size_t &modifiedImageSize, void *objectPointer) {
slsDetectorDefs::sls_detector_header detectorHeader = header.detHeader; slsDetectorDefs::sls_detector_header detectorHeader = header.detHeader;
PRINT_IN_COLOR( PRINT_IN_COLOR(
@ -123,7 +122,7 @@ void GetData(slsDetectorDefs::sls_receiver_header& header, char *dataPointer,
detectorHeader.debug, detectorHeader.roundRNumber, detectorHeader.debug, detectorHeader.roundRNumber,
detectorHeader.detType, detectorHeader.version, detectorHeader.detType, detectorHeader.version,
// header->packetsMask.to_string().c_str(), // header->packetsMask.to_string().c_str(),
((uint8_t)(*((uint8_t *)(dataPointer)))), modifiedImageSize); *reinterpret_cast<uint8_t *>(dataPointer), modifiedImageSize);
// if data is modified, eg ROI and size is reduced // if data is modified, eg ROI and size is reduced
modifiedImageSize = 26000; modifiedImageSize = 26000;

View File

@ -18,8 +18,8 @@ namespace sls {
#define gettid() syscall(SYS_gettid) #define gettid() syscall(SYS_gettid)
#endif #endif
ThreadObject::ThreadObject(int threadIndex, std::string threadType) ThreadObject::ThreadObject(int index, std::string type)
: index(threadIndex), type(threadType) { : index(index), type(type) {
LOG(logDEBUG) << type << " thread created: " << index; LOG(logDEBUG) << type << " thread created: " << index;
sem_init(&semaphore, 1, 0); sem_init(&semaphore, 1, 0);
try { try {

View File

@ -24,7 +24,7 @@ class ThreadObject : private virtual slsDetectorDefs {
const int index{0}; const int index{0};
public: public:
ThreadObject(int threadIndex, std::string threadType); ThreadObject(int index, std::string type);
virtual ~ThreadObject(); virtual ~ThreadObject();
pid_t GetThreadId() const; pid_t GetThreadId() const;
bool IsRunning() const; bool IsRunning() const;