From d89808dad164f21103abf9d0da17b000b10d6af2 Mon Sep 17 00:00:00 2001 From: Giacomo Fiorin Date: Fri, 25 Aug 2023 12:06:18 +0200 Subject: [PATCH] Unformatted state I/O for metadynamics --- src/colvarbias_meta.cpp | 162 +++++++++++++++++++++++++++------------- src/colvarbias_meta.h | 22 ++++-- 2 files changed, 126 insertions(+), 58 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 41d8348d2..86128c6e5 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1342,10 +1342,10 @@ template IST &colvarbias_meta::read_state_data_template_(IST &is) hills_energy_gradients = new colvar_grid_gradient(colvars); } - read_grid_data_template_(is, "hills_energy", hills_energy, - hills_energy_backup); + read_grid_data_template_(is, "hills_energy", hills_energy, + hills_energy_backup); - read_grid_data_template_( + read_grid_data_template_( is, "hills_energy_gradients", hills_energy_gradients, hills_energy_gradients_backup); if (is) { @@ -1375,9 +1375,9 @@ template 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"); } } @@ -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_(is); -// } +cvm::memory_stream &colvarbias_meta::read_state_data(cvm::memory_stream &is) +{ + return read_state_data_template_(is); +} void colvarbias_meta::rebin_grids_after_restart() @@ -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 +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::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_(os, h); +} + + +cvm::memory_stream &colvarbias_meta::write_hill(cvm::memory_stream &os, + colvarbias_meta::hill const &h) +{ + return write_hill_template_(os, h); +} + + template IST &hill_stream_error(IST &is, size_t start_pos, std::string const &key) { is.clear(); @@ -1536,23 +1569,29 @@ template IST &hill_stream_error(IST &is, size_t start_pos, std::s } -std::istream &colvarbias_meta::read_hill(std::istream &is) +template IST &colvarbias_meta::read_hill_template_(IST &is) { if (!is) return is; // do nothing if failbit is set + bool const formatted = !std::is_same::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(is, start_pos, "hill"); + } + } cvm::step_number h_it = 0L; cvm::real h_weight; @@ -1563,35 +1602,28 @@ std::istream &colvarbias_meta::read_hill(std::istream &is) std::vector h_sigmas(num_variables()); std::string h_replica; - if (!read_state_data_key(data_is, "step") || !(data_is >> h_it)) { - return hill_stream_error(is, start_pos, "step"); + if (!read_state_data_key(is, "step") || !(is >> h_it)) { + return hill_stream_error(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(is, start_pos, "weight"); + if (read_state_data_key(is, "weight")) { + if (!(is >> h_weight)) { + return hill_stream_error(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(is, start_pos, "centers"); + if (!(is >> h_centers[i])) { + return hill_stream_error(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(is, start_pos, "widths"); + if (!(is >> h_sigmas[i])) { + return hill_stream_error(is, start_pos, "widths"); } // For backward compatibility, read the widths instead of the sigmas h_sigmas[i] /= 2.0; @@ -1599,9 +1631,9 @@ std::istream &colvarbias_meta::read_hill(std::istream &is) } if (comm != single_replica) { - if (read_state_data_key(data_is, "replicaID")) { - if (!(data_is >> h_replica)) { - return hill_stream_error(is, start_pos, "replicaID"); + if (read_state_data_key(is, "replicaID")) { + if (!(is >> h_replica)) { + return hill_stream_error(is, start_pos, "replicaID"); } if (h_replica != replica_id) { cvm::error("Error: trying to read a hill created by replica \"" + h_replica + @@ -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(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) { @@ -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_(is); +} + + +cvm::memory_stream &colvarbias_meta::read_hill(cvm::memory_stream &is) +{ + return read_hill_template_(is); +} + + int colvarbias_meta::setup_output() { int error_code = COLVARS_OK; @@ -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_(os); -// } +cvm::memory_stream &colvarbias_meta::write_state_data(cvm::memory_stream &os) +{ + return write_state_data_template_(os); +} int colvarbias_meta::write_state_to_replicas() diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index c6d916b38..f85bb0fdc 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -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: @@ -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 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 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