From cb6cbaeeec802b50017e43fe2a395f039830b338 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 15 Sep 2021 17:10:01 +0200 Subject: [PATCH 1/2] frames in file added for master file in receiver, binary done, hdf5 not done --- slsReceiverSoftware/src/BinaryMasterFile.cpp | 14 +++++ slsReceiverSoftware/src/BinaryMasterFile.h | 1 + slsReceiverSoftware/src/DataProcessor.cpp | 44 +++++++++++++- slsReceiverSoftware/src/DataProcessor.h | 7 ++- slsReceiverSoftware/src/File.h | 5 ++ slsReceiverSoftware/src/HDF5MasterFile.cpp | 29 +++++++++ slsReceiverSoftware/src/HDF5MasterFile.h | 2 + slsReceiverSoftware/src/Implementation.cpp | 11 +++- slsReceiverSoftware/src/MasterAttributes.h | 62 ++++++++++++++------ 9 files changed, 154 insertions(+), 21 deletions(-) diff --git a/slsReceiverSoftware/src/BinaryMasterFile.cpp b/slsReceiverSoftware/src/BinaryMasterFile.cpp index 3b11b803a..2c03309af 100644 --- a/slsReceiverSoftware/src/BinaryMasterFile.cpp +++ b/slsReceiverSoftware/src/BinaryMasterFile.cpp @@ -42,3 +42,17 @@ void BinaryMasterFile::CreateMasterFile(const std::string filePath, attr->WriteMasterBinaryAttributes(fd_); CloseFile(); } + +void BinaryMasterFile::UpdateMasterFile(MasterAttributes *attr, + bool silentMode) { + if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "a"))) { + fd_ = nullptr; + throw sls::RuntimeError("Could not append binary master file " + + fileName_); + } + attr->WriteFinalBinaryAttributes(fd_); + CloseFile(); + if (!silentMode) { + LOG(logINFO) << "Updated Master File"; + } +} diff --git a/slsReceiverSoftware/src/BinaryMasterFile.h b/slsReceiverSoftware/src/BinaryMasterFile.h index ae5405828..a779328f1 100644 --- a/slsReceiverSoftware/src/BinaryMasterFile.h +++ b/slsReceiverSoftware/src/BinaryMasterFile.h @@ -15,6 +15,7 @@ class BinaryMasterFile : private virtual slsDetectorDefs, public File { const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, MasterAttributes *attr) override; + void UpdateMasterFile(MasterAttributes *attr, bool silentMode) override; private: FILE *fd_{nullptr}; diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index a506e02fb..699657b0f 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -17,6 +17,7 @@ #include "HDF5VirtualFile.h" #endif #include "DataStreamer.h" +#include "sls/container_utils.h" #include "sls/sls_detector_exceptions.h" #include @@ -56,6 +57,10 @@ bool DataProcessor::GetStartedFlag() { return startedFlag_; } uint64_t DataProcessor::GetNumFramesCaught() { return numFramesCaught_; } +uint64_t DataProcessor::GetNumCompleteFramesCaught() { + return numCompleteFramesCaught_; +} + uint64_t DataProcessor::GetCurrentFrameIndex() { return currentFrameIndex_; } uint64_t DataProcessor::GetProcessedIndex() { @@ -68,6 +73,7 @@ void DataProcessor::ResetParametersforNewAcquisition() { StopRunning(); startedFlag_ = false; numFramesCaught_ = 0; + numCompleteFramesCaught_ = 0; firstIndex_ = 0; currentFrameIndex_ = 0; firstStreamerFrame_ = true; @@ -248,6 +254,41 @@ void DataProcessor::LinkDataInMasterFile(const bool silentMode) { } #endif +void DataProcessor::UpdateMasterFile(bool silentMode) { + if (masterFile_) { + // final attributes + std::unique_ptr masterAttributes; + switch (detectorType_) { + case GOTTHARD: + masterAttributes = sls::make_unique(); + break; + case JUNGFRAU: + masterAttributes = sls::make_unique(); + break; + case EIGER: + masterAttributes = sls::make_unique(); + break; + case MYTHEN3: + masterAttributes = sls::make_unique(); + break; + case GOTTHARD2: + masterAttributes = sls::make_unique(); + break; + case MOENCH: + masterAttributes = sls::make_unique(); + break; + case CHIPTESTBOARD: + masterAttributes = sls::make_unique(); + break; + default: + throw sls::RuntimeError( + "Unknown detector type to set up master file attributes"); + } + masterAttributes->framesInFile = numFramesCaught_; + masterFile_->UpdateMasterFile(masterAttributes.get(), silentMode); + } +} + void DataProcessor::ThreadExecution() { char *buffer = nullptr; fifo_->PopAddress(buffer); @@ -306,9 +347,10 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) { sls_detector_header header = rheader->detHeader; uint64_t fnum = header.frameNumber; currentFrameIndex_ = fnum; + numFramesCaught_++; uint32_t nump = header.packetNumber; if (nump == generalData_->packetsPerFrame) { - numFramesCaught_++; + numCompleteFramesCaught_++; } LOG(logDEBUG1) << "DataProcessing " << index << ": fnum:" << fnum; diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index c05af8784..7b8db99f8 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -37,6 +37,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { bool GetStartedFlag(); uint64_t GetNumFramesCaught(); + uint64_t GetNumCompleteFramesCaught(); /** (-1 if no frames have been caught */ uint64_t GetCurrentFrameIndex(); /** (-1 if no frames have been caught) */ @@ -76,6 +77,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { const int numModY); void LinkDataInMasterFile(const bool silentMode); #endif + void UpdateMasterFile(bool silentMode); /** * Call back for raw data * args to raw data ready callback are @@ -174,9 +176,12 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { std::atomic firstIndex_{0}; // for statistics - /** Number of complete frames caught */ + /** Number of frames caught */ uint64_t numFramesCaught_{0}; + /** Number of complete frames caught */ + uint64_t numCompleteFramesCaught_{0}; + /** Frame Number of latest processed frame number */ std::atomic currentFrameIndex_{0}; diff --git a/slsReceiverSoftware/src/File.h b/slsReceiverSoftware/src/File.h index 70fbd6449..57bd31e93 100644 --- a/slsReceiverSoftware/src/File.h +++ b/slsReceiverSoftware/src/File.h @@ -118,6 +118,11 @@ class File : private virtual slsDetectorDefs { "should be overloaded by a derived class"; }; + virtual void UpdateMasterFile(MasterAttributes *attr, bool silentMode) { + LOG(logERROR) << "This is a generic function UpdateMasterFile that " + "should be overloaded by a derived class"; + }; + protected: slsDetectorDefs::fileFormat format_; }; diff --git a/slsReceiverSoftware/src/HDF5MasterFile.cpp b/slsReceiverSoftware/src/HDF5MasterFile.cpp index 27eaeb245..f525a25e2 100644 --- a/slsReceiverSoftware/src/HDF5MasterFile.cpp +++ b/slsReceiverSoftware/src/HDF5MasterFile.cpp @@ -117,6 +117,7 @@ void HDF5MasterFile::CreateMasterFile(const std::string filePath, Group group5(group3.createGroup("detector")); Group group6(group1.createGroup("sample")); + groupId_ = group5.getId(); attr->WriteMasterHDF5Attributes(fd_, &group5); fd_->close(); @@ -129,4 +130,32 @@ void HDF5MasterFile::CreateMasterFile(const std::string filePath, if (!silentMode) { LOG(logINFO) << "Master File: " << fileName_; } +} + +void HDF5MasterFile::UpdateMasterFile(MasterAttributes *attr, bool silentMode) { + std::lock_guard lock(*hdf5Lib_); + + try { + Exception::dontPrint(); // to handle errors + + FileAccPropList flist; + flist.setFcloseDegree(H5F_CLOSE_STRONG); + fd_ = new H5File(fileName_.c_str(), H5F_ACC_RDWR, + FileCreatPropList::DEFAULT, flist); + + Group group(groupId_); + + // cannot do this TODO + attr->WriteFinalHDF5Attributes(fd_, &group); + fd_->close(); + + } catch (const Exception &error) { + error.printErrorStack(); + CloseFile(); + throw sls::RuntimeError( + "Could not create/overwrite master HDF5 handles"); + } + if (!silentMode) { + LOG(logINFO) << "Updated Master File"; + } } \ No newline at end of file diff --git a/slsReceiverSoftware/src/HDF5MasterFile.h b/slsReceiverSoftware/src/HDF5MasterFile.h index 344e1ec6f..1dcbd70b5 100644 --- a/slsReceiverSoftware/src/HDF5MasterFile.h +++ b/slsReceiverSoftware/src/HDF5MasterFile.h @@ -19,9 +19,11 @@ class HDF5MasterFile : private virtual slsDetectorDefs, public File { const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, MasterAttributes *attr) override; + void UpdateMasterFile(MasterAttributes *attr, bool silentMode) override; private: std::mutex *hdf5Lib_; H5File *fd_{nullptr}; std::string fileName_; + hid_t groupId_{0}; }; \ No newline at end of file diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index ada185335..0e665708c 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -429,7 +429,7 @@ uint64_t Implementation::getFramesCaught() const { for (const auto &it : dataProcessor) { flagsum += it->GetStartedFlag(); - min = std::min(min, it->GetNumFramesCaught()); + min = std::min(min, it->GetNumCompleteFramesCaught()); } // no data processed if (flagsum != dataProcessor.size()) @@ -571,6 +571,13 @@ void Implementation::stopReceiver() { } } #endif + if (fileWriteEnable && masterFileWriteEnable && modulePos == 0) { + try { + dataProcessor[0]->UpdateMasterFile(silentMode); + } catch (...) { + ; // ignore it and just print it + } + } // wait for the processes (dataStreamer) to be done running = true; @@ -589,7 +596,7 @@ void Implementation::stopReceiver() { std::vector mp = getNumMissingPackets(); uint64_t tot = 0; for (int i = 0; i < numThreads; i++) { - int nf = dataProcessor[i]->GetNumFramesCaught(); + int nf = dataProcessor[i]->GetNumCompleteFramesCaught(); tot += nf; std::string mpMessage = std::to_string((int64_t)mp[i]); if ((int64_t)mp[i] < 0) { diff --git a/slsReceiverSoftware/src/MasterAttributes.h b/slsReceiverSoftware/src/MasterAttributes.h index b8074e1f4..dff142f09 100644 --- a/slsReceiverSoftware/src/MasterAttributes.h +++ b/slsReceiverSoftware/src/MasterAttributes.h @@ -16,6 +16,7 @@ using namespace H5; using ns = std::chrono::nanoseconds; struct MasterAttributes { + // (before acquisition) slsDetectorDefs::detectorType detType{slsDetectorDefs::GENERIC}; slsDetectorDefs::timingMode timingMode{slsDetectorDefs::AUTO_TIMING}; uint32_t imageSize{0}; @@ -57,6 +58,9 @@ struct MasterAttributes { uint32_t gates; std::map additionalJsonHeader; + // Final Attributes (after acquisition) + uint64_t framesInFile{0}; + MasterAttributes(){}; virtual ~MasterAttributes(){}; @@ -87,30 +91,42 @@ struct MasterAttributes { }; void WriteBinaryAttributes(FILE *fd, std::string message) { + if (fwrite((void *)message.c_str(), 1, message.length(), fd) != + message.length()) { + throw sls::RuntimeError( + "Master binary file incorrect number of bytes written to file"); + } + }; + + void WriteFinalBinaryAttributes(FILE *fd) { // adding few common parameters to the end + std::ostringstream oss; + if (!additionalJsonHeader.empty()) { - std::ostringstream oss; oss << "Additional Json Header : " << sls::ToString(additionalJsonHeader) << '\n'; - message += oss.str(); } + oss << "Frames in File : " << framesInFile << '\n'; // adding sls_receiver header format - message += std::string("\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"); + oss << '\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'; + + std::string message = oss.str(); // writing to file if (fwrite((void *)message.c_str(), 1, message.length(), fd) != @@ -233,6 +249,18 @@ struct MasterAttributes { "Total Frames", PredType::STD_U64LE, dataspace); dataset.write(&totalFrames, PredType::STD_U64LE); } + }; + + void WriteFinalHDF5Attributes(H5File *fd, Group *group) { + char c[1024]; + memset(c, 0, sizeof(c)); + // Total Frames in file + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet( + "Frames in File", PredType::STD_U64LE, dataspace); + dataset.write(&framesInFile, PredType::STD_U64LE); + } // additional json header if (!additionalJsonHeader.empty()) { std::string json = sls::ToString(additionalJsonHeader); From b98eee5b9a747eb27524ebdd17d9c98aa8a0780c Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 16 Sep 2021 10:09:30 +0200 Subject: [PATCH 2/2] works with hdf5 --- slsReceiverSoftware/src/HDF5MasterFile.cpp | 9 ++++----- slsReceiverSoftware/src/HDF5MasterFile.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/src/HDF5MasterFile.cpp b/slsReceiverSoftware/src/HDF5MasterFile.cpp index f525a25e2..eb9b69e73 100644 --- a/slsReceiverSoftware/src/HDF5MasterFile.cpp +++ b/slsReceiverSoftware/src/HDF5MasterFile.cpp @@ -117,7 +117,9 @@ void HDF5MasterFile::CreateMasterFile(const std::string filePath, Group group5(group3.createGroup("detector")); Group group6(group1.createGroup("sample")); - groupId_ = group5.getId(); + // TODO find a way to get complete group link + attrGroupName_ = "/entry/instrument/detector"; + attr->WriteMasterHDF5Attributes(fd_, &group5); fd_->close(); @@ -137,15 +139,12 @@ void HDF5MasterFile::UpdateMasterFile(MasterAttributes *attr, bool silentMode) { try { Exception::dontPrint(); // to handle errors - FileAccPropList flist; flist.setFcloseDegree(H5F_CLOSE_STRONG); fd_ = new H5File(fileName_.c_str(), H5F_ACC_RDWR, FileCreatPropList::DEFAULT, flist); - Group group(groupId_); - - // cannot do this TODO + Group group = fd_->openGroup(attrGroupName_.c_str()); attr->WriteFinalHDF5Attributes(fd_, &group); fd_->close(); diff --git a/slsReceiverSoftware/src/HDF5MasterFile.h b/slsReceiverSoftware/src/HDF5MasterFile.h index 1dcbd70b5..01b5bfb45 100644 --- a/slsReceiverSoftware/src/HDF5MasterFile.h +++ b/slsReceiverSoftware/src/HDF5MasterFile.h @@ -25,5 +25,5 @@ class HDF5MasterFile : private virtual slsDetectorDefs, public File { std::mutex *hdf5Lib_; H5File *fd_{nullptr}; std::string fileName_; - hid_t groupId_{0}; + std::string attrGroupName_; }; \ No newline at end of file