-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Writing fixed-length string with Ascii encoding #678
Comments
Hello, Here is a working example doing what you want: #include <highfive/H5File.hpp>
using namespace HighFive;
/// First define a new fixed size string of 16, with PADDING, and ASCII
struct MyString: public DataType {
MyString() {
_hid = H5Tcopy(H5T_C_S1);
if (H5Tset_size(_hid, 16) < 0) {
HDF5ErrMapper::ToException<DataTypeException>("Unable to define datatype size to 16");
}
// define encoding to ASCII
H5Tset_cset(_hid, H5T_CSET_ASCII);
H5Tset_strpad(_hid, H5T_STR_SPACEPAD);
}
} myStringType;
int main() {
File file("test_jdumas.h5", File::ReadWrite | File::Create | File::Truncate);
auto group = file.createGroup("/a");
char utf8Str[] = "UnstructuredGrid";
// create the attribute to avoid magicness
auto attr = group.createAttribute("Type", DataSpace{1}, myStringType);
// write it
attr.write("UnstructuredGrid");
return 0;
} Giving:
|
About your 3 examples: group.createAttribute("Type", std::string("UnstructuredGrid"));
group.createAttribute("Type2", "UnstructuredGrid");
group.createAttribute("Type3", std::to_array("UnstructuredGrid")); // using the std::to_array implementation from https://en.cppreference.com/w/cpp/container/array/to_array First one is not valid because on In |
Thanks! It looks like I can open my exported VTK HDF with Paraview now. It crashes when I try to visualize it, but that may be an issue with my exported data -- I'll investigate more.
Yeah, I figured as much. But the former is an array of string, not a string, and the last two are a bit bugged as you mentioned. |
Ok after debugging my mesh export I got the VTK HDF thing working, using your workaround to write a fixed-length string to the HDF file. Feel free to close this issue or leave it open! |
A bit of a side step: Have you found http://xdmf.org/index.php/XDMF_Model_and_Format ? I made some tools https://github.com/tdegeus/XDMFWrite_h5py and https://github.com/tdegeus/XDMFWrite_HighFive (with the latter potentially needing some TLC). |
Having to lug around a .xml file separate from the main .hdf is a chore. That's why the Paraview folks introduced VTK HDF with Paraview 5.11. Imho that's a much better solution, and I was able to write it fairly easily with HighFive once I used the workaround for fixed strings. |
/// First define a new fixed size string of 16, with PADDING, and ASCII
struct MyString: public DataType {
MyString() {
_hid = H5Tcopy(H5T_C_S1);
if (H5Tset_size(_hid, 16) < 0) {
HDF5ErrMapper::ToException<DataTypeException>("Unable to define datatype size to 16");
}
// define encoding to ASCII
H5Tset_cset(_hid, H5T_CSET_ASCII);
H5Tset_strpad(_hid, H5T_STR_SPACEPAD);
}
} myStringType; This looks like it could be added to template<size_t N>
struct FixedLengthString {...}; ? |
I tried to give that a go, but the data isn't actually written, this program: #include <highfive/H5File.hpp>
using HighFive::File;
using HighFive::DataSpace;
using HighFive::DataType;
using HighFive::DataTypeException;
using HighFive::HDF5ErrMapper;
using DataspaceType = DataSpace::DataspaceType;
template<
size_t N,
H5T_cset_t cset = H5T_CSET_UTF8,
H5T_str_t strpad = H5T_STR_NULLTERM
>
struct FixedLengthString: public DataType {
static const H5T_cset_t character_set = cset;
static const H5T_str_t padding = strpad;
static const size_t size = N;
FixedLengthString() {
_hid = H5Tcopy(H5T_C_S1);
if (H5Tset_size(_hid, size) < 0) {
HDF5ErrMapper::ToException<DataTypeException>("Unable to define datatype size");
}
H5Tset_cset(_hid, character_set);
H5Tset_strpad(_hid, padding);
}
};
int main (int argc, const char* argv[]) {
const std::string bar{"bar"};
File file("test.h5", File::ReadWrite | File::Create | File::Truncate);
auto group = file.createGroup("/foo");
DataSpace scalar{DataspaceType::dataspace_scalar};
FixedLengthString<20> dtype;
auto attr = group.createAttribute("bar", scalar, dtype);
attr.write(bar);
return 0;
} Runs, but results in an empty string (no data in the attribute):
|
Very interesting! Try I think I should have time to look at something HighFive related tomorrow. Strings are defiinitely on the TODO list. |
@1uc nope, same result |
@maxnoe Thank you, that narrowed down the places the issue could be considerably. If you look at the output you see:
but you're asking for a scalar dataspace. To fix this you need to use the round-ctor (not curly-ctor):
with that I'm not able to use const std::string bar{"blablabla"};
File file("test.h5", File::Truncate);
auto group = file.createGroup("/foo");
auto space = H5Screate(H5S_SCALAR);
DataSpace scalar(DataspaceType::dataspace_scalar);
FixedLengthString<20> dtype;
auto attr = group.createAttribute("bar", scalar, dtype);
// Note, it's important to repeat the datatype here:
attr.write_raw(bar.c_str(), dtype); which results in:
(Note the |
Thanks, so the problem is that with What is the reason to not allow writing strings or char* into a fixed length string? |
I think it's picking up the HighFive/include/highfive/H5DataSpace.hpp Line 52 in be68bd0
The reason why strings don't work is rather mundane: nobody has made sure they work (hence inevitably they broke or have always been broken) and at BBP we simply don't seem to have any need for them beyond what's implemented. Hence, we never urgently needed to make sure they work. That said, it would be nice if strings worked a lot better than they do now. |
With #744 merged |
Is your feature request related to a problem? Please describe.
Hi. I'm trying to write a VTK HDF file using HighFive. This requires writing the "Type" attribute as a fixed-length string with encoding:
Describe the solution you'd like
I'd appreciate some help in being able to write an attribute with the same properties as above (fixed-length string, ascii encoding, nullpad padding).
Describe alternatives you've considered
I've tried to write the attribute in a few different ways:
The first version produces the following:
The second version crashes with the following error:
The third version produces the following output:
Additional context
The text was updated successfully, but these errors were encountered: