26#include <boost/regex.hpp>
52 if (!H5Fis_hdf5(file.c_str())) {
53 cout << file <<
" is not recognise as HDF5 file format" << endl;
56 file_id_ = H5Fopen(file.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
60 hid_t g_h5md = H5Gopen(
file_id_,
"h5md", H5P_DEFAULT);
61 CheckError(g_h5md,
"Unable to open /h5md group.");
63 hid_t at_version = H5Aopen(g_h5md,
"version", H5P_DEFAULT);
64 CheckError(at_version,
"Unable to read version attribute.");
65 int version[2] = {0, 0};
66 H5Aread(at_version, H5Aget_type(at_version), &version);
67 if (version[0] != 1 || version[1] > 1) {
68 cout <<
"Found H5MD version: " << version[0] <<
"." << version[1] << endl;
69 throw ios_base::failure(
"Wrong version of H5MD file.");
78 throw ios_base::failure(
"The particles group is empty.");
82 hid_t modules = H5Gopen(g_h5md,
"modules", H5P_DEFAULT);
83 std::cout <<
"open modules group" << modules << std::endl;
85 hid_t module_units = H5Gopen(modules,
"units", H5P_DEFAULT);
86 if (module_units > 0) {
87 std::cout <<
"found units module - position and forces will be scaled "
90 H5Gclose(module_units);
98 H5Eset_auto2(H5E_DEFAULT,
nullptr,
nullptr);
101 H5Aclose(at_version);
116 if (particle_group_name_.compare(
"unassigned") == 0) {
117 throw ios_base::failure(
118 "Missing particle group in topology. Please set `h5md_particle_group` "
119 "tag with `name` attribute set to the particle group.");
121 std::string position_group_name = particle_group_name_ +
"/position";
125 "Unable to open " + position_group_name +
" group");
129 "Unable to open " + position_group_name +
"/value dataset");
132 std::string box_gr_name = particle_group_name_ +
"/box";
133 hid_t g_box = H5Gopen(
particle_group_, box_gr_name.c_str(), H5P_DEFAULT);
134 CheckError(g_box,
"Unable to open " + box_gr_name +
" group");
135 hid_t at_box_dimension = H5Aopen(g_box,
"dimension", H5P_DEFAULT);
136 CheckError(at_box_dimension,
"Unable to open dimension attribute.");
138 H5Aread(at_box_dimension, H5Aget_type(at_box_dimension), &dimension);
139 if (dimension != 3) {
140 throw ios_base::failure(
"Wrong dimension " +
141 boost::lexical_cast<std::string>(dimension));
144 std::string box_edges_name = particle_group_name_ +
"/box/edges";
149 cout <<
"H5MD: has /box/edges" << endl;
150 cout <<
"H5MD: time dependent box size" << endl;
153 cout <<
"H5MD: static box" << endl;
154 hid_t ds_edges = H5Dopen(g_box,
"edges", H5P_DEFAULT);
155 CheckError(ds_edges,
"Unable to open /box/edges");
156 std::unique_ptr<double[]> box = std::unique_ptr<double[]>{
new double[3]};
158 cout <<
"H5MD: Found box " << box[0] <<
" x " << box[1] <<
" x " << box[2]
161 m = Eigen::Matrix3d::Zero();
171 std::string force_group_name = particle_group_name_ +
"/force";
177 cout <<
"H5MD: has /force" << endl;
183 std::string velocity_group_name = particle_group_name_ +
"/velocity";
189 cout <<
"H5MD: has /velocity" << endl;
195 std::string id_group_name = particle_group_name_ +
"/id";
201 cout <<
"H5MD: has /id group" << endl;
215 CheckError(fs_atom_position_,
"Unable to open atom position space.");
217 rank_ = H5Sget_simple_extent_dims(fs_atom_position_, dims,
nullptr);
226 cout <<
"Warning: The number of beads (" <<
N_particles_ <<
")";
227 cout <<
" in the trajectory is different than defined in the topology ("
229 cout <<
"The number of beads from topology will be used!" << endl;
252 cout <<
'\r' <<
"Reading frame: " <<
idx_frame_ <<
"\n";
257 std::unique_ptr<double[]> box = std::unique_ptr<double[]>{
new double[3]};
259 m = Eigen::Matrix3d::Zero();
263 cout <<
"Time dependent box:" << endl;
269 double *forces =
nullptr;
270 double *velocities =
nullptr;
276 }
catch (
const std::runtime_error &
e) {
302 Index atom_id = at_idx;
304 if (ids[at_idx] == -1) {
307 atom_id = ids[at_idx];
314 throw std::runtime_error(
"Bead not found: " +
315 boost::lexical_cast<std::string>(atom_id));
318 b->
setPos(Eigen::Vector3d(x, y, z));
324 b->
setVel(Eigen::Vector3d(vx, vy, vz));
332 b->
setF(Eigen::Vector3d(fx, fy, fz));
352 std::unique_ptr<
double[]> &data_out) {
359 hid_t dsp = H5Dget_space(ds);
360 H5Sselect_hyperslab(dsp, H5S_SELECT_SET, offset,
nullptr, ch_rows,
nullptr);
361 hid_t mspace1 = H5Screate_simple(2, ch_rows,
nullptr);
363 H5Dread(ds, ds_data_type, mspace1, dsp, H5P_DEFAULT, data_out.get());
365 throw std::runtime_error(
"Error ReadScalarData: " +
366 boost::lexical_cast<std::string>(status));
371 const std::string &unit_type) {
372 hid_t unit_attr = H5Aopen(ds,
"unit", H5P_DEFAULT);
373 double scaling_factor = 1.0;
375 hid_t type_id = H5Aget_type(unit_attr);
376 hid_t atype_mem = H5Tget_native_type(type_id, H5T_DIR_ASCEND);
377 hsize_t str_size = H5Tget_size(type_id);
378 char buffer[80] = {0};
379 H5Aread(unit_attr, atype_mem, &buffer);
382 std::string value = std::string(buffer, str_size);
387 boost::smatch suffix_match;
390 boost::match_extra)) {
393 unit_pow = std::stoi(suffix_match[2]);
398 scaling_factor * pow(votca_scaling_factor->second, unit_pow);
401 std::cout <<
"Found units " << value <<
" for " << unit_type <<
".";
402 if (scaling_factor != 1.0) {
403 std::cout <<
" Values scaled by a factor " << scaling_factor;
405 std::cout << std::endl;
408 return scaling_factor;
virtual void setPos(const Eigen::Vector3d &bead_position)
void setF(const Eigen::Vector3d &bead_force)
void setVel(const Eigen::Vector3d &r)
DatasetState has_id_group_
void Close() override
Closes original trajectory file.
double ReadScaleFactor(const hid_t &ds, const std::string &unit_type)
~H5MDTrajectoryReader() override
DatasetState has_velocity_
hid_t atom_position_group_
void ReadBox(hid_t ds, hid_t ds_data_type, Index row, std::unique_ptr< double[]> &data_out)
void ReadStaticData(hid_t ds, hid_t ds_data_type, std::unique_ptr< T1 > &outbuf)
bool NextFrame(Topology &conf) override
Reads in the next frame.
T1 * ReadVectorData(hid_t ds, hid_t ds_data_type, Index row)
Reads dataset that contains vectors.
void CheckError(hid_t hid, std::string error_message)
T1 * ReadScalarData(hid_t ds, hid_t ds_data_type, Index row)
Reads dataset with scalar values.
boost::regex suffix_units
std::unordered_map< std::string, double > votca_units_scaling_factors
bool GroupExists(hid_t file_id, std::string path)
void Initialize(Topology &top)
Initialize data structures.
bool Open(const std::string &file) override
Opens original trajectory file.
bool FirstFrame(Topology &conf) override
Reads in the first frame.
bool unit_module_enabled_
hid_t atom_velocity_group_
topology of the whole system
void setBox(const Eigen::Matrix3d &box, BoundaryCondition::eBoxtype boxtype=BoundaryCondition::typeAuto)
std::string getParticleGroup() const
Bead * getBead(const Index i)
Returns a pointer to the bead with index i.
base class for all analysis tools