diff --git a/RELEASE.txt b/RELEASE.txt index 82453290b..1f0efd8a2 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -57,6 +57,7 @@ This document describes the differences between v7.0.0 and v6.x.x - ctb: can set names for all the dacs - fpga/kernel programming, checks if drive is a special file and not a normal file - gotthard 25 um image reconstructed in gui and virtual hdf5 (firmware updated for slave to reverse channels) +- master binary file in json format now - fixed bug introduced in 6.0.0: hdf5 files created 1 file per frame after the initial file which had maxframesperfile 2. Resolved Issues diff --git a/slsReceiverSoftware/CMakeLists.txt b/slsReceiverSoftware/CMakeLists.txt index ef1bfb56d..a72da71b7 100755 --- a/slsReceiverSoftware/CMakeLists.txt +++ b/slsReceiverSoftware/CMakeLists.txt @@ -6,7 +6,6 @@ set(SOURCES src/Receiver.cpp src/File.cpp src/BinaryDataFile.cpp - src/BinaryMasterFile.cpp src/ThreadObject.cpp src/Listener.cpp src/DataProcessor.cpp @@ -14,6 +13,7 @@ set(SOURCES src/Fifo.cpp src/Arping.cpp src/MasterAttributes.cpp + src/MasterFileUtility.cpp ) set(PUBLICHEADERS @@ -28,8 +28,6 @@ if (SLS_USE_HDF5) ) list (APPEND SOURCES src/HDF5DataFile.cpp - src/HDF5MasterFile.cpp - src/HDF5VirtualFile.cpp ) endif (SLS_USE_HDF5) diff --git a/slsReceiverSoftware/src/BinaryMasterFile.cpp b/slsReceiverSoftware/src/BinaryMasterFile.cpp deleted file mode 100644 index eedf88879..000000000 --- a/slsReceiverSoftware/src/BinaryMasterFile.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-other -// Copyright (C) 2021 Contributors to the SLS Detector Package -#include "BinaryMasterFile.h" -#include "MasterAttributes.h" - -BinaryMasterFile::BinaryMasterFile() : File(BINARY) {} - -BinaryMasterFile::~BinaryMasterFile() { CloseFile(); } - -void BinaryMasterFile::CloseFile() { - if (fd_) { - fclose(fd_); - } - fd_ = nullptr; -} - -void BinaryMasterFile::CreateMasterFile(const std::string filePath, - const std::string fileNamePrefix, - const uint64_t fileIndex, - const bool overWriteEnable, - const bool silentMode, - MasterAttributes *attr) { - // create file name - std::ostringstream os; - os << filePath << "/" << fileNamePrefix << "_master" - << "_" << fileIndex << ".raw"; - fileName_ = os.str(); - - // create file - if (!overWriteEnable) { - if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "wx"))) { - fd_ = nullptr; - throw sls::RuntimeError("Could not create binary master file " + - fileName_); - } - } else if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "w"))) { - fd_ = nullptr; - throw sls::RuntimeError( - "Could not create/overwrite binary master file " + fileName_); - } - if (!silentMode) { - LOG(logINFO) << "Master File: " << fileName_; - } - 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 deleted file mode 100644 index 909634c71..000000000 --- a/slsReceiverSoftware/src/BinaryMasterFile.h +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-other -// Copyright (C) 2021 Contributors to the SLS Detector Package -#pragma once - -#include "File.h" -#include "MasterAttributes.h" - -class BinaryMasterFile : private virtual slsDetectorDefs, public File { - - public: - BinaryMasterFile(); - ~BinaryMasterFile(); - - void CloseFile() override; - void CreateMasterFile(const std::string filePath, - const std::string fileNamePrefix, - const uint64_t fileIndex, const bool overWriteEnable, - const bool silentMode, - MasterAttributes *attr) override; - void UpdateMasterFile(MasterAttributes *attr, bool silentMode) override; - - private: - FILE *fd_{nullptr}; - std::string fileName_; -}; \ No newline at end of file diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index a22abdfc1..d6b801e3f 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -9,14 +9,12 @@ #include "DataProcessor.h" #include "BinaryDataFile.h" -#include "BinaryMasterFile.h" #include "Fifo.h" #include "GeneralData.h" #include "MasterAttributes.h" +#include "MasterFileUtility.h" #ifdef HDF5C #include "HDF5DataFile.h" -#include "HDF5MasterFile.h" -#include "HDF5VirtualFile.h" #endif #include "DataStreamer.h" #include "sls/container_utils.h" @@ -82,12 +80,6 @@ void DataProcessor::SetGeneralData(GeneralData *generalData) { void DataProcessor::CloseFiles() { if (dataFile_) dataFile_->CloseFile(); - if (masterFile_) - masterFile_->CloseFile(); -#ifdef HDF5C - if (virtualFile_) - virtualFile_->CloseFile(); -#endif } void DataProcessor::DeleteFiles() { @@ -96,39 +88,20 @@ void DataProcessor::DeleteFiles() { delete dataFile_; dataFile_ = nullptr; } - if (masterFile_) { - delete masterFile_; - masterFile_ = nullptr; - } -#ifdef HDF5C - if (virtualFile_) { - delete virtualFile_; - virtualFile_ = nullptr; - } -#endif } void DataProcessor::SetupFileWriter(const bool filewriteEnable, - const bool masterFilewriteEnable, const fileFormat fileFormatType, - const int modulePos, std::mutex *hdf5Lib) { + std::mutex *hdf5LibMutex) { DeleteFiles(); if (filewriteEnable) { switch (fileFormatType) { #ifdef HDF5C case HDF5: - dataFile_ = new HDF5DataFile(index, hdf5Lib); - if (modulePos == 0 && index == 0) { - if (masterFilewriteEnable) { - masterFile_ = new HDF5MasterFile(hdf5Lib); - } - } + dataFile_ = new HDF5DataFile(index, hdf5LibMutex); break; #endif case BINARY: dataFile_ = new BinaryDataFile(index); - if (modulePos == 0 && index == 0 && masterFilewriteEnable) { - masterFile_ = new BinaryMasterFile(); - } break; default: throw sls::RuntimeError( @@ -138,23 +111,17 @@ void DataProcessor::SetupFileWriter(const bool filewriteEnable, } void DataProcessor::CreateFirstFiles( - MasterAttributes *attr, const std::string filePath, - const std::string fileNamePrefix, const uint64_t fileIndex, - const bool overWriteEnable, const bool silentMode, const int modulePos, - const int numUnitsPerReadout, const uint32_t udpPortNumber, - const uint32_t maxFramesPerFile, const uint64_t numImages, - const uint32_t dynamicRange, const bool detectorDataStream) { + const std::string &filePath, const std::string &fileNamePrefix, + const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, + const int modulePos, const int numUnitsPerReadout, + const uint32_t udpPortNumber, const uint32_t maxFramesPerFile, + const uint64_t numImages, const uint32_t dynamicRange, + const bool detectorDataStream) { if (dataFile_ == nullptr) { throw sls::RuntimeError("file object not contstructed"); } CloseFiles(); - // master file write enabled - if (masterFile_) { - masterFile_->CreateMasterFile(filePath, fileNamePrefix, fileIndex, - overWriteEnable, silentMode, attr); - } - // deactivated (half module/ single port), dont write file if ((!*activated_) || (!detectorDataStream)) { return; @@ -189,21 +156,17 @@ uint32_t DataProcessor::GetFilesInAcquisition() const { return dataFile_->GetFilesInAcquisition(); } -void DataProcessor::CreateVirtualFile( - const std::string filePath, const std::string fileNamePrefix, +std::array DataProcessor::CreateVirtualFile( + const std::string &filePath, const std::string &fileNamePrefix, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, const int modulePos, const int numUnitsPerReadout, const uint32_t maxFramesPerFile, const uint64_t numImages, - const uint32_t dynamicRange, const int numModX, const int numModY, - std::mutex *hdf5Lib) { + const int numModX, const int numModY, const uint32_t dynamicRange, + std::mutex *hdf5LibMutex) { - if (virtualFile_) { - delete virtualFile_; - } bool gotthard25um = ((detectorType_ == GOTTHARD || detectorType_ == GOTTHARD2) && (numModX * numModY) == 2); - virtualFile_ = new HDF5VirtualFile(hdf5Lib, gotthard25um); // maxframesperfile = 0 for infinite files uint32_t framesPerFile = @@ -213,63 +176,55 @@ void DataProcessor::CreateVirtualFile( // files (they exist anyway) assumption2: virtual file max frame index // is from R0 P0 (difference from others when missing frames or for a // stop acquisition) - virtualFile_->CreateVirtualFile( + return masterFileUtility::CreateVirtualHDF5File( filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode, modulePos, numUnitsPerReadout, framesPerFile, numImages, generalData_->nPixelsX, generalData_->nPixelsY, dynamicRange, numFramesCaught_, numModX, numModY, dataFile_->GetPDataType(), - dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes()); + dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes(), + hdf5LibMutex, gotthard25um); } -void DataProcessor::LinkDataInMasterFile(const bool silentMode) { - std::string fname, datasetName; - if (virtualFile_) { - auto res = virtualFile_->GetFileAndDatasetName(); - fname = res[0]; - datasetName = res[1]; - } else { +void DataProcessor::LinkFileInMaster(const std::string &masterFileName, + const std::string &virtualFileName, + const std::string &virtualDatasetName, + const bool silentMode, + std::mutex *hdf5LibMutex) { + std::string fname{virtualFileName}, datasetName{virtualDatasetName}; + // if no virtual file, link data file + if (virtualFileName.empty()) { auto res = dataFile_->GetFileAndDatasetName(); fname = res[0]; datasetName = res[1]; } - // link in master - masterFile_->LinkDataFile(fname, datasetName, - dataFile_->GetParameterNames(), silentMode); + masterFileUtility::LinkHDF5FileInMaster(masterFileName, fname, datasetName, + dataFile_->GetParameterNames(), + silentMode, hdf5LibMutex); } #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); +std::string DataProcessor::CreateMasterFile( + const std::string &filePath, const std::string &fileNamePrefix, + const uint64_t fileIndex, const bool overWriteEnable, bool silentMode, + const fileFormat fileFormatType, MasterAttributes *attr, + std::mutex *hdf5LibMutex) { + + attr->framesInFile = numFramesCaught_; + + std::unique_ptr masterFile{nullptr}; + switch (fileFormatType) { +#ifdef HDF5C + case HDF5: + return masterFileUtility::CreateMasterHDF5File( + filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode, + attr, hdf5LibMutex); +#endif + case BINARY: + return masterFileUtility::CreateMasterBinaryFile( + filePath, fileNamePrefix, fileIndex, overWriteEnable, silentMode, + attr); + default: + throw sls::RuntimeError("Unknown file format (compile with hdf5 flags"); } } diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index ebd5c4ffa..b62bb9d1f 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -45,12 +45,11 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { void CloseFiles(); void DeleteFiles(); void SetupFileWriter(const bool filewriteEnable, - const bool masterFilewriteEnable, - const fileFormat fileFormatType, const int modulePos, - std::mutex *hdf5Lib); + const fileFormat fileFormatType, + std::mutex *hdf5LibMutex); - void CreateFirstFiles(MasterAttributes *attr, const std::string filePath, - const std::string fileNamePrefix, + void CreateFirstFiles(const std::string &filePath, + const std::string &fileNamePrefix, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, const int modulePos, const int numUnitsPerReadout, @@ -60,18 +59,26 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { const bool detectorDataStream); #ifdef HDF5C uint32_t GetFilesInAcquisition() const; - void CreateVirtualFile(const std::string filePath, - const std::string fileNamePrefix, - const uint64_t fileIndex, const bool overWriteEnable, - const bool silentMode, const int modulePos, - const int numUnitsPerReadout, - const uint32_t maxFramesPerFile, - const uint64_t numImages, - const uint32_t dynamicRange, const int numModX, - const int numModY, std::mutex *hdf5Lib); - void LinkDataInMasterFile(const bool silentMode); + std::array CreateVirtualFile( + const std::string &filePath, const std::string &fileNamePrefix, + const uint64_t fileIndex, const bool overWriteEnable, + const bool silentMode, const int modulePos, + const int numUnitsPerReadout, const uint32_t maxFramesPerFile, + const uint64_t numImages, const int numModX, const int numModY, + const uint32_t dynamicRange, std::mutex *hdf5LibMutex); + void LinkFileInMaster(const std::string &masterFileName, + const std::string &virtualFileName, + const std::string &virtualDatasetName, + const bool silentMode, std::mutex *hdf5LibMutex); #endif - void UpdateMasterFile(bool silentMode); + + std::string CreateMasterFile(const std::string &filePath, + const std::string &fileNamePrefix, + const uint64_t fileIndex, + const bool overWriteEnable, bool silentMode, + const fileFormat fileFormatType, + MasterAttributes *attr, + std::mutex *hdf5LibMutex); /** * Call back for raw data * args to raw data ready callback are @@ -179,10 +186,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { bool firstStreamerFrame_{false}; File *dataFile_{nullptr}; - File *masterFile_{nullptr}; -#ifdef HDF5C - File *virtualFile_{nullptr}; -#endif // call back /** diff --git a/slsReceiverSoftware/src/File.h b/slsReceiverSoftware/src/File.h index da7af6ce9..9b386a640 100644 --- a/slsReceiverSoftware/src/File.h +++ b/slsReceiverSoftware/src/File.h @@ -60,20 +60,6 @@ class File : private virtual slsDetectorDefs { return std::vector{}; }; - virtual void CreateVirtualFile( - const std::string filePath, const std::string fileNamePrefix, - const uint64_t fileIndex, const bool overWriteEnable, - const bool silentMode, const int modulePos, - const int numUnitsPerReadout, const uint32_t maxFramesPerFile, - const uint64_t numImages, const uint32_t nPixelsX, - const uint32_t nPixelsY, const uint32_t dynamicRange, - const uint64_t numImagesCaught, const int numModX, const int numModY, - const DataType dataType, const std::vector parameterNames, - const std::vector parameterDataTypes) { - LOG(logERROR) << "This is a generic function CreateVirtualFile that " - "should be overloaded by a derived class"; - } - virtual void CreateFirstHDF5DataFile( const std::string filePath, const std::string fileNamePrefix, const uint64_t fileIndex, const bool overWriteEnable, @@ -85,13 +71,6 @@ class File : private virtual slsDetectorDefs { LOG(logERROR) << "This is a generic function CreateFirstDataFile that " "should be overloaded by a derived class"; }; - - virtual void LinkDataFile(std::string dataFilename, std::string dataSetname, - const std::vector parameterNames, - const bool silentMode) { - LOG(logERROR) << "This is a generic function LinkDataFile that " - "should be overloaded by a derived class"; - }; #endif virtual void CreateFirstBinaryDataFile( const std::string filePath, const std::string fileNamePrefix, @@ -103,27 +82,9 @@ class File : private virtual slsDetectorDefs { "should be overloaded by a derived class"; }; - virtual void CreateMasterFile(const std::string filePath, - const std::string fileNamePrefix, - const uint64_t fileIndex, - const bool overWriteEnable, - const bool silentMode, - MasterAttributes *attr) { - LOG(logERROR) << "This is a generic function CreateMasterFile that " - "should be overloaded by a derived class"; - }; - virtual void WriteToFile(char *buffer, const int buffersize, const uint64_t currentFrameNumber, - const uint32_t numPacketsCaught) { - LOG(logERROR) << "This is a generic function WriteToFile that " - "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"; - }; + const uint32_t numPacketsCaught) = 0; protected: slsDetectorDefs::fileFormat format_; diff --git a/slsReceiverSoftware/src/HDF5MasterFile.cpp b/slsReceiverSoftware/src/HDF5MasterFile.cpp deleted file mode 100644 index 2c3721501..000000000 --- a/slsReceiverSoftware/src/HDF5MasterFile.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-other -// Copyright (C) 2021 Contributors to the SLS Detector Package -#include "HDF5MasterFile.h" -#include "MasterAttributes.h" - -HDF5MasterFile::HDF5MasterFile(std::mutex *hdf5Lib) - : File(HDF5), hdf5Lib_(hdf5Lib) {} - -HDF5MasterFile::~HDF5MasterFile() { CloseFile(); } - -void HDF5MasterFile::CloseFile() { - std::lock_guard lock(*hdf5Lib_); - try { - Exception::dontPrint(); // to handle errors - if (fd_) { - fd_->close(); - delete fd_; - fd_ = nullptr; - } - } catch (const Exception &error) { - LOG(logERROR) << "Could not close master HDF5 handles"; - error.printErrorStack(); - } -} - -void HDF5MasterFile::LinkDataFile(std::string dataFilename, - std::string dataSetname, - const std::vector parameterNames, - const bool silentMode) { - - std::lock_guard lock(*hdf5Lib_); - try { - Exception::dontPrint(); // to handle errors - - FileAccPropList flist; - flist.setFcloseDegree(H5F_CLOSE_STRONG); - - // open master file - H5File masterfd(fileName_.c_str(), H5F_ACC_RDWR, - FileCreatPropList::DEFAULT, flist); - - // open data file - H5File fd(dataFilename.c_str(), H5F_ACC_RDONLY, - FileCreatPropList::DEFAULT, flist); - - // create link for data dataset - DataSet dset = fd.openDataSet(dataSetname.c_str()); - std::string linkname = std::string("/entry/data/") + dataSetname; - if (H5Lcreate_external(dataFilename.c_str(), dataSetname.c_str(), - masterfd.getLocId(), linkname.c_str(), - H5P_DEFAULT, H5P_DEFAULT) < 0) { - throw sls::RuntimeError( - "Could not create link to data dataset in master"); - } - - // create link for parameter datasets - for (unsigned int i = 0; i < parameterNames.size(); ++i) { - DataSet pDset = fd.openDataSet(parameterNames[i].c_str()); - linkname = std::string("/entry/data/") + parameterNames[i]; - if (H5Lcreate_external(dataFilename.c_str(), - parameterNames[i].c_str(), - masterfd.getLocId(), linkname.c_str(), - H5P_DEFAULT, H5P_DEFAULT) < 0) { - throw sls::RuntimeError( - "Could not create link to parameter dataset in master"); - } - } - fd.close(); - masterfd.close(); - } catch (const Exception &error) { - error.printErrorStack(); - CloseFile(); - throw sls::RuntimeError("Could not link in master hdf5 file"); - } - if (!silentMode) { - LOG(logINFO) << "Linked in Master File: " << dataFilename; - } -} - -void HDF5MasterFile::CreateMasterFile(const std::string filePath, - const std::string fileNamePrefix, - const uint64_t fileIndex, - const bool overWriteEnable, - const bool silentMode, - MasterAttributes *attr) { - - std::ostringstream os; - os << filePath << "/" << fileNamePrefix << "_master" - << "_" << fileIndex << ".h5"; - fileName_ = os.str(); - - std::lock_guard lock(*hdf5Lib_); - - try { - Exception::dontPrint(); // to handle errors - - FileAccPropList flist; - flist.setFcloseDegree(H5F_CLOSE_STRONG); - fd_ = nullptr; - if (!(overWriteEnable)) - fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL, - FileCreatPropList::DEFAULT, flist); - else - fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC, - FileCreatPropList::DEFAULT, flist); - - // attributes - version - double dValue = HDF5_WRITER_VERSION; - DataSpace dataspace_attr = DataSpace(H5S_SCALAR); - Attribute attribute = fd_->createAttribute( - "version", PredType::NATIVE_DOUBLE, dataspace_attr); - attribute.write(PredType::NATIVE_DOUBLE, &dValue); - - // Create a group in the file - Group group1(fd_->createGroup("entry")); - Group group2(group1.createGroup("data")); - Group group3(group1.createGroup("instrument")); - Group group4(group3.createGroup("beam")); - Group group5(group3.createGroup("detector")); - Group group6(group1.createGroup("sample")); - - // TODO find a way to get complete group link - attrGroupName_ = "/entry/instrument/detector"; - - attr->WriteMasterHDF5Attributes(fd_, &group5); - fd_->close(); - - } catch (const Exception &error) { - error.printErrorStack(); - CloseFile(); - throw sls::RuntimeError( - "Could not create/overwrite master HDF5 handles"); - } - 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 = fd_->openGroup(attrGroupName_.c_str()); - 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 deleted file mode 100644 index 5fb5dad26..000000000 --- a/slsReceiverSoftware/src/HDF5MasterFile.h +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-other -// Copyright (C) 2021 Contributors to the SLS Detector Package -#pragma once - -#include "File.h" - -#include - -class HDF5MasterFile : private virtual slsDetectorDefs, public File { - - public: - HDF5MasterFile(std::mutex *hdf5Lib); - ~HDF5MasterFile(); - - void CloseFile() override; - void LinkDataFile(std::string dataFilename, std::string dataSetname, - const std::vector parameterNames, - const bool silentMode) override; - void CreateMasterFile(const std::string filePath, - const std::string fileNamePrefix, - 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_; - std::string attrGroupName_; -}; \ No newline at end of file diff --git a/slsReceiverSoftware/src/HDF5VirtualFile.cpp b/slsReceiverSoftware/src/HDF5VirtualFile.cpp deleted file mode 100644 index 015ad0ae3..000000000 --- a/slsReceiverSoftware/src/HDF5VirtualFile.cpp +++ /dev/null @@ -1,211 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-other -// Copyright (C) 2021 Contributors to the SLS Detector Package -#include "HDF5VirtualFile.h" -#include "receiver_defs.h" - -#include - -HDF5VirtualFile::HDF5VirtualFile(std::mutex *hdf5Lib, bool g25) - : File(HDF5), hdf5Lib_(hdf5Lib), gotthard25um(g25) {} - -HDF5VirtualFile::~HDF5VirtualFile() { CloseFile(); } - -std::array HDF5VirtualFile::GetFileAndDatasetName() const { - return std::array{fileName_, dataSetName_}; -} - -void HDF5VirtualFile::CloseFile() { - std::lock_guard lock(*hdf5Lib_); - try { - Exception::dontPrint(); // to handle errors - if (fd_) { - fd_->close(); - delete fd_; - fd_ = nullptr; - } - } catch (const Exception &error) { - LOG(logERROR) << "Could not close virtual HDF5 handles of index"; - error.printErrorStack(); - } -} - -void HDF5VirtualFile::CreateVirtualFile( - const std::string filePath, const std::string fileNamePrefix, - const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, - const int modulePos, const int numUnitsPerReadout, - const uint32_t maxFramesPerFile, const uint64_t numImages, - const uint32_t nPixelsX, const uint32_t nPixelsY, - const uint32_t dynamicRange, const uint64_t numImagesCaught, - const int numModX, const int numModY, const DataType dataType, - const std::vector parameterNames, - const std::vector parameterDataTypes) { - // virtual file name - std::ostringstream osfn; - osfn << filePath << "/" << fileNamePrefix << "_virtual" - << "_" << fileIndex << ".h5"; - fileName_ = osfn.str(); - - unsigned int paraSize = parameterNames.size(); - uint64_t numModZ = numModX; - uint32_t nDimy = nPixelsY; - uint32_t nDimz = ((dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX); - - std::lock_guard lock(*hdf5Lib_); - - try { - Exception::dontPrint(); // to handle errors - - // file - FileAccPropList fapl; - fapl.setFcloseDegree(H5F_CLOSE_STRONG); - fd_ = nullptr; - if (!overWriteEnable) - fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL, - FileCreatPropList::DEFAULT, fapl); - else - fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC, - FileCreatPropList::DEFAULT, fapl); - - // attributes - version - double dValue = HDF5_WRITER_VERSION; - DataSpace dataspace_attr = DataSpace(H5S_SCALAR); - Attribute attribute = fd_->createAttribute( - "version", PredType::NATIVE_DOUBLE, dataspace_attr); - attribute.write(PredType::NATIVE_DOUBLE, &dValue); - - // virtual dataspace - hsize_t vdsDims[3] = {numImagesCaught, numModY * nDimy, - numModZ * nDimz}; - DataSpace vdsDataSpace(3, vdsDims, nullptr); - hsize_t vdsDimsPara[2] = {numImagesCaught, - (unsigned int)numModY * numModZ}; - DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr); - - // property list (fill value and datatype) - int fill_value = -1; - DSetCreatPropList plist; - plist.setFillValue(dataType, &fill_value); - - // property list for parameters (datatype) - std::vector plistPara(paraSize); - - // hyperslab (files) - int numFiles = numImagesCaught / maxFramesPerFile; - if (numImagesCaught % maxFramesPerFile) - ++numFiles; - uint64_t framesSaved = 0; - for (int iFile = 0; iFile < numFiles; ++iFile) { - - uint64_t nDimx = - ((numImagesCaught - framesSaved) > maxFramesPerFile) - ? maxFramesPerFile - : (numImagesCaught - framesSaved); - - hsize_t startLocation[3] = {framesSaved, 0, 0}; - hsize_t strideBetweenBlocks[3] = {1, 1, 1}; - hsize_t numBlocks[3] = {nDimx, nDimy, nDimz}; - hsize_t blockSize[3] = {1, 1, 1}; - - hsize_t startLocationPara[2] = {framesSaved, 0}; - hsize_t strideBetweenBlocksPara[3] = {1, 1}; - hsize_t numBlocksPara[2] = {1, 1}; - hsize_t blockSizePara[3] = {nDimx, 1}; - - // interleaving for g2 - if (gotthard25um) { - strideBetweenBlocks[2] = 2; - } - - for (unsigned int iReadout = 0; iReadout < numModY * numModZ; - ++iReadout) { - - // interleaving for g2 (startLocation is 0 and 1) - if (gotthard25um) { - startLocation[2] = iReadout; - } - - vdsDataSpace.selectHyperslab(H5S_SELECT_SET, numBlocks, - startLocation, strideBetweenBlocks, - blockSize); - - vdsDataSpacePara.selectHyperslab( - H5S_SELECT_SET, numBlocksPara, startLocationPara, - strideBetweenBlocksPara, blockSizePara); - - // source file name - std::ostringstream os; - os << filePath << "/" << fileNamePrefix << "_d" - << (modulePos * numUnitsPerReadout + iReadout) << "_f" - << iFile << '_' << fileIndex << ".h5"; - std::string srcFileName = os.str(); - LOG(logDEBUG1) << srcFileName; - - // find relative path - std::string relative_srcFileName = srcFileName; - { - size_t p = srcFileName.rfind('/', srcFileName.length()); - if (p != std::string::npos) - relative_srcFileName = (srcFileName.substr( - p + 1, srcFileName.length() - p)); - } - - // source dataset name - std::ostringstream osfn; - osfn << "/data"; - if (numImages > 1) - osfn << "_f" << std::setfill('0') << std::setw(12) << iFile; - std::string srcDatasetName = osfn.str(); - - // source dataspace - hsize_t srcDims[3] = {nDimx, nDimy, nDimz}; - hsize_t srcDimsMax[3] = {H5S_UNLIMITED, nDimy, nDimz}; - DataSpace srcDataSpace(3, srcDims, srcDimsMax); - hsize_t srcDimsPara[1] = {nDimx}; - hsize_t srcDimsMaxPara[1] = {H5S_UNLIMITED}; - DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara); - - // mapping of property list - plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(), - srcDatasetName.c_str(), srcDataSpace); - for (unsigned int p = 0; p < paraSize; ++p) { - plistPara[p].setVirtual( - vdsDataSpacePara, relative_srcFileName.c_str(), - parameterNames[p].c_str(), srcDataSpacePara); - } - - // H5Sclose(srcDataspace); - // H5Sclose(srcDataspace_para); - - if (!gotthard25um) { - startLocation[2] += nDimz; - if (startLocation[2] >= (numModZ * nDimz)) { - startLocation[2] = 0; - startLocation[1] += nDimy; - } - } - startLocationPara[1]++; - } - framesSaved += nDimx; - } - // datasets - dataSetName_ = "data"; - DataSet vdsDataSet(fd_->createDataSet(dataSetName_.c_str(), dataType, - vdsDataSpace, plist)); - - for (unsigned int p = 0; p < paraSize; ++p) { - DataSet vdsDataSetPara(fd_->createDataSet( - parameterNames[p].c_str(), parameterDataTypes[p], - vdsDataSpacePara, plistPara[p])); - } - - fd_->close(); - } catch (const Exception &error) { - error.printErrorStack(); - CloseFile(); - throw sls::RuntimeError( - "Could not create/overwrite virtual HDF5 handles"); - } - if (!silentMode) { - LOG(logINFO) << "Virtual File: " << fileName_; - } -} diff --git a/slsReceiverSoftware/src/HDF5VirtualFile.h b/slsReceiverSoftware/src/HDF5VirtualFile.h deleted file mode 100644 index 89b1c0b60..000000000 --- a/slsReceiverSoftware/src/HDF5VirtualFile.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-other -// Copyright (C) 2021 Contributors to the SLS Detector Package -#pragma once - -#include "File.h" - -#include - -class HDF5VirtualFile : private virtual slsDetectorDefs, public File { - - public: - HDF5VirtualFile(std::mutex *hdf5Lib, bool g25); - ~HDF5VirtualFile(); - - std::array GetFileAndDatasetName() const override; - void CloseFile() override; - void CreateVirtualFile( - const std::string filePath, const std::string fileNamePrefix, - const uint64_t fileIndex, const bool overWriteEnable, - const bool silentMode, const int modulePos, - const int numUnitsPerReadout, const uint32_t maxFramesPerFile, - const uint64_t numImages, const uint32_t nPixelsX, - const uint32_t nPixelsY, const uint32_t dynamicRange, - const uint64_t numImagesCaught, const int numModX, const int numModY, - const DataType dataType, const std::vector parameterNames, - const std::vector parameterDataTypes) override; - - private: - std::mutex *hdf5Lib_; - H5File *fd_{nullptr}; - std::string fileName_; - std::string dataSetName_; - bool gotthard25um; -}; \ No newline at end of file diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 484f11988..3ec1831d7 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -240,9 +240,6 @@ void Implementation::setModulePositionId(const int id) { xy portGeometry = GetPortGeometry(); streamingPort = DEFAULT_ZMQ_RX_PORTNO + modulePos * portGeometry.x; - for (const auto &it : dataProcessor) - it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable, - fileFormatType, modulePos, &hdf5Lib); assert(numModules.y != 0); for (unsigned int i = 0; i < listener.size(); ++i) { uint16_t row = 0, col = 0; @@ -372,8 +369,7 @@ void Implementation::setFileFormat(const fileFormat f) { throw sls::RuntimeError("Unknown file format"); } for (const auto &it : dataProcessor) - it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable, - fileFormatType, modulePos, &hdf5Lib); + it->SetupFileWriter(fileWriteEnable, fileFormatType, &hdf5LibMutex); } LOG(logINFO) << "File Format: " << sls::ToString(fileFormatType); @@ -409,8 +405,7 @@ void Implementation::setFileWriteEnable(const bool b) { if (fileWriteEnable != b) { fileWriteEnable = b; for (const auto &it : dataProcessor) - it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable, - fileFormatType, modulePos, &hdf5Lib); + it->SetupFileWriter(fileWriteEnable, fileFormatType, &hdf5LibMutex); } LOG(logINFO) << "File Write Enable: " << (fileWriteEnable ? "enabled" : "disabled"); @@ -423,9 +418,6 @@ bool Implementation::getMasterFileWriteEnable() const { void Implementation::setMasterFileWriteEnable(const bool b) { if (masterFileWriteEnable != b) { masterFileWriteEnable = b; - for (const auto &it : dataProcessor) - it->SetupFileWriter(fileWriteEnable, masterFileWriteEnable, - fileFormatType, modulePos, &hdf5Lib); } LOG(logINFO) << "Master File Write Enable: " << (masterFileWriteEnable ? "enabled" : "disabled"); @@ -584,29 +576,9 @@ void Implementation::stopReceiver() { std::this_thread::sleep_for(std::chrono::milliseconds(5)); } -#ifdef HDF5C - if (fileWriteEnable && fileFormatType == HDF5) { - if (modulePos == 0) { - // more than 1 file, create virtual file - if (dataProcessor[0]->GetFilesInAcquisition() > 1 || - (numModules.x * numModules.y) > 1) { - dataProcessor[0]->CreateVirtualFile( - filePath, fileName, fileIndex, overwriteEnable, silentMode, - modulePos, numUDPInterfaces, framesPerFile, - numberOfTotalFrames, dynamicRange, numModules.x, - numModules.y, &hdf5Lib); - } - // link file in master - dataProcessor[0]->LinkDataInMasterFile(silentMode); - } - } -#endif - if (fileWriteEnable && masterFileWriteEnable && modulePos == 0) { - try { - dataProcessor[0]->UpdateMasterFile(silentMode); - } catch (...) { - ; // ignore it and just print it - } + if (fileWriteEnable && modulePos == 0) { + // master and virtual file (hdf5) + StartMasterWriter(); } // wait for the processes (dataStreamer) to be done @@ -753,100 +725,12 @@ void Implementation::CreateUDPSockets() { } void Implementation::SetupWriter() { - // master file - std::unique_ptr masterAttributes; - if (masterFileWriteEnable && modulePos == 0) { - switch (detType) { - 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->detType = detType; - masterAttributes->timingMode = timingMode; - xy nm{numModules.x, numModules.y}; - if (quadEnable) { - nm.x = 1; - nm.y = 2; - } - masterAttributes->geometry = xy(nm.x, nm.y); - masterAttributes->imageSize = generalData->imageSize; - masterAttributes->nPixels = - xy(generalData->nPixelsX, generalData->nPixelsY); - masterAttributes->maxFramesPerFile = framesPerFile; - masterAttributes->frameDiscardMode = frameDiscardMode; - masterAttributes->framePadding = framePadding; - masterAttributes->scanParams = scanParams; - masterAttributes->totalFrames = numberOfTotalFrames; - masterAttributes->exptime = acquisitionTime; - masterAttributes->period = acquisitionPeriod; - masterAttributes->burstMode = burstMode; - masterAttributes->numUDPInterfaces = numUDPInterfaces; - masterAttributes->dynamicRange = dynamicRange; - masterAttributes->tenGiga = tengigaEnable; - masterAttributes->thresholdEnergyeV = thresholdEnergyeV; - masterAttributes->thresholdAllEnergyeV = thresholdAllEnergyeV; - masterAttributes->subExptime = subExpTime; - masterAttributes->subPeriod = subPeriod; - masterAttributes->quad = quadEnable; - masterAttributes->readNRows = readNRows; - masterAttributes->ratecorr = rateCorrections; - masterAttributes->adcmask = - tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga; - masterAttributes->analog = - (readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) - ? 1 - : 0; - masterAttributes->analogSamples = numberOfAnalogSamples; - masterAttributes->digital = - (readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) - ? 1 - : 0; - masterAttributes->digitalSamples = numberOfDigitalSamples; - masterAttributes->dbitoffset = ctbDbitOffset; - masterAttributes->dbitlist = 0; - for (auto &i : ctbDbitList) { - masterAttributes->dbitlist |= (1 << i); - } - masterAttributes->roi = roi; - masterAttributes->counterMask = counterMask; - masterAttributes->exptime1 = acquisitionTime1; - masterAttributes->exptime2 = acquisitionTime2; - masterAttributes->exptime3 = acquisitionTime3; - masterAttributes->gateDelay1 = gateDelay1; - masterAttributes->gateDelay2 = gateDelay2; - masterAttributes->gateDelay3 = gateDelay3; - masterAttributes->gates = numberOfGates; - masterAttributes->additionalJsonHeader = additionalJsonHeader; - } - try { for (unsigned int i = 0; i < dataProcessor.size(); ++i) { dataProcessor[i]->CreateFirstFiles( - masterAttributes.get(), filePath, fileName, fileIndex, - overwriteEnable, silentMode, modulePos, numUDPInterfaces, - udpPortNum[i], framesPerFile, numberOfTotalFrames, dynamicRange, - detectorDataStream[i]); + filePath, fileName, fileIndex, overwriteEnable, silentMode, + modulePos, numUDPInterfaces, udpPortNum[i], framesPerFile, + numberOfTotalFrames, dynamicRange, detectorDataStream[i]); } } catch (const sls::RuntimeError &e) { shutDownUDPSockets(); @@ -856,6 +740,100 @@ void Implementation::SetupWriter() { } } +void Implementation::StartMasterWriter() { + try { + std::string masterFileName; + // master file + if (masterFileWriteEnable) { + MasterAttributes masterAttributes; + masterAttributes.detType = detType; + masterAttributes.timingMode = timingMode; + xy nm{numModules.x, numModules.y}; + if (quadEnable) { + nm.x = 1; + nm.y = 2; + } + masterAttributes.geometry = xy(nm.x, nm.y); + masterAttributes.imageSize = generalData->imageSize; + masterAttributes.nPixels = + xy(generalData->nPixelsX, generalData->nPixelsY); + masterAttributes.maxFramesPerFile = framesPerFile; + masterAttributes.frameDiscardMode = frameDiscardMode; + masterAttributes.framePadding = framePadding; + masterAttributes.scanParams = scanParams; + masterAttributes.totalFrames = numberOfTotalFrames; + masterAttributes.exptime = acquisitionTime; + masterAttributes.period = acquisitionPeriod; + masterAttributes.burstMode = burstMode; + masterAttributes.numUDPInterfaces = numUDPInterfaces; + masterAttributes.dynamicRange = dynamicRange; + masterAttributes.tenGiga = tengigaEnable; + masterAttributes.thresholdEnergyeV = thresholdEnergyeV; + masterAttributes.thresholdAllEnergyeV = thresholdAllEnergyeV; + masterAttributes.subExptime = subExpTime; + masterAttributes.subPeriod = subPeriod; + masterAttributes.quad = quadEnable; + masterAttributes.readNRows = readNRows; + masterAttributes.ratecorr = rateCorrections; + masterAttributes.adcmask = + tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga; + masterAttributes.analog = (readoutType == ANALOG_ONLY || + readoutType == ANALOG_AND_DIGITAL) + ? 1 + : 0; + masterAttributes.analogSamples = numberOfAnalogSamples; + masterAttributes.digital = (readoutType == DIGITAL_ONLY || + readoutType == ANALOG_AND_DIGITAL) + ? 1 + : 0; + masterAttributes.digitalSamples = numberOfDigitalSamples; + masterAttributes.dbitoffset = ctbDbitOffset; + masterAttributes.dbitlist = 0; + for (auto &i : ctbDbitList) { + masterAttributes.dbitlist |= (1 << i); + } + masterAttributes.roi = roi; + masterAttributes.counterMask = counterMask; + masterAttributes.exptimeArray[0] = acquisitionTime1; + masterAttributes.exptimeArray[1] = acquisitionTime2; + masterAttributes.exptimeArray[2] = acquisitionTime3; + masterAttributes.gateDelayArray[0] = gateDelay1; + masterAttributes.gateDelayArray[1] = gateDelay2; + masterAttributes.gateDelayArray[2] = gateDelay3; + masterAttributes.gates = numberOfGates; + masterAttributes.additionalJsonHeader = additionalJsonHeader; + + // create master file + masterFileName = dataProcessor[0]->CreateMasterFile( + filePath, fileName, fileIndex, overwriteEnable, silentMode, + fileFormatType, &masterAttributes, &hdf5LibMutex); + } +#ifdef HDF5C + if (fileFormatType == HDF5) { + std::array virtualFileAndDatasetNames; + // create virtual hdf5 file (if multiple files) + if (dataProcessor[0]->GetFilesInAcquisition() > 1 || + (numModules.x * numModules.y) > 1) { + virtualFileAndDatasetNames = + dataProcessor[0]->CreateVirtualFile( + filePath, fileName, fileIndex, overwriteEnable, + silentMode, modulePos, numUDPInterfaces, framesPerFile, + numberOfTotalFrames, numModules.x, numModules.y, + dynamicRange, &hdf5LibMutex); + } + // link file in master + if (masterFileWriteEnable) { + dataProcessor[0]->LinkFileInMaster( + masterFileName, virtualFileAndDatasetNames[0], + virtualFileAndDatasetNames[1], silentMode, &hdf5LibMutex); + } + } +#endif + } catch (...) { + ; // ignore it and just print it + } +} + void Implementation::StartRunning() { // set running mask and post semaphore to start the inner loop in execution diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index e798f1a20..c792430e5 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -274,6 +274,7 @@ class Implementation : private virtual slsDetectorDefs { void ResetParametersforNewAcquisition(); void CreateUDPSockets(); void SetupWriter(); + void StartMasterWriter(); void StartRunning(); /************************************************** @@ -386,5 +387,6 @@ class Implementation : private virtual slsDetectorDefs { std::vector> fifo; Arping arping; - std::mutex hdf5Lib; + // mutex shared across all hdf5 virtual, master and data files + std::mutex hdf5LibMutex; }; diff --git a/slsReceiverSoftware/src/MasterAttributes.cpp b/slsReceiverSoftware/src/MasterAttributes.cpp index 447495fce..b82cc0e42 100644 --- a/slsReceiverSoftware/src/MasterAttributes.cpp +++ b/slsReceiverSoftware/src/MasterAttributes.cpp @@ -2,675 +2,723 @@ // Copyright (C) 2021 Contributors to the SLS Detector Package #include "MasterAttributes.h" -void MasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { - LOG(logERROR) << "WriteMasterBinaryAttributes should have been called " - "by a child class"; +void MasterAttributes::GetBinaryAttributes( + rapidjson::PrettyWriter *w) { + w->StartObject(); + GetCommonBinaryAttributes(w); + switch (detType) { + case slsDetectorDefs::GOTTHARD: + GetGotthardBinaryAttributes(w); + break; + case slsDetectorDefs::JUNGFRAU: + GetJungfrauBinaryAttributes(w); + break; + case slsDetectorDefs::EIGER: + GetEigerBinaryAttributes(w); + break; + case slsDetectorDefs::MYTHEN3: + GetMythen3BinaryAttributes(w); + break; + case slsDetectorDefs::GOTTHARD2: + GetGotthard2BinaryAttributes(w); + break; + case slsDetectorDefs::MOENCH: + GetMoenchBinaryAttributes(w); + break; + case slsDetectorDefs::CHIPTESTBOARD: + GetCtbBinaryAttributes(w); + break; + default: + throw sls::RuntimeError( + "Unknown Detector type to get master attributes"); + } + GetFinalBinaryAttributes(w); + w->EndObject(); } -std::string MasterAttributes::GetBinaryMasterAttributes() { +#ifdef HDF5C +void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) { + WriteCommonHDF5Attributes(fd, group); + switch (detType) { + case slsDetectorDefs::GOTTHARD: + WriteGotthardHDF5Attributes(fd, group); + break; + case slsDetectorDefs::JUNGFRAU: + WriteJungfrauHDF5Attributes(fd, group); + break; + case slsDetectorDefs::EIGER: + WriteEigerHDF5Attributes(fd, group); + break; + case slsDetectorDefs::MYTHEN3: + WriteMythen3HDF5Attributes(fd, group); + break; + case slsDetectorDefs::GOTTHARD2: + WriteGotthard2HDF5Attributes(fd, group); + break; + case slsDetectorDefs::MOENCH: + WriteMoenchHDF5Attributes(fd, group); + break; + case slsDetectorDefs::CHIPTESTBOARD: + WriteCtbHDF5Attributes(fd, group); + break; + default: + throw sls::RuntimeError( + "Unknown Detector type to get master attributes"); + } + WriteFinalHDF5Attributes(fd, group); +} +#endif + +void MasterAttributes::GetCommonBinaryAttributes( + rapidjson::PrettyWriter *w) { + w->Key("Version"); + w->SetMaxDecimalPlaces(2); + w->Double(BINARY_WRITER_VERSION); + w->Key("Timestamp"); time_t t = time(nullptr); - std::ostringstream oss; - oss << "Version : " << std::setprecision(2) - << BINARY_WRITER_VERSION << '\n' - << "TimeStamp : " << ctime(&t) << '\n' - << "Detector Type : " << sls::ToString(detType) << '\n' - << "Timing Mode : " << sls::ToString(timingMode) << '\n' - << "Geometry : " << sls::ToString(geometry) << '\n' - << "Image Size : " << imageSize << " bytes" << '\n' - << "Pixels : " << sls::ToString(nPixels) << '\n' - << "Max Frames Per File : " << maxFramesPerFile << '\n' - << "Frame Discard Policy : " << sls::ToString(frameDiscardMode) - << '\n' - << "Frame Padding : " << framePadding << '\n' - << "Scan Parameters : " << sls::ToString(scanParams) << '\n' - << "Total Frames : " << totalFrames << '\n'; - return oss.str(); -}; + std::string sTime(ctime(&t)); + std::replace(sTime.begin(), sTime.end(), '\n', '\0'); + w->String(sTime.c_str()); + w->Key("Detector Type"); + w->String(sls::ToString(detType).c_str()); + w->Key("Timing Mode"); + w->String(sls::ToString(timingMode).c_str()); + w->Key("Geometry"); + w->StartObject(); + w->Key("x"); + w->Uint(geometry.x); + w->Key("y"); + w->Uint(geometry.y); + w->EndObject(); + w->Key("Image Size in bytes"); + w->Uint(imageSize); + w->Key("Pixels"); + w->StartObject(); + w->Key("x"); + w->Uint(nPixels.x); + w->Key("y"); + w->Uint(nPixels.y); + w->EndObject(); + w->Key("Max Frames Per File"); + w->Uint(maxFramesPerFile); + w->Key("Frame Discard Policy"); + w->String(sls::ToString(frameDiscardMode).c_str()); + w->Key("Frame Padding"); + w->Uint(framePadding); + w->Key("Scan Parameters"); + w->String(sls::ToString(scanParams).c_str()); + w->Key("Total Frames"); + w->Uint64(totalFrames); +} -void MasterAttributes::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 MasterAttributes::WriteFinalBinaryAttributes(FILE *fd) { +void MasterAttributes::GetFinalBinaryAttributes( + rapidjson::PrettyWriter *w) { // adding few common parameters to the end - std::ostringstream oss; - if (!additionalJsonHeader.empty()) { - oss << "Additional Json Header : " - << sls::ToString(additionalJsonHeader) << '\n'; + w->Key("Additional Json Header"); + w->String(sls::ToString(additionalJsonHeader).c_str()); } - oss << "Frames in File : " << framesInFile << '\n'; - - // adding sls_receiver header format - 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) != - message.length()) { - throw sls::RuntimeError( - "Master binary file incorrect number of bytes written to file"); - } -}; + w->Key("Frames in File"); + w->Uint64(framesInFile); + w->Key("Frame Header Format"); + w->StartObject(); + w->Key("Frame Number"); + w->String("8 bytes"); + w->Key("SubFrame Number/ExpLength"); + w->String("4 bytes"); + w->Key("Packet Number"); + w->String("4 bytes"); + w->Key("Bunch ID"); + w->String("8 bytes"); + w->Key("Timestamp"); + w->String("8 bytes"); + w->Key("Module Id"); + w->String("2 bytes"); + w->Key("Row"); + w->String("2 bytes"); + w->Key("Column"); + w->String("2 bytes"); + w->Key("Reserved"); + w->String("2 bytes"); + w->Key("Debug"); + w->String("4 bytes"); + w->Key("Round Robin Number"); + w->String("2 bytes"); + w->Key("Detector Type"); + w->String("1 byte"); + w->Key("Header Version"); + w->String("1 byte"); + w->Key("Packets Caught Mask"); + w->String("64 bytes"); + w->EndObject(); +} #ifdef HDF5C -void MasterAttributes::WriteMasterHDF5Attributes(H5File *fd, Group *group) { - LOG(logERROR) << "WriteMasterHdf5Attributes should have been called " - "by a child class"; -}; - -void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) { - char c[1024]; - memset(c, 0, sizeof(c)); - // clang-format off - // version - { - double version = BINARY_WRITER_VERSION; - DataSpace dataspace = DataSpace(H5S_SCALAR); - Attribute attribute = fd->createAttribute( - "Version", PredType::NATIVE_DOUBLE, dataspace); - attribute.write(PredType::NATIVE_DOUBLE, &version); - } - // timestamp - { - time_t t = time(nullptr); - StrType strdatatype(PredType::C_S1, 256); - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = +void MasterAttributes::WriteCommonHDF5Attributes(H5File *fd, Group *group) { + char c[1024]{}; + // version + { + double version = BINARY_WRITER_VERSION; + DataSpace dataspace = DataSpace(H5S_SCALAR); + Attribute attribute = + fd->createAttribute("Version", PredType::NATIVE_DOUBLE, dataspace); + attribute.write(PredType::NATIVE_DOUBLE, &version); + } + // timestamp + { + time_t t = time(nullptr); + StrType strdatatype(PredType::C_S1, 256); + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Timestamp", strdatatype, dataspace); - sls::strcpy_safe(c, std::string(ctime(&t))); - dataset.write(c, strdatatype); - } - // detector type - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = + sls::strcpy_safe(c, std::string(ctime(&t))); + dataset.write(c, strdatatype); + } + // detector type + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = group->createDataSet("Detector Type", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(detType)); - dataset.write(c, strdatatype); - } - // timing mode - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = + sls::strcpy_safe(c, sls::ToString(detType)); + dataset.write(c, strdatatype); + } + // timing mode + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = group->createDataSet("Timing Mode", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(timingMode)); - dataset.write(c, strdatatype); - } - //TODO: make this into an array? - // geometry x - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Geometry in x axis", PredType::NATIVE_INT, dataspace); - dataset.write(&geometry.x, PredType::NATIVE_INT); - } - // geometry y - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Geometry in y axis", PredType::NATIVE_INT, dataspace); - dataset.write(&geometry.y, PredType::NATIVE_INT); - } - // Image Size - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Image Size", PredType::NATIVE_INT, dataspace); - dataset.write(&imageSize, PredType::NATIVE_INT); - DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - Attribute attribute = - dataset.createAttribute("Unit", strdatatype, dataspaceAttr); - sls::strcpy_safe(c, "bytes"); - attribute.write(strdatatype, c); - } - //TODO: make this into an array? - // npixels x - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Number of pixels in x axis", PredType::NATIVE_INT, dataspace); - dataset.write(&nPixels.x, PredType::NATIVE_INT); - } - // npixels y - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Number of pixels in y axis", PredType::NATIVE_INT, dataspace); - dataset.write(&nPixels.y, PredType::NATIVE_INT); - } - // Maximum frames per file - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Maximum frames per file", PredType::NATIVE_INT, dataspace); - dataset.write(&maxFramesPerFile, PredType::NATIVE_INT); - } - // Frame Discard Policy - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Frame Discard Policy", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(frameDiscardMode)); - dataset.write(c, strdatatype); - } - // Frame Padding - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Frame Padding", PredType::NATIVE_INT, dataspace); - dataset.write(&framePadding, PredType::NATIVE_INT); - } - // Scan Parameters - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Scan Parameters", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(scanParams)); - dataset.write(c, strdatatype); - } - // Total Frames - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Total Frames", PredType::STD_U64LE, dataspace); - dataset.write(&totalFrames, PredType::STD_U64LE); - } - }; - - void MasterAttributes::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); - StrType strdatatype(PredType::C_S1, json.length()); - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Additional JSON Header", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(additionalJsonHeader)); - dataset.write(c, strdatatype); - } - }; - - void MasterAttributes::WriteHDF5Exptime(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Exposure Time", strdatatype, dataspace); - char c[1024]; - memset(c, 0, sizeof(c)); - sls::strcpy_safe(c, sls::ToString(exptime)); + sls::strcpy_safe(c, sls::ToString(timingMode)); dataset.write(c, strdatatype); - }; - - void MasterAttributes::WriteHDF5Period(H5File *fd, Group *group) { + } + // TODO: make this into an array? + // geometry x + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Geometry in x axis", + PredType::NATIVE_INT, dataspace); + dataset.write(&geometry.x, PredType::NATIVE_INT); + } + // geometry y + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Geometry in y axis", + PredType::NATIVE_INT, dataspace); + dataset.write(&geometry.y, PredType::NATIVE_INT); + } + // Image Size + { DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); DataSet dataset = - group->createDataSet("Acquisition Period", strdatatype, dataspace); - char c[1024]; - memset(c, 0, sizeof(c)); - sls::strcpy_safe(c, sls::ToString(period)); - dataset.write(c, strdatatype); - }; - - void MasterAttributes::WriteHDF5DynamicRange(H5File *fd, Group *group) { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Dynamic Range", PredType::NATIVE_INT, dataspace); - dataset.write(&dynamicRange, PredType::NATIVE_INT); + group->createDataSet("Image Size", PredType::NATIVE_INT, dataspace); + dataset.write(&imageSize, PredType::NATIVE_INT); DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); StrType strdatatype(PredType::C_S1, 256); Attribute attribute = - dataset.createAttribute("Unit", strdatatype, dataspaceAttr); - char c[1024] = "bits"; - attribute.write( strdatatype, c); - }; - - void MasterAttributes::WriteHDF5TenGiga(H5File *fd, Group *group) { + dataset.createAttribute("Unit", strdatatype, dataspaceAttr); + sls::strcpy_safe(c, "bytes"); + attribute.write(strdatatype, c); + } + // TODO: make this into an array? + // npixels x + { DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Ten Giga Enable", PredType::NATIVE_INT, dataspace); - dataset.write(&tenGiga, PredType::NATIVE_INT); - }; + DataSet dataset = group->createDataSet("Number of pixels in x axis", + PredType::NATIVE_INT, dataspace); + dataset.write(&nPixels.x, PredType::NATIVE_INT); + } + // npixels y + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Number of pixels in y axis", + PredType::NATIVE_INT, dataspace); + dataset.write(&nPixels.y, PredType::NATIVE_INT); + } + // Maximum frames per file + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Maximum frames per file", + PredType::NATIVE_INT, dataspace); + dataset.write(&maxFramesPerFile, PredType::NATIVE_INT); + } + // Frame Discard Policy + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = group->createDataSet("Frame Discard Policy", + strdatatype, dataspace); + sls::strcpy_safe(c, sls::ToString(frameDiscardMode)); + dataset.write(c, strdatatype); + } + // Frame Padding + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Frame Padding", + PredType::NATIVE_INT, dataspace); + dataset.write(&framePadding, PredType::NATIVE_INT); + } + // Scan Parameters + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Scan Parameters", strdatatype, dataspace); + sls::strcpy_safe(c, sls::ToString(scanParams)); + dataset.write(c, strdatatype); + } + // Total Frames + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Total Frames", + PredType::STD_U64LE, dataspace); + dataset.write(&totalFrames, PredType::STD_U64LE); + } +} + +void MasterAttributes::WriteFinalHDF5Attributes(H5File *fd, Group *group) { + char c[1024]{}; + // 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); + StrType strdatatype(PredType::C_S1, json.length()); + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Additional JSON Header", + strdatatype, dataspace); + sls::strcpy_safe(c, sls::ToString(additionalJsonHeader)); + dataset.write(c, strdatatype); + } +} + +void MasterAttributes::WriteHDF5Exptime(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Exposure Time", strdatatype, dataspace); + char c[1024]{}; + sls::strcpy_safe(c, sls::ToString(exptime)); + dataset.write(c, strdatatype); +} + +void MasterAttributes::WriteHDF5Period(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Acquisition Period", strdatatype, dataspace); + char c[1024]{}; + sls::strcpy_safe(c, sls::ToString(period)); + dataset.write(c, strdatatype); +} + +void MasterAttributes::WriteHDF5DynamicRange(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Dynamic Range", PredType::NATIVE_INT, dataspace); + dataset.write(&dynamicRange, PredType::NATIVE_INT); + DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + Attribute attribute = + dataset.createAttribute("Unit", strdatatype, dataspaceAttr); + char c[1024] = "bits"; + attribute.write(strdatatype, c); +} + +void MasterAttributes::WriteHDF5TenGiga(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Ten Giga Enable", + PredType::NATIVE_INT, dataspace); + dataset.write(&tenGiga, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5ROI(H5File *fd, Group *group) { + // Roi xmin + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("roi xmin", PredType::NATIVE_INT, dataspace); + dataset.write(&roi.xmin, PredType::NATIVE_INT); + } + // Roi xmax + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("roi xmax", PredType::NATIVE_INT, dataspace); + dataset.write(&roi.xmax, PredType::NATIVE_INT); + } +} + +void MasterAttributes::WriteHDF5NumUDPInterfaces(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Number of UDP Interfaces", + PredType::NATIVE_INT, dataspace); + dataset.write(&numUDPInterfaces, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5ReadNRows(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Number of rows", PredType::NATIVE_INT, dataspace); + dataset.write(&readNRows, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5ThresholdEnergy(H5File *fd, Group *group) { + char c[1024]{}; + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Threshold Energy", + PredType::NATIVE_INT, dataspace); + dataset.write(&thresholdEnergyeV, PredType::NATIVE_INT); + DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + Attribute attribute = + dataset.createAttribute("Unit", strdatatype, dataspaceAttr); + sls::strcpy_safe(c, "eV"); + attribute.write(strdatatype, c); +} + +void MasterAttributes::WriteHDF5ThresholdEnergies(H5File *fd, Group *group) { + char c[1024]{}; + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 1024); + DataSet dataset = + group->createDataSet("Threshold Energies", strdatatype, dataspace); + sls::strcpy_safe(c, sls::ToString(thresholdAllEnergyeV)); + dataset.write(c, strdatatype); +} + +void MasterAttributes::WriteHDF5SubExpTime(H5File *fd, Group *group) { + char c[1024]{}; + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Sub Exposure Time", strdatatype, dataspace); + sls::strcpy_safe(c, sls::ToString(subExptime)); + dataset.write(c, strdatatype); +} + +void MasterAttributes::WriteHDF5SubPeriod(H5File *fd, Group *group) { + char c[1024]{}; + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Sub Period", strdatatype, dataspace); + sls::strcpy_safe(c, sls::ToString(subPeriod)); + dataset.write(c, strdatatype); +} + +void MasterAttributes::WriteHDF5SubQuad(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Quad", PredType::NATIVE_INT, dataspace); + dataset.write(&quad, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5RateCorrections(H5File *fd, Group *group) { + char c[1024]{}; + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 1024); + DataSet dataset = + group->createDataSet("Rate Corrections", strdatatype, dataspace); + sls::strcpy_safe(c, sls::ToString(ratecorr)); + dataset.write(c, strdatatype); +} + +void MasterAttributes::WriteHDF5CounterMask(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Counter Mask", PredType::STD_U32LE, dataspace); + dataset.write(&counterMask, PredType::STD_U32LE); +} + +void MasterAttributes::WriteHDF5ExptimeArray(H5File *fd, Group *group) { + for (int i = 0; i != 3; ++i) { + char c[1024]{}; + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Exposure Time1", strdatatype, dataspace); + sls::strcpy_safe(c, sls::ToString(exptimeArray[i])); + dataset.write(c, strdatatype); + } +} + +void MasterAttributes::WriteHDF5GateDelayArray(H5File *fd, Group *group) { + for (int i = 0; i != 3; ++i) { + char c[1024]{}; + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Gate Delay1", strdatatype, dataspace); + sls::strcpy_safe(c, sls::ToString(gateDelayArray[i])); + dataset.write(c, strdatatype); + } +} + +void MasterAttributes::WriteHDF5Gates(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Gates", PredType::STD_U32LE, dataspace); + dataset.write(&gates, PredType::STD_U32LE); +} + +void MasterAttributes::WriteHDF5BurstMode(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = + group->createDataSet("Burst Mode", strdatatype, dataspace); + char c[1024]{}; + sls::strcpy_safe(c, sls::ToString(burstMode)); + dataset.write(c, strdatatype); +} + +void MasterAttributes::WriteHDF5AdcMask(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("ADC Mask", PredType::NATIVE_INT, dataspace); + dataset.write(&adcmask, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5AnalogFlag(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Analog Flag", PredType::NATIVE_INT, dataspace); + dataset.write(&analog, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5AnalogSamples(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Analog Samples", PredType::NATIVE_INT, dataspace); + dataset.write(&analogSamples, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5DigitalFlag(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Digital Flag", PredType::NATIVE_INT, dataspace); + dataset.write(&digital, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5DigitalSamples(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Digital Samples", + PredType::NATIVE_INT, dataspace); + dataset.write(&digitalSamples, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5DbitOffset(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = + group->createDataSet("Dbit Offset", PredType::NATIVE_INT, dataspace); + dataset.write(&dbitoffset, PredType::NATIVE_INT); +} + +void MasterAttributes::WriteHDF5DbitList(H5File *fd, Group *group) { + DataSpace dataspace = DataSpace(H5S_SCALAR); + DataSet dataset = group->createDataSet("Dbit Bitset List", + PredType::STD_U64LE, dataspace); + dataset.write(&dbitlist, PredType::STD_U64LE); +} #endif - void GotthardMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { - std::ostringstream oss; - oss << MasterAttributes::GetBinaryMasterAttributes() - << "Exptime : " << sls::ToString(exptime) << '\n' - << "Period : " << sls::ToString(period) << '\n' - << "Roi (xmin, xmax) : " << sls::ToString(roi) << '\n'; - std::string message = oss.str(); - MasterAttributes::WriteBinaryAttributes(fd, message); - }; +void MasterAttributes::GetGotthardBinaryAttributes( + rapidjson::PrettyWriter *w) { + w->Key("Exptime"); + w->String(sls::ToString(exptime).c_str()); + w->Key("Period"); + w->String(sls::ToString(period).c_str()); + w->Key("Roi (xmin, xmax)"); + w->String(sls::ToString(roi).c_str()); +}; #ifdef HDF5C - void GotthardMasterAttributes::WriteMasterHDF5Attributes(H5File *fd, Group *group) { - MasterAttributes::WriteHDF5Attributes(fd, group); - MasterAttributes::WriteHDF5Exptime(fd, group); - MasterAttributes::WriteHDF5Period(fd, group); - // Roi xmin - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "roi xmin", PredType::NATIVE_INT, dataspace); - dataset.write(&roi.xmin, PredType::NATIVE_INT); - } - // Roi xmax - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "roi xmax", PredType::NATIVE_INT, dataspace); - dataset.write(&roi.xmax, PredType::NATIVE_INT); - } - }; +void MasterAttributes::WriteGotthardHDF5Attributes(H5File *fd, Group *group) { + MasterAttributes::WriteHDF5Exptime(fd, group); + MasterAttributes::WriteHDF5Period(fd, group); + MasterAttributes::WriteHDF5ROI(fd, group); +} #endif - void JungfrauMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { - std::ostringstream oss; - oss << MasterAttributes::GetBinaryMasterAttributes() - << "Exptime : " << sls::ToString(exptime) << '\n' - << "Period : " << sls::ToString(period) << '\n' - << "Number of UDP Interfaces : " << numUDPInterfaces << '\n' - << "Number of rows : " << readNRows << '\n'; - std::string message = oss.str(); - MasterAttributes::WriteBinaryAttributes(fd, message); - }; +void MasterAttributes::GetJungfrauBinaryAttributes( + rapidjson::PrettyWriter *w) { + w->Key("Exptime"); + w->String(sls::ToString(exptime).c_str()); + w->Key("Period"); + w->String(sls::ToString(period).c_str()); + w->Key("Number of UDP Interfaces"); + w->Uint(numUDPInterfaces); + w->Key("Number of rows"); + w->Uint(readNRows); +} #ifdef HDF5C - void JungfrauMasterAttributes::WriteMasterHDF5Attributes(H5File *fd, Group *group) { - MasterAttributes::WriteHDF5Attributes(fd, group); - MasterAttributes::WriteHDF5Exptime(fd, group); - MasterAttributes::WriteHDF5Period(fd, group); - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Number of UDP Interfaces", PredType::NATIVE_INT, dataspace); - dataset.write(&numUDPInterfaces, PredType::NATIVE_INT); - } - // readNRows - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Number of rows", PredType::NATIVE_INT, dataspace); - dataset.write(&readNRows, PredType::NATIVE_INT); - } - }; +void MasterAttributes::WriteJungfrauHDF5Attributes(H5File *fd, Group *group) { + MasterAttributes::WriteHDF5Exptime(fd, group); + MasterAttributes::WriteHDF5Period(fd, group); + MasterAttributes::WriteHDF5NumUDPInterfaces(fd, group); + MasterAttributes::WriteHDF5ReadNRows(fd, group); +} #endif - void EigerMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { - std::ostringstream oss; - oss << MasterAttributes::GetBinaryMasterAttributes() - << "Dynamic Range : " << dynamicRange << '\n' - << "Ten Giga : " << tenGiga << '\n' - << "Exptime : " << sls::ToString(exptime) << '\n' - << "Period : " << sls::ToString(period) << '\n' - << "Threshold Energy : " << thresholdEnergyeV << '\n' - << "SubExptime : " << sls::ToString(subExptime) - << '\n' - << "SubPeriod : " << sls::ToString(subPeriod) - << '\n' - << "Quad : " << quad << '\n' - << "Number of rows : " << readNRows << '\n' - << "Rate Corrections : " << sls::ToString(ratecorr) - << '\n'; - std::string message = oss.str(); - MasterAttributes::WriteBinaryAttributes(fd, message); - }; +void MasterAttributes::GetEigerBinaryAttributes( + rapidjson::PrettyWriter *w) { + w->Key("Dynamic Range"); + w->Uint(dynamicRange); + w->Key("Ten Giga"); + w->Uint(tenGiga); + w->Key("Exptime"); + w->String(sls::ToString(exptime).c_str()); + w->Key("Period"); + w->String(sls::ToString(period).c_str()); + w->Key("Threshold Energy"); + w->Int(thresholdEnergyeV); + w->Key("Sub Exptime"); + w->String(sls::ToString(subExptime).c_str()); + w->Key("Sub Period"); + w->String(sls::ToString(subPeriod).c_str()); + w->Key("Quad"); + w->Int(quad); + w->Key("Number of rows"); + w->Int(readNRows); + w->Key("Rate Corrections"); + w->String(sls::ToString(ratecorr).c_str()); +} #ifdef HDF5C - void EigerMasterAttributes::WriteMasterHDF5Attributes(H5File *fd, Group *group) { - MasterAttributes::WriteHDF5Attributes(fd, group); - MasterAttributes::WriteHDF5DynamicRange(fd, group); - MasterAttributes::WriteHDF5TenGiga(fd, group); - MasterAttributes::WriteHDF5Exptime(fd, group); - MasterAttributes::WriteHDF5Period(fd, group); - char c[1024]; - memset(c, 0, sizeof(c)); - // threshold - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Threshold Energy", PredType::NATIVE_INT, dataspace); - dataset.write(&thresholdEnergyeV, PredType::NATIVE_INT); - DataSpace dataspaceAttr = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - Attribute attribute = - dataset.createAttribute("Unit", strdatatype, dataspaceAttr); - sls::strcpy_safe(c, "eV"); - attribute.write(strdatatype, c); - } - // SubExptime - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = group->createDataSet("Sub Exposure Time", - strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(subExptime)); - dataset.write(c, strdatatype); - } - // SubPeriod - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Sub Period", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(subPeriod)); - dataset.write(c, strdatatype); - } - // Quad - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Quad", PredType::NATIVE_INT, dataspace); - dataset.write(&quad, PredType::NATIVE_INT); - } - // readNRows - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Number of rows", PredType::NATIVE_INT, dataspace); - dataset.write(&readNRows, PredType::NATIVE_INT); - } - // Rate corrections - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 1024); - DataSet dataset = group->createDataSet("Rate Corrections", - strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(ratecorr)); - dataset.write(c, strdatatype); - } - }; +void MasterAttributes::WriteEigerHDF5Attributes(H5File *fd, Group *group) { + MasterAttributes::WriteHDF5DynamicRange(fd, group); + MasterAttributes::WriteHDF5TenGiga(fd, group); + MasterAttributes::WriteHDF5Exptime(fd, group); + MasterAttributes::WriteHDF5Period(fd, group); + MasterAttributes::WriteHDF5ThresholdEnergy(fd, group); + MasterAttributes::WriteHDF5SubExpTime(fd, group); + MasterAttributes::WriteHDF5SubPeriod(fd, group); + MasterAttributes::WriteHDF5SubQuad(fd, group); + MasterAttributes::WriteHDF5ReadNRows(fd, group); + MasterAttributes::WriteHDF5RateCorrections(fd, group); +} #endif - void Mythen3MasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { - std::ostringstream oss; - oss << MasterAttributes::GetBinaryMasterAttributes() - << "Dynamic Range : " << dynamicRange << '\n' - << "Ten Giga : " << tenGiga << '\n' - << "Period : " << sls::ToString(period) << '\n' - << "Counter Mask : " << sls::ToStringHex(counterMask) - << '\n' - << "Exptime1 : " << sls::ToString(exptime1) - << '\n' - << "Exptime2 : " << sls::ToString(exptime2) - << '\n' - << "Exptime3 : " << sls::ToString(exptime3) - << '\n' - << "GateDelay1 : " << sls::ToString(gateDelay1) - << '\n' - << "GateDelay2 : " << sls::ToString(gateDelay2) - << '\n' - << "GateDelay3 : " << sls::ToString(gateDelay3) - << '\n' - << "Gates : " << gates << '\n' - << "Threshold Energies : " - << sls::ToString(thresholdAllEnergyeV) << '\n'; - std::string message = oss.str(); - MasterAttributes::WriteBinaryAttributes(fd, message); - }; +void MasterAttributes::GetMythen3BinaryAttributes( + rapidjson::PrettyWriter *w) { + w->Key("Dynamic Range"); + w->Uint(dynamicRange); + w->Key("Ten Giga"); + w->Uint(tenGiga); + w->Key("Period"); + w->String(sls::ToString(period).c_str()); + w->Key("Counter Mask"); + w->String(sls::ToStringHex(counterMask).c_str()); + for (int i = 0; i != 3; ++i) { + w->Key((std::string("Exptime") + std::to_string(i + 1)).c_str()); + w->String(sls::ToString(exptimeArray[i]).c_str()); + } + for (int i = 0; i != 3; ++i) { + w->Key((std::string("GateDelay") + std::to_string(i + 1)).c_str()); + w->String(sls::ToString(gateDelayArray[i]).c_str()); + } + w->Key("Gates"); + w->Uint(gates); + w->Key("Threshold Energies"); + w->String(sls::ToString(thresholdAllEnergyeV).c_str()); +} #ifdef HDF5C - void Mythen3MasterAttributes::WriteMasterHDF5Attributes(H5File *fd, Group *group) { - MasterAttributes::WriteHDF5Attributes(fd, group); - MasterAttributes::WriteHDF5DynamicRange(fd, group); - MasterAttributes::WriteHDF5TenGiga(fd, group); - MasterAttributes::WriteHDF5Period(fd, group); - char c[1024]; - memset(c, 0, sizeof(c)); - // Counter Mask - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Counter Mask", PredType::STD_U32LE, dataspace); - dataset.write(&counterMask, PredType::STD_U32LE); - } - // Exptime1 - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Exposure Time1", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(exptime1)); - dataset.write(c, strdatatype); - } - // Exptime2 - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Exposure Time2", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(exptime2)); - dataset.write(c, strdatatype); - } - // Exptime3 - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Exposure Time3", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(exptime3)); - dataset.write(c, strdatatype); - } - // GateDelay1 - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Gate Delay1", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(gateDelay1)); - dataset.write(c, strdatatype); - } - // GateDelay2 - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Gate Delay2", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(gateDelay2)); - dataset.write(c, strdatatype); - } - // GateDelay3 - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Gate Delay3", strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(gateDelay3)); - dataset.write(c, strdatatype); - } - // Gates - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = - group->createDataSet("Gates", PredType::STD_U32LE, dataspace); - dataset.write(&gates, PredType::STD_U32LE); - } - // Threshold Energies - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 1024); - DataSet dataset = group->createDataSet("Threshold Energies", - strdatatype, dataspace); - sls::strcpy_safe(c, sls::ToString(thresholdAllEnergyeV)); - dataset.write(c, strdatatype); - } - }; +void MasterAttributes::WriteMythen3HDF5Attributes(H5File *fd, Group *group) { + MasterAttributes::WriteHDF5DynamicRange(fd, group); + MasterAttributes::WriteHDF5TenGiga(fd, group); + MasterAttributes::WriteHDF5Period(fd, group); + MasterAttributes::WriteHDF5CounterMask(fd, group); + MasterAttributes::WriteHDF5ExptimeArray(fd, group); + MasterAttributes::WriteHDF5GateDelayArray(fd, group); + MasterAttributes::WriteHDF5Gates(fd, group); + MasterAttributes::WriteHDF5ThresholdEnergies(fd, group); +} #endif - void Gotthard2MasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { - std::ostringstream oss; - oss << MasterAttributes::GetBinaryMasterAttributes() - << "Exptime : " << sls::ToString(exptime) << '\n' - << "Period : " << sls::ToString(period) << '\n' - << "Burst Mode : " << sls::ToString(burstMode) - << '\n'; - std::string message = oss.str(); - MasterAttributes::WriteBinaryAttributes(fd, message); - }; +void MasterAttributes::GetGotthard2BinaryAttributes( + rapidjson::PrettyWriter *w) { + w->Key("Exptime"); + w->String(sls::ToString(exptime).c_str()); + w->Key("Period"); + w->String(sls::ToString(period).c_str()); + w->Key("Burst Mode"); + w->String(sls::ToString(burstMode).c_str()); +} #ifdef HDF5C - void Gotthard2MasterAttributes::WriteMasterHDF5Attributes(H5File *fd, Group *group) { - MasterAttributes::WriteHDF5Attributes(fd, group); - MasterAttributes::WriteHDF5Exptime(fd, group); - MasterAttributes::WriteHDF5Period(fd, group); - // burst mode - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - StrType strdatatype(PredType::C_S1, 256); - DataSet dataset = - group->createDataSet("Burst Mode", strdatatype, dataspace); - char c[1024]; - memset(c, 0, sizeof(c)); - sls::strcpy_safe(c, sls::ToString(burstMode)); - dataset.write(c, strdatatype); - } - }; +void MasterAttributes::WriteGotthard2HDF5Attributes(H5File *fd, Group *group) { + MasterAttributes::WriteHDF5Exptime(fd, group); + MasterAttributes::WriteHDF5Period(fd, group); + MasterAttributes::WriteHDF5BurstMode(fd, group); +} #endif - void MoenchMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { - std::ostringstream oss; - oss << MasterAttributes::GetBinaryMasterAttributes() - << "Exptime : " << sls::ToString(exptime) << '\n' - << "Period : " << sls::ToString(period) << '\n' - << "Ten Giga : " << tenGiga << '\n' - << "ADC Mask : " << sls::ToStringHex(adcmask) - << '\n' - << "Analog Samples : " << analogSamples << '\n'; - std::string message = oss.str(); - MasterAttributes::WriteBinaryAttributes(fd, message); - }; +void MasterAttributes::GetMoenchBinaryAttributes( + rapidjson::PrettyWriter *w) { + w->Key("Exptime"); + w->String(sls::ToString(exptime).c_str()); + w->Key("Period"); + w->String(sls::ToString(period).c_str()); + w->Key("Ten Giga"); + w->Uint(tenGiga); + w->Key("ADC Mask"); + w->String(sls::ToStringHex(adcmask).c_str()); + w->Key("Analog Samples"); + w->Uint(analogSamples); +} #ifdef HDF5C - void MoenchMasterAttributes::WriteMasterHDF5Attributes(H5File *fd, Group *group) { - MasterAttributes::WriteHDF5Attributes(fd, group); - MasterAttributes::WriteHDF5Exptime(fd, group); - MasterAttributes::WriteHDF5Period(fd, group); - MasterAttributes::WriteHDF5TenGiga(fd, group); - // ADC Mask - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "ADC Mask", PredType::NATIVE_INT, dataspace); - dataset.write(&adcmask, PredType::NATIVE_INT); - } - // Analog Samples - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Analog Samples", PredType::NATIVE_INT, dataspace); - dataset.write(&analogSamples, PredType::NATIVE_INT); - } - }; +void MasterAttributes::WriteMoenchHDF5Attributes(H5File *fd, Group *group) { + MasterAttributes::WriteHDF5Exptime(fd, group); + MasterAttributes::WriteHDF5Period(fd, group); + MasterAttributes::WriteHDF5TenGiga(fd, group); + MasterAttributes::WriteHDF5AdcMask(fd, group); + MasterAttributes::WriteHDF5AnalogSamples(fd, group); +} #endif - void CtbMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { - std::ostringstream oss; - oss << MasterAttributes::GetBinaryMasterAttributes() - << "Exptime : " << sls::ToString(exptime) << '\n' - << "Period : " << sls::ToString(period) << '\n' - << "Ten Giga : " << tenGiga << '\n' - << "ADC Mask : " << sls::ToStringHex(adcmask) - << '\n' - << "Analog Flag : " << analog << '\n' - << "Analog Samples : " << analogSamples << '\n' - << "Digital Flag : " << digital << '\n' - << "Digital Samples : " << digitalSamples << '\n' - << "Dbit Offset : " << dbitoffset << '\n' - << "Dbit Bitset : " << dbitlist << '\n'; - std::string message = oss.str(); - MasterAttributes::WriteBinaryAttributes(fd, message); - }; +void MasterAttributes::GetCtbBinaryAttributes( + rapidjson::PrettyWriter *w) { + w->Key("Exptime"); + w->String(sls::ToString(exptime).c_str()); + w->Key("Period"); + w->String(sls::ToString(period).c_str()); + w->Key("Ten Giga"); + w->Uint(tenGiga); + w->Key("ADC Mask"); + w->String(sls::ToStringHex(adcmask).c_str()); + w->Key("Analog Flag"); + w->Uint(analog); + w->Key("Analog Samples"); + w->Uint(analogSamples); + w->Key("Digital Flag"); + w->Uint(digital); + w->Key("Digital Samples"); + w->Uint(digitalSamples); + w->Key("Dbit Offset"); + w->Uint(dbitoffset); + w->Key("Dbit Bitset"); + w->Uint64(dbitlist); +} #ifdef HDF5C - void CtbMasterAttributes::WriteMasterHDF5Attributes(H5File *fd, Group *group) { - MasterAttributes::WriteHDF5Attributes(fd, group); - MasterAttributes::WriteHDF5Exptime(fd, group); - MasterAttributes::WriteHDF5Period(fd, group); - MasterAttributes::WriteHDF5TenGiga(fd, group); - // ADC Mask - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "ADC mMsk", PredType::NATIVE_INT, dataspace); - dataset.write(&adcmask, PredType::NATIVE_INT); - } - // Analog Flag - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Analog Flag", PredType::NATIVE_INT, dataspace); - dataset.write(&analog, PredType::NATIVE_INT); - } - // Analog Samples - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Analog Samples", PredType::NATIVE_INT, dataspace); - dataset.write(&analogSamples, PredType::NATIVE_INT); - } - // Digital Flag - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Digital Flag", PredType::NATIVE_INT, dataspace); - dataset.write(&digital, PredType::NATIVE_INT); - } - // Digital Samples - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Digital Samples", PredType::NATIVE_INT, dataspace); - dataset.write(&digitalSamples, PredType::NATIVE_INT); - } - // Dbit Offset - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Dbit Offset", PredType::NATIVE_INT, dataspace); - dataset.write(&dbitoffset, PredType::NATIVE_INT); - } - // Dbit List - { - DataSpace dataspace = DataSpace(H5S_SCALAR); - DataSet dataset = group->createDataSet( - "Dbit Bitset List", PredType::STD_U64LE, dataspace); - dataset.write(&dbitlist, PredType::STD_U64LE); - } - }; +void MasterAttributes::WriteCtbHDF5Attributes(H5File *fd, Group *group) { + MasterAttributes::WriteHDF5Exptime(fd, group); + MasterAttributes::WriteHDF5Period(fd, group); + MasterAttributes::WriteHDF5TenGiga(fd, group); + MasterAttributes::WriteHDF5AdcMask(fd, group); + MasterAttributes::WriteHDF5AnalogFlag(fd, group); + MasterAttributes::WriteHDF5AnalogSamples(fd, group); + MasterAttributes::WriteHDF5DigitalFlag(fd, group); + MasterAttributes::WriteHDF5DigitalSamples(fd, group); + MasterAttributes::WriteHDF5DbitOffset(fd, group); + MasterAttributes::WriteHDF5DbitList(fd, group); +} #endif diff --git a/slsReceiverSoftware/src/MasterAttributes.h b/slsReceiverSoftware/src/MasterAttributes.h index 945ac7756..34479bfb0 100644 --- a/slsReceiverSoftware/src/MasterAttributes.h +++ b/slsReceiverSoftware/src/MasterAttributes.h @@ -7,6 +7,9 @@ #include "sls/logger.h" #include "sls/sls_detector_defs.h" +#include +#include + #ifdef HDF5C #include "H5Cpp.h" #ifndef H5_NO_NAMESPACE @@ -53,94 +56,92 @@ class MasterAttributes { uint64_t dbitlist{0}; slsDetectorDefs::ROI roi{}; uint32_t counterMask{0}; - ns exptime1{0}; - ns exptime2{0}; - ns exptime3{0}; - ns gateDelay1{0}; - ns gateDelay2{0}; - ns gateDelay3{0}; + std::array exptimeArray{}; + std::array gateDelayArray{}; uint32_t gates; std::map additionalJsonHeader; - - // Final Attributes (after acquisition) uint64_t framesInFile{0}; MasterAttributes() = default; - virtual ~MasterAttributes() = default; - virtual void WriteMasterBinaryAttributes(FILE *fd); - std::string GetBinaryMasterAttributes(); - void WriteBinaryAttributes(FILE *fd, std::string message); - void WriteFinalBinaryAttributes(FILE *fd); + ~MasterAttributes() = default; + + void GetBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - virtual void WriteMasterHDF5Attributes(H5File *fd, Group *group); void WriteHDF5Attributes(H5File *fd, Group *group); +#endif + + void + GetCommonBinaryAttributes(rapidjson::PrettyWriter *w); + void + GetFinalBinaryAttributes(rapidjson::PrettyWriter *w); +#ifdef HDF5C + void WriteCommonHDF5Attributes(H5File *fd, Group *group); void WriteFinalHDF5Attributes(H5File *fd, Group *group); void WriteHDF5Exptime(H5File *fd, Group *group); void WriteHDF5Period(H5File *fd, Group *group); void WriteHDF5DynamicRange(H5File *fd, Group *group); void WriteHDF5TenGiga(H5File *fd, Group *group); + void WriteHDF5ROI(H5File *fd, Group *group); + void WriteHDF5NumUDPInterfaces(H5File *fd, Group *group); + void WriteHDF5ReadNRows(H5File *fd, Group *group); + void WriteHDF5ThresholdEnergy(H5File *fd, Group *group); + void WriteHDF5ThresholdEnergies(H5File *fd, Group *group); + void WriteHDF5SubExpTime(H5File *fd, Group *group); + void WriteHDF5SubPeriod(H5File *fd, Group *group); + void WriteHDF5SubQuad(H5File *fd, Group *group); + void WriteHDF5RateCorrections(H5File *fd, Group *group); + void WriteHDF5CounterMask(H5File *fd, Group *group); + void WriteHDF5ExptimeArray(H5File *fd, Group *group); + void WriteHDF5GateDelayArray(H5File *fd, Group *group); + void WriteHDF5Gates(H5File *fd, Group *group); + void WriteHDF5BurstMode(H5File *fd, Group *group); + void WriteHDF5AdcMask(H5File *fd, Group *group); + void WriteHDF5AnalogFlag(H5File *fd, Group *group); + void WriteHDF5AnalogSamples(H5File *fd, Group *group); + void WriteHDF5DigitalFlag(H5File *fd, Group *group); + void WriteHDF5DigitalSamples(H5File *fd, Group *group); + void WriteHDF5DbitOffset(H5File *fd, Group *group); + void WriteHDF5DbitList(H5File *fd, Group *group); #endif -}; -class GotthardMasterAttributes : public MasterAttributes { - public: - GotthardMasterAttributes() = default; - void WriteMasterBinaryAttributes(FILE *fd) override; + void + GetGotthardBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; + void WriteGotthardHDF5Attributes(H5File *fd, Group *group); #endif -}; -class JungfrauMasterAttributes : public MasterAttributes { - public: - JungfrauMasterAttributes() = default; - void WriteMasterBinaryAttributes(FILE *fd) override; + void + GetJungfrauBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; + void WriteJungfrauHDF5Attributes(H5File *fd, Group *group); #endif -}; -class EigerMasterAttributes : public MasterAttributes { - public: - EigerMasterAttributes() = default; - void WriteMasterBinaryAttributes(FILE *fd) override; + void + GetEigerBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; + void WriteEigerHDF5Attributes(H5File *fd, Group *group); #endif -}; -class Mythen3MasterAttributes : public MasterAttributes { - public: - Mythen3MasterAttributes() = default; - void WriteMasterBinaryAttributes(FILE *fd) override; + void + GetMythen3BinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; + void WriteMythen3HDF5Attributes(H5File *fd, Group *group); #endif -}; -class Gotthard2MasterAttributes : public MasterAttributes { - public: - Gotthard2MasterAttributes() = default; - void WriteMasterBinaryAttributes(FILE *fd) override; + void + GetGotthard2BinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; + void WriteGotthard2HDF5Attributes(H5File *fd, Group *group); #endif -}; -class MoenchMasterAttributes : public MasterAttributes { - public: - MoenchMasterAttributes() = default; - void WriteMasterBinaryAttributes(FILE *fd) override; + void + GetMoenchBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; + void WriteMoenchHDF5Attributes(H5File *fd, Group *group); #endif -}; -class CtbMasterAttributes : public MasterAttributes { - public: - CtbMasterAttributes() = default; - void WriteMasterBinaryAttributes(FILE *fd) override; + void GetCtbBinaryAttributes(rapidjson::PrettyWriter *w); #ifdef HDF5C - void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; + void WriteCtbHDF5Attributes(H5File *fd, Group *group); #endif }; diff --git a/slsReceiverSoftware/src/MasterFileUtility.cpp b/slsReceiverSoftware/src/MasterFileUtility.cpp new file mode 100644 index 000000000..506ba7b83 --- /dev/null +++ b/slsReceiverSoftware/src/MasterFileUtility.cpp @@ -0,0 +1,351 @@ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2021 Contributors to the SLS Detector Package +#include "MasterFileUtility.h" +#include "sls/container_utils.h" + +#include + +namespace masterFileUtility { + +std::string CreateMasterBinaryFile(const std::string &filePath, + const std::string &fileNamePrefix, + const uint64_t fileIndex, + const bool overWriteEnable, + const bool silentMode, + MasterAttributes *attr) { + std::ostringstream os; + os << filePath << "/" << fileNamePrefix << "_master" + << "_" << fileIndex << ".json"; + std::string fileName = os.str(); + + std::string mode = "w"; + if (!overWriteEnable) + mode = "wx"; + FILE *fd = fopen(fileName.c_str(), mode.c_str()); + if(!fd) { + throw sls::RuntimeError("Could not create/overwrite binary master file " + + fileName); + } + + rapidjson::StringBuffer s; + rapidjson::PrettyWriter writer(s); + attr->GetBinaryAttributes(&writer); + if (fwrite(s.GetString(), 1, strlen(s.GetString()), fd) != + strlen(s.GetString())) { + throw sls::RuntimeError( + "Master binary file incorrect number of bytes written to file"); + } + if (fd) { + fclose(fd); + } + if (!silentMode) { + LOG(logINFO) << "Master File: " << fileName; + } + return fileName; +} + +#ifdef HDF5C +void LinkHDF5FileInMaster(const std::string &masterFileName, + const std::string &dataFilename, + const std::string &dataSetname, + const std::vector parameterNames, + const bool silentMode, std::mutex *hdf5LibMutex) { + + std::lock_guard lock(*hdf5LibMutex); + std::unique_ptr fd{nullptr}; + try { + Exception::dontPrint(); // to handle errors + + FileAccPropList flist; + flist.setFcloseDegree(H5F_CLOSE_STRONG); + + // open master file + H5File masterfd(masterFileName.c_str(), H5F_ACC_RDWR, + FileCreatPropList::DEFAULT, flist); + + // open data file + fd = sls::make_unique(dataFilename.c_str(), H5F_ACC_RDONLY, + FileCreatPropList::DEFAULT, flist); + + // create link for data dataset + DataSet dset = fd->openDataSet(dataSetname.c_str()); + std::string linkname = std::string("/entry/data/") + dataSetname; + if (H5Lcreate_external(dataFilename.c_str(), dataSetname.c_str(), + masterfd.getLocId(), linkname.c_str(), + H5P_DEFAULT, H5P_DEFAULT) < 0) { + throw sls::RuntimeError( + "Could not create link to data dataset in master"); + } + + // create link for parameter datasets + for (unsigned int i = 0; i < parameterNames.size(); ++i) { + DataSet pDset = fd->openDataSet(parameterNames[i].c_str()); + linkname = std::string("/entry/data/") + parameterNames[i]; + if (H5Lcreate_external(dataFilename.c_str(), + parameterNames[i].c_str(), + masterfd.getLocId(), linkname.c_str(), + H5P_DEFAULT, H5P_DEFAULT) < 0) { + throw sls::RuntimeError( + "Could not create link to parameter dataset in master"); + } + } + fd->close(); + masterfd.close(); + } catch (const Exception &error) { + error.printErrorStack(); + if (fd != nullptr) + fd->close(); + throw sls::RuntimeError("Could not link in master hdf5 file"); + } + if (!silentMode) { + LOG(logINFO) << "Linked in Master File: " << dataFilename; + } +} + +std::string CreateMasterHDF5File(const std::string &filePath, + const std::string &fileNamePrefix, + const uint64_t fileIndex, + const bool overWriteEnable, + const bool silentMode, MasterAttributes *attr, + std::mutex *hdf5LibMutex) { + + std::ostringstream os; + os << filePath << "/" << fileNamePrefix << "_master" + << "_" << fileIndex << ".h5"; + std::string fileName = os.str(); + + std::lock_guard lock(*hdf5LibMutex); + + std::unique_ptr fd{nullptr}; + try { + Exception::dontPrint(); // to handle errors + + FileAccPropList flist; + flist.setFcloseDegree(H5F_CLOSE_STRONG); + + unsigned int createFlags = H5F_ACC_EXCL; + if (overWriteEnable) { + createFlags = H5F_ACC_TRUNC; + } + fd = sls::make_unique(fileName.c_str(), createFlags, + FileCreatPropList::DEFAULT, flist); + + // attributes - version + double dValue = HDF5_WRITER_VERSION; + DataSpace dataspace_attr = DataSpace(H5S_SCALAR); + Attribute attribute = fd->createAttribute( + "version", PredType::NATIVE_DOUBLE, dataspace_attr); + attribute.write(PredType::NATIVE_DOUBLE, &dValue); + + // Create a group in the file + Group group1(fd->createGroup("entry")); + Group group2(group1.createGroup("data")); + Group group3(group1.createGroup("instrument")); + Group group4(group3.createGroup("beam")); + Group group5(group3.createGroup("detector")); + Group group6(group1.createGroup("sample")); + + attr->WriteHDF5Attributes(fd.get(), &group5); + fd->close(); + } catch (const Exception &error) { + error.printErrorStack(); + if (fd != nullptr) + fd->close(); + throw sls::RuntimeError( + "Could not create/overwrite master HDF5 handles"); + } + if (!silentMode) { + LOG(logINFO) << "Master File: " << fileName; + } + return fileName; +} + +std::array CreateVirtualHDF5File( + const std::string &filePath, const std::string &fileNamePrefix, + const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, + const int modulePos, const int numUnitsPerReadout, + const uint32_t maxFramesPerFile, const uint64_t numImages, + const uint32_t nPixelsX, const uint32_t nPixelsY, + const uint32_t dynamicRange, const uint64_t numImagesCaught, + const int numModX, const int numModY, const DataType dataType, + const std::vector parameterNames, + const std::vector parameterDataTypes, std::mutex *hdf5LibMutex, + bool gotthard25um) { + + // virtual file name + std::ostringstream osfn; + osfn << filePath << "/" << fileNamePrefix << "_virtual" + << "_" << fileIndex << ".h5"; + std::string fileName = osfn.str(); + + std::string dataSetName = "data"; + + unsigned int paraSize = parameterNames.size(); + uint64_t numModZ = numModX; + uint32_t nDimy = nPixelsY; + uint32_t nDimz = ((dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX); + + std::lock_guard lock(*hdf5LibMutex); + + std::unique_ptr fd{nullptr}; + try { + Exception::dontPrint(); // to handle errors + + // file + FileAccPropList fapl; + fapl.setFcloseDegree(H5F_CLOSE_STRONG); + if (!overWriteEnable) + fd = sls::make_unique(fileName.c_str(), H5F_ACC_EXCL, + FileCreatPropList::DEFAULT, fapl); + else + fd = sls::make_unique(fileName.c_str(), H5F_ACC_TRUNC, + FileCreatPropList::DEFAULT, fapl); + + // attributes - version + double dValue = HDF5_WRITER_VERSION; + DataSpace dataspace_attr = DataSpace(H5S_SCALAR); + Attribute attribute = fd->createAttribute( + "version", PredType::NATIVE_DOUBLE, dataspace_attr); + attribute.write(PredType::NATIVE_DOUBLE, &dValue); + + // virtual dataspace + hsize_t vdsDims[3] = {numImagesCaught, numModY * nDimy, + numModZ * nDimz}; + DataSpace vdsDataSpace(3, vdsDims, nullptr); + hsize_t vdsDimsPara[2] = {numImagesCaught, + (unsigned int)numModY * numModZ}; + DataSpace vdsDataSpacePara(2, vdsDimsPara, nullptr); + + // property list (fill value and datatype) + int fill_value = -1; + DSetCreatPropList plist; + plist.setFillValue(dataType, &fill_value); + + // property list for parameters (datatype) + std::vector plistPara(paraSize); + + // hyperslab (files) + int numFiles = numImagesCaught / maxFramesPerFile; + if (numImagesCaught % maxFramesPerFile) + ++numFiles; + uint64_t framesSaved = 0; + for (int iFile = 0; iFile < numFiles; ++iFile) { + + uint64_t nDimx = + ((numImagesCaught - framesSaved) > maxFramesPerFile) + ? maxFramesPerFile + : (numImagesCaught - framesSaved); + + hsize_t startLocation[3] = {framesSaved, 0, 0}; + hsize_t strideBetweenBlocks[3] = {1, 1, 1}; + hsize_t numBlocks[3] = {nDimx, nDimy, nDimz}; + hsize_t blockSize[3] = {1, 1, 1}; + + hsize_t startLocationPara[2] = {framesSaved, 0}; + hsize_t strideBetweenBlocksPara[3] = {1, 1}; + hsize_t numBlocksPara[2] = {1, 1}; + hsize_t blockSizePara[3] = {nDimx, 1}; + + // interleaving for g2 + if (gotthard25um) { + strideBetweenBlocks[2] = 2; + } + + for (unsigned int iReadout = 0; iReadout < numModY * numModZ; + ++iReadout) { + + // interleaving for g2 (startLocation is 0 and 1) + if (gotthard25um) { + startLocation[2] = iReadout; + } + + vdsDataSpace.selectHyperslab(H5S_SELECT_SET, numBlocks, + startLocation, strideBetweenBlocks, + blockSize); + + vdsDataSpacePara.selectHyperslab( + H5S_SELECT_SET, numBlocksPara, startLocationPara, + strideBetweenBlocksPara, blockSizePara); + + // source file name + std::ostringstream os; + os << filePath << "/" << fileNamePrefix << "_d" + << (modulePos * numUnitsPerReadout + iReadout) << "_f" + << iFile << '_' << fileIndex << ".h5"; + std::string srcFileName = os.str(); + LOG(logDEBUG1) << srcFileName; + + // find relative path + std::string relative_srcFileName = srcFileName; + { + size_t p = srcFileName.rfind('/', srcFileName.length()); + if (p != std::string::npos) + relative_srcFileName = (srcFileName.substr( + p + 1, srcFileName.length() - p)); + } + + // source dataset name + std::ostringstream osfn; + osfn << "/data"; + if (numImages > 1) + osfn << "_f" << std::setfill('0') << std::setw(12) << iFile; + std::string srcDatasetName = osfn.str(); + + // source dataspace + hsize_t srcDims[3] = {nDimx, nDimy, nDimz}; + hsize_t srcDimsMax[3] = {H5S_UNLIMITED, nDimy, nDimz}; + DataSpace srcDataSpace(3, srcDims, srcDimsMax); + hsize_t srcDimsPara[1] = {nDimx}; + hsize_t srcDimsMaxPara[1] = {H5S_UNLIMITED}; + DataSpace srcDataSpacePara(1, srcDimsPara, srcDimsMaxPara); + + // mapping of property list + plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(), + srcDatasetName.c_str(), srcDataSpace); + for (unsigned int p = 0; p < paraSize; ++p) { + plistPara[p].setVirtual( + vdsDataSpacePara, relative_srcFileName.c_str(), + parameterNames[p].c_str(), srcDataSpacePara); + } + + // H5Sclose(srcDataspace); + // H5Sclose(srcDataspace_para); + + if (!gotthard25um) { + startLocation[2] += nDimz; + if (startLocation[2] >= (numModZ * nDimz)) { + startLocation[2] = 0; + startLocation[1] += nDimy; + } + } + startLocationPara[1]++; + } + framesSaved += nDimx; + } + // datasets + DataSet vdsDataSet(fd->createDataSet(dataSetName.c_str(), dataType, + vdsDataSpace, plist)); + + for (unsigned int p = 0; p < paraSize; ++p) { + DataSet vdsDataSetPara(fd->createDataSet( + parameterNames[p].c_str(), parameterDataTypes[p], + vdsDataSpacePara, plistPara[p])); + } + + fd->close(); + } catch (const Exception &error) { + error.printErrorStack(); + if (fd) { + fd->close(); + } + throw sls::RuntimeError( + "Could not create/overwrite virtual HDF5 handles"); + } + if (!silentMode) { + LOG(logINFO) << "Virtual File: " << fileName; + } + return std::array{fileName, dataSetName}; +} +#endif + +} // namespace masterFileUtility diff --git a/slsReceiverSoftware/src/MasterFileUtility.h b/slsReceiverSoftware/src/MasterFileUtility.h new file mode 100644 index 000000000..ed90cc52e --- /dev/null +++ b/slsReceiverSoftware/src/MasterFileUtility.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2021 Contributors to the SLS Detector Package +#pragma once + +#include "MasterAttributes.h" + +#ifdef HDF5C +#include "H5Cpp.h" +#include +#ifndef H5_NO_NAMESPACE +using namespace H5; +#endif +#endif + +namespace masterFileUtility { + +std::string CreateMasterBinaryFile(const std::string &filePath, + const std::string &fileNamePrefix, + const uint64_t fileIndex, + const bool overWriteEnable, + const bool silentMode, + MasterAttributes *attr); + +#ifdef HDF5C +void LinkHDF5FileInMaster(const std::string &masterFileName, + const std::string &dataFilename, + const std::string &dataSetname, + const std::vector parameterNames, + const bool silentMode, std::mutex *hdf5LibMutex); + +std::string CreateMasterHDF5File(const std::string &filePath, + const std::string &fileNamePrefix, + const uint64_t fileIndex, + const bool overWriteEnable, + const bool silentMode, MasterAttributes *attr, + std::mutex *hdf5LibMutex); + +std::array CreateVirtualHDF5File( + const std::string &filePath, const std::string &fileNamePrefix, + const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, + const int modulePos, const int numUnitsPerReadout, + const uint32_t maxFramesPerFile, const uint64_t numImages, + const uint32_t nPixelsX, const uint32_t nPixelsY, + const uint32_t dynamicRange, const uint64_t numImagesCaught, + const int numModX, const int numModY, const DataType dataType, + const std::vector parameterNames, + const std::vector parameterDataTypes, std::mutex *hdf5LibMutex, + bool gotthard25um); +#endif +} // namespace masterFileUtility \ No newline at end of file diff --git a/slsReceiverSoftware/src/receiver_defs.h b/slsReceiverSoftware/src/receiver_defs.h index 53cc31d2f..c2d85dceb 100644 --- a/slsReceiverSoftware/src/receiver_defs.h +++ b/slsReceiverSoftware/src/receiver_defs.h @@ -18,7 +18,7 @@ // versions #define HDF5_WRITER_VERSION (6.4) // 1 decimal places -#define BINARY_WRITER_VERSION (6.4) // 1 decimal places +#define BINARY_WRITER_VERSION (7.0) // 1 decimal places #define MAX_FRAMES_PER_FILE 20000 #define SHORT_MAX_FRAMES_PER_FILE 100000