HDF5 NeXus writer User's Guide


H5NX is a high-level HDF5 API written in C++ that allows to save HDF5 datasets, groups and attributes, in a HDF5 file conforming to the NeXus specification using only HDF5 API calls from the HDF5 C interface. The following section show examples of use of H5NX.

Programming Hints:

To use any of these functions or subroutines, you must first include the relevant include file in your application.

The following line includes the HDF5 NeXus writer API package, H5NX, in C++ applications:

#include "h5nx.hpp"

H5NX programming examples:

How to save a scalar dataset

To save a scalar dataset, the H5NXmake_dataset_scalar function is used.

Here is a complete C++ program that makes use of this function.
#include "h5nx.hpp"
#include "napi.h"
using namespace std;

int main() 
{
  H5nx h5nx;

  if (h5nx.H5NXcreate_file("h5nx_ex_scalar.h5") < 0) { };

  if (h5nx.H5NXmake_dataset_scalar("/", "dset", float(1)) < 0) { };

  if (h5nx.H5NXclose_file() < 0) { };

  return 0;
}

How to save a string dataset

To save a string dataset, the H5NXmake_dataset_string function is used.

Here is a complete C++ program that makes use of this function.
#include "h5nx.hpp"
#include "napi.h"
using namespace std;

int main() 
{
  H5nx h5nx;

  if (h5nx.H5NXcreate_file("h5nx_ex_string.nxs.h5") < 0) { };

  if (h5nx.H5NXmake_dataset_string("/", "dset", "my string") < 0) { };

  if (h5nx.H5NXclose_file() < 0) { };

  return 0;
}

How to save a vector dataset

To save a vector dataset, the H5NXmake_dataset_vector function is used.

Here is a complete C++ program that makes use of this function.
#include "h5nx.hpp"
#include "napi.h"
using namespace std;

#define DIM 4

int main() 
{
  H5nx h5nx;
  std::vector<hsize_t> vec_dim;
  std::vector<float> vec_data;
  vec_dim.push_back(DIM);
  vec_data.assign(DIM,1);

  if (h5nx.H5NXcreate_file("h5nx_ex_vector.nxs.h5") < 0) { };

  if (h5nx.H5NXmake_dataset_vector("/", "dset", vec_data, vec_dim) < 0) { };

  if (h5nx.H5NXclose_file() < 0) { };

  return 0;
}

How to create a group

To create a HDF5 group, the H5NXmake_group is used.

Here is a complete C++ program that makes use of this function.
#include "h5nx.hpp"
#include "napi.h"
using namespace std;

int main() 
{
  H5nx h5nx;

  if (h5nx.H5NXcreate_file("h5nx_ex_group.nxs.h5") < 0) { };

  if (h5nx.H5NXmake_group("entry", "NXentry") < 0) { };

  if (h5nx.H5NXmake_dataset_scalar("/entry", "dset", uint64_t(1)) < 0) { };

  if (h5nx.H5NXclose_file() < 0) { };

  return 0;
}

How to save a scalar attribute

To save a scalar HDF5 attribute, the H5NXmake_attribute_scalar function is used.

Here is a complete C++ program that makes use of this function.
#include "h5nx.hpp"
#include "napi.h"
using namespace std;

#define DATASET_NAME "dset"

int main() 
{
  H5nx h5nx;
  std::string path;

  if (h5nx.H5NXcreate_file("h5nx_ex_attr_scalar.nxs.h5") < 0) { };

  path = "/entry";

  if (h5nx.H5NXmake_group( path, "NXentry") < 0) { };

  if (h5nx.H5NXmake_dataset_scalar(path, DATASET_NAME, uint64_t(1)) < 0) { };

  path += "/";
  path += DATASET_NAME;

  if (h5nx.H5NXmake_attribute_scalar(path, "attr", uint8_t(1)) < 0) { };

  if (h5nx.H5NXclose_file() < 0) { };

  return 0;
}

How to save a string attribute

To save a string HDF5 attribute, the H5NXmake_attribute_string function is used.

Here is a complete C++ program that makes use of this function.
#include "h5nx.hpp"
#include "napi.h"
using namespace std;

#define DATASET_NAME "dset"

int main() 
{
  H5nx h5nx;
  std::string path;

  if (h5nx.H5NXcreate_file("h5nx_ex_attr_string.nxs.h5") < 0) { };

  path = "/entry";

  if (h5nx.H5NXmake_group( path, "NXentry") < 0) { };

  if (h5nx.H5NXmake_dataset_scalar(path, DATASET_NAME, uint64_t(1)) < 0) { };

  path += "/";
  path += DATASET_NAME;

  if (h5nx.H5NXmake_attribute_string(path, "attr", "my string") < 0) { };

  if (h5nx.H5NXclose_file() < 0) { };

  return 0;
}

How to create a link

To create a HDF5 link, the H5NXmake_link function is used.

Here is a complete C++ program that makes use of this function.
#include "h5nx.hpp"
#include "napi.h"
using namespace std;

#define DATASET_NAME "dset"

int main() 
{
  H5nx h5nx;
  std::string path;

  if (h5nx.H5NXcreate_file("h5nx_ex_link.nxs.h5") < 0) { };

  path = "/";

  if (h5nx.H5NXmake_dataset_scalar(path, DATASET_NAME, uint32_t(1)) < 0) { };

  path = "/entry";

  if (h5nx.H5NXmake_group( path, "NXentry") < 0) { };

  path += "/";
  path += DATASET_NAME;

  if (h5nx.H5NXmake_link( DATASET_NAME, path ) < 0 ) { };

  if (h5nx.H5NXclose_file() < 0) { };

  return 0;
}

How to write an extendable dataset

An extendable dataset is a dataset that can be appended data to. To write an extendable dataset, the H5NXcreate_dataset_extend and H5NXappend_slab functions are used.

Here is a complete C++ program that makes use of these functions.
#include "h5nx.hpp"
#include "napi.h"
using namespace std;
#define CHUNK_SIZE 14
#define SLAB       14

int main() 
{
  H5nx h5nx;
  std::vector<double> slab;
  slab.assign(SLAB,1);

  if (h5nx.H5NXcreate_file("h5nx_ex_extendable.nxs") < 0) { };

  if (h5nx.H5NXcreate_dataset_extend("/", "value", NX_FLOAT64, CHUNK_SIZE) < 0) { };

  if (h5nx.H5NXappend_slab("/value", slab) < 0) { };

  if (h5nx.H5NXclose_file() < 0) { };

  return 0;
}

Performance Hints:

The dataset is first created and then appended at a later point in time. The table shows a scheme for a use case where the chunk size does not match the slab size: row 1 shows 5 chunks, labeled from A to E (all with the same size).

A B C D E
1 2 3 4 5

Row 2 shows an example of the number of times that the dataset is appended, 5 times. We call every block of data that we write every time, a slab. Row 2 shows 5 slabs in green color.

So, every slab does not match exactly the size of a chunk. Due to the nature of the HDF5 chunk, this poses a performance hit when writing a slab. The next table shows in scheme what happens in a case where slab 3 is written to disk and the dataset is compressed.

B C D
2 3

What the HDF5 library does in this particular case is:

  1. Read chunk B from disk back into memory
  2. Decompress it, because data in disk is compressed.
  3. Write the slab to the uncompressed version in memory, the data that defines the B, C, D area in pink color. Note: only part of D chunk contains data information from the slab, the rest is filled with zeros in disk.
  4. Recompress it.
  5. Write the modified 3 chunks labeled B, C, D, back to disk.

H5NX is used at the Spallation Neutron Source of the Oak Ridge National Laboratory