Create a 3 dimension dataset

I created a 3 dimension dataset and viewed it in HDFView 3.2.0. I expected to see 3 arrays of dimension 32x32. Instead, I see 32 3x32 arrays. Here is my code. :

// Create the dataset
hsize_t dims[3];

dims[0] = 3;
dims[1] = 32;
dims[2] = 32;

// Data initialization.
int data[3][32][32];     // buffer for data to write

const int RANK = dims[0];		// This is a three dimensional array

for (int i = 0; i < blk.Components.size(); i++) {

	int blk_rows = blk.Components[i].Info.Height();
	int blk_cols = blk.Components[i].Info.Width();

	for (int row = 0; row < blk_rows; row++) {
		for (int col = 0; col < blk_cols; col++) {
			if (int(row * blk_cols + col) < blk.Components[i].Data.size()) {
				data[i][row][col] = blk.Components[i].GetValue(row, col);
			}
		}
	}
}

// Try block to detect exceptions raised by any of the calls inside it
try {
	// Turn off the auto-printing when failure occurs so that we can
	// handle the errors appropriately
	Exception::dontPrint();

	DataSpace dataspace = DataSpace(RANK, dims);	// create new dataspace

	// Create the dataset.
	DataSet dataset = DataSet(blocks_group->createDataSet(dsname, PredType::STD_I32BE, dataspace));

	// Write the data to the dataset using default memory space, file
	// space, and transfer properties.
	dataset.write(data, PredType::NATIVE_INT);

} // end of try block

// catch failure caused by the H5File operations
catch (FileIException error) {
	error.printErrorStack();
	throw std::runtime_error("HDF5 FileIException");
}

// catch failure caused by the DataSet operations
catch (DataSetIException error) {
	error.printErrorStack();
	throw std::runtime_error("HDF5 DataSetIException");
}

// catch failure caused by the DataSpace operations
catch (DataSpaceIException error) {
	error.printErrorStack();
	throw std::runtime_error("HDF5 DataSpaceException");
}

HDFView has a weird way of presenting datasets with a rank > 2. What does

h5dump -pH -d <dsname> <filename.h5>

show? G.

1 Like

Some linear algebra systems support cubes, here is an example with armadillo and H5CPP

#include <armadillo>
#include <h5cpp/all>

int main(){
	h5::fd_t fd = h5::create("arma.h5",H5F_ACC_TRUNC);
	h5::write(fd,"cube.dat", arma::cube(2,3,4));
}

And here is another one to have more control over the layout:

#include <armadillo>
#include <h5cpp/all>

int main(){
	{ // CREATE - WRITE
		arma::cube M(2,3,4); M.ones();				            // create a matrix
		h5::fd_t fd = h5::create("arma.h5",H5F_ACC_TRUNC); 	// and a file
		h5::ds_t ds = h5::create<double>(fd,"create then write"
				,h5::current_dims{5,6,7}
				,h5::max_dims{5,6,H5S_UNLIMITED}
				,h5::chunk{5,6,10} | h5::fill_value<double>{3.14} |  h5::gzip{9}
		);
		h5::write( ds,  M, h5::offset{1,1,1});
	}
}

best: steve

HDFView can only show a two dimensional slice in a table with a third dimension allowing paging through those slices. More dimensions must be swapped in and out by the user.

HDFView must make assumptions about the array and interprets the 3 dimensions from slowest to fastest changing and assigns the dimensions 2,1,0 as slowest to fastest changing. Therefore, dimension 2 is the page index and dimension 1 is the row index and dimension 0 is the column index.

The assignment can be changed by choosing the “show as” button (or right click selection) and changing the assignments.

2 Likes