colvar::cartesian::cartesian(std::string const &conf)
  : cvc(conf)
{
  b_inverse_gradients = false;
  b_Jacobian_derivative = false;
  function_type = "cartesian";

  parse_group(conf, "atoms", atoms);
  atom_groups.push_back(&atoms);

  bool use_x, use_y, use_z;
  get_keyval(conf, "useX", use_x, true);
  get_keyval(conf, "useY", use_y, true);
  get_keyval(conf, "useZ", use_z, true);

  axes.clear();
  if (use_x) axes.push_back(0);
  if (use_y) axes.push_back(1);
  if (use_z) axes.push_back(2);

  if (axes.size() == 0) {
    cvm::error("Error: a \"cartesian\" component was defined with all three axes disabled.\n");
  }

  x.type(colvarvalue::type_vector);
  x.vector1d_value.resize(atoms.size() * axes.size());
}
示例#2
0
colvar::cartesian::cartesian(std::string const &conf)
  : cvc(conf)
{
  function_type = "cartesian";

  atoms = parse_group(conf, "atoms");

  bool use_x, use_y, use_z;
  get_keyval(conf, "useX", use_x, true);
  get_keyval(conf, "useY", use_y, true);
  get_keyval(conf, "useZ", use_z, true);

  axes.clear();
  if (use_x) axes.push_back(0);
  if (use_y) axes.push_back(1);
  if (use_z) axes.push_back(2);

  if (axes.size() == 0) {
    cvm::error("Error: a \"cartesian\" component was defined with all three axes disabled.\n");
    return;
  }

  x.type(colvarvalue::type_vector);
  enable(f_cvc_implicit_gradient);
  x.vector1d_value.resize(atoms->size() * axes.size());
}
colvar::h_bond::h_bond(std::string const &conf)
  : cvc(conf)
{
  if (cvm::debug())
    cvm::log("Initializing h_bond object.\n");

  function_type = "h_bond";
  x.type(colvarvalue::type_scalar);

  int a_num, d_num;
  get_keyval(conf, "acceptor", a_num, -1);
  get_keyval(conf, "donor",    d_num, -1);

  if ( (a_num == -1) || (d_num == -1) ) {
    cvm::fatal_error("Error: either acceptor or donor undefined.\n");
  }

  cvm::atom acceptor = cvm::atom(a_num);
  cvm::atom donor    = cvm::atom(d_num);
  atom_groups.push_back(new cvm::atom_group);
  atom_groups[0]->add_atom(acceptor);
  atom_groups[0]->add_atom(donor);

  get_keyval(conf, "cutoff",   r0, (3.3 * cvm::unit_angstrom()));
  get_keyval(conf, "expNumer", en, 6);
  get_keyval(conf, "expDenom", ed, 8);

  if ( (en%2) || (ed%2) ) {
    cvm::fatal_error("Error: odd exponents provided, can only use even ones.\n");
  }

  if (cvm::debug())
    cvm::log("Done initializing h_bond object.\n");
}
colvar::distance_z::distance_z(std::string const &conf)
  : cvc(conf)
{
  function_type = "distance_z";
  b_inverse_gradients = true;
  b_Jacobian_derivative = true;
  x.type(colvarvalue::type_scalar);

  // TODO detect PBC from MD engine (in simple cases)
  // and then update period in real time
  if (period != 0.0)
    b_periodic = true;

  if ((wrap_center != 0.0) && (period == 0.0)) {
    cvm::error("Error: wrapAround was defined in a distanceZ component,"
                " but its period has not been set.\n");
    return;
  }

  parse_group(conf, "main", main);
  parse_group(conf, "ref", ref1);
  atom_groups.push_back(&main);
  atom_groups.push_back(&ref1);
  // this group is optional
  parse_group(conf, "ref2", ref2, true);

  if (ref2.size()) {
    atom_groups.push_back(&ref2);
    cvm::log("Using axis joining the centers of mass of groups \"ref\" and \"ref2\"");
    fixed_axis = false;
    if (key_lookup(conf, "axis"))
      cvm::log("Warning: explicit axis definition will be ignored!");
  } else {
    if (get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0))) {
      if (axis.norm2() == 0.0) {
        cvm::error("Axis vector is zero!");
        return;
      }
      if (axis.norm2() != 1.0) {
        axis = axis.unit();
        cvm::log("The normalized axis is: "+cvm::to_str(axis)+".\n");
      }
    }
    fixed_axis = true;
  }

  if (get_keyval(conf, "forceNoPBC", b_no_PBC, false)) {
    cvm::log("Computing distance using absolute positions (not minimal-image)");
  }
  if (get_keyval(conf, "oneSiteSystemForce", b_1site_force, false)) {
    cvm::log("Computing system force on group \"main\" only");
  }
}
示例#5
0
colvar::distance_z::distance_z(std::string const &conf)
  : cvc(conf)
{
  function_type = "distance_z";
  provide(f_cvc_inv_gradient);
  provide(f_cvc_Jacobian);
  enable(f_cvc_com_based);
  x.type(colvarvalue::type_scalar);

  // TODO detect PBC from MD engine (in simple cases)
  // and then update period in real time
  if (period != 0.0)
    b_periodic = true;

  if ((wrap_center != 0.0) && (period == 0.0)) {
    cvm::error("Error: wrapAround was defined in a distanceZ component,"
                " but its period has not been set.\n");
    return;
  }

  main = parse_group(conf, "main");
  ref1 = parse_group(conf, "ref");
  // this group is optional
  ref2 = parse_group(conf, "ref2", true);

  if (ref2 && ref2->size()) {
    cvm::log("Using axis joining the centers of mass of groups \"ref\" and \"ref2\"");
    fixed_axis = false;
    if (key_lookup(conf, "axis"))
      cvm::log("Warning: explicit axis definition will be ignored!");
  } else {
    if (get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0))) {
      if (axis.norm2() == 0.0) {
        cvm::error("Axis vector is zero!");
        return;
      }
      if (axis.norm2() != 1.0) {
        axis = axis.unit();
        cvm::log("The normalized axis is: "+cvm::to_str(axis)+".\n");
      }
    }
    fixed_axis = true;
  }

  if (get_keyval(conf, "forceNoPBC", b_no_PBC, false)) {
    cvm::log("Computing distance using absolute positions (not minimal-image)");
  }

  init_total_force_params(conf);

}
示例#6
0
colvar::distance_inv::distance_inv(std::string const &conf)
  : cvc(conf)
{
  function_type = "distance_inv";

  group1 = parse_group(conf, "group1");
  group2 = parse_group(conf, "group2");

  get_keyval(conf, "exponent", exponent, 6);
  if (exponent%2) {
    cvm::error("Error: odd exponent provided, can only use even ones.\n");
    return;
  }
  if (exponent <= 0) {
    cvm::error("Error: negative or zero exponent provided.\n");
    return;
  }

  for (cvm::atom_iter ai1 = group1->begin(); ai1 != group1->end(); ai1++) {
    for (cvm::atom_iter ai2 = group2->begin(); ai2 != group2->end(); ai2++) {
      if (ai1->id == ai2->id) {
        cvm::error("Error: group1 and group2 have some atoms in common: this is not allowed for distanceInv.\n");
        return;
      }
    }
  }

  x.type(colvarvalue::type_scalar);
}
colvar::inertia_z::inertia_z (std::string const &conf)
  : inertia (conf)
{
  function_type = "inertia_z";
  if (get_keyval (conf, "axis", axis, cvm::rvector (0.0, 0.0, 1.0))) {
    if (axis.norm2() == 0.0)
      cvm::fatal_error ("Axis vector is zero!");
    axis = axis.unit();
  }
  x.type (colvarvalue::type_scalar);
}
colvar::distance::distance (std::string const &conf, bool twogroups)
  : cvc (conf)
{
  function_type = "distance";
  b_inverse_gradients = true;
  b_Jacobian_derivative = true;
  if (get_keyval (conf, "forceNoPBC", b_no_PBC, false)) {
    cvm::log ("Computing distance using absolute positions (not minimal-image)");
  }
  if (twogroups && get_keyval (conf, "oneSiteSystemForce", b_1site_force, false)) {
    cvm::log ("Computing system force on group 1 only");
  }
  parse_group (conf, "group1", group1);
  atom_groups.push_back (&group1);
  if (twogroups) {
    parse_group (conf, "group2", group2);
    atom_groups.push_back (&group2);
  }
  x.type (colvarvalue::type_scalar);
}
colvar::selfcoordnum::selfcoordnum(std::string const &conf)
 : distance(conf, false)
{
  function_type = "selfcoordnum";
  x.type(colvarvalue::type_scalar);

  // group1 is already initialized by distance()

  // need to specify this explicitly because the distance() constructor
  // has set it to true
  b_inverse_gradients = false;

  get_keyval(conf, "cutoff", r0, cvm::real(4.0 * cvm::unit_angstrom()));
  get_keyval(conf, "expNumer", en, int(6) );
  get_keyval(conf, "expDenom", ed, int(12));

  if ( (en%2) || (ed%2) ) {
    cvm::fatal_error("Error: odd exponents provided, can only use even ones.\n");
  }
}
示例#10
0
colvar::coordnum::coordnum(std::string const &conf)
  : distance(conf), b_anisotropic(false), b_group2_center_only(false)
{
  function_type = "coordnum";
  x.type(colvarvalue::type_scalar);

  // group1 and group2 are already initialized by distance()
  if (group1.b_dummy)
    cvm::fatal_error("Error: only group2 is allowed to be a dummy atom\n");


  // need to specify this explicitly because the distance() constructor
  // has set it to true
  b_inverse_gradients = false;

  bool const b_scale = get_keyval(conf, "cutoff", r0,
                                   cvm::real(4.0 * cvm::unit_angstrom()));

  if (get_keyval(conf, "cutoff3", r0_vec,
                  cvm::rvector(4.0, 4.0, 4.0), parse_silent)) {

    if (b_scale)
      cvm::fatal_error("Error: cannot specify \"scale\" and "
                        "\"scale3\" at the same time.\n");
    b_anisotropic = true;
    // remove meaningless negative signs
    if (r0_vec.x < 0.0) r0_vec.x *= -1.0;
    if (r0_vec.y < 0.0) r0_vec.y *= -1.0;
    if (r0_vec.z < 0.0) r0_vec.z *= -1.0;
  }

  get_keyval(conf, "expNumer", en, int(6) );
  get_keyval(conf, "expDenom", ed, int(12));

  if ( (en%2) || (ed%2) ) {
    cvm::fatal_error("Error: odd exponents provided, can only use even ones.\n");
  }

  get_keyval(conf, "group2CenterOnly", b_group2_center_only, group2.b_dummy);
}
示例#11
0
colvar::dipole_angle::dipole_angle(std::string const &conf)
  : cvc(conf)
{
  function_type = "dipole_angle";
  group1 = parse_group(conf, "group1");
  group2 = parse_group(conf, "group2");
  group3 = parse_group(conf, "group3");

  if (get_keyval(conf, "oneSiteSystemForce", b_1site_force, false)) {
    cvm::log("Computing system force on group 1 only");
  }
  x.type(colvarvalue::type_scalar);
}
// key_release_event: When a keyboard key is released
// ----------------------------------------------- >>
gboolean key_release_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
	guint keyval = get_keyval(event);

	string key = gdk_keyval_name(keyval);
	//printf("\"%s\"\n", key.c_str());

	binds.unset(key, (GdkModifierType)event->state, &released_keys);
	keys_edit();
	released_keys.clear();

	return false;
}
示例#13
0
colvar::tilt::tilt(std::string const &conf)
  : orientation(conf)
{
  function_type = "tilt";

  get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0));

  if (axis.norm2() != 1.0) {
    axis /= axis.norm();
    cvm::log("Normalizing rotation axis to "+cvm::to_str(axis)+".\n");
  }

  x.type(colvarvalue::type_scalar);
}
示例#14
0
colvar::inertia_z::inertia_z (std::string const &conf)
  : inertia (conf)
{
  function_type = "inertia_z";
  if (get_keyval (conf, "axis", axis, cvm::rvector (0.0, 0.0, 1.0))) {
    if (axis.norm2() == 0.0)
      cvm::fatal_error ("Axis vector is zero!");
    if (axis.norm2() != 1.0) {
      axis = axis.unit();
      cvm::log ("The normalized axis is: "+cvm::to_str (axis)+".\n");
    }
  }
  x.type (colvarvalue::type_scalar);
}
示例#15
0
colvar::distance_pairs::distance_pairs(std::string const &conf)
  : cvc(conf)
{
  function_type = "distance_pairs";

  if (get_keyval(conf, "forceNoPBC", b_no_PBC, false)) {
    cvm::log("Computing distance using absolute positions (not minimal-image)");
  }

  group1 = parse_group(conf, "group1");
  group2 = parse_group(conf, "group2");

  x.type(colvarvalue::type_vector);
  x.vector1d_value.resize(group1->size() * group2->size());
}
// key_press_event: When a keyboard key is pressed
// -------------------------------------------- >>
gboolean key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
	//printf("keyval: %d (%s)\nhardware: %d\n", event->keyval, gdk_keyval_name(event->keyval), event->hardware_keycode);

	down_pos.set(mouse);

	guint keyval = get_keyval(event);

	string key = gdk_keyval_name(keyval);
	//printf("\"%s\"\n", key.c_str());
	binds.set(key, (GdkModifierType)event->state, &pressed_keys);
	keys_edit();
	pressed_keys.clear();

	return false;
}
示例#17
0
colvar::spin_angle::spin_angle(std::string const &conf)
  : orientation(conf)
{
  function_type = "spin_angle";

  get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0));

  if (axis.norm2() != 1.0) {
    axis /= axis.norm();
    cvm::log("Normalizing rotation axis to "+cvm::to_str(axis)+".\n");
  }

  period = 360.0;
  b_periodic = true;
  x.type(colvarvalue::type_scalar);
}
示例#18
0
colvar::angle::angle(std::string const &conf)
  : cvc(conf)
{
  function_type = "angle";
  provide(f_cvc_inv_gradient);
  provide(f_cvc_Jacobian);
  provide(f_cvc_com_based);

  group1 = parse_group(conf, "group1");
  group2 = parse_group(conf, "group2");
  group3 = parse_group(conf, "group3");
  if (get_keyval(conf, "oneSiteSystemForce", b_1site_force, false)) {
    cvm::log("Computing system force on group 1 only");
  }
  x.type(colvarvalue::type_scalar);
}
colvar::angle::angle (std::string const &conf)
  : cvc (conf)
{
  function_type = "angle";
  b_inverse_gradients = true;
  b_Jacobian_derivative = true;
  parse_group (conf, "group1", group1);
  parse_group (conf, "group2", group2);
  parse_group (conf, "group3", group3);
  atom_groups.push_back (&group1);
  atom_groups.push_back (&group2);
  atom_groups.push_back (&group3);
  if (get_keyval (conf, "oneSiteSystemForce", b_1site_force, false)) {
    cvm::log ("Computing system force on group 1 only");
  }
  x.type (colvarvalue::type_scalar);
}
示例#20
0
colvar::distance::distance(std::string const &conf)
  : cvc(conf)
{
  function_type = "distance";
  provide(f_cvc_inv_gradient);
  provide(f_cvc_Jacobian);
  enable(f_cvc_com_based);

  group1 = parse_group(conf, "group1");
  group2 = parse_group(conf, "group2");

  if (get_keyval(conf, "forceNoPBC", b_no_PBC, false)) {
    cvm::log("Computing distance using absolute positions (not minimal-image)");
  }

  init_total_force_params(conf);

  x.type(colvarvalue::type_scalar);
}
示例#21
0
colvar::distance_pairs::distance_pairs(std::string const &conf)
  : cvc(conf)
{
  function_type = "distance_pairs";
  b_inverse_gradients = false;
  b_Jacobian_derivative = false;

  if (get_keyval(conf, "forceNoPBC", b_no_PBC, false)) {
    cvm::log("Computing distance using absolute positions (not minimal-image)");
  }

  parse_group(conf, "group1", group1);
  atom_groups.push_back(&group1);

  parse_group(conf, "group2", group2);
  atom_groups.push_back(&group2);

  x.type(colvarvalue::type_vector);
  x.vector1d_value.resize(group1.size() * group2.size());
}
示例#22
0
colvar::dihedral::dihedral(std::string const &conf)
  : cvc(conf)
{
  function_type = "dihedral";
  period = 360.0;
  b_periodic = true;
  provide(f_cvc_inv_gradient);
  provide(f_cvc_Jacobian);
  provide(f_cvc_com_based);

  if (get_keyval(conf, "oneSiteSystemForce", b_1site_force, false)) {
    cvm::log("Computing system force on group 1 only");
  }
  group1 = parse_group(conf, "group1");
  group2 = parse_group(conf, "group2");
  group3 = parse_group(conf, "group3");
  group4 = parse_group(conf, "group4");

  x.type(colvarvalue::type_scalar);
}
示例#23
0
colvar::distance_inv::distance_inv (std::string const &conf)
  : distance (conf)
{
  function_type = "distance_inv";
  get_keyval (conf, "exponent", exponent, 6);
  if (exponent%2) {
    cvm::fatal_error ("Error: odd exponent provided, can only use even ones.\n");
  }
  if (exponent <= 0) {
    cvm::fatal_error ("Error: negative or zero exponent provided.\n");
  }

  for (cvm::atom_iter ai1 = group1.begin(); ai1 != group1.end(); ai1++) {
    for (cvm::atom_iter ai2 = group2.begin(); ai2 != group2.end(); ai2++) {
      if (ai1->id == ai2->id)
        cvm::fatal_error ("Error: group1 and group1 have some atoms in common: this is not allowed for distanceInv.\n");
    }
  }

  b_inverse_gradients = false;
  b_Jacobian_derivative = false;
  x.type (colvarvalue::type_scalar);
}
示例#24
0
colvar::cvc::cvc(std::string const &conf)
  : sup_coeff(1.0),
    sup_np(1),
    b_periodic(false),
    b_try_scalable(true)
{
  if (cvm::debug())
    cvm::log("Initializing cvc base object.\n");

  init_cvc_requires();

  if (get_keyval(conf, "name", this->name, std::string(""), parse_silent)) {
    // Temporary description until child object is initialized
    description = "cvc " + name;
  } else {
    description = "uninitialized cvc";
  }

  get_keyval(conf, "componentCoeff", sup_coeff, 1.0);
  get_keyval(conf, "componentExp", sup_np, 1);

  get_keyval(conf, "period", period, 0.0);
  get_keyval(conf, "wrapAround", wrap_center, 0.0);

  // 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);
  }

  // Attempt scalable calculations when in parallel? (By default yes, if available)
  get_keyval(conf, "scalable", b_try_scalable, true);

  if (cvm::debug())
    cvm::log("Done initializing cvc base object.\n");
}
colvar::cvc::cvc (std::string const &conf)
  : sup_coeff (1.0), sup_np (1),
    b_periodic (false),
    b_debug_gradients (false),
    b_inverse_gradients (false),
    b_Jacobian_derivative (false)
{
  if (cvm::debug())
    cvm::log ("Initializing cvc base object.\n");

  get_keyval (conf, "name", this->name, std::string (""), parse_silent);

  get_keyval (conf, "componentCoeff", sup_coeff, 1.0);
  get_keyval (conf, "componentExp", sup_np, 1);

  get_keyval (conf, "period", period, 0.0);
  get_keyval (conf, "wrapAround", wrap_center, 0.0);

  get_keyval (conf, "debugGradients", b_debug_gradients, false, parse_silent);

  if (cvm::debug())
    cvm::log ("Done initializing cvc base object.\n");
}
colvar::eigenvector::eigenvector (std::string const &conf)
  : cvc (conf)
{
  b_inverse_gradients = true;
  b_Jacobian_derivative = true;
  function_type = "eigenvector";
  x.type (colvarvalue::type_scalar);

  parse_group (conf, "atoms", atoms);
  atom_groups.push_back (&atoms);

  if (atoms.b_rotate) {
    cvm::fatal_error ("Error: rotateReference should be disabled:"
        "eigenvector component will set it internally.");
  }

  if (get_keyval (conf, "refPositions", ref_pos, ref_pos)) {
    cvm::log ("Using reference positions from input file.\n");
    if (ref_pos.size() != atoms.size()) {
      cvm::fatal_error ("Error: reference positions do not "
                        "match the number of requested atoms.\n");
    }
  }

  {
    std::string file_name;
    if (get_keyval (conf, "refPositionsFile", file_name)) {

      std::string file_col;
      double file_col_value;
      if (get_keyval (conf, "refPositionsCol", file_col, std::string (""))) {
        // use PDB flags if column is provided
        bool found = get_keyval (conf, "refPositionsColValue", file_col_value, 0.0);
        if (found && !file_col_value)
          cvm::fatal_error ("Error: refPositionsColValue, "
                            "if provided, must be non-zero.\n");
      } else {
        // if not, use atom indices
        atoms.create_sorted_ids();
      }

      ref_pos.resize (atoms.size());
      cvm::load_coords (file_name.c_str(), ref_pos, atoms.sorted_ids, file_col, file_col_value);
    }
  }

  // Set mobile frame of reference for atom group
  atoms.b_center = true;
  atoms.b_rotate = true;
  atoms.ref_pos = ref_pos;

  // now load the eigenvector
  if (get_keyval (conf, "vector", eigenvec, eigenvec)) {
    cvm::log ("Using vector components from input file.\n");
    if (eigenvec.size() != atoms.size()) {
      cvm::fatal_error ("Error: vector components do not "
                        "match the number of requested atoms.\n");
    }
  }

  {
    std::string file_name;
    if (get_keyval (conf, "vectorFile", file_name)) {

      std::string file_col;
      if (!get_keyval (conf, "vectorCol", file_col, std::string (""))) {
        cvm::fatal_error ("Error: parameter vectorCol is required if vectorFile is set.\n");
      }

      double file_col_value;
      bool found = get_keyval (conf, "vectorColValue", file_col_value, 0.0);
      if (found && !file_col_value)
        cvm::fatal_error ("Error: eigenvectorColValue, "
                          "if provided, must be non-zero.\n");

      eigenvec.resize (atoms.size());
      cvm::load_coords (file_name.c_str(), eigenvec, atoms.sorted_ids, file_col, file_col_value);
    }
  }

  if (!ref_pos.size() || !eigenvec.size()) {
    cvm::fatal_error ("Error: both reference coordinates"
                      "and eigenvector must be defined.\n");
  }

  cvm::rvector center (0.0, 0.0, 0.0);
  eigenvec_invnorm2 = 0.0;

  for (size_t i = 0; i < atoms.size(); i++) {
    center += eigenvec[i];
  }

  cvm::log ("Subtracting sum of eigenvector components: " + cvm::to_str (center) + "\n");

  for (size_t i = 0; i < atoms.size(); i++) {
    eigenvec[i] = eigenvec[i] - center;
    eigenvec_invnorm2 += eigenvec[i].norm2();
  }
  eigenvec_invnorm2 = 1.0 / eigenvec_invnorm2;

  // request derivatives of optimal rotation wrt 2nd group
  // for Jacobian
  atoms.rot.request_group1_gradients(atoms.size());
  atoms.rot.request_group2_gradients(atoms.size());
}
int main(int argc, char **argv)
{
	char *descriptor;
	char *curpos; /* current position in input string */
	struct keyval *parser_id; /* the parser we are creating output for */
	FILE *outputf;
	struct keyval *rkv; /* current read key:val */
	struct keyval_list *curlist;
	bool do_token_check = true; /* if the check for valid tokens is done */
	bool only_ident = true; /* if the only token type is ident */
	bool is_generic = false;

	struct keyval_list base;
	struct keyval_list IDENT;
	struct keyval_list IDENT_LIST;
	struct keyval_list LENGTH_UNIT;
	struct keyval_list URI;
	struct keyval_list WRAP;
	struct keyval_list NUMBER;
	struct keyval_list COLOR;


	if (argc < 2) {
		fprintf(stderr,"Usage: %s [-o <filename>] <descriptor>\n", argv[0]);
		return 1;
	}

	if ((argv[1][0] == '-') && (argv[1][1] == 'o')) {
		if (argc != 4) {
			fprintf(stderr,"Usage: %s [-o <filename>] <descriptor>\n", argv[0]);
			return 1;
		}
		outputf = fopen(argv[2], "w");
		if (outputf == NULL) {
			perror("unable to open file");
		}
		descriptor = strdup(argv[3]);
	} else {
		outputf = stdout;
		descriptor = strdup(argv[1]);
	}
	curpos = descriptor;

	base.count = 0;
	IDENT.count = 0;
	URI.count = 0;
	WRAP.count = 0;
	NUMBER.count = 0;
	COLOR.count = 0;
	LENGTH_UNIT.count = 0;
	IDENT_LIST.count = 0;

	curlist = &base;

	while (*curpos != 0) {
		rkv = get_keyval(&curpos);
		if (rkv == NULL) {
			fprintf(stderr,"Token error at offset %ld\n", curpos - descriptor);
			fclose(outputf);
			return 2;
		}

		if (strcmp(rkv->key, "WRAP") == 0) {
			WRAP.item[WRAP.count++] = rkv;
			only_ident = false;
		} else if (strcmp(rkv->key, "NUMBER") == 0) {
			if (rkv->val[0] == '(') {
				curlist = &NUMBER;
			} else if (rkv->val[0] == ')') {
				curlist = &base;
			} else {
				NUMBER.item[NUMBER.count++] = rkv;
			}
			only_ident = false;
		} else if (strcmp(rkv->key, "IDENT") == 0) {
			if (rkv->val[0] == '(') {
				curlist = &IDENT;
			} else if (rkv->val[0] == ')') {
				curlist = &base;
			} else if (strcmp(rkv->val, str_INHERIT) == 0) {
				IDENT.item[IDENT.count++] = &ident_inherit;
			}
		} else if (strcmp(rkv->key, "IDENT_LIST") == 0) {
			if (rkv->val[0] == '(') {
				curlist = &IDENT_LIST;
			} else if (rkv->val[0] == ')') {
				curlist = &base;
			} 
		} else if (strcmp(rkv->key, "LENGTH_UNIT") == 0) {
			if (rkv->val[0] == '(') {
				curlist = &LENGTH_UNIT;
			} else if (rkv->val[0] == ')') {
				curlist = &base;
			} 
			only_ident = false;
			do_token_check = false;
		} else if (strcmp(rkv->key, "COLOR") == 0) {
			COLOR.item[COLOR.count++] = rkv;
			do_token_check = false;
			only_ident = false;
		} else if (strcmp(rkv->key, "URI") == 0) {
			URI.item[URI.count++] = rkv;
			only_ident = false;
		} else if (strcmp(rkv->key, "GENERIC") == 0) {
			is_generic = true;
		} else {
			/* just append to current list */
			curlist->item[curlist->count++] = rkv;
		}
	}

	if (base.count != 1) {
		fprintf(stderr,"Incorrect base element count (got %d expected 1)\n", base.count);
		fclose(outputf);
		return 3;
	}


	/* header */
output_header(outputf, descriptor, base.item[0], is_generic);

	if (WRAP.count > 0) {
		output_wrap(outputf, base.item[0], &WRAP);
	} else {
		/* check token type is correct */
		output_token_type_check(outputf, do_token_check,  &IDENT, &URI, &NUMBER);

		if (IDENT.count > 0)
			output_ident(outputf, only_ident, base.item[0], &IDENT);

		if (URI.count > 0)
			output_uri(outputf, base.item[0], &URI);

		if (NUMBER.count > 0)
			output_number(outputf, base.item[0], &NUMBER);

		/* terminal blocks, these end the ladder ie no trailing else */
		if (COLOR.count > 0) {
			output_color(outputf, base.item[0], &COLOR);
		} else if (LENGTH_UNIT.count > 0) {
			output_length_unit(outputf, base.item[0], &LENGTH_UNIT);
		} else if (IDENT_LIST.count > 0) {
			output_ident_list(outputf, base.item[0], &IDENT_LIST);
		} else {
			output_invalidcss(outputf);
		}

		output_footer(outputf);

	}

	fclose(outputf);

	return 0;
}
示例#28
0
int colvarbias_abf::init(std::string const &conf)
{
  colvarbias::init(conf);

  enable(f_cvb_scalar_variables);
  enable(f_cvb_calc_pmf);

  // TODO relax this in case of VMD plugin
  if (cvm::temperature() == 0.0)
    cvm::log("WARNING: ABF should not be run without a thermostat or at 0 Kelvin!\n");

  // ************* parsing general ABF options ***********************

  get_keyval_feature((colvarparse *)this, conf, "applyBias",  f_cvb_apply_force, true);
  if (!is_enabled(f_cvb_apply_force)){
    cvm::log("WARNING: ABF biases will *not* be applied!\n");
  }

  get_keyval(conf, "updateBias",  update_bias, true);
  if (update_bias) {
    enable(f_cvb_history_dependent);
  } else {
    cvm::log("WARNING: ABF biases will *not* be updated!\n");
  }

  get_keyval(conf, "hideJacobian", hide_Jacobian, false);
  if (hide_Jacobian) {
    cvm::log("Jacobian (geometric) forces will be handled internally.\n");
  } else {
    cvm::log("Jacobian (geometric) forces will be included in reported free energy gradients.\n");
  }

  get_keyval(conf, "fullSamples", full_samples, 200);
  if ( full_samples <= 1 ) full_samples = 1;
  min_samples = full_samples / 2;
  // full_samples - min_samples >= 1 is guaranteed

  get_keyval(conf, "inputPrefix",  input_prefix, std::vector<std::string>());
  get_keyval(conf, "outputFreq", output_freq, cvm::restart_out_freq);
  get_keyval(conf, "historyFreq", history_freq, 0);
  b_history_files = (history_freq > 0);

  // shared ABF
  get_keyval(conf, "shared", shared_on, false);
  if (shared_on) {
    if (!cvm::replica_enabled() || cvm::replica_num() <= 1) {
      cvm::error("Error: shared ABF requires more than one replica.");
      return COLVARS_ERROR;
    }
    cvm::log("shared ABF will be applied among "+ cvm::to_str(cvm::replica_num()) + " replicas.\n");
    if (cvm::proxy->smp_enabled() == COLVARS_OK) {
      cvm::error("Error: shared ABF is currently not available with SMP parallelism; "
                 "please set \"SMP off\" at the top of the Colvars configuration file.\n",
                 COLVARS_NOT_IMPLEMENTED);
      return COLVARS_NOT_IMPLEMENTED;
    }

    // If shared_freq is not set, we default to output_freq
    get_keyval(conf, "sharedFreq", shared_freq, output_freq);
  }

  // ************* checking the associated colvars *******************

  if (num_variables() == 0) {
    cvm::error("Error: no collective variables specified for the ABF bias.\n");
    return COLVARS_ERROR;
  }

  if (update_bias) {
    // Request calculation of total force
    if(enable(f_cvb_get_total_force)) return cvm::get_error();
  }

  bool b_extended = false;
  size_t i;
  for (i = 0; i < num_variables(); i++) {

    if (colvars[i]->value().type() != colvarvalue::type_scalar) {
      cvm::error("Error: ABF bias can only use scalar-type variables.\n");
    }
    colvars[i]->enable(f_cv_grid);
    if (hide_Jacobian) {
      colvars[i]->enable(f_cv_hide_Jacobian);
    }

    // If any colvar is extended-system, we need to collect the extended
    // system gradient
    if (colvars[i]->is_enabled(f_cv_extended_Lagrangian))
      b_extended = true;

    // Cannot mix and match coarse time steps with ABF because it gives
    // wrong total force averages - total force needs to be averaged over
    // every time step
    if (colvars[i]->get_time_step_factor() != time_step_factor) {
      cvm::error("Error: " + colvars[i]->description + " has a value of timeStepFactor ("
        + cvm::to_str(colvars[i]->get_time_step_factor()) + ") different from that of "
        + description + " (" + cvm::to_str(time_step_factor) + ").\n");
      return COLVARS_ERROR;
    }

    // Here we could check for orthogonality of the Cartesian coordinates
    // and make it just a warning if some parameter is set?
  }

  if (get_keyval(conf, "maxForce", max_force)) {
    if (max_force.size() != num_variables()) {
      cvm::error("Error: Number of parameters to maxForce does not match number of colvars.");
    }
    for (i = 0; i < num_variables(); i++) {
      if (max_force[i] < 0.0) {
        cvm::error("Error: maxForce should be non-negative.");
      }
    }
    cap_force = true;
  } else {
    cap_force = false;
  }

  bin.assign(num_variables(), 0);
  force_bin.assign(num_variables(), 0);
  system_force = new cvm::real [num_variables()];

  // Construct empty grids based on the colvars
  if (cvm::debug()) {
    cvm::log("Allocating count and free energy gradient grids.\n");
  }

  samples   = new colvar_grid_count(colvars);
  gradients = new colvar_grid_gradient(colvars);
  gradients->samples = samples;
  samples->has_parent_data = true;

  // Data for eAB F z-based estimator
  if ( b_extended ) {
    get_keyval(conf, "CZARestimator", b_CZAR_estimator, true);
    // CZAR output files for stratified eABF
    get_keyval(conf, "writeCZARwindowFile", b_czar_window_file, false,
               colvarparse::parse_silent);

    z_bin.assign(num_variables(), 0);
    z_samples   = new colvar_grid_count(colvars);
    z_samples->request_actual_value();
    z_gradients = new colvar_grid_gradient(colvars);
    z_gradients->request_actual_value();
    z_gradients->samples = z_samples;
    z_samples->has_parent_data = true;
    czar_gradients = new colvar_grid_gradient(colvars);
  }

  // For now, we integrate on-the-fly iff the grid is < 3D
  if ( num_variables() <= 3 ) {
    pmf = new integrate_potential(colvars, gradients);
    if ( b_CZAR_estimator ) {
      czar_pmf = new integrate_potential(colvars, czar_gradients);
    }
    get_keyval(conf, "integrate", b_integrate, true); // Integrate for output
    if ( num_variables() > 1 ) {
      // Projected ABF
      get_keyval(conf, "pABFintegrateFreq", pabf_freq, 0);
      // Parameters for integrating initial (and final) gradient data
      get_keyval(conf, "integrateInitSteps", integrate_initial_steps, 1e4);
      get_keyval(conf, "integrateInitTol", integrate_initial_tol, 1e-6);
      // for updating the integrated PMF on the fly
      get_keyval(conf, "integrateSteps", integrate_steps, 100);
      get_keyval(conf, "integrateTol", integrate_tol, 1e-4);
    }
  } else {
    b_integrate = false;
  }

  // For shared ABF, we store a second set of grids.
  // This used to be only if "shared" was defined,
  // but now we allow calling share externally (e.g. from Tcl).
  last_samples   = new colvar_grid_count(colvars);
  last_gradients = new colvar_grid_gradient(colvars);
  last_gradients->samples = last_samples;
  last_samples->has_parent_data = true;
  shared_last_step = -1;

  // If custom grids are provided, read them
  if ( input_prefix.size() > 0 ) {
    read_gradients_samples();
    // Update divergence to account for input data
    pmf->set_div();
  }

  // if extendedLangrangian is on, then call UI estimator
  if (b_extended) {
    get_keyval(conf, "UIestimator", b_UI_estimator, false);

    if (b_UI_estimator) {
    std::vector<double> UI_lowerboundary;
    std::vector<double> UI_upperboundary;
    std::vector<double> UI_width;
    std::vector<double> UI_krestr;

    bool UI_restart = (input_prefix.size() > 0);

    for (i = 0; i < num_variables(); i++)
    {
      UI_lowerboundary.push_back(colvars[i]->lower_boundary);
      UI_upperboundary.push_back(colvars[i]->upper_boundary);
      UI_width.push_back(colvars[i]->width);
      UI_krestr.push_back(colvars[i]->force_constant());
    }
      eabf_UI = UIestimator::UIestimator(UI_lowerboundary,
                                         UI_upperboundary,
                                         UI_width,
                                         UI_krestr,                // force constant in eABF
                                         output_prefix,              // the prefix of output files
                                         cvm::restart_out_freq,
                                         UI_restart,                    // whether restart from a .count and a .grad file
                                         input_prefix,   // the prefixes of input files
                                         cvm::temperature());
    }
  }

  cvm::log("Finished ABF setup.\n");
  return COLVARS_OK;
}
示例#29
0
colvar::eigenvector::eigenvector(std::string const &conf)
  : cvc(conf)
{
  provide(f_cvc_inv_gradient);
  provide(f_cvc_Jacobian);
  function_type = "eigenvector";
  x.type(colvarvalue::type_scalar);

  atoms = parse_group(conf, "atoms");

  {
    bool const b_inline = get_keyval(conf, "refPositions", ref_pos, ref_pos);

    if (b_inline) {
      cvm::log("Using reference positions from input file.\n");
      if (ref_pos.size() != atoms->size()) {
        cvm::error("Error: reference positions do not "
                   "match the number of requested atoms.\n");
        return;
      }
    }

    std::string file_name;
    if (get_keyval(conf, "refPositionsFile", file_name)) {

      if (b_inline) {
        cvm::error("Error: refPositions and refPositionsFile cannot be specified at the same time.\n");
        return;
      }

      std::string file_col;
      double file_col_value=0.0;
      if (get_keyval(conf, "refPositionsCol", file_col, std::string(""))) {
        // use PDB flags if column is provided
        bool found = get_keyval(conf, "refPositionsColValue", file_col_value, 0.0);
        if (found && file_col_value==0.0) {
          cvm::error("Error: refPositionsColValue, "
                            "if provided, must be non-zero.\n");
          return;
        }
      } else {
        // if not, use atom indices
        atoms->create_sorted_ids();
      }

      ref_pos.resize(atoms->size());
      cvm::load_coords(file_name.c_str(), ref_pos, atoms->sorted_ids, file_col, file_col_value);
    }
  }

  if (ref_pos.size() == 0) {
    cvm::error("Error: reference positions were not provided.\n", INPUT_ERROR);
    return;
  }

  if (ref_pos.size() != atoms->size()) {
    cvm::error("Error: reference positions do not "
               "match the number of requested atoms.\n", INPUT_ERROR);
    return;
  }

  // save for later the geometric center of the provided positions (may not be the origin)
  cvm::rvector ref_pos_center(0.0, 0.0, 0.0);
  for (size_t i = 0; i < atoms->size(); i++) {
    ref_pos_center += ref_pos[i];
  }
  ref_pos_center *= 1.0 / atoms->size();

  if (atoms->b_user_defined_fit) {
    cvm::log("WARNING: explicit fitting parameters were provided for atom group \"atoms\".\n");
  } else {
    // default: fit everything
    cvm::log("Enabling \"centerReference\" and \"rotateReference\", to minimize RMSD before calculating the vector projection: "
              "if this is not the desired behavior, disable them explicitly within the \"atoms\" block.\n");
    atoms->b_center = true;
    atoms->b_rotate = true;
    atoms->ref_pos = ref_pos;
    atoms->center_ref_pos();
    atoms->disable(f_ag_fit_gradients); // cancel out if group is fitted on itself
                                        // and cvc is translationally invariant

    // request the calculation of the derivatives of the rotation defined by the atom group
    atoms->rot.request_group1_gradients(atoms->size());
    // request derivatives of optimal rotation wrt reference coordinates for Jacobian:
    // this is only required for ABF, but we do both groups here for better caching
    atoms->rot.request_group2_gradients(atoms->size());
  }

  {
    bool const b_inline = get_keyval(conf, "vector", eigenvec, eigenvec);
    // now load the eigenvector
    if (b_inline) {
      cvm::log("Using vector components from input file.\n");
      if (eigenvec.size() != atoms->size()) {
        cvm::error("Error: vector components do not "
                          "match the number of requested atoms->\n");
        return;
      }
    }

    std::string file_name;
    if (get_keyval(conf, "vectorFile", file_name)) {

      if (b_inline) {
        cvm::error("Error: vector and vectorFile cannot be specified at the same time.\n");
        return;
      }

      std::string file_col;
      double file_col_value=0.0;
      if (get_keyval(conf, "vectorCol", file_col, std::string(""))) {
        // use PDB flags if column is provided
        bool found = get_keyval(conf, "vectorColValue", file_col_value, 0.0);
        if (found && file_col_value==0.0) {
          cvm::error("Error: vectorColValue, if provided, must be non-zero.\n");
          return;
        }
      } else {
        // if not, use atom indices
        atoms->create_sorted_ids();
      }

      eigenvec.resize(atoms->size());
      cvm::load_coords(file_name.c_str(), eigenvec, atoms->sorted_ids, file_col, file_col_value);
    }
  }

  if (!ref_pos.size() || !eigenvec.size()) {
    cvm::error("Error: both reference coordinates"
                      "and eigenvector must be defined.\n");
    return;
  }

  cvm::atom_pos eig_center(0.0, 0.0, 0.0);
  for (size_t eil = 0; eil < atoms->size(); eil++) {
    eig_center += eigenvec[eil];
  }
  eig_center *= 1.0 / atoms->size();
  cvm::log("Geometric center of the provided vector: "+cvm::to_str(eig_center)+"\n");

  bool b_difference_vector = false;
  get_keyval(conf, "differenceVector", b_difference_vector, false);

  if (b_difference_vector) {

    if (atoms->b_center) {
      // both sets should be centered on the origin for fitting
      for (size_t i = 0; i < atoms->size(); i++) {
        eigenvec[i] -= eig_center;
        ref_pos[i]  -= ref_pos_center;
      }
    }
    if (atoms->b_rotate) {
      atoms->rot.calc_optimal_rotation(eigenvec, ref_pos);
      for (size_t i = 0; i < atoms->size(); i++) {
        eigenvec[i] = atoms->rot.rotate(eigenvec[i]);
      }
    }
    cvm::log("\"differenceVector\" is on: subtracting the reference positions from the provided vector: v = v - x0.\n");
    for (size_t i = 0; i < atoms->size(); i++) {
      eigenvec[i] -= ref_pos[i];
    }
    if (atoms->b_center) {
      // bring back the ref positions to where they were
      for (size_t i = 0; i < atoms->size(); i++) {
        ref_pos[i] += ref_pos_center;
      }
    }

  } else {
    cvm::log("Centering the provided vector to zero.\n");
    for (size_t i = 0; i < atoms->size(); i++) {
      eigenvec[i] -= eig_center;
    }
  }

  // cvm::log("The first three components(v1x, v1y, v1z) of the resulting vector are: "+cvm::to_str (eigenvec[0])+".\n");

  // for inverse gradients
  eigenvec_invnorm2 = 0.0;
  for (size_t ein = 0; ein < atoms->size(); ein++) {
    eigenvec_invnorm2 += eigenvec[ein].norm2();
  }
  eigenvec_invnorm2 = 1.0 / eigenvec_invnorm2;

  if (b_difference_vector) {
    cvm::log("\"differenceVector\" is on: normalizing the vector.\n");
    for (size_t i = 0; i < atoms->size(); i++) {
      eigenvec[i] *= eigenvec_invnorm2;
    }
  } else {
    cvm::log("The norm of the vector is |v| = "+cvm::to_str(eigenvec_invnorm2)+".\n");
  }
}
示例#30
0
colvar::rmsd::rmsd(std::string const &conf)
  : cvc(conf)
{
  provide(f_cvc_inv_gradient);
  function_type = "rmsd";
  x.type(colvarvalue::type_scalar);

  atoms = parse_group(conf, "atoms");

  if (!atoms || atoms->size() == 0) {
    cvm::error("Error: \"atoms\" must contain at least 1 atom to compute RMSD.");
    return;
  }

  bool b_Jacobian_derivative = true;
  if (atoms->fitting_group != NULL && b_Jacobian_derivative) {
    cvm::log("The option \"refPositionsGroup\" (alternative group for fitting) was enabled: "
              "Jacobian derivatives of the RMSD will not be calculated.\n");
    b_Jacobian_derivative = false;
  }
  if (b_Jacobian_derivative) provide(f_cvc_Jacobian);

  // the following is a simplified version of the corresponding atom group options;
  // we need this because the reference coordinates defined inside the atom group
  // may be used only for fitting, and even more so if fitting_group is used
  if (get_keyval(conf, "refPositions", ref_pos, ref_pos)) {
    cvm::log("Using reference positions from configuration file to calculate the variable.\n");
    if (ref_pos.size() != atoms->size()) {
      cvm::error("Error: the number of reference positions provided ("+
                  cvm::to_str(ref_pos.size())+
                  ") does not match the number of atoms of group \"atoms\" ("+
                  cvm::to_str(atoms->size())+").\n");
      return;
    }
  }
  {
    std::string ref_pos_file;
    if (get_keyval(conf, "refPositionsFile", ref_pos_file, std::string(""))) {

      if (ref_pos.size()) {
        cvm::error("Error: cannot specify \"refPositionsFile\" and "
                          "\"refPositions\" at the same time.\n");
        return;
      }

      std::string ref_pos_col;
      double ref_pos_col_value=0.0;

      if (get_keyval(conf, "refPositionsCol", ref_pos_col, std::string(""))) {
        // if provided, use PDB column to select coordinates
        bool found = get_keyval(conf, "refPositionsColValue", ref_pos_col_value, 0.0);
        if (found && ref_pos_col_value==0.0) {
          cvm::error("Error: refPositionsColValue, "
                     "if provided, must be non-zero.\n");
          return;
        }
      } else {
        // if not, rely on existing atom indices for the group
        atoms->create_sorted_ids();
        ref_pos.resize(atoms->size());
      }

      cvm::load_coords(ref_pos_file.c_str(), ref_pos, atoms->sorted_ids,
                        ref_pos_col, ref_pos_col_value);
    }
  }

  if (ref_pos.size() != atoms->size()) {
    cvm::error("Error: found " + cvm::to_str(ref_pos.size()) +
                    " reference positions; expected " + cvm::to_str(atoms->size()));
    return;
  }

  if (atoms->b_user_defined_fit) {
    cvm::log("WARNING: explicit fitting parameters were provided for atom group \"atoms\".");
  } else {
    // Default: fit everything
    cvm::log("Enabling \"centerReference\" and \"rotateReference\", to minimize RMSD before calculating it as a variable: "
              "if this is not the desired behavior, disable them explicitly within the \"atoms\" block.\n");
    atoms->b_center = true;
    atoms->b_rotate = true;
    // default case: reference positions for calculating the rmsd are also those used
    // for fitting
    atoms->ref_pos = ref_pos;
    atoms->center_ref_pos();

    cvm::log("This is a standard minimum RMSD, derivatives of the optimal rotation "
              "will not be computed as they cancel out in the gradients.");
    atoms->disable(f_ag_fit_gradients);

    // request the calculation of the derivatives of the rotation defined by the atom group
    atoms->rot.request_group1_gradients(atoms->size());
    // request derivatives of optimal rotation wrt reference coordinates for Jacobian:
    // this is only required for ABF, but we do both groups here for better caching
    atoms->rot.request_group2_gradients(atoms->size());
  }
}