Skip to content

Commit d689dc7

Browse files
authored
Merge pull request #678 from UWB-Biocomputing/issue-656-add-registerVariableForHdf5Recorder
implement registerVariable in Hdf5 Recorder
2 parents b6e2aaa + dec6c20 commit d689dc7

File tree

4 files changed

+119
-4
lines changed

4 files changed

+119
-4
lines changed

Simulator/Recorders/Hdf5Recorder.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ void Hdf5Recorder::init()
4949
if ((resultFileName_.size() <= suffix.size())
5050
|| (resultFileName_.compare(resultFileName_.size() - suffix.size(), suffix.size(), suffix)
5151
!= 0)) {
52-
//perror("the file extention is not .h5 ");
5352
string errorMsg
5453
= "Error: the file extension is not .h5. Provided file name: " + resultFileName_;
5554
perror(errorMsg.c_str());
@@ -108,4 +107,22 @@ void Hdf5Recorder::term()
108107
void Hdf5Recorder::initDataSet()
109108
{
110109
}
110+
111+
/// Receives a recorded variable entity from the variable owner class
112+
/// used when the return type from recordable variable is supported by Recorder
113+
/**
114+
* @brief Registers a single instance of a class derived from RecordableBase.
115+
* @param varName Name of the recorded variable.
116+
* @param recordVar Reference to the recorded variable.
117+
* @param variableType Type of the recorded variable.
118+
*/
119+
void Hdf5Recorder::registerVariable(const string &varName, RecordableBase &recordVar,
120+
UpdatedType variableType)
121+
{
122+
// Create a singleVariableInfo object for the variable
123+
singleVariableInfo hdf5VarInfo(varName, recordVar, variableType);
124+
125+
// Add the variable information to the variableTable_
126+
variableTable_.push_back(hdf5VarInfo);
127+
}
111128
#endif // HDF5

Simulator/Recorders/Hdf5Recorder.h

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,76 @@ class Hdf5Recorder : public Recorder {
8585
* @param variableType Type of the recorded variable.
8686
*/
8787
virtual void registerVariable(const string &varName, RecordableBase &recordVar,
88-
UpdatedType variableType) override
89-
{
90-
}
88+
UpdatedType variableType) override;
9189

9290
/// Register a vector of instance of a class derived from RecordableBase.
9391
virtual void registerVariable(const string &varName, vector<RecordableBase *> &recordVars,
9492
UpdatedType variableType) override
9593
{
9694
}
9795

96+
struct singleVariableInfo {
97+
/// the name of each variable
98+
string variableName_;
99+
100+
/// the basic data type in the Recorded variable
101+
string dataType_;
102+
103+
/// the data type in Hdf5 file
104+
DataType hdf5Datatype_;
105+
106+
/// the data set for Hdf5 file
107+
DataSet hdf5DataSet_;
108+
109+
/// the variable type: updated frequency
110+
UpdatedType variableType_;
111+
112+
/// a reference to a RecordableBase variable
113+
/// As the simulator runs, the values in the RecordableBase object will be updated
114+
RecordableBase &variableLocation_;
115+
116+
// Constructor accepting the variable name, the address of recorded variable, the updated type
117+
singleVariableInfo(const string &name, RecordableBase &location, UpdatedType variableType) :
118+
variableLocation_(location), variableName_(name), variableType_(variableType)
119+
{
120+
dataType_ = location.getDataType();
121+
convertType();
122+
}
123+
124+
// Converts the data type of the variable to HDF5 data type
125+
void convertType()
126+
{
127+
if (dataType_ == typeid(uint64_t).name()) {
128+
hdf5Datatype_ = PredType::NATIVE_UINT64;
129+
} else if (dataType_ == typeid(bool).name()) {
130+
hdf5Datatype_ = PredType::NATIVE_UINT8;
131+
} else if (dataType_ == typeid(int).name()) {
132+
hdf5Datatype_ = PredType::NATIVE_INT;
133+
} else if (dataType_ == typeid(float).name()) {
134+
hdf5Datatype_ = PredType::NATIVE_FLOAT;
135+
} else if (dataType_ == typeid(double).name()) {
136+
hdf5Datatype_ = PredType::NATIVE_DOUBLE;
137+
} else {
138+
//string errorMsg = "Not supported type for type: " + dataType_;
139+
throw runtime_error("Unsupported data type");
140+
}
141+
}
142+
143+
// Creates a dynamic dataset in the HDF5 file
144+
void createDynamicDataset(H5File *resultOut_)
145+
{
146+
// Create dataspace with initial size and unlimited max size
147+
hsize_t dims[1] = {static_cast<hsize_t>(variableLocation_.getNumElements())};
148+
hsize_t maxDims[1] = {H5S_UNLIMITED};
149+
DataSpace dataspace(1, dims, maxDims);
150+
151+
// Create dataset
152+
hdf5DataSet_ = resultOut_->createDataSet(variableName_, hdf5Datatype_, dataspace);
153+
154+
std::cout << "Created dataset: " << variableName_ << std::endl;
155+
}
156+
};
157+
98158
///@{
99159
/** These methods are intended only for unit tests */
100160
/// constructor only for unit test
@@ -103,6 +163,12 @@ class Hdf5Recorder : public Recorder {
103163
resultFileName_ = fileName;
104164
}
105165

166+
// Accessor method to retrieve variableTable_
167+
const vector<singleVariableInfo> &getVariableTable() const
168+
{
169+
return variableTable_;
170+
}
171+
106172
private:
107173
virtual void initDataSet();
108174

@@ -147,6 +213,8 @@ class Hdf5Recorder : public Recorder {
147213
// track spikes count of probed neurons
148214
vector<vector<uint64_t>> spikesProbedNeurons_;
149215

216+
/// List of registered variables for recording
217+
vector<singleVariableInfo> variableTable_;
150218
// Other member functions...
151219
};
152220

Testing/UnitTesting/Hdf5RecorderTests.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,38 @@
1+
#include "EventBuffer.h"
12
#include "Hdf5Recorder.h"
3+
#include "RecordableBase.h"
4+
#include "RecordableVector.h"
25
#include "Recorder.h"
36
#include "gtest/gtest.h"
47

58
#if defined(HDF5)
9+
#include "H5Cpp.h"
10+
11+
// Unit test for verifying the registerVariable method
12+
TEST(Hdf5RecorderTest, RegisterVariableTest)
13+
{
14+
// Create an instance of Hdf5Recorder
15+
std::string outputFile = "../Testing/UnitTesting/TestOutput/Hdf5test_output_register.h5";
16+
Hdf5Recorder recorder(outputFile);
17+
recorder.init();
18+
19+
// Create an EventBuffer for testing
20+
EventBuffer eventBuffer;
21+
const H5std_string hdf5Name("test_var");
22+
23+
// Register the variable
24+
recorder.registerVariable(hdf5Name, eventBuffer, Recorder::UpdatedType::CONSTANT);
25+
26+
// Retrieve the registered variable info
27+
const Hdf5Recorder::singleVariableInfo &varInfo = recorder.getVariableTable()[0];
28+
29+
// Verify the variable type
30+
ASSERT_EQ(Recorder::UpdatedType::CONSTANT, varInfo.variableType_);
31+
// Verify the variable name
32+
ASSERT_EQ(hdf5Name, varInfo.variableName_);
33+
// Verify the HDF5 data type
34+
ASSERT_EQ(PredType::NATIVE_UINT64, varInfo.hdf5Datatype_);
35+
}
636

737
// Test case for initializing the Hdf5Recorder
838
TEST(Hdf5RecorderTest, CreateInstanceSuccess)

build/test_output.h5

800 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)