Skip to content

Commit

Permalink
Unformatted state I/O for metadynamics
Browse files Browse the repository at this point in the history
  • Loading branch information
giacomofiorin committed Aug 25, 2023
1 parent d6f5a7a commit d89808d
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 58 deletions.
162 changes: 110 additions & 52 deletions src/colvarbias_meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1342,10 +1342,10 @@ template <typename IST> IST &colvarbias_meta::read_state_data_template_(IST &is)
hills_energy_gradients = new colvar_grid_gradient(colvars);
}

read_grid_data_template_<std::istream, colvar_grid_scalar>(is, "hills_energy", hills_energy,
hills_energy_backup);
read_grid_data_template_<IST, colvar_grid_scalar>(is, "hills_energy", hills_energy,
hills_energy_backup);

read_grid_data_template_<std::istream, colvar_grid_gradient>(
read_grid_data_template_<IST, colvar_grid_gradient>(
is, "hills_energy_gradients", hills_energy_gradients, hills_energy_gradients_backup);

if (is) {
Expand Down Expand Up @@ -1375,9 +1375,9 @@ template <typename IST> IST &colvarbias_meta::read_state_data_template_(IST &is)
while (read_hill(is)) {
if (cvm::debug()) {
cvm::log("Read a previously saved hill under the "
"metadynamics bias \""+
this->name+"\", created at step "+
cvm::to_str((hills.back()).it)+".\n");
"metadynamics bias \"" +
this->name + "\", created at step " + cvm::to_str((hills.back()).it) +
"; position in stream is " + cvm::to_str(is.tellg()) + ".\n");
}
}

Expand Down Expand Up @@ -1429,10 +1429,10 @@ std::istream & colvarbias_meta::read_state_data(std::istream& is)
}


// cvm::memory_stream &colvarbias_meta::read_state_data(cvm::memory_stream &is)
// {
// return read_state_data_template_<cvm::memory_stream>(is);
// }
cvm::memory_stream &colvarbias_meta::read_state_data(cvm::memory_stream &is)
{
return read_state_data_template_<cvm::memory_stream>(is);
}


void colvarbias_meta::rebin_grids_after_restart()
Expand Down Expand Up @@ -1486,45 +1486,78 @@ void colvarbias_meta::rebin_grids_after_restart()
}


std::ostream &colvarbias_meta::write_hill(std::ostream &os, colvarbias_meta::hill const &h)
template <typename OST>
OST &colvarbias_meta::write_hill_template_(OST &os, colvarbias_meta::hill const &h)
{
os.setf(std::ios::scientific, std::ios::floatfield);
bool const formatted = !std::is_same<OST, cvm::memory_stream>::value;

if (formatted) {
os.setf(std::ios::scientific, std::ios::floatfield);
}

write_state_data_key(os, "hill", false);

os << "{\n";
if (formatted)
os << "{\n";

write_state_data_key(os, "step", false);
os << std::setw(cvm::it_width) << h.it << "\n";
os << std::setw(cvm::it_width) << h.it;
if (formatted)
os << "\n";

write_state_data_key(os, "weight", false);
os << std::setprecision(cvm::en_prec) << std::setw(cvm::en_width) << h.W << "\n";
os << std::setprecision(cvm::en_prec) << std::setw(cvm::en_width) << h.W;
if (formatted)
os << "\n";

if (h.replica.size()) {
write_state_data_key(os, "replicaID", false);
os << h.replica << "\n";
os << h.replica;
if (formatted) {
os << "\n";
}
}

size_t i;
write_state_data_key(os, "centers", false);
for (i = 0; i < (h.centers).size(); i++) {
os << " " << std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width) << h.centers[i];
if (formatted)
os << " " << std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width);
os << h.centers[i];
}
os << "\n";
if (formatted)
os << "\n";

// For backward compatibility, write the widths instead of the sigmas
write_state_data_key(os, "widths", false);
for (i = 0; i < (h.sigmas).size(); i++) {
os << " " << std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width) << 2.0 * h.sigmas[i];
if (formatted)
os << " ";
os << std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width) << 2.0 * h.sigmas[i];
}
os << "\n";
if (formatted)
os << "\n";

os << "}\n";
if (formatted)
os << "}\n";

return os;
}


std::ostream &colvarbias_meta::write_hill(std::ostream &os, colvarbias_meta::hill const &h)
{
return write_hill_template_<std::ostream>(os, h);
}


cvm::memory_stream &colvarbias_meta::write_hill(cvm::memory_stream &os,
colvarbias_meta::hill const &h)
{
return write_hill_template_<cvm::memory_stream>(os, h);
}


template <typename IST> IST &hill_stream_error(IST &is, size_t start_pos, std::string const &key)
{
is.clear();
Expand All @@ -1536,23 +1569,29 @@ template <typename IST> IST &hill_stream_error(IST &is, size_t start_pos, std::s
}


std::istream &colvarbias_meta::read_hill(std::istream &is)
template <typename IST> IST &colvarbias_meta::read_hill_template_(IST &is)
{
if (!is)
return is; // do nothing if failbit is set

bool const formatted = !std::is_same<IST, cvm::memory_stream>::value;

auto const start_pos = is.tellg();

std::string data;
if (!(is >> read_block("hill", &data))) {
auto state = is.rdstate();
std::string key;
if (!(is >> key) || (key != "hill")) {
is.clear();
is.seekg(start_pos);
is.setstate(state);
is.setstate(std::ios::failbit);
return is;
}

std::istringstream data_is(data);
if (formatted) {
std::string brace;
if (!(is >> brace) || (brace != "{")) {
return hill_stream_error<IST>(is, start_pos, "hill");
}
}

cvm::step_number h_it = 0L;
cvm::real h_weight;
Expand All @@ -1563,45 +1602,38 @@ std::istream &colvarbias_meta::read_hill(std::istream &is)
std::vector<cvm::real> h_sigmas(num_variables());
std::string h_replica;

if (!read_state_data_key(data_is, "step") || !(data_is >> h_it)) {
return hill_stream_error<std::istream>(is, start_pos, "step");
if (!read_state_data_key(is, "step") || !(is >> h_it)) {
return hill_stream_error<IST>(is, start_pos, "step");
}

if ((h_it <= state_file_step) && !restart_keep_hills) {
if (cvm::debug())
cvm::log("Skipping a hill older than the state file for metadynamics bias \"" + this->name +
"\"" + ((comm != single_replica) ? ", replica \"" + replica_id + "\"" : "") + "\n");
return is;
}

if (read_state_data_key(data_is, "weight")) {
if (!(data_is >> h_weight)) {
return hill_stream_error<std::istream>(is, start_pos, "weight");
if (read_state_data_key(is, "weight")) {
if (!(is >> h_weight)) {
return hill_stream_error<IST>(is, start_pos, "weight");
}
}

if (read_state_data_key(data_is, "centers")) {
if (read_state_data_key(is, "centers")) {
for (size_t i = 0; i < num_variables(); i++) {
if (!(data_is >> h_centers[i])) {
return hill_stream_error<std::istream>(is, start_pos, "centers");
if (!(is >> h_centers[i])) {
return hill_stream_error<IST>(is, start_pos, "centers");
}
}
}

if (read_state_data_key(data_is, "widths")) {
if (read_state_data_key(is, "widths")) {
for (size_t i = 0; i < num_variables(); i++) {
if (!(data_is >> h_sigmas[i])) {
return hill_stream_error<std::istream>(is, start_pos, "widths");
if (!(is >> h_sigmas[i])) {
return hill_stream_error<IST>(is, start_pos, "widths");
}
// For backward compatibility, read the widths instead of the sigmas
h_sigmas[i] /= 2.0;
}
}

if (comm != single_replica) {
if (read_state_data_key(data_is, "replicaID")) {
if (!(data_is >> h_replica)) {
return hill_stream_error<std::istream>(is, start_pos, "replicaID");
if (read_state_data_key(is, "replicaID")) {
if (!(is >> h_replica)) {
return hill_stream_error<IST>(is, start_pos, "replicaID");
}
if (h_replica != replica_id) {
cvm::error("Error: trying to read a hill created by replica \"" + h_replica +
Expand All @@ -1611,6 +1643,20 @@ std::istream &colvarbias_meta::read_hill(std::istream &is)
}
}

if (formatted) {
std::string brace;
if (!(is >> brace) || (brace != "}")) {
return hill_stream_error<IST>(is, start_pos, "hill");
}
}

if ((h_it <= state_file_step) && !restart_keep_hills) {
if (cvm::debug())
cvm::log("Skipping a hill older than the state file for metadynamics bias \"" + this->name +
"\"" + ((comm != single_replica) ? ", replica \"" + replica_id + "\"" : "") + "\n");
return is;
}

hill_iter const hills_end = hills.end();
hills.push_back(hill(h_it, h_weight, h_centers, h_sigmas, h_replica));
if (new_hills_begin == hills_end) {
Expand All @@ -1634,6 +1680,18 @@ std::istream &colvarbias_meta::read_hill(std::istream &is)
}


std::istream &colvarbias_meta::read_hill(std::istream &is)
{
return read_hill_template_<std::istream>(is);
}


cvm::memory_stream &colvarbias_meta::read_hill(cvm::memory_stream &is)
{
return read_hill_template_<cvm::memory_stream>(is);
}


int colvarbias_meta::setup_output()
{
int error_code = COLVARS_OK;
Expand Down Expand Up @@ -1803,10 +1861,10 @@ std::ostream & colvarbias_meta::write_state_data(std::ostream& os)
}


// cvm::memory_stream &colvarbias_meta::write_state_data(cvm::memory_stream &os)
// {
// return write_state_data_template_<cvm::memory_stream>(os);
// }
cvm::memory_stream &colvarbias_meta::write_state_data(cvm::memory_stream &os)
{
return write_state_data_template_<cvm::memory_stream>(os);
}


int colvarbias_meta::write_state_to_replicas()
Expand Down
22 changes: 16 additions & 6 deletions src/colvarbias_meta.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ class colvarbias_meta
virtual int set_state_params(std::string const &state_conf);

virtual std::ostream &write_state_data(std::ostream &os);
// virtual cvm::memory_stream &write_state_data(cvm::memory_stream &os);
virtual cvm::memory_stream &write_state_data(cvm::memory_stream &os);
virtual std::istream &read_state_data(std::istream &is);
// virtual cvm::memory_stream &read_state_data(cvm::memory_stream &is);
virtual cvm::memory_stream &read_state_data(cvm::memory_stream &is);

private:

Expand Down Expand Up @@ -123,14 +123,24 @@ class colvarbias_meta

/// Regenerate the hills_off_grid list
void recount_hills_off_grid(hill_iter h_first, hill_iter h_last,
colvar_grid_scalar *ge);
colvar_grid_scalar *ge);

/// Write a hill to a stream
std::ostream & write_hill(std::ostream &os, hill const &h);
template <typename OST> OST &write_hill_template_(OST &os, colvarbias_meta::hill const &h);

/// Read a new hill from a state stream
/// Write a hill to a formatted stream
std::ostream &write_hill(std::ostream &os, hill const &h);

/// Write a hill to an unformatted stream
cvm::memory_stream &write_hill(cvm::memory_stream &os, hill const &h);

template <typename IST> IST &read_hill_template_(IST &is);

/// Read a new hill from a formatted stream
std::istream & read_hill(std::istream &is);

/// Read a new hill from an unformatted stream
cvm::memory_stream & read_hill(cvm::memory_stream &is);

/// \brief Add a new hill; if a .hills trajectory is written,
/// write it there; if there is more than one replica, communicate
/// it to the others
Expand Down

0 comments on commit d89808d

Please sign in to comment.