#ifndef DIALS_NEXUS_SERIALIZE_H #define DIALS_NEXUS_SERIALIZE_H #include #include #include #include #include namespace dials { namespace nexus { using scitbx::vec2; using scitbx::vec3; std::string dataset_name(const H5::DataSet& ds) { size_t len = H5Iget_name(ds.getId(),NULL,0); char buffer[len]; H5Iget_name(ds.getId(),buffer,len+1); std::string n = buffer; return n; } template struct serialize { template static T load(const Handle &handle); template static void dump(const T &obj, Handle &handle); }; template <> struct serialize { template static std::string load(const Handle &dataset) { std::string result; H5::DataType datatype = dataset.getDataType(); H5::DataSpace dataspace = dataset.getSpace(); DIALS_ASSERT(datatype.isVariableStr()); DIALS_ASSERT(dataspace.isSimple()); int ndims = dataspace.getSimpleExtentNdims(); DIALS_ASSERT(ndims == 1); hsize_t dims = 0; dataspace.getSimpleExtentDims(&dims); DIALS_ASSERT(dims == 1); dataset.read(result, datatype); return result; } template static void dump(const std::string &obj, Handle &handle) { } }; template <> struct serialize { template static bool load(const Handle &dataset) { bool result; H5::DataType datatype = dataset.getDataType(); H5::DataSpace dataspace = dataset.getSpace(); DIALS_ASSERT(dataspace.isSimple()); bool ndims = dataspace.getSimpleExtentNdims(); DIALS_ASSERT(ndims == 1); hsize_t dims = 0; dataspace.getSimpleExtentDims(&dims); DIALS_ASSERT(dims == 1); dataset.read(&result, H5::PredType::NATIVE_HBOOL); return result; } template static void dump(const bool &obj, Handle &handle) { } }; template <> struct serialize { template static int load(const Handle &dataset) { int result; H5::DataType datatype = dataset.getDataType(); H5::DataSpace dataspace = dataset.getSpace(); DIALS_ASSERT(dataspace.isSimple()); int ndims = dataspace.getSimpleExtentNdims(); DIALS_ASSERT(ndims == 1); hsize_t dims = 0; dataspace.getSimpleExtentDims(&dims); DIALS_ASSERT(dims == 1); dataset.read(&result, H5::PredType::NATIVE_INT); return result; } template static void dump(const int &obj, Handle &handle) { } }; template <> struct serialize { template static double load(const Handle &dataset) { double result; H5::DataType datatype = dataset.getDataType(); H5::DataSpace dataspace = dataset.getSpace(); DIALS_ASSERT(dataspace.isSimple()); int ndims = dataspace.getSimpleExtentNdims(); DIALS_ASSERT(ndims == 1); hsize_t dims = 0; dataspace.getSimpleExtentDims(&dims); DIALS_ASSERT(dims == 1); dataset.read(&result, H5::PredType::NATIVE_DOUBLE); return result; } template static void dump(const double &obj, Handle &handle) { } }; template <> struct serialize< vec2 > { template static vec2 load(const Handle &dataset) { vec2 result; H5::DataType datatype = dataset.getDataType(); H5::DataSpace dataspace = dataset.getSpace(); DIALS_ASSERT(dataspace.isSimple()); vec2 ndims = dataspace.getSimpleExtentNdims(); DIALS_ASSERT(ndims == 1); hsize_t dims = 0; dataspace.getSimpleExtentDims(&dims); DIALS_ASSERT(dims == 2); dataset.read(&result[0], H5::PredType::NATIVE_INT); return result; } template static void dump(const vec2 &obj, Handle &handle) { } }; template <> struct serialize > { template static af::shared load(const Handle &dataset) { af::shared result; H5::DataType datatype = dataset.getDataType(); H5::DataSpace dataspace = dataset.getSpace(); DIALS_ASSERT(dataspace.isSimple()); int ndims = dataspace.getSimpleExtentNdims(); DIALS_ASSERT(ndims == 1); hsize_t dims = 0; dataspace.getSimpleExtentDims(&dims); result.resize(dims); dataset.read(&result[0], H5::PredType::NATIVE_DOUBLE); return result; } template static void dump(const af::shared &obj, Handle &handle) { } }; template <> struct serialize< af::versa > > { template static af::versa > load(const Handle &dataset) { af::versa > result; H5::DataType datatype = dataset.getDataType(); H5::DataSpace dataspace = dataset.getSpace(); DIALS_ASSERT(dataspace.isSimple()); int ndims = dataspace.getSimpleExtentNdims(); DIALS_ASSERT(ndims == 2); hsize_t dims[2] = {0,0}; dataspace.getSimpleExtentDims(dims); result.resize(af::c_grid<2>(dims[0], dims[1])); dataset.read(&result[0], H5::PredType::NATIVE_DOUBLE); return result; } template static void dump(const af::versa > &obj, Handle &handle) { } }; template <> struct serialize< af::versa > > { template static af::versa > load(const Handle &dataset) { af::versa > result; H5::DataType datatype = dataset.getDataType(); H5::DataSpace dataspace = dataset.getSpace(); DIALS_ASSERT(dataspace.isSimple()); int ndims = dataspace.getSimpleExtentNdims(); DIALS_ASSERT(ndims == 2); hsize_t dims[2] = { 0, 0}; dataspace.getSimpleExtentDims(dims); result.resize(af::c_grid<2>(dims[0], dims[1])); dataset.read(&result[0], H5::PredType::NATIVE_INT); return result; } template static void dump(const af::versa > &obj, Handle &handle) { } }; template bool is_nx_class(const Handle &handle, std::string test_name) { if (handle.attrExists("NX_class")) { H5::Attribute attr = handle.openAttribute("NX_class"); H5::DataType dtype = attr.getDataType(); if (dtype.isVariableStr()) { std::string name; attr.read(dtype, name); if (name == test_name) { return true; } } } return false; } template bool is_nxmx_entry(const Handle &handle) { try { if ("NXmx" == serialize::load( handle.openDataSet("definition"))) { return true; } } catch(H5::Exception) { // Do nothing } catch(std::exception) { // Do nothing } return false; } template bool is_nx_entry(const Handle &handle) { if (handle.attrExists("NX_class")) { H5::Attribute attr = handle.openAttribute("NX_class"); H5::DataType dtype = attr.getDataType(); if (dtype.isVariableStr()) { std::string name; attr.read(dtype, name); if (name == "NXentry" || name == "NXsubentry") { return true; } } } return false; } template void find_nx_entries(Handle &handle, Iterator out) { for (std::size_t i = 0; i < handle.getNumObjs(); ++i) { if (handle.getObjTypeByIdx(i) == H5G_GROUP) { std::string name = handle.getObjnameByIdx(i); H5::Group group = handle.openGroup(name); if (is_nx_entry(group)) { *out++ = group; find_nx_entries(group, out); } } } } }} // namespace dials::nexus #endif // DIALS_NEXUS_SERIALIZE_H