wip, binary file refactored for stringbuffer, hdf5 mid way, masterattributes to be de (inherited) :)

This commit is contained in:
maliakal_d 2022-03-28 17:43:58 +02:00
parent 9a969c1549
commit f2be834d55
12 changed files with 362 additions and 445 deletions

View File

@ -3,7 +3,7 @@
#include "BinaryMasterFile.h" #include "BinaryMasterFile.h"
#include "MasterAttributes.h" #include "MasterAttributes.h"
void BinaryMasterFile::CreateMasterFile(const std::string filePath, std::string BinaryMasterFile::CreateMasterFile(const std::string filePath,
const std::string fileNamePrefix, const std::string fileNamePrefix,
const uint64_t fileIndex, const uint64_t fileIndex,
const bool overWriteEnable, const bool overWriteEnable,
@ -28,11 +28,31 @@ void BinaryMasterFile::CreateMasterFile(const std::string filePath,
throw sls::RuntimeError( throw sls::RuntimeError(
"Could not create/overwrite binary master file " + fileName); "Could not create/overwrite binary master file " + fileName);
} }
if (!silentMode) {
LOG(logINFO) << "Master File: " << fileName; std::string message = BinaryMasterFile::GetMasterAttributes(attr);
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");
} }
attr->WriteMasterBinaryAttributes(fd);
if (fd) { if (fd) {
fclose(fd); fclose(fd);
} }
if (!silentMode) {
LOG(logINFO) << "Master File: " << fileName;
}
return fileName;
}
std::string BinaryMasterFile::GetMasterAttributes(MasterAttributes *attr) {
rapidjson::StringBuffer s;
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
writer.StartObject();
attr->GetCommonBinaryAttributes(&writer);
attr->GetSpecificBinaryAttributes(&writer);
attr->GetFinalBinaryAttributes(&writer);
writer.EndObject();
return s.GetString();
} }

View File

@ -8,9 +8,13 @@
class BinaryMasterFile : private virtual slsDetectorDefs { class BinaryMasterFile : private virtual slsDetectorDefs {
public: public:
static void CreateMasterFile(const std::string filePath, static std::string CreateMasterFile(const std::string filePath,
const std::string fileNamePrefix, const std::string fileNamePrefix,
const uint64_t fileIndex, const uint64_t fileIndex,
const bool overWriteEnable, const bool overWriteEnable,
const bool silentMode, MasterAttributes *attr); const bool silentMode,
MasterAttributes *attr);
private:
static std::string GetMasterAttributes(MasterAttributes *attr);
}; };

View File

@ -94,10 +94,6 @@ void DataProcessor::DeleteFiles() {
delete dataFile_; delete dataFile_;
dataFile_ = nullptr; dataFile_ = nullptr;
} }
/* if (masterFile_) {
delete masterFile_;
masterFile_ = nullptr;
}*/
#ifdef HDF5C #ifdef HDF5C
if (virtualFile_) { if (virtualFile_) {
delete virtualFile_; delete virtualFile_;
@ -107,13 +103,13 @@ void DataProcessor::DeleteFiles() {
} }
void DataProcessor::SetupFileWriter(const bool filewriteEnable, void DataProcessor::SetupFileWriter(const bool filewriteEnable,
const fileFormat fileFormatType, const fileFormat fileFormatType,
std::mutex *hdf5Lib) { std::mutex *hdf5LibMutex) {
DeleteFiles(); DeleteFiles();
if (filewriteEnable) { if (filewriteEnable) {
switch (fileFormatType) { switch (fileFormatType) {
#ifdef HDF5C #ifdef HDF5C
case HDF5: case HDF5:
dataFile_ = new HDF5DataFile(index, hdf5Lib); dataFile_ = new HDF5DataFile(index, hdf5LibMutex);
break; break;
#endif #endif
case BINARY: case BINARY:
@ -178,7 +174,7 @@ void DataProcessor::CreateVirtualFile(
const int modulePos, const int numUnitsPerReadout, const int modulePos, const int numUnitsPerReadout,
const uint32_t maxFramesPerFile, const uint64_t numImages, const uint32_t maxFramesPerFile, const uint64_t numImages,
const uint32_t dynamicRange, const int numModX, const int numModY, const uint32_t dynamicRange, const int numModX, const int numModY,
std::mutex *hdf5Lib) { std::mutex *hdf5LibMutex) {
if (virtualFile_) { if (virtualFile_) {
delete virtualFile_; delete virtualFile_;
@ -186,7 +182,7 @@ void DataProcessor::CreateVirtualFile(
bool gotthard25um = bool gotthard25um =
((detectorType_ == GOTTHARD || detectorType_ == GOTTHARD2) && ((detectorType_ == GOTTHARD || detectorType_ == GOTTHARD2) &&
(numModX * numModY) == 2); (numModX * numModY) == 2);
virtualFile_ = new HDF5VirtualFile(hdf5Lib, gotthard25um); virtualFile_ = new HDF5VirtualFile(hdf5LibMutex, gotthard25um);
// maxframesperfile = 0 for infinite files // maxframesperfile = 0 for infinite files
uint32_t framesPerFile = uint32_t framesPerFile =
@ -204,7 +200,9 @@ void DataProcessor::CreateVirtualFile(
dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes()); dataFile_->GetParameterNames(), dataFile_->GetParameterDataTypes());
} }
void DataProcessor::LinkDataInMasterFile(const bool silentMode) { void DataProcessor::LinkDataInMasterFile(const string &masterFileName,
const bool silentMode,
std::mutex *hdf5LibMutex) {
std::string fname, datasetName; std::string fname, datasetName;
if (virtualFile_) { if (virtualFile_) {
auto res = virtualFile_->GetFileAndDatasetName(); auto res = virtualFile_->GetFileAndDatasetName();
@ -216,15 +214,17 @@ void DataProcessor::LinkDataInMasterFile(const bool silentMode) {
datasetName = res[1]; datasetName = res[1];
} }
// link in master // link in master
masterFile_->LinkDataFile(fname, datasetName, HDF5MasterFile::LinkDataFile(masterFileName, fname, datasetName,
dataFile_->GetParameterNames(), silentMode); dataFile_->GetParameterNames(), silentMode,
&hdf5LibMutex);
} }
#endif #endif
void DataProcessor::CreateMasterFile( std::string DataProcessor::CreateMasterFile(
const std::string filePath, const std::string fileNamePrefix, const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, bool silentMode, const uint64_t fileIndex, const bool overWriteEnable, bool silentMode,
const fileFormat fileFormatType, MasterAttributes *attr) { const fileFormat fileFormatType, MasterAttributes *attr,
std::mutex *hdf5LibMutex) {
attr->framesInFile = numFramesCaught_; attr->framesInFile = numFramesCaught_;
@ -232,13 +232,14 @@ void DataProcessor::CreateMasterFile(
switch (fileFormatType) { switch (fileFormatType) {
#ifdef HDF5C #ifdef HDF5C
case HDF5: case HDF5:
masterFile = sls::make_unique<HDF5MasterFile>(hdf5Lib); return HDF5MasterFile::CreateMasterFile(filePath, fileNamePrefix,
break; fileIndex, overWriteEnable,
silentMode, attr, hdf5LibMutex);
#endif #endif
case BINARY: case BINARY:
BinaryMasterFile::CreateMasterFile(filePath, fileNamePrefix, fileIndex, return BinaryMasterFile::CreateMasterFile(filePath, fileNamePrefix,
overWriteEnable, silentMode, attr); fileIndex, overWriteEnable,
break; silentMode, attr);
default: default:
throw sls::RuntimeError("Unknown file format (compile with hdf5 flags"); throw sls::RuntimeError("Unknown file format (compile with hdf5 flags");
} }

View File

@ -45,7 +45,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
void CloseFiles(); void CloseFiles();
void DeleteFiles(); void DeleteFiles();
void SetupFileWriter(const bool filewriteEnable, void SetupFileWriter(const bool filewriteEnable,
const fileFormat fileFormatType, std::mutex *hdf5Lib); const fileFormat fileFormatType,
std::mutex *hdf5LibMutex);
void CreateFirstFiles(const std::string filePath, void CreateFirstFiles(const std::string filePath,
const std::string fileNamePrefix, const std::string fileNamePrefix,
@ -58,22 +59,26 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
const bool detectorDataStream); const bool detectorDataStream);
#ifdef HDF5C #ifdef HDF5C
uint32_t GetFilesInAcquisition() const; uint32_t GetFilesInAcquisition() const;
void CreateVirtualFile(const std::string filePath, void CreateVirtualFile(const std::string &filePath,
const std::string fileNamePrefix, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode, const int modulePos, const bool silentMode, const int modulePos,
const int numUnitsPerReadout, const int numUnitsPerReadout,
const uint32_t maxFramesPerFile, const uint32_t maxFramesPerFile,
const uint64_t numImages, const uint64_t numImages,
const uint32_t dynamicRange, const int numModX, const uint32_t dynamicRange, const int numModX,
const int numModY, std::mutex *hdf5Lib); const int numModY, std::mutex *hdf5LibMutex);
void LinkDataInMasterFile(const bool silentMode); void LinkDataInMasterFile(const string &masterFileName,
const bool silentMode, std::mutex *hdf5LibMutex);
#endif #endif
void CreateMasterFile(const std::string filePath,
const std::string fileNamePrefix, std::string CreateMasterFile(const std::string &filePath,
const uint64_t fileIndex, const bool overWriteEnable, const std::string &fileNamePrefix,
bool silentMode, const fileFormat fileFormatType, const uint64_t fileIndex,
MasterAttributes *attr); const bool overWriteEnable, bool silentMode,
const fileFormat fileFormatType,
MasterAttributes *attr,
std::mutex *hdf5LibMutex);
/** /**
* Call back for raw data * Call back for raw data
* args to raw data ready callback are * args to raw data ready callback are

View File

@ -3,30 +3,12 @@
#include "HDF5MasterFile.h" #include "HDF5MasterFile.h"
#include "MasterAttributes.h" #include "MasterAttributes.h"
HDF5MasterFile::HDF5MasterFile(std::mutex *hdf5Lib) void HDF5MasterFile::LinkDataFile(const std::string &masterFileName,
: File(HDF5), hdf5Lib_(hdf5Lib) {} const std::string &dataFilename,
const std::string &dataSetname,
HDF5MasterFile::~HDF5MasterFile() { CloseFile(); }
void HDF5MasterFile::CloseFile() {
std::lock_guard<std::mutex> 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<std::string> parameterNames, const std::vector<std::string> parameterNames,
const bool silentMode) { const bool silentMode,
std::mutex *hdf5LibMutex) {
std::lock_guard<std::mutex> lock(*hdf5Lib_); std::lock_guard<std::mutex> lock(*hdf5Lib_);
try { try {
@ -36,7 +18,7 @@ void HDF5MasterFile::LinkDataFile(std::string dataFilename,
flist.setFcloseDegree(H5F_CLOSE_STRONG); flist.setFcloseDegree(H5F_CLOSE_STRONG);
// open master file // open master file
H5File masterfd(fileName_.c_str(), H5F_ACC_RDWR, H5File masterfd(masterFileName.c_str(), H5F_ACC_RDWR,
FileCreatPropList::DEFAULT, flist); FileCreatPropList::DEFAULT, flist);
// open data file // open data file
@ -69,7 +51,7 @@ void HDF5MasterFile::LinkDataFile(std::string dataFilename,
masterfd.close(); masterfd.close();
} catch (const Exception &error) { } catch (const Exception &error) {
error.printErrorStack(); error.printErrorStack();
CloseFile(); fd.close();
throw sls::RuntimeError("Could not link in master hdf5 file"); throw sls::RuntimeError("Could not link in master hdf5 file");
} }
if (!silentMode) { if (!silentMode) {
@ -77,17 +59,15 @@ void HDF5MasterFile::LinkDataFile(std::string dataFilename,
} }
} }
void HDF5MasterFile::CreateMasterFile(const std::string filePath, std::string HDF5MasterFile::CreateMasterFile(
const std::string fileNamePrefix, const std::string filePath, const std::string fileNamePrefix,
const uint64_t fileIndex, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
const bool overWriteEnable, MasterAttributes *attr, std::mutex *hdf5LibMutex) {
const bool silentMode,
MasterAttributes *attr) {
std::ostringstream os; std::ostringstream os;
os << filePath << "/" << fileNamePrefix << "_master" os << filePath << "/" << fileNamePrefix << "_master"
<< "_" << fileIndex << ".h5"; << "_" << fileIndex << ".h5";
fileName_ = os.str(); std::string fileName = os.str();
std::lock_guard<std::mutex> lock(*hdf5Lib_); std::lock_guard<std::mutex> lock(*hdf5Lib_);
@ -96,67 +76,39 @@ void HDF5MasterFile::CreateMasterFile(const std::string filePath,
FileAccPropList flist; FileAccPropList flist;
flist.setFcloseDegree(H5F_CLOSE_STRONG); flist.setFcloseDegree(H5F_CLOSE_STRONG);
fd_ = nullptr;
if (!(overWriteEnable)) unsigned int createFlags = H5F_ACC_EXCL;
fd_ = new H5File(fileName_.c_str(), H5F_ACC_EXCL, if (overWriteEnable) {
FileCreatPropList::DEFAULT, flist); createFlags = H5F_ACC_TRUNC;
else }
fd_ = new H5File(fileName_.c_str(), H5F_ACC_TRUNC, H5File fd(fileName.c_str(), createFlags, FileCreatPropList::DEFAULT,
FileCreatPropList::DEFAULT, flist); flist);
// attributes - version // attributes - version
double dValue = HDF5_WRITER_VERSION; double dValue = HDF5_WRITER_VERSION;
DataSpace dataspace_attr = DataSpace(H5S_SCALAR); DataSpace dataspace_attr = DataSpace(H5S_SCALAR);
Attribute attribute = fd_->createAttribute( Attribute attribute = fd.createAttribute(
"version", PredType::NATIVE_DOUBLE, dataspace_attr); "version", PredType::NATIVE_DOUBLE, dataspace_attr);
attribute.write(PredType::NATIVE_DOUBLE, &dValue); attribute.write(PredType::NATIVE_DOUBLE, &dValue);
// Create a group in the file // Create a group in the file
Group group1(fd_->createGroup("entry")); Group group1(fd.createGroup("entry"));
Group group2(group1.createGroup("data")); Group group2(group1.createGroup("data"));
Group group3(group1.createGroup("instrument")); Group group3(group1.createGroup("instrument"));
Group group4(group3.createGroup("beam")); Group group4(group3.createGroup("beam"));
Group group5(group3.createGroup("detector")); Group group5(group3.createGroup("detector"));
Group group6(group1.createGroup("sample")); Group group6(group1.createGroup("sample"));
// TODO find a way to get complete group link attr->WriteMasterHDF5Attributes(&fd, &group5);
attrGroupName_ = "/entry/instrument/detector"; fd.close();
attr->WriteMasterHDF5Attributes(fd_, &group5);
fd_->close();
} catch (const Exception &error) { } catch (const Exception &error) {
error.printErrorStack(); error.printErrorStack();
CloseFile(); fd.close();
throw sls::RuntimeError( throw sls::RuntimeError(
"Could not create/overwrite master HDF5 handles"); "Could not create/overwrite master HDF5 handles");
} }
if (!silentMode) { if (!silentMode) {
LOG(logINFO) << "Master File: " << fileName_; LOG(logINFO) << "Master File: " << fileName;
}
}
void HDF5MasterFile::UpdateMasterFile(MasterAttributes *attr, bool silentMode) {
std::lock_guard<std::mutex> 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";
} }
return fileName;
} }

View File

@ -7,23 +7,16 @@
#include <mutex> #include <mutex>
class HDF5MasterFile : private virtual slsDetectorDefs, public File { class HDF5MasterFile : private virtual slsDetectorDefs, public File {
public: public:
HDF5MasterFile(std::mutex *hdf5Lib); void LinkDataFile(const std::string &masterFileName,
~HDF5MasterFile(); const std::string &dataFilename,
const &std::string dataSetname,
void LinkDataFile(std::string dataFilename, std::string dataSetname,
const std::vector<std::string> parameterNames, const std::vector<std::string> parameterNames,
const bool silentMode) override; const bool silentMode, std::mutex *hdf5LibMutex);
void CreateMasterFile(const std::string filePath, std::string CreateMasterFile(const std::string &filePath,
const std::string fileNamePrefix, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const uint64_t fileIndex,
const bool silentMode, const bool overWriteEnable,
MasterAttributes *attr) override; const bool silentMode, MasterAttributes *attr,
std::mutex *hdf5LibMutex);
private:
std::mutex *hdf5Lib_;
H5File *fd_{nullptr};
std::string fileName_;
std::string attrGroupName_;
}; };

View File

@ -5,8 +5,8 @@
#include <iomanip> #include <iomanip>
HDF5VirtualFile::HDF5VirtualFile(std::mutex *hdf5Lib, bool g25) HDF5VirtualFile::HDF5VirtualFile(std::mutex *hdf5LibMutex, bool g25)
: File(HDF5), hdf5Lib_(hdf5Lib), gotthard25um(g25) {} : File(HDF5), hdf5Lib_(hdf5LibMutex), gotthard25um(g25) {}
HDF5VirtualFile::~HDF5VirtualFile() { CloseFile(); } HDF5VirtualFile::~HDF5VirtualFile() { CloseFile(); }
@ -30,7 +30,7 @@ void HDF5VirtualFile::CloseFile() {
} }
void HDF5VirtualFile::CreateVirtualFile( void HDF5VirtualFile::CreateVirtualFile(
const std::string filePath, const std::string fileNamePrefix, const &std::string filePath, const &std::string fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode,
const int modulePos, const int numUnitsPerReadout, const int modulePos, const int numUnitsPerReadout,
const uint32_t maxFramesPerFile, const uint64_t numImages, const uint32_t maxFramesPerFile, const uint64_t numImages,

View File

@ -9,13 +9,13 @@
class HDF5VirtualFile : private virtual slsDetectorDefs, public File { class HDF5VirtualFile : private virtual slsDetectorDefs, public File {
public: public:
HDF5VirtualFile(std::mutex *hdf5Lib, bool g25); HDF5VirtualFile(std::mutex *hdf5LibMutex, bool g25);
~HDF5VirtualFile(); ~HDF5VirtualFile();
std::array<std::string, 2> GetFileAndDatasetName() const override; std::array<std::string, 2> GetFileAndDatasetName() const override;
void CloseFile() override; void CloseFile() override;
void CreateVirtualFile( void CreateVirtualFile(
const std::string filePath, const std::string fileNamePrefix, const std::string &filePath, const std::string &fileNamePrefix,
const uint64_t fileIndex, const bool overWriteEnable, const uint64_t fileIndex, const bool overWriteEnable,
const bool silentMode, const int modulePos, const bool silentMode, const int modulePos,
const int numUnitsPerReadout, const uint32_t maxFramesPerFile, const int numUnitsPerReadout, const uint32_t maxFramesPerFile,

View File

@ -369,7 +369,7 @@ void Implementation::setFileFormat(const fileFormat f) {
throw sls::RuntimeError("Unknown file format"); throw sls::RuntimeError("Unknown file format");
} }
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetupFileWriter(fileWriteEnable, fileFormatType, &hdf5Lib); it->SetupFileWriter(fileWriteEnable, fileFormatType, &hdf5LibMutex);
} }
LOG(logINFO) << "File Format: " << sls::ToString(fileFormatType); LOG(logINFO) << "File Format: " << sls::ToString(fileFormatType);
@ -405,7 +405,7 @@ void Implementation::setFileWriteEnable(const bool b) {
if (fileWriteEnable != b) { if (fileWriteEnable != b) {
fileWriteEnable = b; fileWriteEnable = b;
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetupFileWriter(fileWriteEnable, fileFormatType, &hdf5Lib); it->SetupFileWriter(fileWriteEnable, fileFormatType, &hdf5LibMutex);
} }
LOG(logINFO) << "File Write Enable: " LOG(logINFO) << "File Write Enable: "
<< (fileWriteEnable ? "enabled" : "disabled"); << (fileWriteEnable ? "enabled" : "disabled");
@ -741,9 +741,11 @@ void Implementation::SetupWriter() {
} }
void Implementation::StartMasterWriter() { void Implementation::StartMasterWriter() {
try {
std::string masterFileName;
// master file // master file
if (masterFileWriteEnable) { if (masterFileWriteEnable) {
std::unique_ptr<MasterAttributes> masterAttributes; std::unique_ptr<MasterAttributes> masterAttributes{nullptr};
switch (detType) { switch (detType) {
case GOTTHARD: case GOTTHARD:
masterAttributes = sls::make_unique<GotthardMasterAttributes>(); masterAttributes = sls::make_unique<GotthardMasterAttributes>();
@ -758,7 +760,8 @@ void Implementation::StartMasterWriter() {
masterAttributes = sls::make_unique<Mythen3MasterAttributes>(); masterAttributes = sls::make_unique<Mythen3MasterAttributes>();
break; break;
case GOTTHARD2: case GOTTHARD2:
masterAttributes = sls::make_unique<Gotthard2MasterAttributes>(); masterAttributes =
sls::make_unique<Gotthard2MasterAttributes>();
break; break;
case MOENCH: case MOENCH:
masterAttributes = sls::make_unique<MoenchMasterAttributes>(); masterAttributes = sls::make_unique<MoenchMasterAttributes>();
@ -801,13 +804,13 @@ void Implementation::StartMasterWriter() {
masterAttributes->ratecorr = rateCorrections; masterAttributes->ratecorr = rateCorrections;
masterAttributes->adcmask = masterAttributes->adcmask =
tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga; tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga;
masterAttributes->analog = masterAttributes->analog = (readoutType == ANALOG_ONLY ||
(readoutType == ANALOG_ONLY || readoutType == ANALOG_AND_DIGITAL) readoutType == ANALOG_AND_DIGITAL)
? 1 ? 1
: 0; : 0;
masterAttributes->analogSamples = numberOfAnalogSamples; masterAttributes->analogSamples = numberOfAnalogSamples;
masterAttributes->digital = masterAttributes->digital = (readoutType == DIGITAL_ONLY ||
(readoutType == DIGITAL_ONLY || readoutType == ANALOG_AND_DIGITAL) readoutType == ANALOG_AND_DIGITAL)
? 1 ? 1
: 0; : 0;
masterAttributes->digitalSamples = numberOfDigitalSamples; masterAttributes->digitalSamples = numberOfDigitalSamples;
@ -827,30 +830,32 @@ void Implementation::StartMasterWriter() {
masterAttributes->gates = numberOfGates; masterAttributes->gates = numberOfGates;
masterAttributes->additionalJsonHeader = additionalJsonHeader; masterAttributes->additionalJsonHeader = additionalJsonHeader;
try { // create master file
dataProcessor[0]->CreateMasterFile( masterFileName = dataProcessor[0]->CreateMasterFile(
filePath, fileName, fileIndex, overwriteEnable, silentMode, filePath, fileName, fileIndex, overwriteEnable, silentMode,
fileFormatType, masterAttributes.get()); fileFormatType, masterAttributes.get(), &hdf5LibMutex);
} catch (...) {
; // ignore it and just print it
}
} }
#ifdef HDF5C #ifdef HDF5C
if (fileFormatType == HDF5) { if (fileFormatType == HDF5) {
// virtual hdf5 file (if multiple files) // create virtual hdf5 file (if multiple files)
if (dataProcessor[0]->GetFilesInAcquisition() > 1 || if (dataProcessor[0]->GetFilesInAcquisition() > 1 ||
(numModules.x * numModules.y) > 1) { (numModules.x * numModules.y) > 1) {
dataProcessor[0]->CreateVirtualFile( dataProcessor[0]->CreateVirtualFile(
filePath, fileName, fileIndex, overwriteEnable, silentMode, filePath, fileName, fileIndex, overwriteEnable, silentMode,
modulePos, numUDPInterfaces, framesPerFile, numberOfTotalFrames, modulePos, numUDPInterfaces, framesPerFile,
dynamicRange, numModules.x, numModules.y, &hdf5Lib); numberOfTotalFrames, dynamicRange, numModules.x,
numModules.y, &hdf5LibMutex);
} }
// link file in master // link file in master
if (masterFileWriteEnable) { if (masterFileWriteEnable) {
dataProcessor[0]->LinkDataInMasterFile(silentMode); dataProcessor[0]->LinkDataInMasterFile(
masterFileName, silentMode, &hdf5LibMutex);
} }
} }
#endif #endif
} catch (...) {
; // ignore it and just print it
}
} }
void Implementation::StartRunning() { void Implementation::StartRunning() {

View File

@ -387,5 +387,6 @@ class Implementation : private virtual slsDetectorDefs {
std::vector<std::unique_ptr<Fifo>> fifo; std::vector<std::unique_ptr<Fifo>> fifo;
Arping arping; Arping arping;
std::mutex hdf5Lib; // mutex shared across all hdf5 virtual, master and data files
std::mutex hdf5LibMutex;
}; };

View File

@ -2,22 +2,21 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#include "MasterAttributes.h" #include "MasterAttributes.h"
#include <rapidjson/stringbuffer.h> void MasterAttributes::GetSpecificBinaryAttributes(
rapidjson::Writer<rapidjson::StringBuffer> *w) {
void MasterAttributes::WriteMasterBinaryAttributes(FILE *fd) {
LOG(logERROR) << "WriteMasterBinaryAttributes should have been called " LOG(logERROR) << "WriteMasterBinaryAttributes should have been called "
"by a child class"; "by a child class";
} }
void MasterAttributes::GetBinaryMasterAttributes( void MasterAttributes::GetCommonBinaryAttributes(
rapidjson::Writer<rapidjson::StringBuffer> *w) { rapidjson::Writer<rapidjson::StringBuffer> *w) {
time_t t = time(nullptr);
w->Key("Version"); w->Key("Version");
w->SetMaxDecimalPlaces(2); w->SetMaxDecimalPlaces(2);
w->Double(BINARY_WRITER_VERSION); w->Double(BINARY_WRITER_VERSION);
w->Key("Timestamp"); w->Key("Timestamp");
time_t t = time(nullptr);
w->String(ctime(&t)); w->String(ctime(&t));
w->Key("Detector Type"); w->Key("Detector Type");
@ -61,15 +60,7 @@ void MasterAttributes::GetBinaryMasterAttributes(
w->Uint64(totalFrames); w->Uint64(totalFrames);
}; };
void MasterAttributes::WriteBinaryAttributes(FILE *fd, std::string message) { void MasterAttributes::GetFinalBinaryAttributes(
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(
rapidjson::Writer<rapidjson::StringBuffer> *w) { rapidjson::Writer<rapidjson::StringBuffer> *w) {
// adding few common parameters to the end // adding few common parameters to the end
@ -309,25 +300,15 @@ void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) {
}; };
#endif #endif
void GotthardMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { void GotthardMasterAttributes::GetSpecificBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w) {
rapidjson::StringBuffer s; w->Key("Exptime");
rapidjson::Writer<rapidjson::StringBuffer> writer(s); w->String(sls::ToString(exptime).c_str());
writer.StartObject();
MasterAttributes::GetBinaryMasterAttributes(&writer);
writer.Key("Exptime"); w->Key("Period");
writer.String(sls::ToString(exptime).c_str()); w->String(sls::ToString(period).c_str());
writer.Key("Period"); w->Key("Roi (xmin, xmax)");
writer.String(sls::ToString(period).c_str()); w->String(sls::ToString(roi).c_str());
writer.Key("Roi (xmin, xmax)");
writer.String(sls::ToString(roi).c_str());
MasterAttributes::WriteFinalBinaryAttributes(&writer);
writer.EndObject();
std::string message = s.GetString();
MasterAttributes::WriteBinaryAttributes(fd, message);
}; };
#ifdef HDF5C #ifdef HDF5C
@ -349,31 +330,22 @@ void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) {
"roi xmax", PredType::NATIVE_INT, dataspace); "roi xmax", PredType::NATIVE_INT, dataspace);
dataset.write(&roi.xmax, PredType::NATIVE_INT); dataset.write(&roi.xmax, PredType::NATIVE_INT);
} }
MasterAttributes::WriteFinalHDF5Attributes(fd, group);
}; };
#endif #endif
void JungfrauMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { void JungfrauMasterAttributes::GetSpecificBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w) {
rapidjson::StringBuffer s; w->Key("Exptime");
rapidjson::Writer<rapidjson::StringBuffer> writer(s); w->String(sls::ToString(exptime).c_str());
writer.StartObject();
MasterAttributes::GetBinaryMasterAttributes(&writer);
writer.Key("Exptime"); w->Key("Period");
writer.String(sls::ToString(exptime).c_str()); w->String(sls::ToString(period).c_str());
writer.Key("Period"); w->Key("Number of UDP Interfaces");
writer.String(sls::ToString(period).c_str()); w->Uint(numUDPInterfaces);
writer.Key("Number of UDP Interfaces"); w->Key("Number of rows");
writer.Uint(numUDPInterfaces); w->Uint(readNRows);
writer.Key("Number of rows");
writer.Uint(readNRows);
MasterAttributes::WriteFinalBinaryAttributes(&writer);
writer.EndObject();
std::string message = s.GetString();
MasterAttributes::WriteBinaryAttributes(fd, message);
}; };
#ifdef HDF5C #ifdef HDF5C
@ -394,49 +366,40 @@ void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) {
"Number of rows", PredType::NATIVE_INT, dataspace); "Number of rows", PredType::NATIVE_INT, dataspace);
dataset.write(&readNRows, PredType::NATIVE_INT); dataset.write(&readNRows, PredType::NATIVE_INT);
} }
MasterAttributes::WriteFinalHDF5Attributes(fd, group);
}; };
#endif #endif
void EigerMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { void EigerMasterAttributes::GetSpecificBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w) {
rapidjson::StringBuffer s; w->Key("Dynamic Range");
rapidjson::Writer<rapidjson::StringBuffer> writer(s); w->Uint(dynamicRange);
writer.StartObject();
MasterAttributes::GetBinaryMasterAttributes(&writer);
writer.Key("Dynamic Range"); w->Key("Ten Giga");
writer.Uint(dynamicRange); w->Uint(tenGiga);
writer.Key("Ten Giga"); w->Key("Exptime");
writer.Uint(tenGiga); w->String(sls::ToString(exptime).c_str());
writer.Key("Exptime"); w->Key("Period");
writer.String(sls::ToString(exptime).c_str()); w->String(sls::ToString(period).c_str());
writer.Key("Period"); w->Key("Threshold Energy");
writer.String(sls::ToString(period).c_str()); w->Int(thresholdEnergyeV);
writer.Key("Threshold Energy"); w->Key("Sub Exptime");
writer.Int(thresholdEnergyeV); w->String(sls::ToString(subExptime).c_str());
writer.Key("Sub Exptime"); w->Key("Sub Period");
writer.String(sls::ToString(subExptime).c_str()); w->String(sls::ToString(subPeriod).c_str());
writer.Key("Sub Period"); w->Key("Quad");
writer.String(sls::ToString(subPeriod).c_str()); w->Int(quad);
writer.Key("Quad"); w->Key("Number of rows");
writer.Int(quad); w->Int(readNRows);
writer.Key("Number of rows"); w->Key("Rate Corrections");
writer.Int(readNRows); w->String(sls::ToString(ratecorr).c_str());
writer.Key("Rate Corrections");
writer.String(sls::ToString(ratecorr).c_str());
MasterAttributes::WriteFinalBinaryAttributes(&writer);
writer.EndObject();
std::string message = s.GetString();
MasterAttributes::WriteBinaryAttributes(fd, message);
}; };
#ifdef HDF5C #ifdef HDF5C
@ -502,55 +465,46 @@ void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) {
sls::strcpy_safe(c, sls::ToString(ratecorr)); sls::strcpy_safe(c, sls::ToString(ratecorr));
dataset.write(c, strdatatype); dataset.write(c, strdatatype);
} }
MasterAttributes::WriteFinalHDF5Attributes(fd, group);
}; };
#endif #endif
void Mythen3MasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { void Mythen3MasterAttributes::GetSpecificBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w) {
rapidjson::StringBuffer s; w->Key("Dynamic Range");
rapidjson::Writer<rapidjson::StringBuffer> writer(s); w->Uint(dynamicRange);
writer.StartObject();
MasterAttributes::GetBinaryMasterAttributes(&writer);
writer.Key("Dynamic Range"); w->Key("Ten Giga");
writer.Uint(dynamicRange); w->Uint(tenGiga);
writer.Key("Ten Giga"); w->Key("Period");
writer.Uint(tenGiga); w->String(sls::ToString(period).c_str());
writer.Key("Period"); w->Key("Counter Mask");
writer.String(sls::ToString(period).c_str()); w->String(sls::ToStringHex(counterMask).c_str());
writer.Key("Counter Mask"); w->Key("Exptime1");
writer.String(sls::ToStringHex(counterMask).c_str()); w->String(sls::ToString(exptime1).c_str());
writer.Key("Exptime1"); w->Key("Exptime2");
writer.String(sls::ToString(exptime1).c_str()); w->String(sls::ToString(exptime2).c_str());
writer.Key("Exptime2"); w->Key("Exptime3");
writer.String(sls::ToString(exptime2).c_str()); w->String(sls::ToString(exptime3).c_str());
writer.Key("Exptime3"); w->Key("GateDelay1");
writer.String(sls::ToString(exptime3).c_str()); w->String(sls::ToString(gateDelay1).c_str());
writer.Key("GateDelay1"); w->Key("GateDelay2");
writer.String(sls::ToString(gateDelay1).c_str()); w->String(sls::ToString(gateDelay2).c_str());
writer.Key("GateDelay2"); w->Key("GateDelay3");
writer.String(sls::ToString(gateDelay2).c_str()); w->String(sls::ToString(gateDelay3).c_str());
writer.Key("GateDelay3"); w->Key("Gates");
writer.String(sls::ToString(gateDelay3).c_str()); w->Uint(gates);
writer.Key("Gates"); w->Key("Threshold Energies");
writer.Uint(gates); w->String(sls::ToString(thresholdAllEnergyeV).c_str());
writer.Key("Threshold Energies");
writer.String(sls::ToString(thresholdAllEnergyeV).c_str());
MasterAttributes::WriteFinalBinaryAttributes(&writer);
writer.EndObject();
std::string message = s.GetString();
MasterAttributes::WriteBinaryAttributes(fd, message);
}; };
#ifdef HDF5C #ifdef HDF5C
@ -638,28 +592,19 @@ void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) {
sls::strcpy_safe(c, sls::ToString(thresholdAllEnergyeV)); sls::strcpy_safe(c, sls::ToString(thresholdAllEnergyeV));
dataset.write(c, strdatatype); dataset.write(c, strdatatype);
} }
MasterAttributes::WriteFinalHDF5Attributes(fd, group);
}; };
#endif #endif
void Gotthard2MasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { void Gotthard2MasterAttributes::GetSpecificBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w) {
rapidjson::StringBuffer s; w->Key("Exptime");
rapidjson::Writer<rapidjson::StringBuffer> writer(s); w->String(sls::ToString(exptime).c_str());
writer.StartObject();
MasterAttributes::GetBinaryMasterAttributes(&writer);
writer.Key("Exptime"); w->Key("Period");
writer.String(sls::ToString(exptime).c_str()); w->String(sls::ToString(period).c_str());
writer.Key("Period"); w->Key("Burst Mode");
writer.String(sls::ToString(period).c_str()); w->String(sls::ToString(burstMode).c_str());
writer.Key("Burst Mode");
writer.String(sls::ToString(burstMode).c_str());
MasterAttributes::WriteFinalBinaryAttributes(&writer);
writer.EndObject();
std::string message = s.GetString();
MasterAttributes::WriteBinaryAttributes(fd, message);
}; };
#ifdef HDF5C #ifdef HDF5C
@ -678,34 +623,25 @@ void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) {
sls::strcpy_safe(c, sls::ToString(burstMode)); sls::strcpy_safe(c, sls::ToString(burstMode));
dataset.write(c, strdatatype); dataset.write(c, strdatatype);
} }
MasterAttributes::WriteFinalHDF5Attributes(fd, group);
}; };
#endif #endif
void MoenchMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { void MoenchMasterAttributes::GetSpecificBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w) {
rapidjson::StringBuffer s; w->Key("Exptime");
rapidjson::Writer<rapidjson::StringBuffer> writer(s); w->String(sls::ToString(exptime).c_str());
writer.StartObject();
MasterAttributes::GetBinaryMasterAttributes(&writer);
writer.Key("Exptime"); w->Key("Period");
writer.String(sls::ToString(exptime).c_str()); w->String(sls::ToString(period).c_str());
writer.Key("Period"); w->Key("Ten Giga");
writer.String(sls::ToString(period).c_str()); w->Uint(tenGiga);
writer.Key("Ten Giga"); w->Key("ADC Mask");
writer.Uint(tenGiga); w->String(sls::ToStringHex(adcmask).c_str());
writer.Key("ADC Mask"); w->Key("Analog Samples");
writer.String(sls::ToStringHex(adcmask).c_str()); w->Uint(analogSamples);
writer.Key("Analog Samples");
writer.Uint(analogSamples);
MasterAttributes::WriteFinalBinaryAttributes(&writer);
writer.EndObject();
std::string message = s.GetString();
MasterAttributes::WriteBinaryAttributes(fd, message);
}; };
#ifdef HDF5C #ifdef HDF5C
@ -728,49 +664,40 @@ void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) {
"Analog Samples", PredType::NATIVE_INT, dataspace); "Analog Samples", PredType::NATIVE_INT, dataspace);
dataset.write(&analogSamples, PredType::NATIVE_INT); dataset.write(&analogSamples, PredType::NATIVE_INT);
} }
MasterAttributes::WriteFinalHDF5Attributes(fd, group);
}; };
#endif #endif
void CtbMasterAttributes::WriteMasterBinaryAttributes(FILE *fd) { void CtbMasterAttributes::GetSpecificBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w) {
rapidjson::StringBuffer s; w->Key("Exptime");
rapidjson::Writer<rapidjson::StringBuffer> writer(s); w->String(sls::ToString(exptime).c_str());
writer.StartObject();
MasterAttributes::GetBinaryMasterAttributes(&writer);
writer.Key("Exptime"); w->Key("Period");
writer.String(sls::ToString(exptime).c_str()); w->String(sls::ToString(period).c_str());
writer.Key("Period"); w->Key("Ten Giga");
writer.String(sls::ToString(period).c_str()); w->Uint(tenGiga);
writer.Key("Ten Giga"); w->Key("ADC Mask");
writer.Uint(tenGiga); w->String(sls::ToStringHex(adcmask).c_str());
writer.Key("ADC Mask"); w->Key("Analog Flag");
writer.String(sls::ToStringHex(adcmask).c_str()); w->Uint(analog);
writer.Key("Analog Flag"); w->Key("Analog Samples");
writer.Uint(analog); w->Uint(analogSamples);
writer.Key("Analog Samples"); w->Key("Digital Flag");
writer.Uint(analogSamples); w->Uint(digital);
writer.Key("Digital Flag"); w->Key("Digital Samples");
writer.Uint(digital); w->Uint(digitalSamples);
writer.Key("Digital Samples"); w->Key("Dbit Offset");
writer.Uint(digitalSamples); w->Uint(dbitoffset);
writer.Key("Dbit Offset"); w->Key("Dbit Bitset");
writer.Uint(dbitoffset); w->Uint64(dbitlist);
writer.Key("Dbit Bitset");
writer.Uint64(dbitlist);
MasterAttributes::WriteFinalBinaryAttributes(&writer);
writer.EndObject();
std::string message = s.GetString();
MasterAttributes::WriteBinaryAttributes(fd, message);
}; };
#ifdef HDF5C #ifdef HDF5C
@ -828,5 +755,6 @@ void MasterAttributes::WriteHDF5Attributes(H5File *fd, Group *group) {
"Dbit Bitset List", PredType::STD_U64LE, dataspace); "Dbit Bitset List", PredType::STD_U64LE, dataspace);
dataset.write(&dbitlist, PredType::STD_U64LE); dataset.write(&dbitlist, PredType::STD_U64LE);
} }
MasterAttributes::WriteFinalHDF5Attributes(fd, group);
}; };
#endif #endif

View File

@ -7,6 +7,7 @@
#include "sls/logger.h" #include "sls/logger.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h> #include <rapidjson/writer.h>
#ifdef HDF5C #ifdef HDF5C
@ -69,12 +70,12 @@ class MasterAttributes {
MasterAttributes() = default; MasterAttributes() = default;
virtual ~MasterAttributes() = default; virtual ~MasterAttributes() = default;
virtual void WriteMasterBinaryAttributes(FILE *fd); virtual void
GetSpecificBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w);
void void
GetBinaryMasterAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w); GetCommonBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w);
void WriteBinaryAttributes(FILE *fd, std::string message);
void void
WriteFinalBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w); GetFinalBinaryAttributes(rapidjson::Writer<rapidjson::StringBuffer> *w);
#ifdef HDF5C #ifdef HDF5C
virtual void WriteMasterHDF5Attributes(H5File *fd, Group *group); virtual void WriteMasterHDF5Attributes(H5File *fd, Group *group);
void WriteHDF5Attributes(H5File *fd, Group *group); void WriteHDF5Attributes(H5File *fd, Group *group);
@ -89,7 +90,8 @@ class MasterAttributes {
class GotthardMasterAttributes : public MasterAttributes { class GotthardMasterAttributes : public MasterAttributes {
public: public:
GotthardMasterAttributes() = default; GotthardMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override; void GetSpecificBinaryAttributes(
rapidjson::Writer<rapidjson::StringBuffer> *w) override;
#ifdef HDF5C #ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
#endif #endif
@ -98,7 +100,8 @@ class GotthardMasterAttributes : public MasterAttributes {
class JungfrauMasterAttributes : public MasterAttributes { class JungfrauMasterAttributes : public MasterAttributes {
public: public:
JungfrauMasterAttributes() = default; JungfrauMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override; void GetSpecificBinaryAttributes(
rapidjson::Writer<rapidjson::StringBuffer> *w) override;
#ifdef HDF5C #ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
#endif #endif
@ -107,7 +110,8 @@ class JungfrauMasterAttributes : public MasterAttributes {
class EigerMasterAttributes : public MasterAttributes { class EigerMasterAttributes : public MasterAttributes {
public: public:
EigerMasterAttributes() = default; EigerMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override; void GetSpecificBinaryAttributes(
rapidjson::Writer<rapidjson::StringBuffer> *w) override;
#ifdef HDF5C #ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
#endif #endif
@ -116,7 +120,8 @@ class EigerMasterAttributes : public MasterAttributes {
class Mythen3MasterAttributes : public MasterAttributes { class Mythen3MasterAttributes : public MasterAttributes {
public: public:
Mythen3MasterAttributes() = default; Mythen3MasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override; void GetSpecificBinaryAttributes(
rapidjson::Writer<rapidjson::StringBuffer> *w) override;
#ifdef HDF5C #ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
#endif #endif
@ -125,7 +130,8 @@ class Mythen3MasterAttributes : public MasterAttributes {
class Gotthard2MasterAttributes : public MasterAttributes { class Gotthard2MasterAttributes : public MasterAttributes {
public: public:
Gotthard2MasterAttributes() = default; Gotthard2MasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override; void GetSpecificBinaryAttributes(
rapidjson::Writer<rapidjson::StringBuffer> *w) override;
#ifdef HDF5C #ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
#endif #endif
@ -134,7 +140,8 @@ class Gotthard2MasterAttributes : public MasterAttributes {
class MoenchMasterAttributes : public MasterAttributes { class MoenchMasterAttributes : public MasterAttributes {
public: public:
MoenchMasterAttributes() = default; MoenchMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override; void GetSpecificBinaryAttributes(
rapidjson::Writer<rapidjson::StringBuffer> *w) override;
#ifdef HDF5C #ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
#endif #endif
@ -143,7 +150,8 @@ class MoenchMasterAttributes : public MasterAttributes {
class CtbMasterAttributes : public MasterAttributes { class CtbMasterAttributes : public MasterAttributes {
public: public:
CtbMasterAttributes() = default; CtbMasterAttributes() = default;
void WriteMasterBinaryAttributes(FILE *fd) override; void GetSpecificBinaryAttributes(
rapidjson::Writer<rapidjson::StringBuffer> *w) override;
#ifdef HDF5C #ifdef HDF5C
void WriteMasterHDF5Attributes(H5File *fd, Group *group) override; void WriteMasterHDF5Attributes(H5File *fd, Group *group) override;
#endif #endif