Skip to content
Hunter Belanger edited this page Mar 10, 2022 · 7 revisions

This page provides an overview of how to use the exdir-cpp library, once it has been built. This assumes that you have either installed the libraries and headers into the default locations, or you put them somewhere else where you know how to use them.

Includes

To use exdir-cpp in your code, you should include the exdir/exdir.hpp header file in your source file. This should be the only header you need to include, and will include the other exdir-cpp header files, giving you access to all of the libraries features. All of the library features exists inside of the exdir namespace.

Creating and Opening an Exdir Directory

An Exdir directory is represented as an exdir::File object. You can create a new Exdir directory with

exdir::File exdir_file = create_file("name/of/file.exdir");

The argument can be either an std::string, or an std::filesystem::path object to where you would like the directory to be. This like of code will create the required folder, and exdir.yaml file within. If the name of the directory already exists, a runtime error will be thrown.

If you would like to open an Exdir directory which already exists on your system, you can then use

exdir::File exdir_file("name/of/existing/file.exdir");

where the argument can again be an std::string or std::filesystem::path object.

Groups

To access a Group which already exists, both File and Group objects have a method called get_group, which takes a string with the name of the group. Continuing the previous example, if there is a group called "test_group" in the exdir_file, then we can access it with

exdir::Group group = exdir_file.get_group("group_name");

A list of all groups contained in a File or parent Group can be obtained with the member_groups() method, which returns an std::vectorstd::string object of all the groups which are present within that object. A new group can be added with

exdir::Group group2 = exdir_file.create_group("group_name_2");

NDArray

An NDArray<T> is an n-dimensional array, very similar to a Numpy array in Python. It can only contain one type, and the only acceptable types are:

  • char
  • unsigned char
  • uint16_t
  • uint32_t
  • uint64_t
  • int16_t
  • int32_t
  • int64_t
  • float
  • double
  • std::complex<float>
  • std::complex<double> No other types are allowed, as it would not be possible to store them in a .npy file, which is required by the Exdir standard.

You can retrive the shape of an NDArray as a vector, and perform indexing with the () operator:

NDArray<double> array({1.,2.,3.,4.}, {2,2});
// array = [[1., 2.],
//          [3., 4.]]

array(0,1) = 9.;
// array = [[1., 9.],
//          [3., 4.]]

You can go through the array linearly using the [] operator:

for (std::size_t i = 0; i < array.size(); i++) {
    array[i] *= 3.;
}

Datasets

A Dataset<T> contains a public member data, which is an NDArray<T> instance, containing the data for the Dataset. On destruction, the data in data will be written to disk, along with any attributes. It is only possible to template Dataset against one of the possible types for NDArray. This also means that you must know the desired type of your data when creating or retrieving a dataset.

exdir::Dataset<double> data_set = group.create_dataset<double>("data_set_1");

data_set.data.reshape({2,2});

for (std::size_t i = 0; i < data_set.data.size(); i++) {
    data_set.data[i] = i;
}

// data_set.data = [[1., 2.],
//                  [3., 4.]]

Raws

Raws can be accessed or created with commands similar to those of groups.

exdir::Raw raw = data_set.get_raw("raw_data");
exdir::Raw raw2 = data_set.create_raw("more_raw_data");

Other objects may not be added to Raws. Raws do have a special method which returns a vector of strings of the files inside the directory.

std::vector<std::string> raw_files = raw.member_file();

Attributes

All objects (File, Group, Dataset, Raw) are able to contain attributes, which contain properties about them. These are accesses through the attrs member of the object. This public object is actually a raw yaml-cpp node. It works somewhat like a dictionary, taking an std::string as a key. You can set an attribute for an object with something along the lines of

group2.attrs["density"] = 2.3;

To learn more about how to use the attributes and yaml-cpp nodes, take a look at their tutorial here.

If you make changes to attributes are saved on destruction of an object. If you would like to write them to dist, then you can use the write() method:

group2.write();
Clone this wiki locally