update colvars to version 2016-08-10

This commit is contained in:
Axel Kohlmeyer
2016-08-10 09:03:25 -04:00
parent aef16fed2a
commit f2ddf828e4
14 changed files with 222 additions and 241 deletions

View File

@ -43,7 +43,8 @@ colvar::colvar(std::string const &conf)
kinetic_energy = 0.0;
potential_energy = 0.0;
cvm::combine_errors(error_code, init_components(conf));
error_code |= init_components(conf);
if (error_code != COLVARS_OK) return;
size_t i;
@ -492,110 +493,44 @@ int colvar::init_components(std::string const &conf)
{
int error_code = COLVARS_OK;
cvm::combine_errors(error_code,
init_components_type<distance>(conf,
"distance", "distance"));
cvm::combine_errors(error_code,
init_components_type<distance_vec>(conf,
"distance vector", "distanceVec"));
cvm::combine_errors(error_code,
init_components_type<cartesian>(conf,
"Cartesian coordinates", "cartesian"));
cvm::combine_errors(error_code,
init_components_type<distance_dir>(conf,
"distance vector "
"direction", "distanceDir"));
cvm::combine_errors(error_code,
init_components_type<distance_z>(conf,
"distance projection "
"on an axis", "distanceZ"));
cvm::combine_errors(error_code,
init_components_type<distance_xy>(conf,
"distance projection "
"on a plane", "distanceXY"));
cvm::combine_errors(error_code,
init_components_type<distance_inv>(conf,
"average distance "
"weighted by inverse power",
"distanceInv"));
cvm::combine_errors(error_code,
init_components_type<distance_pairs>(conf,
"N1xN2-long vector "
"of pairwise distances",
"distancePairs"));
cvm::combine_errors(error_code,
init_components_type<coordnum>(conf,
"coordination "
"number", "coordNum"));
cvm::combine_errors(error_code,
init_components_type<selfcoordnum>(conf,
"self-coordination "
"number", "selfCoordNum"));
cvm::combine_errors(error_code,
init_components_type<angle>(conf,
"angle", "angle"));
cvm::combine_errors(error_code,
init_components_type<dipole_angle>(conf,
"dipole angle", "dipoleAngle"));
cvm::combine_errors(error_code,
init_components_type<dihedral>(conf,
"dihedral", "dihedral"));
cvm::combine_errors(error_code,
init_components_type<h_bond>(conf,
"hydrogen bond", "hBond"));
// cvm::combine_errors(error_code, init_components_type<alpha_dihedrals>(conf, "alpha helix", "alphaDihedrals"));
cvm::combine_errors(error_code,
init_components_type<alpha_angles>(conf,
"alpha helix", "alpha"));
cvm::combine_errors(error_code,
init_components_type<dihedPC>(conf,
"dihedral "
"principal component", "dihedralPC"));
cvm::combine_errors(error_code,
init_components_type<orientation>(conf,
"orientation", "orientation"));
cvm::combine_errors(error_code,
init_components_type<orientation_angle>(conf,
"orientation "
"angle", "orientationAngle"));
cvm::combine_errors(error_code,
init_components_type<orientation_proj>(conf,
"orientation "
"projection", "orientationProj"));
cvm::combine_errors(error_code,
init_components_type<tilt>(conf,
"tilt", "tilt"));
cvm::combine_errors(error_code,
init_components_type<spin_angle>(conf,
"spin angle", "spinAngle"));
cvm::combine_errors(error_code,
init_components_type<rmsd>(conf,
"RMSD", "rmsd"));
// cvm::combine_errors(error_code, init_components_type <logmsd>(conf,"logarithm of MSD", "logmsd"));
cvm::combine_errors(error_code,
init_components_type<gyration>(conf,
"radius of "
"gyration", "gyration"));
cvm::combine_errors(error_code,
init_components_type<inertia>(conf,
"moment of "
"inertia", "inertia"));
cvm::combine_errors(error_code,
init_components_type<inertia_z>(conf,
"moment of inertia around an axis",
"inertiaZ"));
cvm::combine_errors(error_code,
init_components_type<eigenvector>(conf,
"eigenvector", "eigenvector"));
error_code |= init_components_type<distance>(conf, "distance", "distance");
error_code |= init_components_type<distance_vec>(conf, "distance vector", "distanceVec");
error_code |= init_components_type<cartesian>(conf, "Cartesian coordinates", "cartesian");
error_code |= init_components_type<distance_dir>(conf, "distance vector "
"direction", "distanceDir");
error_code |= init_components_type<distance_z>(conf, "distance projection "
"on an axis", "distanceZ");
error_code |= init_components_type<distance_xy>(conf, "distance projection "
"on a plane", "distanceXY");
error_code |= init_components_type<distance_inv>(conf, "average distance "
"weighted by inverse power", "distanceInv");
error_code |= init_components_type<distance_pairs>(conf, "N1xN2-long vector "
"of pairwise distances", "distancePairs");
error_code |= init_components_type<coordnum>(conf, "coordination "
"number", "coordNum");
error_code |= init_components_type<selfcoordnum>(conf, "self-coordination "
"number", "selfCoordNum");
error_code |= init_components_type<angle>(conf, "angle", "angle");
error_code |= init_components_type<dipole_angle>(conf, "dipole angle", "dipoleAngle");
error_code |= init_components_type<dihedral>(conf, "dihedral", "dihedral");
error_code |= init_components_type<h_bond>(conf, "hydrogen bond", "hBond");
error_code |= init_components_type<alpha_angles>(conf, "alpha helix", "alpha");
error_code |= init_components_type<dihedPC>(conf, "dihedral "
"principal component", "dihedralPC");
error_code |= init_components_type<orientation>(conf, "orientation", "orientation");
error_code |= init_components_type<orientation_angle>(conf, "orientation "
"angle", "orientationAngle");
error_code |= init_components_type<orientation_proj>(conf, "orientation "
"projection", "orientationProj");
error_code |= init_components_type<tilt>(conf, "tilt", "tilt");
error_code |= init_components_type<spin_angle>(conf, "spin angle", "spinAngle");
error_code |= init_components_type<rmsd>(conf, "RMSD", "rmsd");
error_code |= init_components_type<gyration>(conf, "radius of "
"gyration", "gyration");
error_code |= init_components_type<inertia>(conf, "moment of "
"inertia", "inertia");
error_code |= init_components_type<inertia_z>(conf, "moment of inertia around an axis", "inertiaZ");
error_code |= init_components_type<eigenvector>(conf, "eigenvector", "eigenvector");
if (!cvcs.size() || (error_code != COLVARS_OK)) {
cvm::error("Error: no valid components were provided "
@ -732,7 +667,7 @@ int colvar::parse_analysis(std::string const &conf)
} else {
cvm::log("Unknown type of correlation function, \""+
acf_type_str+"\".\n");
cvm::set_error_bit(INPUT_ERROR);
cvm::set_error_bits(INPUT_ERROR);
}
get_keyval(conf, "corrFuncOffset", acf_offset, 0);
@ -803,9 +738,11 @@ int colvar::calc()
// Note: if anything is added here, it should be added also in the SMP block of calc_colvars()
int error_code = COLVARS_OK;
if (is_enabled(f_cv_active)) {
cvm::combine_errors(error_code, update_cvc_flags());
cvm::combine_errors(error_code, calc_cvcs());
cvm::combine_errors(error_code, collect_cvc_data());
error_code |= update_cvc_flags();
if (error_code != COLVARS_OK) return error_code;
error_code |= calc_cvcs();
if (error_code != COLVARS_OK) return error_code;
error_code |= collect_cvc_data();
}
return error_code;
}
@ -818,15 +755,15 @@ int colvar::calc_cvcs(int first_cvc, size_t num_cvcs)
cvm::log("Calculating colvar \""+this->name+"\", components "+
cvm::to_str(first_cvc)+" through "+cvm::to_str(first_cvc+num_cvcs)+".\n");
cvm::combine_errors(error_code, check_cvc_range(first_cvc, num_cvcs));
error_code |= check_cvc_range(first_cvc, num_cvcs);
if (error_code != COLVARS_OK) {
return error_code;
}
cvm::combine_errors(error_code, calc_cvc_values(first_cvc, num_cvcs));
cvm::combine_errors(error_code, calc_cvc_gradients(first_cvc, num_cvcs));
cvm::combine_errors(error_code, calc_cvc_sys_forces(first_cvc, num_cvcs));
cvm::combine_errors(error_code, calc_cvc_Jacobians(first_cvc, num_cvcs));
error_code |= calc_cvc_values(first_cvc, num_cvcs);
error_code |= calc_cvc_gradients(first_cvc, num_cvcs);
error_code |= calc_cvc_sys_forces(first_cvc, num_cvcs);
error_code |= calc_cvc_Jacobians(first_cvc, num_cvcs);
if (cvm::debug())
cvm::log("Done calculating colvar \""+this->name+"\".\n");
@ -842,12 +779,11 @@ int colvar::collect_cvc_data()
int error_code = COLVARS_OK;
cvm::combine_errors(error_code, collect_cvc_values());
cvm::combine_errors(error_code, collect_cvc_gradients());
cvm::combine_errors(error_code, collect_cvc_sys_forces());
cvm::combine_errors(error_code, collect_cvc_Jacobians());
cvm::combine_errors(error_code, calc_colvar_properties());
error_code |= collect_cvc_values();
error_code |= collect_cvc_gradients();
error_code |= collect_cvc_sys_forces();
error_code |= collect_cvc_Jacobians();
error_code |= calc_colvar_properties();
if (cvm::debug())
cvm::log("Done calculating colvar \""+this->name+"\"'s properties.\n");
@ -1374,7 +1310,7 @@ bool colvar::periodic_boundaries(colvarvalue const &lb, colvarvalue const &ub) c
if ( (!is_enabled(f_cv_lower_boundary)) || (!is_enabled(f_cv_upper_boundary)) ) {
cvm::log("Error: checking periodicity for collective variable \""+this->name+"\" "
"requires lower and upper boundaries to be defined.\n");
cvm::set_error_bit(INPUT_ERROR);
cvm::set_error_bits(INPUT_ERROR);
}
if (period > 0.0) {

View File

@ -297,7 +297,7 @@ int cvm::atom_group::parse(std::string const &conf)
std::string numbers_conf = "";
size_t pos = 0;
while (key_lookup(group_conf, "atomNumbers", numbers_conf, pos)) {
cvm::combine_errors(parse_error, add_atom_numbers(numbers_conf));
parse_error |= add_atom_numbers(numbers_conf);
numbers_conf = "";
}
}
@ -306,7 +306,7 @@ int cvm::atom_group::parse(std::string const &conf)
std::string index_group_name;
if (get_keyval(group_conf, "indexGroup", index_group_name)) {
// use an index group from the index file read globally
cvm::combine_errors(parse_error, add_index_group(index_group_name));
parse_error |= add_index_group(index_group_name);
}
}
@ -315,7 +315,7 @@ int cvm::atom_group::parse(std::string const &conf)
size_t pos = 0;
while (key_lookup(group_conf, "atomNumbersRange",
range_conf, pos)) {
cvm::combine_errors(parse_error, add_atom_numbers_range(range_conf));
parse_error |= add_atom_numbers_range(range_conf);
range_conf = "";
}
}
@ -342,8 +342,8 @@ int cvm::atom_group::parse(std::string const &conf)
cvm::error("Error: more instances of \"atomNameResidueRange\" than "
"values of \"psfSegID\".\n", INPUT_ERROR);
} else {
cvm::combine_errors(parse_error, add_atom_name_residue_range(psf_segids.size() ?
*psii : std::string(""), range_conf));
parse_error |= add_atom_name_residue_range(psf_segids.size() ?
*psii : std::string(""), range_conf);
if (psf_segids.size()) psii++;
}
range_conf = "";
@ -407,7 +407,7 @@ int cvm::atom_group::parse(std::string const &conf)
index = (cvm::proxy)->init_atom_group(atoms_ids);
}
cvm::combine_errors(parse_error, parse_fitting_options(group_conf));
parse_error |= parse_fitting_options(group_conf);
// TODO move this to colvarparse object
check_keywords(group_conf, key.c_str());

View File

@ -203,7 +203,7 @@ cvm::real colvarbias::energy_difference(std::string const &conf)
}
// So far, these are only implemented in colvarsbias_abf
// So far, these are only implemented in colvarbias_abf
int colvarbias::bin_num()
{
cvm::error("Error: bin_num() not implemented.\n");

View File

@ -104,7 +104,7 @@ int colvarbias_histogram::update()
{
int error_code = COLVARS_OK;
// update base class
cvm::combine_errors(error_code, colvarbias::update());
error_code |= colvarbias::update();
if (cvm::debug()) {
cvm::log("Updating histogram bias " + this->name);
@ -157,7 +157,7 @@ int colvarbias_histogram::update()
write_output_files();
}
cvm::combine_errors(error_code, cvm::get_error());
error_code |= cvm::get_error();
return error_code;
}

View File

@ -43,11 +43,7 @@ colvar::cvc::cvc(std::string const &conf)
// All cvcs implement this
provide(f_cvc_debug_gradient);
{
bool b_debug_gradient;
get_keyval(conf, "debugGradients", b_debug_gradient, false, parse_silent);
if (b_debug_gradient) enable(f_cvc_debug_gradient);
}
get_keyval(conf, "debugGradients", set_feature(f_cvc_debug_gradient), false, parse_silent);
// Attempt scalable calculations when in parallel? (By default yes, if available)
get_keyval(conf, "scalable", b_try_scalable, true);

View File

@ -215,7 +215,7 @@ void cvm::deps::init_cvb_requires() {
// Initialize feature_states for each instance
feature_states.reserve(f_cvb_ntot);
for (i = 0; i < f_cvb_ntot; i++) {
feature_states.push_back(new feature_state(true, false));
feature_states.push_back(new feature_state(this, feature_states.size(), true, false));
// Most features are available, so we set them so
// and list exceptions below
}
@ -319,7 +319,7 @@ void cvm::deps::init_cv_requires() {
// Initialize feature_states for each instance
feature_states.reserve(f_cv_ntot);
for (i = 0; i < f_cv_ntot; i++) {
feature_states.push_back(new feature_state(true, false));
feature_states.push_back(new feature_state(this, feature_states.size(), true, false));
// Most features are available, so we set them so
// and list exceptions below
}
@ -385,7 +385,7 @@ void cvm::deps::init_cvc_requires() {
// default as unavailable, not enabled
feature_states.reserve(f_cvc_ntot);
for (i = 0; i < cvm::deps::f_cvc_ntot; i++) {
feature_states.push_back(new feature_state(false, false));
feature_states.push_back(new feature_state(this, feature_states.size(), false, false));
}
// Features that are implemented by all cvcs by default
@ -429,7 +429,7 @@ void cvm::deps::init_ag_requires() {
// default as unavailable, not enabled
feature_states.reserve(f_ag_ntot);
for (i = 0; i < cvm::deps::f_ag_ntot; i++) {
feature_states.push_back(new feature_state(false, false));
feature_states.push_back(new feature_state(this, feature_states.size(), false, false));
}
// Features that are implemented (or not) by all atom groups

View File

@ -27,9 +27,16 @@ public:
std::string description; // reference to object name (cv, cvc etc.)
/// This contains the current state of each feature for each object
struct feature_state {
feature_state(bool a, bool e)
: available(a), enabled(e) {}
class feature_state {
private:
cvm::deps *const deps_object;
int const id;
operator int() {} // never cast as int
public:
inline cvm::deps *object() const { return deps_object; }
inline int feature_id() const { return id; }
feature_state(cvm::deps *o, int i, bool a, bool e)
: deps_object(o), id(i), available(a), enabled(e) {}
/// Available means: supported, subject to dependencies as listed,
/// MAY BE ENABLED AS A RESULT OF DEPENDENCY SOLVING
@ -48,6 +55,12 @@ public:
/// List of the state of all features
std::vector<feature_state *> feature_states;
/// Allow setting a feature state while parsing its kewyord
inline feature_state * set_feature(int id)
{
return feature_states[id];
}
/// Describes a feature and its dependecies
/// used in a static array within each subclass
class feature {

View File

@ -340,8 +340,8 @@ int colvarmodule::parse_biases(std::string const &conf)
int colvarmodule::catch_input_errors(int result)
{
if (result != COLVARS_OK || get_error()) {
set_error_bit(result);
set_error_bit(INPUT_ERROR);
set_error_bits(result);
set_error_bits(INPUT_ERROR);
parse->init();
return get_error();
}
@ -493,27 +493,27 @@ int colvarmodule::calc()
cvm::to_str(cvm::step_absolute())+"\n");
}
combine_errors(error_code, calc_colvars());
error_code |= calc_colvars();
// set biasing forces to zero before biases are calculated and summed over
for (std::vector<colvar *>::iterator cvi = colvars.begin();
cvi != colvars.end(); cvi++) {
(*cvi)->reset_bias_force();
}
combine_errors(error_code, calc_biases());
combine_errors(error_code, update_colvar_forces());
error_code |= calc_biases();
error_code |= update_colvar_forces();
if (cvm::b_analysis) {
combine_errors(error_code, analyze());
error_code |= analyze();
}
// write trajectory files, if needed
if (cv_traj_freq && cv_traj_name.size()) {
combine_errors(error_code, write_traj_files());
error_code |= write_traj_files();
}
// write restart files, if needed
if (restart_out_freq && restart_out_name.size()) {
combine_errors(error_code, write_restart_files());
error_code |= write_restart_files();
}
return error_code;
@ -551,7 +551,7 @@ int colvarmodule::calc_colvars()
for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
if (!(*cvi)->is_enabled()) continue;
combine_errors(error_code, (*cvi)->update_cvc_flags());
error_code |= (*cvi)->update_cvc_flags();
size_t num_items = (*cvi)->num_active_cvcs();
colvars_smp.reserve(colvars_smp.size() + num_items);
@ -566,12 +566,12 @@ int colvarmodule::calc_colvars()
cvm::decrease_depth();
// calculate colvar components in parallel
combine_errors(error_code, proxy->smp_colvars_loop());
error_code |= proxy->smp_colvars_loop();
cvm::increase_depth();
for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
if (!(*cvi)->is_enabled()) continue;
combine_errors(error_code, (*cvi)->collect_cvc_data());
error_code |= (*cvi)->collect_cvc_data();
}
cvm::decrease_depth();
@ -581,7 +581,7 @@ int colvarmodule::calc_colvars()
cvm::increase_depth();
for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
if (!(*cvi)->is_enabled()) continue;
combine_errors(error_code, (*cvi)->calc());
error_code |= (*cvi)->calc();
if (cvm::get_error()) {
return COLVARS_ERROR;
}
@ -589,7 +589,7 @@ int colvarmodule::calc_colvars()
cvm::decrease_depth();
}
combine_errors(error_code, cvm::get_error());
error_code |= cvm::get_error();
return error_code;
}
@ -609,21 +609,21 @@ int colvarmodule::calc_biases()
if (use_scripted_forces && !scripting_after_biases) {
// calculate biases and scripted forces in parallel
combine_errors(error_code, proxy->smp_biases_script_loop());
error_code |= proxy->smp_biases_script_loop();
} else {
// calculate biases in parallel
combine_errors(error_code, proxy->smp_biases_loop());
error_code |= proxy->smp_biases_loop();
}
} else {
if (use_scripted_forces && !scripting_after_biases) {
combine_errors(error_code, calc_scripted_forces());
error_code |= calc_scripted_forces();
}
cvm::increase_depth();
for (bi = biases.begin(); bi != biases.end(); bi++) {
combine_errors(error_code, (*bi)->update());
error_code |= (*bi)->update();
if (cvm::get_error()) {
return COLVARS_ERROR;
}
@ -661,7 +661,7 @@ int colvarmodule::update_colvar_forces()
cvm::decrease_depth();
if (use_scripted_forces && scripting_after_biases) {
combine_errors(error_code, calc_scripted_forces());
error_code |= calc_scripted_forces();
}
cvm::real total_colvar_energy = 0.0;
@ -913,17 +913,17 @@ int colvarmodule::setup_output()
std::string(""));
if (cv_traj_freq && cv_traj_name.size()) {
combine_errors(error_code, open_traj_file(cv_traj_name));
error_code |= open_traj_file(cv_traj_name);
}
for (std::vector<colvarbias *>::iterator bi = biases.begin();
bi != biases.end();
bi++) {
combine_errors(error_code, (*bi)->setup_output());
error_code |= (*bi)->setup_output();
}
if (error_code != COLVARS_OK || cvm::get_error()) {
set_error_bit(FILE_ERROR);
set_error_bits(FILE_ERROR);
}
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
@ -1259,29 +1259,20 @@ size_t & cvm::depth()
}
void colvarmodule::set_error_bit(int code)
void colvarmodule::set_error_bits(int code)
{
if (code > 0) {
cvm::fatal_error("Error: set_error_bit() received positive error code.\n");
if (code < 0) {
cvm::fatal_error("Error: set_error_bits() received negative error code.\n");
return;
}
proxy->smp_lock();
errorCode = -1 * ((-1 * errorCode) | (-1 * code) | (-1 * COLVARS_ERROR));
errorCode |= code | COLVARS_ERROR;
proxy->smp_unlock();
}
bool colvarmodule::get_error_bit(int code)
{
return bool((-1 * errorCode) & (-1 * code));
}
void colvarmodule::combine_errors(int &target, int const code)
{
if (code > 0 || target > 0) {
cvm::fatal_error("Error: combine_errors() received positive error code.\n");
return;
}
target = -1 * ((-1 * target) | (-1 * code));
return bool(errorCode & code);
}
void colvarmodule::clear_error()
@ -1294,7 +1285,7 @@ void colvarmodule::clear_error()
void cvm::error(std::string const &message, int code)
{
set_error_bit(code);
set_error_bits(code);
proxy->error(message);
}
@ -1303,7 +1294,7 @@ void cvm::fatal_error(std::string const &message)
{
// TODO once all non-fatal errors have been set to be handled by error(),
// set DELETE_COLVARS here for VMD to handle it
set_error_bit(FATAL_ERROR);
set_error_bits(FATAL_ERROR);
proxy->fatal_error(message);
}

View File

@ -4,7 +4,7 @@
#define COLVARMODULE_H
#ifndef COLVARS_VERSION
#define COLVARS_VERSION "2016-08-05"
#define COLVARS_VERSION "2016-08-10"
#endif
#ifndef COLVARS_DEBUG
@ -23,19 +23,16 @@
/// shared between all object instances) to be accessed from other
/// objects.
// Error codes are the negative of powers-of-two
// as a result, error codes should NOT be bitwise-ORed but only
// accessed through set_error_bit() and get_error_bit()
#define COLVARS_OK 0
#define COLVARS_ERROR -1
#define COLVARS_NOT_IMPLEMENTED (-1*(1<<1))
#define INPUT_ERROR (-1*(1<<2)) // out of bounds or inconsistent input
#define BUG_ERROR (-1*(1<<3)) // Inconsistent state indicating bug
#define FILE_ERROR (-1*(1<<4))
#define MEMORY_ERROR (-1*(1<<5))
#define FATAL_ERROR (-1*(1<<6)) // Should be set, or not, together with other bits
#define DELETE_COLVARS (-1*(1<<7)) // Instruct the caller to delete cvm
#define COLVARS_NO_SUCH_FRAME (-1*(1<<8)) // Cannot load the requested frame
#define COLVARS_ERROR 1
#define COLVARS_NOT_IMPLEMENTED (1<<1)
#define INPUT_ERROR (1<<2) // out of bounds or inconsistent input
#define BUG_ERROR (1<<3) // Inconsistent state indicating bug
#define FILE_ERROR (1<<4)
#define MEMORY_ERROR (1<<5)
#define FATAL_ERROR (1<<6) // Should be set, or not, together with other bits
#define DELETE_COLVARS (1<<7) // Instruct the caller to delete cvm
#define COLVARS_NO_SUCH_FRAME (1<<8) // Cannot load the requested frame
#include <iostream>
#include <iomanip>
@ -118,12 +115,10 @@ protected:
public:
static void set_error_bit(int code);
static void set_error_bits(int code);
static bool get_error_bit(int code);
static void combine_errors(int &target, int const code);
static inline int get_error()
{
return errorCode;

View File

@ -354,6 +354,21 @@ bool colvarparse::get_keyval(std::string const &conf,
}
bool colvarparse::get_keyval(std::string const &conf,
char const *key,
cvm::deps::feature_state *value,
bool const &def_value,
Parse_Mode const parse_mode)
{
bool feature_flag = def_value;
bool const b_found = get_keyval(conf, key, feature_flag, def_value, parse_mode);
if (feature_flag) {
value->object()->enable(value->feature_id());
}
return b_found;
}
// multiple-value keyword parsers
bool colvarparse::get_keyval(std::string const &conf,
@ -548,6 +563,10 @@ bool colvarparse::key_lookup(std::string const &conf,
std::string &data,
size_t &save_pos)
{
if (cvm::debug()) {
cvm::log("Looking for the keyword \""+std::string(key_in)+"\" and its value.\n");
}
// add this keyword to the register (in its camelCase version)
add_keyword(key_in);
@ -568,11 +587,14 @@ bool colvarparse::key_lookup(std::string const &conf,
// start from the first occurrence of key
size_t pos = conf_lower.find(key, save_pos);
// iterate over all instances until it finds the isolated keyword
// iterate over all instances of the substring until it finds it as isolated keyword
while (true) {
if (pos == std::string::npos) {
// no valid instance of the keyword has been found
if (cvm::debug()) {
cvm::log("Keyword \""+std::string(key_in)+"\" not found.\n");
}
return false;
}
@ -625,25 +647,46 @@ bool colvarparse::key_lookup(std::string const &conf,
size_t data_begin = (to_lower_cppstr(line)).find(key) + key.size();
data_begin = line.find_first_not_of(white_space, data_begin+1);
// size_t data_begin_absolute = data_begin + line_begin;
// size_t data_end_absolute = data_begin;
if (data_begin != std::string::npos) {
size_t data_end = line.find_last_not_of(white_space) + 1;
data_end = (data_end == std::string::npos) ? line.size() : data_end;
// data_end_absolute = data_end + line_begin;
if (line.find('{', data_begin) != std::string::npos) {
size_t brace = line.find('{', data_begin); // look for an opening brace
size_t brace_last = brace;
size_t brace_count = 1;
size_t brace = line.find('{', data_begin); // start from the first opening brace
if (brace != std::string::npos) {
// find the matching closing brace
if (cvm::debug()) {
cvm::log("Multi-line value, config is now \""+line+"\".\n");
}
int brace_count = 1;
while (brace_count > 0) {
// find the matching closing brace
brace = line.find_first_of("{}", brace+1);
while (brace == std::string::npos) {
brace = line.find_first_of("{}", brace_last+1);
// find all braces within this line
while (brace < std::string::npos) {
brace_last = brace;
if (line[brace] == '{') brace_count++;
if (line[brace] == '}') brace_count--;
if (brace_count == 0) {
data_end = brace+1;
break;
}
brace = line.find_first_of("{}", brace+1);
}
if (brace_count == 0) {
data_end = brace+1;
break;
}
if (brace == std::string::npos) {
// add a new line
if (line_end >= conf.size()) {
cvm::error("Parse error: reached the end while "
@ -653,7 +696,6 @@ bool colvarparse::key_lookup(std::string const &conf,
return false;
}
size_t const old_end = line.size();
// data_end_absolute += old_end+1;
line_begin = line_end;
nl = conf.find('\n', line_begin+1);
@ -663,36 +705,37 @@ bool colvarparse::key_lookup(std::string const &conf,
line_end = nl;
line.append(conf, line_begin, (line_end-line_begin));
brace = line.find_first_of("{}", old_end);
if (cvm::debug()) {
cvm::log("Added a new line, config is now \""+line+"\".\n");
}
}
if (line[brace] == '{') brace_count++;
if (line[brace] == '}') brace_count--;
if (brace_count < 0) {
cvm::error("Error: found closing brace without opening brace.\n", INPUT_ERROR);
}
}
// set data_begin after the opening brace
data_begin = line.find_first_of('{', data_begin) + 1;
cvm::log("Value so far = "+line.substr(data_begin, (data_end-data_begin))+".\n");
// strip the leading and trailing braces
data_begin = line.find_first_of('{') + 1;
data_begin = line.find_first_not_of(white_space,
data_begin);
// set data_end before the closing brace
data_end = brace;
data_end = line.find_last_not_of(white_space+"}",
data_end) + 1;
// data_end_absolute = line_end;
if (data_end > line.size())
data_end = line.size();
data_end = line.find_last_of('}', line.size()) - 1;
data_end = line.find_last_not_of(white_space,
data_end) + 1;
}
data.append(line, data_begin, (data_end-data_begin));
if (cvm::debug()) {
cvm::log("Keyword value = \""+data+"\".\n");
}
if (data.size() && save_delimiters) {
data_begin_pos.push_back(conf.find(data, pos+key.size()));
data_end_pos.push_back(data_begin_pos.back()+data.size());
// std::cerr << "key = " << key << ", data = \""
// << data << "\", data_begin, data_end = "
// << data_begin_pos.back() << ", " << data_end_pos.back()
// << "\n";
}
}

View File

@ -8,6 +8,7 @@
#include "colvarmodule.h"
#include "colvarvalue.h"
#include "colvardeps.h"
/// \file colvarparse.h Parsing functions for collective variables
@ -180,6 +181,11 @@ public:
bool &value,
bool const &def_value = false,
Parse_Mode const parse_mode = parse_normal);
bool get_keyval(std::string const &conf,
char const *key,
cvm::deps::feature_state *value,
bool const &def_value = false,
Parse_Mode const parse_mode = parse_normal);
bool get_keyval(std::string const &conf,
char const *key,

View File

@ -69,12 +69,12 @@ public:
virtual cvm::real rand_gaussian(void) = 0;
/// \brief Get the current frame number
// Negative return values indicate error
virtual int frame() { return COLVARS_NOT_IMPLEMENTED; }
// Returns error code
virtual int get_frame(long int&) { return COLVARS_NOT_IMPLEMENTED; }
/// \brief Set the current frame number
// return frame number on success, COLVARS_NO_SUCH_FRAME otherwise
virtual int frame(int) { return COLVARS_NOT_IMPLEMENTED; }
/// \brief Set the current frame number (as well as colvarmodule::it)
// Returns error code
virtual int set_frame(long int) { return COLVARS_NOT_IMPLEMENTED; }
/// \brief Prefix to be used for input files (restarts, not
/// configuration)

View File

@ -55,14 +55,14 @@ int colvarscript::run(int argc, char const *argv[]) {
if (cmd == "delete") {
// Note: the delete bit may be ignored by some backends
// it is mostly useful in VMD
colvars->set_error_bit(DELETE_COLVARS);
colvars->set_error_bits(DELETE_COLVARS);
return COLVARS_OK;
}
if (cmd == "update") {
cvm::combine_errors(error_code, proxy->update_input());
cvm::combine_errors(error_code, colvars->calc());
cvm::combine_errors(error_code, proxy->update_output());
error_code |= proxy->update_input();
error_code |= colvars->calc();
error_code |= proxy->update_output();
if (error_code) {
result += "Error updating the colvars module.\n";
}
@ -142,8 +142,8 @@ int colvarscript::run(int argc, char const *argv[]) {
}
proxy->output_prefix_str = argv[2];
int error = 0;
cvm::combine_errors(error, colvars->setup_output());
cvm::combine_errors(error, colvars->write_output_files());
error |= colvars->setup_output();
error |= colvars->write_output_files();
return error ? COLVARSCRIPT_ERROR : COLVARS_OK;
}
@ -163,8 +163,9 @@ int colvarscript::run(int argc, char const *argv[]) {
if (cmd == "frame") {
if (argc == 2) {
int f = proxy->frame();
if (f >= 0) {
long int f;
int error = proxy->get_frame(f);
if (error == COLVARS_OK) {
result = cvm::to_str(f);
return COLVARS_OK;
} else {
@ -173,10 +174,9 @@ int colvarscript::run(int argc, char const *argv[]) {
}
} else if (argc == 3) {
// Failure of this function does not trigger an error, but
// returns the plain result to let scripts detect available frames
long int f = proxy->frame(strtol(argv[2], NULL, 10));
colvars->it = proxy->frame();
result = cvm::to_str(f);
// returns nonzero, to let scripts detect available frames
int error = proxy->set_frame(strtol(argv[2], NULL, 10));
result = cvm::to_str(error == COLVARS_OK ? 0 : -1);
return COLVARS_OK;
} else {
result = "Wrong arguments to command \"frame\"\n" + help_string();
@ -414,7 +414,8 @@ Input and output:\n\
printframe -- return a summary of the current frame\n\
printframelabels -- return labels to annotate printframe's output\n";
if (proxy->frame() != COLVARS_NOT_IMPLEMENTED) {
long int tmp;
if (proxy->get_frame(tmp) != COLVARS_NOT_IMPLEMENTED) {
buf += "\
frame -- return current frame number\n\
frame <new_frame> -- set frame number\n";