diff --git a/mosdef_gomc/formats/charmm_writer.py b/mosdef_gomc/formats/charmm_writer.py index 11418105..6f1fc001 100644 --- a/mosdef_gomc/formats/charmm_writer.py +++ b/mosdef_gomc/formats/charmm_writer.py @@ -1,1514 +1,4 @@ -import datetime -import os -from collections import OrderedDict -from warnings import warn - -import numpy as np -from mbuild.box import Box -from mbuild.compound import Compound -from mbuild.utils.conversion import RB_to_CHARMM -from mbuild.utils.sorting import natural_sort -from parmed.periodic_table import Element -from parmed.utils.io import genopen - -from mosdef_gomc.utils.conversion import ( - base10_to_base16_alph_num, - base10_to_base26_alph, - base10_to_base52_alph, - base10_to_base62_alph_num, -) -from mosdef_gomc.utils.specific_ff_to_residue import specific_ff_to_residue - - -def _get_bond_type_key( - bond, sigma_conversion_factor, epsilon_conversion_factor -): - """Get the bond_type key for a bond - - Parameters - ---------- - bond : mbuild.compound.Compound - The bond information from the mbuild.compound.Compound - sigma_conversion_factor : float or int - The sigma conversion factor - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - tuple, (bond_k_constant, bond_bo_length, bond_atom_1_and_2_types_tuple, - bond_atom_1_residue_name, bond_atom_2_residue_name) - bond_k_constant : float - Harmonic bond k-constant or bond energy scaling factor - bond_bo_length : float - Harmonic bonds equilibrium length - bond_atom_1_and_2_types_tuple : tuple - A sorted tuple ofstrings for the bonded atom types for atoms 1 and 2. - bond_atom_1_residue_name : str - The residue name for atom 1 in the bond. - bond_atom_2_residue_name : str - The residue name for atom 2 in the bond. - """ - bond_k_constant = round( - bond.type.k - * (sigma_conversion_factor**2 / epsilon_conversion_factor), - 8, - ) - bond_bo_length = round(bond.type.req / sigma_conversion_factor, 8) - bond_atom_1_and_2_types_tuple = tuple( - sorted((bond.atom1.type, bond.atom2.type)) - ) - bond_atom_1_residue_name = bond.atom1.residue.name - bond_atom_2_residue_name = bond.atom2.residue.name - - return ( - bond_k_constant, - bond_bo_length, - bond_atom_1_and_2_types_tuple, - bond_atom_1_residue_name, - bond_atom_2_residue_name, - ) - - -def _get_angle_type_key( - angle, sigma_conversion_factor, epsilon_conversion_factor -): - """Get the angle_type key for an harmonic angle - - Parameters - ---------- - angle : parmed.topologyobjects.Angle - The angle information from the parmed.topologyobjects.Angle - sigma_conversion_factor : float or int - The sigma conversion factor - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - tuple, (angle_k_constant, angle_theta_o, angle_center_atom_type_2, angle_end_atom_types_1_and_3_tuple, - angle_residue_atom_1, angle_residue_atom_2, angle_residue_atom_3) - angle_k_constant : float - Harmonic angle k-constant or bond energy scaling factor - angle_theta_o : float - Harmonic equilbrium angle between the atoms - angle_center_atom_type_2 : str - The center atom type for the angle (atom type 2) - angle_end_atom_types_1_and_3_tuple : tuple - A sorted tuple of atom types (strings) for the end angle atoms - (atoms 1 and 3). - angle_atom_1_residue_name : str - The residue name for atom 1 in the angle (end atom). - angle_atom_2_residue_name : str - The residue name for atom 2 in the angle (center atom). - angle_atom_3_residue_name : str - The residue name for atom 3 in the angle (end atom). - """ - - angle_k_constant = round( - angle.type.k - * (sigma_conversion_factor**2 / epsilon_conversion_factor), - 8, - ) - angle_theta_o = round(angle.type.theteq, 8) - angle_center_atom_type_2 = angle.atom2.type - angle_end_atom_types_1_and_3_tuple = tuple( - sorted((angle.atom1.type, angle.atom3.type)) - ) - angle_residue_atom_1 = angle.atom1.residue.name - angle_residue_atom_2 = angle.atom2.residue.name - angle_residue_atom_3 = angle.atom3.residue.name - - return ( - angle_k_constant, - angle_theta_o, - angle_center_atom_type_2, - angle_end_atom_types_1_and_3_tuple, - angle_residue_atom_1, - angle_residue_atom_2, - angle_residue_atom_3, - ) - - -def _get_dihedral_rb_torsion_key(dihedral, epsilon_conversion_factor): - """Get the dihedral_type key for a Ryckaert-Bellemans (RB) dihedrals/torsions - - Parameters - ---------- - dihedral : parmed.topologyobjects.Dihedral - The dihedral information from the parmed.topologyobjects.Angle - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - tuple, (dihed_type_RB_c0, dihed_type_RB_c1, dihed_type_RB_c2, dihed_type_RB_c3, dihed_type_RB_c4, - dihed_type_RB_c5, dihed_type_scee, dihed_type_scnb, dihed_atom_1_type, dihed_atom_2_type, - dihed_atom_3_type, dihed_atom_4_type, dihed_atom_1_res_type, dihed_atom_2_res_type, - dihed_atom_3_res_type, dihed_atom_4_res_type) - dihed_type_RB_c0 : float - Ryckaert-Bellemans (RB) dihedrals/torsions C0 constant. - dihed_type_RB_c1 : float - Ryckaert-Bellemans (RB) dihedrals/torsions C1 constant. - dihed_type_RB_c2 : float - Ryckaert-Bellemans (RB) dihedrals/torsions C2 constant. - dihed_type_RB_c3 : float - Ryckaert-Bellemans (RB) dihedrals/torsions C3 constant. - dihed_type_RB_c4 : float - Ryckaert-Bellemans (RB) dihedrals/torsions C4 constant. - dihed_type_RB_c5 : float - Ryckaert-Bellemans (RB) dihedrals/torsions C5 constant. - dihed_type_scee : float, default = 1.0 - The 1-4 electrostatic scaling factor - dihed_type_scnb : float, default = 1.0 - The 1-4 Lennard-Jones scaling factor. - dihed_atom_1_type : str - The atom type for atom number 1 in the dihedral - dihed_atom_2_type : str - The atom type for atom number 2 in the dihedral - dihed_atom_3_type : str - The atom type for atom number 3 in the dihedral - dihed_atom_4_type : str - The atom type for atom number 4 in the dihedral - dihed_atom_1_res_type : str - The residue name for atom number 1 in the dihedral - dihed_atom_2_res_type : str - The residue name for atom number 2 in the dihedral - dihed_atom_3_res_type : str - The residue name for atom number 3 in the dihedral - dihed_atom_4_res_type : str - The residue name for atom number 4 in the dihedral - """ - - lj_unit = 1 / epsilon_conversion_factor - - dihed_type_RB_c0 = round(dihedral.type.c0 * lj_unit, 8) - dihed_type_RB_c1 = round(dihedral.type.c1 * lj_unit, 8) - dihed_type_RB_c2 = round(dihedral.type.c2 * lj_unit, 8) - dihed_type_RB_c3 = round(dihedral.type.c3 * lj_unit, 8) - dihed_type_RB_c4 = round(dihedral.type.c4 * lj_unit, 8) - dihed_type_RB_c5 = round(dihedral.type.c5 * lj_unit, 8) - - dihed_type_scee = round(dihedral.type.scee, 4) - dihed_type_scnb = round(dihedral.type.scnb, 4) - - dihed_atom_1_type = dihedral.atom1.type - dihed_atom_2_type = dihedral.atom2.type - dihed_atom_3_type = dihedral.atom3.type - dihed_atom_4_type = dihedral.atom4.type - - dihed_atom_1_res_type = dihedral.atom1.residue.name - dihed_atom_2_res_type = dihedral.atom2.residue.name - dihed_atom_3_res_type = dihedral.atom3.residue.name - dihed_atom_4_res_type = dihedral.atom4.residue.name - - return ( - dihed_type_RB_c0, - dihed_type_RB_c1, - dihed_type_RB_c2, - dihed_type_RB_c3, - dihed_type_RB_c4, - dihed_type_RB_c5, - dihed_type_scee, - dihed_type_scnb, - dihed_atom_1_type, - dihed_atom_2_type, - dihed_atom_3_type, - dihed_atom_4_type, - dihed_atom_1_res_type, - dihed_atom_2_res_type, - dihed_atom_3_res_type, - dihed_atom_4_res_type, - ) - - -def _get_improper_type_key(improper, epsilon_conversion_factor): - """Get the improper_type key for the harmonic improper - - Parameters - ---------- - improper : parmed.topologyobjects.Dihedral - The improper information from the parmed.topologyobjects.Angle - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - tuple, (improper_k_constant, improper_psi_o, improper_atom_1_type, - (improper_atom_2_type, improper_atom_3_type, improper_atom_4_type), improper_atom_1_res_type, - (improper_atom_2_res_type, improper_atom_3_res_type, improper_atom_4_res_type) - improper_k_constant : float - Harmonic k-constant or bond energy scaling factor - improper_psi_o : float - Harmonic equilbrium improper angle - improper_atom_1_type : str - The atom type for atom number 1 in the dihedral - improper_atom_2_type : str - The atom type for atom number 2 in the dihedral - improper_atom_3_type : str - The atom type for atom number 3 in the dihedral - improper_atom_4_type : str - The atom type for atom number 4 in the dihedral - improper_atom_1_res_type : str - The residue name for atom number 1 in the dihedral - improper_atom_2_res_type : str - The residue name for atom number 2 in the dihedral - improper_atom_3_res_type : str - The residue name for atom number 3 in the dihedral - improper_atom_4_res_type : str - The residue name for atom number 4 in the dihedral - """ - lj_unit = 1 / epsilon_conversion_factor - - improper_k_constant = round(improper.type.psi_k * lj_unit, 8) - improper_psi_o = round(improper.type.psi_eq, 8) - improper_atom_1_type = improper.atom1.type - improper_atom_2_type = improper.atom2.type - improper_atom_3_type = improper.atom3.type - improper_atom_4_type = improper.atom4.type - improper_atom_1_res_type = improper.atom1.residue.name - improper_atom_2_res_type = improper.atom2.residue.name - improper_atom_3_res_type = improper.atom3.residue.name - improper_atom_4_res_type = improper.atom4.residue.name - - return ( - improper_k_constant, - improper_psi_o, - improper_atom_1_type, - (improper_atom_2_type, improper_atom_3_type, improper_atom_4_type), - improper_atom_1_res_type, - ( - improper_atom_2_res_type, - improper_atom_3_res_type, - improper_atom_4_res_type, - ), - ) - - -def _get_unique_bond_types( - structure, sigma_conversion_factor, epsilon_conversion_factor -): - """Get the unique bond types for a structure in a dictionary - - Parameters - ---------- - structure : parmed.structure.Structure - This is a parmed stucture input (parmed.structure.Structure) - sigma_conversion_factor : float or int - The sigma conversion factor - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - bond_key_dict : dict, {(float, float, (str, str), str, str) : unique_number} - This provides a way to uniquely number the harmonic bond types - by providing all the bond parameters as a key and the - unique number as the value. An example of the dict is below: - {(bond_k_constant, bond_bo_length, (bond_atom_type_1, bond_atom_type_2), - bond_atom_1_residue_name, bond_atom_2_residue_name ) : 1, - ..., - (bond_k_constant, bond_bo_length, (bond_atom_type_1, bond_atom_type_2), - bond_atom_1_residue_name, bond_atom_2_residue_name ) : n - } - """ - - unique_bond_set = set() - for bond in structure.bonds: - unique_bond_set.add( - _get_bond_type_key( - bond, sigma_conversion_factor, epsilon_conversion_factor - ) - ) - - bond_key_dict = { - bond_key: i + 1 for i, bond_key in enumerate(unique_bond_set) - } - - return bond_key_dict - - -def _get_unique_angle_types( - structure, sigma_conversion_factor, epsilon_conversion_factor -): - """Get the unique angle types for a structure and return a dictionary - - Parameters - ---------- - structure : parmed.structure.Structure - This is a parmed stucture input (parmed.structure.Structure) - sigma_conversion_factor : float or int - The sigma conversion factor - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - angle_key_dict : dict, {(float, float, str, (str, str), str, str, str) : unique_number} - This provides a way to uniquely number the harmonic angle types - by providing all the angle parameters as a key and the - unique number as the value. An example of the dict is below: - {(angle_k_constant, angle_theta_o, angle_center_atom_type_2, - (angle_end_atom_type_1, angle_end_atom_type_3), - angle_residue_atom_1, angle_residue_atom_2, angle_residue_atom_3 - ) : 1, - ..., - (angle_k_constant, angle_theta_o, angle_center_atom_type_2, - (angle_end_atom_type_1, angle_end_atom_type_3), - angle_residue_atom_1, angle_residue_atom_2, angle_residue_atom_3) : n - } - """ - - unique_angle_set = set() - for angle in structure.angles: - unique_angle_set.add( - _get_angle_type_key( - angle, sigma_conversion_factor, epsilon_conversion_factor - ) - ) - - angle_key_dict = { - angle_key: i + 1 for i, angle_key in enumerate(unique_angle_set) - } - - return angle_key_dict - - -def _get_unique_rb_torsion_types(structure, epsilon_conversion_factor): - """Get the unique rb torsion types for a structure and return a dictionary - - Parameters - ---------- - structure : parmed.structure.Structure - This is a parmed stucture input (parmed.structure.Structure) - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - dihed_key_dict : dict, {(float, float, float, float, float, float, float, float, - str, str, str, str, str, str, str, str) : unique_number} - This provides a way to uniquely number the Ryckaert-Bellemans (RB) - dihedral types by providing all the dihedral parameters as a key and the - unique number as the value. An example of the dict is below: - {(dihed_type_RB_c0, dihed_type_RB_c1, dihed_type_RB_c2, - dihed_type_RB_c3, dihed_type_RB_c4, dihed_type_RB_c5, - dihed_type_scee, dihed_type_scnb, - dihed_atom_1_type, dihed_atom_2_type, - dihed_atom_3_type, dihed_atom_4_type, - dihed_atom_1_res_type, dihed_atom_2_res_type, - dihed_atom_3_res_type, dihed_atom_4_res_type - ) : 1, - ..., - (dihed_type_RB_c0, dihed_type_RB_c1, dihed_type_RB_c2, - dihed_type_RB_c3, dihed_type_RB_c4, dihed_type_RB_c5, - dihed_type_scee, dihed_type_scnb, - dihed_atom_1_type, dihed_atom_2_type, - dihed_atom_3_type, dihed_atom_4_type, - dihed_atom_1_res_type, dihed_atom_2_res_type, - dihed_atom_3_res_type, dihed_atom_4_res_type - ) : n - } - """ - unique_dihedral_set = set() - for dihedral in structure.rb_torsions: - unique_dihedral_set.add( - _get_dihedral_rb_torsion_key(dihedral, epsilon_conversion_factor) - ) - - dihed_key_dict = { - dihed_key: i + 1 for i, dihed_key in enumerate(unique_dihedral_set) - } - - return dihed_key_dict - - -def _get_unique_improper_types(structure, epsilon_conversion_factor): - """Get the unique improper types for a structure and return a dictionary - - Parameters - ---------- - structure : parmed.structure.Structure - This is a parmed stucture input (parmed.structure.Structure) - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - improper_key_dict : dict, {(float, float, str, (str, str, str), str, (str, str, str)) : unique_number} - This provides a way to uniquely number the harmonic improper - types by providing all the improper parameters as a key and the - unique number as the value. An example of the dict is below: - {(improper_k_constant, improper_psi_o, - improper_atom_1_type, (improper_atom_2_type, - improper_atom_3_type, improper_atom_4_type), - improper_atom_1_res_type, (improper_atom_2_res_type, - improper_atom_3_res_type, improper_atom_4_res_type) - ) : 1, - ..., - (improper_k_constant, improper_psi_o, - improper_atom_1_type, (improper_atom_2_type, - improper_atom_3_type, improper_atom_4_type), - improper_atom_1_res_type, (improper_atom_2_res_type, - improper_atom_3_res_type, improper_atom_4_res_type) - ) : n - } - """ - unique_improper_set = set() - for improper in structure.impropers: - unique_improper_set.add( - _get_improper_type_key(improper, epsilon_conversion_factor) - ) - - improper_key_dict = { - improper_key: i + 1 - for i, improper_key in enumerate(unique_improper_set) - } - - return improper_key_dict - - -def _get_bond_types( - structure, sigma_conversion_factor, epsilon_conversion_factor -): - """Get a list of unique bond types that are used to create the Charmm style - parameter file (i.e. force field file). This also checks that the reverse bond order - is considered the same unique bond type. - - Parameters - ---------- - structure : parmed.Structure - The parmed structure - sigma_conversion_factor : float or int - The sigma conversion factor - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - bond_types : list - The bond types by number in the structure - unique_bond_types : OrderedDict, ((float, float, (str, str), str, str), unique_number) - This provides the unique harmonic bond types, numbering, and the data values - so it can easily be extracted. An example of the OrderedDict is below: - OrderedDict([(bond_k_constant, bond_bo_length, (bond_atom_type_1, bond_atom_type_2), - bond_atom_1_residue_name, bond_atom_2_residue_name), 1), - ..., - (bond_k_constant, bond_bo_length, (bond_atom_type_1, bond_atom_type_2), - bond_atom_1_residue_name, bond_atom_2_residue_name), n)]) - """ - - unique_bond_types = _get_unique_bond_types( - structure, sigma_conversion_factor, epsilon_conversion_factor - ) - - bond_types = [ - unique_bond_types[ - _get_bond_type_key( - bond, sigma_conversion_factor, epsilon_conversion_factor - ) - ] - for bond in structure.bonds - ] - - unique_bond_check_dict = {} - for i_value_bond, i_key_bond in unique_bond_types.items(): - i_value_duplicated = False - for j_value_bond, j_key_bond in unique_bond_types.items(): - j_value_bond_reorder = ( - j_value_bond[0], - j_value_bond[1], - j_value_bond[2][0], - j_value_bond[2][0], - j_value_bond[3], - j_value_bond[4], - ) - - if i_value_bond == j_value_bond_reorder: - i_value_duplicated = True - if i_value_bond[2][0] > j_value_bond[2][0]: - unique_bond_check_dict.update( - {j_value_bond: len(unique_bond_check_dict)} - ) - else: - unique_bond_check_dict.update( - {i_value_bond: len(unique_bond_check_dict)} - ) - - if i_value_duplicated is False: - unique_bond_check_dict.update( - {i_value_bond: len(unique_bond_check_dict)} - ) - - unique_bond_types = OrderedDict( - [(y, x) for y, x in unique_bond_check_dict.items()] - ) - - return bond_types, unique_bond_types - - -def _get_angle_types( - structure, - sigma_conversion_factor, - epsilon_conversion_factor, - use_urey_bradleys=False, -): - """ - Get a list of unique angle types that are used to create the Charmm style - parameter file (i.e. force field file). This also checks that the alternately - ordered angle types are considered the same unique angle type. - - Parameters - ---------- - structure : parmed.Structure - The parmed structure - sigma_conversion_factor : float or int - The sigma conversion factor - epsilon_conversion_factor : float or int - The epsilon conversion factor - use_urey_bradleys : bool - The option that Urey-Bradleys are included in the angles - - Returns - ---------- - angle_types : list - The angle types by number in the structure - unique_angle_types : OrderedDict, ((float, float, (str, str), str, str), unique_number) - This provides the unique harmonic angles types, numbering, and the data values - so it can easily be extracted. An example of the OrderedDict is below: - OrderedDict([(angle_k_constant, angle_theta_o, angle_center_atom_type_2, - (angle_end_atom_type_1, angle_end_atom_type_3), - angle_residue_atom_1, angle_residue_atom_2, angle_residue_atom_3), 1, - ..., - (angle_k_constant, angle_theta_o, angle_center_atom_type_2, - (angle_end_atom_type_1, angle_end_atom_type_3), - angle_residue_atom_1, angle_residue_atom_2, angle_residue_atom_3), n]) - """ - - if use_urey_bradleys: - print_warn_text = ( - "WARNING: Urey-Bradleys are not available in the current " - "version of this psf, pdb, and GOMC writer." - ) - warn(print_warn_text) - return None, None - else: - unique_angle_types = _get_unique_angle_types( - structure, sigma_conversion_factor, epsilon_conversion_factor - ) - - angle_types = [ - unique_angle_types[ - _get_angle_type_key( - angle, sigma_conversion_factor, epsilon_conversion_factor - ) - ] - for angle in structure.angles - ] - - unique_angle_check_dict = {} - for i_value_ang, i_key_ang in unique_angle_types.items(): - i_value_duplicated = False - for j_value_ang, j_key_ang in unique_angle_types.items(): - j_value_ang_reorder = ( - j_value_ang[0], - j_value_ang[1], - j_value_ang[2], - j_value_ang[3][0], - j_value_ang[3][1], - j_value_ang[4], - j_value_ang[5], - j_value_ang[6], - ) - - if i_value_ang == j_value_ang_reorder: - i_value_duplicated = True - if i_value_ang[2] > j_value_ang[2]: - unique_angle_check_dict.update( - {j_value_ang: len(unique_angle_check_dict)} - ) - else: - unique_angle_check_dict.update( - {i_value_ang: len(unique_angle_check_dict)} - ) - - if not i_value_duplicated: - unique_angle_check_dict.update( - {i_value_ang: len(unique_angle_check_dict)} - ) - - unique_angle_types = OrderedDict( - [(y, x) for y, x in unique_angle_check_dict.items()] - ) - - return angle_types, unique_angle_types - - -def _get_dihedral_types( - structure, use_rb_torsions, use_dihedrals, epsilon_conversion_factor -): - """ - Get a list of unique dihedral types that are used to create the Charmm style - parameter file (i.e. force field file). This also checks that the alternately - ordered dihedral types are considered the same unique dihedral type. - - Parameters - ---------- - structure : parmed.Structure - The parmed structure - use_rb_torsions : bool - The Ryckaert-Bellemans (RB) dihedrals/torsions - use_dihedrals : bool - The CHARMM style dihedrals style equations. - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - dihedral_types : list - The dihedral types by number in the structure - unique_dihedral_types : OrderedDict, ([(float, float, float, float, float, float, float, float, - str, str, str, str, str, str, str, str), unique_number]) - This provides the unique dihedrals types, numbering, and the data values - so it can easily be extracted. An example of the OrderedDict is below: - OrderedDict([(dihed_type_RB_c0, dihed_type_RB_c1, dihed_type_RB_c2, - dihed_type_RB_c3, dihed_type_RB_c4, dihed_type_RB_c5, - dihed_type_scee, dihed_type_scnb, - dihed_atom_1_type, dihed_atom_2_type, - dihed_atom_3_type, dihed_atom_4_type, - dihed_atom_1_res_type, dihed_atom_2_res_type, - dihed_atom_3_res_type, dihed_atom_4_res_type), 1, - ..., - (dihed_type_RB_c0, dihed_type_RB_c1, dihed_type_RB_c2, - dihed_type_RB_c3, dihed_type_RB_c4, dihed_type_RB_c5, - dihed_type_scee, dihed_type_scnb, - dihed_atom_1_type, dihed_atom_2_type, - dihed_atom_3_type, dihed_atom_4_type, - dihed_atom_1_res_type, dihed_atom_2_res_type, - dihed_atom_3_res_type, dihed_atom_4_res_type), n]) - """ - if use_rb_torsions: - unique_dihedral_types = _get_unique_rb_torsion_types( - structure, epsilon_conversion_factor - ) - - dihedral_types = [ - unique_dihedral_types[ - _get_dihedral_rb_torsion_key( - dihedral, epsilon_conversion_factor - ) - ] - for dihedral in structure.rb_torsions - ] - - elif use_dihedrals: - print_warn_text = ( - "WARNING: Using the charmm style and impropers is not " - "available in the current version of this psf, pdb, and GOMC writer." - ) - warn(print_warn_text) - return None, None - - unique_dihedral_check_dict = OrderedDict() - for i_value_dihed, i_key_dihed in unique_dihedral_types.items(): - i_value_duplicated = False - for j_value_dihed, j_key_dihed in unique_dihedral_types.items(): - j_value_dihed_reorder = ( - j_value_dihed[0], - j_value_dihed[1], - j_value_dihed[2], - j_value_dihed[3], - j_value_dihed[4], - j_value_dihed[5], - j_value_dihed[6], - j_value_dihed[7], - j_value_dihed[11], - j_value_dihed[10], - j_value_dihed[9], - j_value_dihed[8], - j_value_dihed[15], - j_value_dihed[14], - j_value_dihed[13], - j_value_dihed[12], - ) - - if i_value_dihed == j_value_dihed_reorder: - i_value_duplicated = True - if i_value_dihed[8] > j_value_dihed[8]: - unique_dihedral_check_dict.update( - {j_value_dihed: len(unique_dihedral_check_dict) + 1} - ) - else: - unique_dihedral_check_dict.update( - {i_value_dihed: len(unique_dihedral_check_dict) + 1} - ) - if i_value_duplicated is False: - unique_dihedral_check_dict.update( - {i_value_dihed: len(unique_dihedral_check_dict) + 1} - ) - - unique_dihedral_types = OrderedDict( - [(y, x) for y, x in unique_dihedral_check_dict.items()] - ) - - return dihedral_types, unique_dihedral_types - - -def _get_impropers(structure, epsilon_conversion_factor): - """ - Get a list of unique improper types that are used to create the Charmm style - parameter file (i.e. force field file). This also checks that the alternately - ordered improper types are considered the same unique improper type. - - Parameters - ---------- - structure : parmed.Structure - The parmed structure - epsilon_conversion_factor : float or int - The epsilon conversion factor - - Returns - ---------- - improper_types : list - The improper types by number in the structure - unique_improper_types : OrderedDict, ([(float, float, str, (str, str, str), str, (str, str, str)), unique_number]) - This provides the unique improper types, numbering, and the data values - so it can easily be extracted. An example of the OrderedDict is below: - OrderedDict([(improper_k_constant, improper_psi_o, - improper_atom_1_type, (improper_atom_2_type, - improper_atom_3_type, improper_atom_4_type), - improper_atom_1_res_type, (improper_atom_2_res_type, - improper_atom_3_res_type, improper_atom_4_res_type) - ), 1, - ..., - (improper_k_constant, improper_psi_o, - improper_atom_1_type, (improper_atom_2_type, - improper_atom_3_type, improper_atom_4_type), - improper_atom_1_res_type, (improper_atom_2_res_type, - improper_atom_3_res_type, improper_atom_4_res_type) - ), n ]) - """ - unique_improper_types = _get_unique_improper_types( - structure, epsilon_conversion_factor - ) - improper_types = [ - unique_improper_types[ - _get_improper_type_key(improper, epsilon_conversion_factor) - ] - for improper in structure.impropers - ] - - unique_improper_check_dict = OrderedDict() - for i_value_improper, i_key_improper in unique_improper_types.items(): - i_value_duplicated = False - - i_value_improper_k_constant = i_value_improper[0] - i_value_improper_psi_o = i_value_improper[1] - - i_value_impr_1_atoms_reorder = i_value_improper[2] - i_value_impr_atoms_2_3_4_reorder = sorted( - set( - i_value_improper[3][0], - i_value_improper[3][1], - i_value_improper[3][2], - ) - ) - - i_value_impr_1_res_reorder = i_value_improper[4] - i_value_impr_res_2_3_4_reorder = sorted( - set( - i_value_improper[5][0], - i_value_improper[5][1], - i_value_improper[5][2], - ) - ) - i_improper_reformed = ( - i_value_improper_k_constant, - i_value_improper_psi_o, - i_value_impr_1_atoms_reorder, - i_value_impr_atoms_2_3_4_reorder, - i_value_impr_1_res_reorder, - i_value_impr_res_2_3_4_reorder, - ) - - for j_value_improper, j_key_improper in unique_improper_types.items(): - j_value_improper_k_constant = j_value_improper[0] - j_value_improper_psi_o = j_value_improper[1] - - j_value_impr_1_atoms_reorder = j_value_improper[2] - j_value_impr_atoms_2_3_4_reorder = sorted( - set( - j_value_improper[3][0], - j_value_improper[3][1], - j_value_improper[3][2], - ) - ) - j_value_impr_1_res_reorder = j_value_improper[4] - j_value_impr_res_2_3_4_reorder = sorted( - set( - j_value_improper[5][0], - j_value_improper[5][1], - j_value_improper[5][2], - ) - ) - - j_improper_reformed = ( - j_value_improper_k_constant, - j_value_improper_psi_o, - j_value_impr_1_atoms_reorder, - j_value_impr_atoms_2_3_4_reorder, - j_value_impr_1_res_reorder, - j_value_impr_res_2_3_4_reorder, - ) - - if i_improper_reformed == j_improper_reformed: - i_value_duplicated = True - if i_value_improper[2] > j_value_improper[2]: - unique_improper_check_dict.update( - {j_value_improper: len(unique_improper_check_dict) + 1} - ) - else: - unique_improper_check_dict.update( - {i_value_improper: len(unique_improper_check_dict) + 1} - ) - if i_value_duplicated is False: - unique_improper_check_dict.update( - {i_value_improper: len(unique_improper_check_dict) + 1} - ) - - unique_improper_types = OrderedDict( - [(y, x) for y, x in unique_improper_check_dict.items()] - ) - - return improper_types, unique_improper_types - - -def unique_atom_naming( - structure, residue_id_list, residue_names_list, bead_to_atom_name_dict=None -): - """ - Generates unique atom/bead names for each molecule, which is required for some - simulation types (Example: special Monte Carlo moves) - - Parameters - ---------- - structure : compound object - residue_id_list : list, in sequential order - The residue ID for every atom in the system - residue_names_list : list, in sequential order - The atom names for every atom in the system - bead_to_atom_name_dict: dictionary ; optional, default =None - For all atom names/elements/beads with 2 or less digits, this converts - the atom name in the GOMC psf and pdb files to a unique atom name, - provided they do not exceed 3844 atoms (62^2) of the same name/element/bead - per residue. For all atom names/elements/beads with 3 digits, this converts - the atom name in the GOMC psf and pdb files to a unique atom name, - provided they do not exceed 62 of the same name/element pre residue. - Example dictionary: {'_CH3':'C', '_CH2':'C', '_CH':'C', '_HC':'C'} - - Returns - ---------- - unique_individual_atom_names_dict : dictionary - All the unique atom names comno_piled into a dictionary. - individual_atom_names_list : list, in sequential order - The atom names for every atom in the system - missing_bead_to_atom_name : list, in sequential order - The bead names of any atoms beads that did not have a name specificed to them - via the bead_to_atom_name_dict - """ - unique_individual_atom_names_dict = {} - individual_atom_names_list = [] - missing_bead_to_atom_name = [] - for i, atom in enumerate(structure.atoms): - interate_thru_names = True - j = 0 - while interate_thru_names is True: - j = j + 1 - if str(atom.name)[:1] == "_": - if ( - bead_to_atom_name_dict is not None - and (str(atom.name) in bead_to_atom_name_dict) is True - ): - if len(bead_to_atom_name_dict[str(atom.name)]) > 2: - text_to_write = ( - "ERROR: only enter atom names that have 2 or less digits" - + " in the Bead to atom naming dictionary (bead_to_atom_name_dict)." - ) - warn(text_to_write) - return None, None, None - else: - atom_name_value = bead_to_atom_name_dict[str(atom.name)] - no_digits_atom_name = 2 - else: - missing_bead_to_atom_name.append(1) - atom_name_value = "BD" - no_digits_atom_name = 2 - elif len(str(atom.name)) > 2: - if len(str(atom.name)) == 3: - no_digits_atom_name = 1 - atom_name_value = atom.name - else: - text_to_write = ( - "ERROR: atom numbering will not work propery at" - + " the element has more than 4 charaters" - ) - warn(text_to_write) - return None, None, None - else: - no_digits_atom_name = 2 - atom_name_value = atom.name - atom_name_iteration = str(atom_name_value) + str( - base10_to_base62_alph_num(j) - ) - atom_res_no_resname_atomname_iteration = ( - str(residue_id_list[i]) - + "_" - + str(residue_names_list[i]) - + "_" - + atom_name_iteration - ) - - if ( - unique_individual_atom_names_dict.get( - str(atom_res_no_resname_atomname_iteration) - ) - is None - ): - unique_individual_atom_names_dict.update( - {atom_res_no_resname_atomname_iteration: i + 1} - ) - interate_thru_names = False - individual_atom_names_list.append( - str(atom_name_value) - + str( - str(base10_to_base62_alph_num(j))[-no_digits_atom_name:] - ) - ) - - if sum(missing_bead_to_atom_name) > 0: - warn( - "NOTE: All bead names were not found in the Bead to atom naming dictionary (bead_to_atom_name_dict) " - ) - - return [ - unique_individual_atom_names_dict, - individual_atom_names_list, - missing_bead_to_atom_name, - ] - - -def _lengths_angles_to_vectors(lengths, angles, precision=6): - """Converts the length and angles into CellBasisVectors - - Parameters - ---------- - lengths : list-like, shape=(3,), dtype=float - Lengths of the edges of the box (user chosen units). - angles : list-like, shape=(3,), dtype=float, default=None - Angles (in degrees) that define the tilt of the edges of the box. If - None is given, angles are assumed to be [90.0, 90.0, 90.0]. These are - also known as alpha, beta, gamma in the crystallography community. - precision : int, optional, default=6 - Control the precision of the floating point representation of box - attributes. If none provided, the default is 6 decimals. - - Returns - ------- - box_vectors: numpy.ndarray, [[float, float, float], [float, float, float], [float, float, float]] - Three (3) sets vectors for box 0 each with 3 float values, which represent - the vectors for the Charmm-style systems (units are the same as entered for lengths) - - """ - - (a, b, c) = lengths - - (alpha, beta, gamma) = np.deg2rad(angles) - cos_a = np.clip(np.cos(alpha), -1.0, 1.0) - cos_b = np.clip(np.cos(beta), -1.0, 1.0) - cos_g = np.clip(np.cos(gamma), -1.0, 1.0) - - sin_a = np.clip(np.sin(alpha), -1.0, 1.0) - sin_b = np.clip(np.sin(beta), -1.0, 1.0) - sin_g = np.clip(np.sin(gamma), -1.0, 1.0) - a_vec = np.asarray([a, 0.0, 0.0]) - - b_x = b * cos_g - b_y = b * sin_g - b_vec = np.asarray([b_x, b_y, 0.0]) - - c_x = c * cos_b - c_cos_y_term = (cos_a - (cos_b * cos_g)) / sin_g - c_y = c * c_cos_y_term - c_z = c * np.sqrt(1 - np.square(cos_b) - np.square(c_cos_y_term)) - c_vec = np.asarray([c_x, c_y, c_z]) - box_vectors = np.asarray((a_vec, b_vec, c_vec)) - box_vectors.reshape(3, 3) - # still leaves some floating values in some cases - box_vectors = np.around(box_vectors, decimals=precision) - - return box_vectors - - -def _check_fixed_bonds_angles_lists( - gomc_fix_bonds_and_or_angles, - gomc_fix_bonds_and_or_angles_selection, - residues, -): - """Check the GOMC fixed bonds and angles lists for input errors. - - Parameters - ---------- - gomc_fix_bonds_and_or_angles : list of strings, [str, ..., str] - A list of the residues (i.e., molecules since GOMC currently considers a - a whole molecule as a residue) to have their bonds and/or angles held - rigid/fixed for the GOMC simulation engine. - The `gomc_fix_bonds_angles`, `gomc_fix_bonds`, `gomc_fix_angles` are the only possible - variables from the `Charmm` object to be entered. - In GOMC, the residues currently are the same for every bead or atom in - the molecules. Therefore, when the residue is selected, the whole molecule - is selected. - gomc_fix_bonds_and_or_angles_selection : str - The name of the variable that is used but formatted as a string, which is fed - to the error and information outputs. The - `gomc_fix_bonds_angles`, `gomc_fix_bonds`, `gomc_fix_angles` are the only possible - variables from the `Charmm` object to be entered. - Whichever variable you choose, the variable name is just input as a - string here. For example, if `gomc_fix_bonds_and_or_angles` is equal to - gomc_fix_bonds_angles, then this should be 'gomc_fix_bonds_angles' - (i.e., `gomc_fix_bonds_and_or_angles_selection` = 'gomc_fix_bonds_angles'). - residues : list, [str, ..., str] - Labels of unique residues in the Compound. Residues are assigned by - checking against Compound.name. Only supply residue names as 4 character - strings, as the residue names are truncated to 4 characters to fit in the - psf and pdb file. - - Returns - ------- - Provides a ValueError or TypeError if the input is not correct. - """ - - if gomc_fix_bonds_and_or_angles is not None and not isinstance( - gomc_fix_bonds_and_or_angles, list - ): - print_error_message = ( - "ERROR: Please ensure the residue names in the ({}) variable " - "are in a list.".format(gomc_fix_bonds_and_or_angles_selection) - ) - raise TypeError(print_error_message) - - if isinstance(gomc_fix_bonds_and_or_angles, list): - for gomc_fix_i in gomc_fix_bonds_and_or_angles: - if gomc_fix_i not in residues: - print_error_message = ( - "ERROR: Please ensure that all the residue names in the " - "{} list are also in the residues list.".format( - gomc_fix_bonds_and_or_angles_selection - ) - ) - raise ValueError(print_error_message) - elif not isinstance(gomc_fix_i, str): - print_error_message = "ERROR: Please enter a fix_res_bonds list with only string values." - raise TypeError(print_error_message) - else: - print( - "INFORMATION: The following residues will have these fixed parameters: " - + "gomc_fix_bonds = {}".format(gomc_fix_bonds_and_or_angles) - ) - - -# Currently the NBFIX is disabled as since only the OPLS and TRAPPE force fields are currently supported class Charmm: - """Generates a Charmm object that is required to produce the Charmm style parameter - (force field), PDB, PSF files, which are usable in the GOMC and NAMD engines. - Additionally, this Charmm object is also used in generating the GOMC control file. - - The units for the GOMC data files. - * Mw = g/mol - * charge = e - * Harmonic bonds : Kb = kcal/mol, b0 = Angstroms - * Harmonic angles : Ktheta = kcal/mole/rad**2 , Theta0 = degrees - * Dihedral angles: Ktheta = kcal/mole, n = interger (unitless), delta = degrees - * Improper angles (currently unavailable) : TBD - * LJ-NONBONDED : epsilon = kcal/mol, Rmin/2 = Angstroms - * Mie-NONBONDED (currently unavailable): epsilon = K, sigma = Angstroms, n = interger (unitless) - * Buckingham-NONBONDED (currently unavailable): epsilon = K, sigma = Angstroms, n = interger (unitless) - * LJ-NBFIX (currently unavailable) : epsilon = kcal/mol, Rmin = Angstroms - * Mie-NBFIX (currently unavailable) : same as Mie-NONBONDED - * Buckingham-NBFIX (currently unavailable) : same as Buckingham-NONBONDED - - Note: units are the same as the NAMD units and the LAMMPS real units. The atom style - is the same as the lammps 'full' atom style format. - - Parameters - ---------- - structure_box_0 : mbuild Compound object (mbuild.Compound) or mbuild Box object (mbuild.Box); - If the structure has atoms/beads it must be an mbuild Compound. - If the structure is empty it must be and mbuild Box object. - Note: If 1 structures are provided (i.e., only structure_box_0), - it must be an mbuild Compound. - Note: If 2 structures are provided, - only 1 structure can be an empty box (i.e., either structure_box_0 or structure_box_1) - filename_box_0 : str - The file name of the output file for structure_box_0. Note: the extension should - not be provided, as multiple extension (.pdb and .psf) are added to this name. - structure_box_1 : mbuild Compound object (mbuild.Compound) or mbuild Box object (mbuild.Box), default = None; - If the structure has atoms/beads it must be an mbuild Compound. - Note: When running a GEMC or GCMC simulation the box 1 stucture should be input - here. Otherwise, there is no guarantee that any of the atom type and force field - information will all work together correctly with box 0, if it is built separately. - Note: If 2 structures are provided, only 1 structure can be an empty box - (i.e., either structure_box_0 or structure_box_1). - filename_box_1 : str , default = None - The file name of the output file for structure_box_1 (Ex: for GCMC or GEMC simulations - which have mulitiple simulation boxes). Note: the extension should - not be provided, as multiple extension (.pdb and .psf) are added to this name. - Note: When running a GEMC or GCMC simulation the box 1 stucture should be input - here. Otherwise, there is no guarantee that any of the atom type and force field - information will all work together correctly with box 0, if it is built separately. - non_bonded_type : str, default = 'LJ' (i.e., Lennard-Jones ) - Specify the type of non-bonded potential for the GOMC force field files. - Note: Currently, on the 'LJ' potential is supported. - residues : list, [str, ..., str] - Labels of unique residues in the Compound. Residues are assigned by - checking against Compound.name. Only supply residue names as 4 character - strings, as the residue names are truncated to 4 characters to fit in the - psf and pdb file. - forcefield_selection : str or dictionary, default = None - Apply a forcefield to the output file by selecting a force field XML file with - its path or by using the standard force field name provided the `foyer` package. - Note: to write the NAMD/GOMC force field, pdb, and psf files, the - residues and forcefields must be provided in a str or - dictionary. If a dictionary is provided all residues must - be specified to a force field. - * Example dict for FF file: {'ETH' : 'oplsaa.xml', 'OCT': 'path_to_file/trappe-ua.xml'} - - * Example str for FF file: 'path_to file/trappe-ua.xml' - - * Example dict for standard FF names : {'ETH' : 'oplsaa', 'OCT': 'trappe-ua'} - - * Example str for standard FF names: 'trappe-ua' - - * Example of a mixed dict with both : {'ETH' : 'oplsaa', 'OCT': 'path_to_file/'trappe-ua.xml'} - detect_forcefield_style : boolean, default = True - If True, format NAMD/GOMC/LAMMPS parameters based on the contents of - the parmed structure_box_0 and structure_box_1. - gomc_fix_bonds_angles : list, default = None - When list of residues is provided, the selected residues will have - their bonds and angles fixed in the GOMC engine. This is specifically - for the GOMC engine and it changes the residue's bond constants (Kbs) - and angle constants (Kthetas) values to 999999999999 in the - FF file (i.e., the .inp file). - bead_to_atom_name_dict : dict, optional, default =None - For all atom names/elements/beads with 2 or less digits, this converts - the atom name in the GOMC psf and pdb files to a unique atom name, - provided they do not exceed 3844 atoms (62^2) of the same name/element/bead - per residue. For all atom names/elements/beads with 3 digits, this converts - the atom name in the GOMC psf and pdb files to a unique atom name, - provided they do not exceed 62 of the same name/element pre residue. - - * Example dictionary: {'_CH3':'C', '_CH2':'C', '_CH':'C', '_HC':'C'} - - * Example name structure: {atom_type: first_part_pf atom name_without_numbering} - - fix_residue : list or None, default = None - Changes occcur in the pdb file only. - All the atoms in the residue are have their Beta values in the PDB file set to 1.00; - Otherwise, they will be 0.00. - NOTE: In GOMC, this only fixes atoms automatically as listed below. - NOTE: In NAMD, these all fixes need to be manually set in the control file (please see NAMD manual). - When residues are listed here, all the atoms in the residue are - fixed and can not move via setting the Beta values in the PDB file to 1.00 - If neither fix_residue or fix_residue_in_box lists a - residue or both equal None, then the Beta (Temperature factor) values for all the atoms - in the residue are free to move in the simulation and Beta values - in the PDB file is set to 0.00. - fix_residue_in_box : list or None, default = None - Changes occcur in the pdb file only. - All the atoms in the residue are have their Beta values in the PDB file set to 2.00; - Otherwise, they will be 0.00. - NOTE: In GOMC, this only fixes atoms automatically as listed below. - NOTE: In NAMD, these all fixes need to be manually set in the control file (please see NAMD manual). - When residues are listed here, all the atoms in the residue - can move within the box but cannot be transferred between boxes - via setting the Beta (Temperature factor) values in the PDB file to 2.00. - If neither fix_residue or fix_residue_in_box lists a - residue or both equal None, then the Beta values for all the atoms - in the residue are free to move in the simulation and Beta values - in the PDB file is set to 0.00. - NOTE that this is mainly for GOMC but also applies for NAMD (please see NAMD manual). - set_residue_pdb_occupancy_to_1 : list or None, default = None - Changes occcur in the pdb file only. - All the atoms in the residue are have their occupancy values in the PDB file set to 1.00; - Otherwise, they will be 0.00. - NOTE: In GOMC, This defines which atoms belong to which box for the GCMC and GEMC ensembles. - NOTE: In NAMD, This can be used for fixes which are manually set in the control file (please see NAMD manual). - ff_filename : str, default =None - If a string, it will write the force field files that work in - GOMC and NAMD structures. - reorder_res_in_pdb_psf : bool, default =False - If False, the order of of the atoms in the pdb file is kept in - its original order, as in the Compound sent to the writer. - If True, the order of the atoms is reordered based on their - residue names in the 'residues' list that was entered. - - Attributes - ---------- - input_error : bool - This error is typically incurred from an error in the user's input values. - However, it could also be due to a bug, provided the user is inputting - the data as this Class intends. - structure_box_0 : mbuild.compound.Compound - The mbuild Compound for the input box 0 - structure_box_1 : mbuild.compound.Compound or None, default = None - The mbuild Compound for the input box 1 - filename_box_0 : str - The file name of the output file for structure_box_0. Note: the extension should - not be provided, as multiple extension (.pdb and .psf) are added to this name. - filename_box_1 : str or None , default = None - The file name of the output file for structure_box_1. Note: the extension should - not be provided, as multiple extension (.pdb and .psf) are added to this name. - (i.e., either structure_box_0 or structure_box_1). - non_bonded_type : str, default = 'LJ' (i.e., Lennard-Jones ) - Specify the type of non-bonded potential for the GOMC force field files. - Note: Currently, on the 'LJ' potential is supported. - residues : list, [str, ..., str] - Labels of unique residues in the Compound. Residues are assigned by - checking against Compound.name. Only supply residue names as 4 character - strings, as the residue names are truncated to 4 characters to fit in the - psf and pdb file. - forcefield_selection : str or dictionary, default = None - Apply a forcefield to the output file by selecting a force field XML file with - its path or by using the standard force field name provided the `foyer` package. - Note: to write the NAMD/GOMC force field, pdb, and psf files, the - residues and forcefields must be provided in a str or - dictionary. If a dictionary is provided all residues must - be specified to a force field. - - * Example dict for FF file: {'ETH' : 'oplsaa.xml', 'OCT': 'path_to_file/trappe-ua.xml'} - - * Example str for FF file: 'path_to file/trappe-ua.xml' - - * Example dict for standard FF names : {'ETH' : 'oplsaa', 'OCT': 'trappe-ua'} - - * Example str for standard FF names: 'trappe-ua' - - * Example of a mixed dict with both : {'ETH' : 'oplsaa', 'OCT': 'path_to_file/'trappe-ua.xml'} - - detect_forcefield_style : bool, default = True - If True, format NAMD/GOMC/LAMMPS parameters based on the contents of - the parmed structure_box_0 and structure_box_1 - gomc_fix_bonds_angles : list, default = None - When list of residues is provided, the selected residues will have - their bonds and angles fixed and will ignore the relative bond energies and - related angle energies in the GOMC engine. Note that GOMC - does not sample bond stretching. This is specifically - for the GOMC engine and it changes the residue's bond constants (Kbs) - and angle constants (Kthetas) values to 999999999999 in the - FF file (i.e., the .inp file). - If the residues are listed in either the gomc_fix_angles or the gomc_fix_bonds_angles - lists, the angles will be fixed for that residue. - If the residues are listed in either the gomc_fix_bonds or the gomc_fix_bonds_angles - lists, the bonds will be fixed for that residue. - NOTE if this option is utilized it may cause issues if using the FF file in NAMD. - gomc_fix_bonds : list, default = None - When list of residues is provided, the selected residues will have their - relative bond energies ignored in the GOMC engine. Note that GOMC - does not sample bond stretching. This is specifically - for the GOMC engine and it changes the residue's bond constants (Kbs) - values to 999999999999 in the FF file (i.e., the .inp file). - If the residues are listed in either the gomc_fix_bonds or the gomc_fix_bonds_angles - lists, the relative bond energy will be ignored. - NOTE if this option is utilized it may cause issues if using the FF file in NAMD. - gomc_fix_angles : list, default = None - When list of residues is provided, the selected residues will have - their angles fixed and will ignore the related angle energies in the GOMC engine. - This is specifically for the GOMC engine and it changes the residue's angle - constants (Kthetas) values to 999999999999 in the FF file (i.e., the .inp file), - which fixes the angles and ignores related angle energy. - If the residues are listed in either the gomc_fix_angles or the gomc_fix_bonds_angles - lists, the angles will be fixed and the related angle energy will be ignored - for that residue. - NOTE if this option is utilized it may cause issues if using the FF file in NAMD. - bead_to_atom_name_dict : dict, optional, default =None - For all atom names/elements/beads with 2 or less digits, this converts - the atom name in the GOMC psf and pdb files to a unique atom name, - provided they do not exceed 3844 atoms (62^2) of the same name/element/bead - per residue. For all atom names/elements/beads with 3 digits, this converts - the atom name in the GOMC psf and pdb files to a unique atom name, - provided they do not exceed 62 of the same name/element pre residue. - - * Example dictionary: {'_CH3':'C', '_CH2':'C', '_CH':'C', '_HC':'C'} - - * Example name structure: {atom_type: first_part_pf atom name_without_numbering} - - fix_residue : list or None, default = None - Changes occcur in the pdb file only. - All the atoms in the residue are have their Beta values in the PDB file set to 1.00; - Otherwise, they will be 0.00. - NOTE: In GOMC, this only fixes atoms automatically as listed below. - NOTE: In NAMD, these all fixes need to be manually set in the control file (please see NAMD manual). - When residues are listed here, all the atoms in the residue are - fixed and can not move via setting the Beta values in the PDB file to 1.00 - If neither fix_residue or fix_residue_in_box lists a - residue or both equal None, then the Beta (Temperature factor) values for all the atoms - in the residue are free to move in the simulation and Beta values - in the PDB file is set to 0.00. - fix_residue_in_box : list or None, default = None - Changes occcur in the pdb file only. - All the atoms in the residue are have their Beta values in the PDB file set to 2.00; - Otherwise, they will be 0.00. - NOTE: In GOMC, this only fixes atoms automatically as listed below. - NOTE: In NAMD, these all fixes need to be manually set in the control file (please see NAMD manual). - When residues are listed here, all the atoms in the residue - can move within the box but cannot be transferred between boxes - via setting the Beta (Temperature factor) values in the PDB file to 2.00. - If neither fix_residue or fix_residue_in_box lists a - residue or both equal None, then the Beta values for all the atoms - in the residue are free to move in the simulation and Beta values - in the PDB file is set to 0.00. - NOTE that this is mainly for GOMC but also applies for NAMD (please see NAMD manual). - set_residue_pdb_occupancy_to_1 : list or None, default = None - Changes occcur in the pdb file only. - All the atoms in the residue are have their occupancy values in the PDB file set to 1.00; - Otherwise, they will be 0.00. - NOTE: In GOMC, This defines which atoms belong to which box for the GCMC and GEMC ensembles. - NOTE: In NAMD, This can be used for fixes which are manually set in the control file (please see NAMD manual). - ff_filename : str, default =None - If a string, it will write the force field files that work in - GOMC and NAMD structures. - reorder_res_in_pdb_psf : bool, default =False - If False, the order of of the atoms in the pdb file is kept in - its original order, as in the Compound sent to the writer. - If True, the order of the atoms is reordered based on their - residue names in the 'residues' list that was entered. - box_0 : Box - The Box class that contains the attributes Lx, Ly, Lz for the length - of the box 0 (units in nanometers (nm)). It also contains the xy, xz, and yz Tilt factors - needed to displace an orthogonal box's xy face to its - parallelepiped structure for box 0. - box_1 : Box - The Box class that contains the attributes Lx, Ly, Lz for the length - of the box 1 (units in nanometers (nm)). It also contains the xy, xz, and yz Tilt factors - needed to displace an orthogonal box's xy face to its - parallelepiped structure for box 0. - box_0_vectors : numpy.ndarray, [[float, float, float], [float, float, float], [float, float, float]] - Three (3) sets vectors for box 0 each with 3 float values, which represent - the vectors for the Charmm-style systems (units in Angstroms (Ang)) - box_1_vectors : numpy.ndarray, [[float, float, float], [float, float, float], [float, float, float]] - Three (3) sets vectors for box 1 each with 3 float values, which represent - the vectors for the Charmm-style systems (units in Angstroms (Ang)) - structure_box_0_ff : parmed.structure.Structure - The box 0 structure (structure_box_0) after all the provided - force fields are applied. - structure_box_1_ff : parmed.structure.Structure - The box 0 structure (structure_box_0) after all the provided - force fields are applied. This only exists if the box 1 structure - (structure_box_1) is provided. - coulomb14scalar_dict_box_0 : dict - The residue/moleclues (key) of box 0 and their corresponding - coulombic 1-4 scalers (value). Note: NAMD and GOMC can only have one (1) - value for the coulombic 1-4 scalers, as they both only accept a - single value in the NAMD and GOMC control files. - coulomb14scalar_dict_box_1 : dict - The residue/moleclues (key) of box 1 and their corresponding - coulombic 1-4 scalers (value). Note: NAMD and GOMC can only have one (1) - value for the coulombic 1-4 scalers, as they both only accept a - single value in the NAMD and GOMC control files. - This only exists if the box 1 structure (structure_box_1) is provided. - LJ14scalar_dict_box_0 : dict - The residue/moleclues (key) of box 0 and their corresponding - Lennard-Jones (LJ) 1-4 scalers (value). Note: NAMD and GOMC can have - multiple values for the LJ 1-4 scalers, since they are provided as an - individual input for each atom type in the force field (.inp) file. - LJ14scalar_dict_box_1 : dict - The residue/moleclues (key) of box 1 and their corresponding - Lennard-Jones (LJ) 1-4 scalers (value). Note: NAMD and GOMC can have - multiple values for the LJ 1-4 scalers, since they are provided as an - individual input for each atom type in the force field (.inp) file. - This only exists if the box 1 structure (structure_box_1) is provided. - residues_applied_list_box_0 : list - The residues in box 0 that were found and had the force fields applied to them. - residues_applied_list_box_1 : list - The residues in box 1 that were found and had the force fields applied to them. - This only exists if the box 1 structure (structure_box_1) is provided. - boxes_for_simulation : int, [0, 1] - The number of boxes used when writing the Charmm object and force fielding - the system. If only box 0 is provided, the value is 0. If box 0 and box 1 - are provided, the value is 1. - epsilon_dict : dict {str: float or int} - The uniquely numbered atom type (key) and it's non-bonded epsilon - coefficient (value). - sigma_dict : dict {str: float or int} - The uniquely numbered atom type (key) and it's non-bonded sigma - coefficient (value). - LJ_1_4_dict : dict {str: float or int} - The uniquely numbered atom type (key) and it's non-bonded 1-4 - Lennard-Jones, LJ, scaling factor (value). - coul_1_4 : float or int - The non-bonded 1-4 coulombic scaling factor, which is the - same for all the residues/molecules, regardless if - differenct force fields are utilized. Note: if - 1-4 coulombic scaling factor is not the same for all - molecules the Charmm object will fail with an error. - combined_1_4_coul_dict_per_residue : dict, {str: float or int} - The residue name/molecule (key) and it's non-bonded 1-4 coulombic - scaling factor (value). - forcefield_dict : dict - The uniquely numbered atom type (key) with it's corresponding - foyer atom typing and residue name. The residue name is added - to provide a distinction between other residues with the same - atom types. This allows the CHARMM force field to fix the - bonds and angles specific residues without effecting other - residues with the same atom types. - all_individual_atom_names_list : list - A list of all the atom names for the combined structures - (box 0 and box 1 (if supplied)), in order. - all_residue_names_List : list - A list of all the residue names for the combined structures - (box 0 and box 1 (if supplied)), in order. - max_residue_no : int - The maximum number that the residue number will count to - before restarting the counting back to 1, which is predetermined - by the PDB format. This is a constant, which equals 9999 - max_resname_char : int - The maximum number of characters allowed in the residue name, - which is predetermined by the PDB format. This is a constant, - which equals 4. - all_res_unique_atom_name_dict : dict, {str : [str, ..., str]} - A dictionary that provides the residue names (keys) and a list - of the unique atom names in the residue (value), for the - combined structures (box 0 and box 1 (if supplied)). - - Notes - ----- - Impropers, Urey-Bradleys, and NBFIX are not currenly supported. - Currently the NBFIX is disabled as since only the OPLS and TRAPPE force fields are supported. - OPLS and CHARMM forcefield styles are supported (without impropers), - AMBER forcefield styles are NOT supported. - - The atom typing is currently provided via a base 52 numbering (capital and lowercase lettering). - This base 52 numbering allows for (52)^4 unique atom types. - - Unique atom names are provided if the system do not exceed 3844 atoms (62^2) of the same - name/bead per residue (base 62 numbering). For all atom names/elements with 3 or less digits, - this converts the atom name in the GOMC psf and pdb files to a unique atom name, - provided they do not exceed 62 of the same name/element pre residue. - - Generating an empty box (i.e., pdb and psf files): - Single Box system: Enter residues = [], but the accompanying structure (structure_box_0) - must be an empty mb.Box. However, when doing this, the forcefield_selection - must be supplied, or it will provide an error - (i.e., forcefield_selection can not be equal to None). - Dual Box System: Enter an empty mb.Box structure for either structure_box_0 or - structure_box_1. - - In this current FF/psf/pdb writer, a residue type is essentially a molecule type. - Therefore, it can only correctly write systems where every bead/atom in the molecule - has the same residue name, and the residue name is specific to that molecule type. - For example: a protein molecule with many residue names is not currently supported, - but is planned to be supported in the future. - """ - def __init__( self, structure_box_0, @@ -1529,2518 +19,11 @@ def __init__( ff_filename=None, reorder_res_in_pdb_psf=False, ): - # depreciation warning that charmm_writer will be depreciated soon - depreciation_warning = ( - "The mosdef_gomc charmm_writer.py will be depreciated soon, (by the end of 2022 or sooner). " - "The this only effects the mosdef-gomc charmm_writer parmed version. The GMSO version, " - "gmso_charmm_writer.py, will replace it." - ) - warn(depreciation_warning, DeprecationWarning) - - # set all input variables to the class - self.structure_box_0 = structure_box_0 - self.filename_box_0 = filename_box_0 - self.structure_box_1 = structure_box_1 - self.filename_box_1 = filename_box_1 - self.non_bonded_type = non_bonded_type - self.forcefield_selection = forcefield_selection - self.residues = residues - self.detect_forcefield_style = detect_forcefield_style - self.gomc_fix_bonds_angles = gomc_fix_bonds_angles - self.gomc_fix_bonds = gomc_fix_bonds - self.gomc_fix_angles = gomc_fix_angles - self.bead_to_atom_name_dict = bead_to_atom_name_dict - self.fix_residue = fix_residue - self.fix_residue_in_box = fix_residue_in_box - self.set_residue_pdb_occupancy_to_1 = set_residue_pdb_occupancy_to_1 - self.ff_filename = ff_filename - self.reorder_res_in_pdb_psf = reorder_res_in_pdb_psf - - # value to check for errors, with self.input_error = True or False. Set to False initally - self.input_error = False - - if not isinstance(self.structure_box_0, (Compound, Box)): - self.input_error = True - print_error_message = ( - "ERROR: The structure_box_0 expected to be of type: " - "{} or {}, received: {}".format( - type(Compound()), - type(Box(lengths=[1, 1, 1])), - type(structure_box_0), - ) - ) - raise TypeError(print_error_message) - - if self.structure_box_1 is not None and not isinstance( - self.structure_box_1, (Compound, Box) - ): - self.input_error = True - print_error_message = ( - "ERROR: The structure_box_1 expected to be of type: " - "{} or {}, received: {}".format( - type(Compound()), - type(Box(lengths=[1, 1, 1])), - type(structure_box_1), - ) - ) - raise TypeError(print_error_message) - - if isinstance(self.structure_box_0, Box) and isinstance( - self.structure_box_1, Box - ): - self.input_error = True - print_error_message = ( - "ERROR: Both structure_box_0 and structure_box_0 are empty Boxes {}. " - "At least 1 structure must be an mbuild compound {} with 1 " - "or more atoms in it".format( - type(Box(lengths=[1, 1, 1])), type(Compound()) - ) - ) - raise TypeError(print_error_message) - - if self.structure_box_1 is None and not isinstance( - self.structure_box_0, Compound - ): - self.input_error = True - print_error_message = ( - "ERROR: Only 1 structure is provided and it can not be an empty mbuild Box {}. " - "it must be an mbuild compound {} with at least 1 " - "or more atoms in it.".format( - type(Box(lengths=[1, 1, 1])), type(Compound()) - ) - ) - raise TypeError(print_error_message) - - if not isinstance(self.residues, list): - self.input_error = True - print_error_message = "ERROR: Please enter the residues list (residues) in a list format." - raise TypeError(print_error_message) - - if isinstance(self.residues, list): - for each_residue in self.residues: - if not isinstance(each_residue, str): - self.input_error = True - print_error_message = "ERROR: Please enter a residues list (residues) with only string values." - raise TypeError(print_error_message) - - if self.residues is None: - self.input_error = True - print_error_message = ( - "ERROR: Please enter the residues list (residues)" - ) - raise TypeError(print_error_message) - if not isinstance(self.filename_box_0, str): - self.input_error = True - print_error_message = ( - "ERROR: Please enter the filename_box_0 as a string." - ) - raise TypeError(print_error_message) - - unique_residue_test_name_list = [] - for res_m in range(0, len(self.residues)): - if self.residues[res_m] not in unique_residue_test_name_list: - unique_residue_test_name_list.append(self.residues[res_m]) - if len(unique_residue_test_name_list) != len(self.residues): - self.input_error = True - print_error_message = "ERROR: Please enter the residues list (residues) that has only unique residue names." - raise ValueError(print_error_message) - - if self.filename_box_1 is not None and not isinstance( - self.filename_box_1, str - ): - self.input_error = True - print_error_message = ( - "ERROR: Please enter the filename_box_1 as a string." - ) - raise TypeError(print_error_message) - - if self.ff_filename is not None: - if not isinstance(self.ff_filename, str): - self.input_error = True - print_error_message = "ERROR: Please enter GOMC force field name (ff_filename) as a string." - raise TypeError(print_error_message) - if isinstance(self.ff_filename, str): - extension_ff_name = os.path.splitext(self.ff_filename)[-1] - if extension_ff_name == "": - self.ff_filename = self.ff_filename + ".inp" - elif extension_ff_name == ".inp": - self.ff_filename = self.ff_filename + "" - elif extension_ff_name != ".inp": - self.input_error = True - print_error_message = ( - "ERROR: Please enter GOMC force field name without an " - "extention or the .inp extension." - ) - raise ValueError(print_error_message) - - if self.forcefield_selection is not None: - print( - "write_gomcdata: forcefield_selection = " - + str(self.forcefield_selection) - + ", " - + "residues = " - + str(self.residues) - ) - if not isinstance(self.forcefield_selection, (dict, str)): - self.input_error = True - print_error_message = ( - "ERROR: The force field selection (forcefield_selection) " - "is not a string or a dictionary with all the residues specified " - 'to a force field. -> String Ex: "path/trappe-ua.xml" or Ex: "trappe-ua" ' - "Otherise provided a dictionary with all the residues specified " - "to a force field " - '->Dictionary Ex: {"Water" : "oplsaa", "OCT": "path/trappe-ua.xml"}, ' - "Note: the file path must be specified the force field file if " - "a standard foyer force field is not used." - ) - raise TypeError(print_error_message) - - if isinstance(self.forcefield_selection, str): - ff_name = self.forcefield_selection - self.forcefield_selection = {} - for i in range(0, len(self.residues)): - self.forcefield_selection.update( - {self.residues[i]: ff_name} - ) - print( - "FF forcefield_selection = " - + str(self.forcefield_selection) - ) - - elif self.forcefield_selection is None: - self.input_error = True - print_error_message = "ERROR: Please enter the forcefield_selection as it was not provided." - raise TypeError(print_error_message) - - if self.residues is not None and not isinstance(self.residues, list): - self.input_error = True - print_error_message = ( - "ERROR: Please enter the residues (residues) in a list format" - ) - raise TypeError(print_error_message) - - _check_fixed_bonds_angles_lists( - self.gomc_fix_bonds_angles, "gomc_fix_bonds_angles", self.residues - ) - _check_fixed_bonds_angles_lists( - self.gomc_fix_bonds, "gomc_fix_bonds", self.residues - ) - _check_fixed_bonds_angles_lists( - self.gomc_fix_angles, "gomc_fix_angles", self.residues - ) - - if self.fix_residue is not None and not isinstance( - self.fix_residue, list - ): - self.input_error = True - print_error_message = ( - "ERROR: Please enter the fix_residue in a list format" - ) - raise TypeError(print_error_message) - - if isinstance(self.fix_residue, list): - for fix_residue_q in self.fix_residue: - if fix_residue_q not in self.residues: - self.input_error = True - print_error_message = ( - "Error: Please ensure that all the residue names in the fix_residue " - "list are also in the residues list." - ) - raise ValueError(print_error_message) - - if self.fix_residue_in_box is not None and not isinstance( - self.fix_residue_in_box, list - ): - self.input_error = True - print_error_message = ( - "ERROR: Please enter the fix_residue_in_box in a list format." - ) - raise TypeError(print_error_message) - - if isinstance(self.fix_residue_in_box, list): - for fix_residue_in_box_q in self.fix_residue_in_box: - if fix_residue_in_box_q not in self.residues: - self.input_error = True - print_error_message = ( - "Error: Please ensure that all the residue names in the " - "fix_residue_in_box list are also in the residues list." - ) - raise ValueError(print_error_message) - - if self.set_residue_pdb_occupancy_to_1 is not None and not isinstance( - self.set_residue_pdb_occupancy_to_1, list - ): - self.input_error = True - print_error_message = "ERROR: Please enter the set_residue_pdb_occupancy_to_1 in a list format." - raise TypeError(print_error_message) - - if isinstance(self.set_residue_pdb_occupancy_to_1, list): - for ( - set_residue_pdb_occupancy_to_1_q - ) in self.set_residue_pdb_occupancy_to_1: - if set_residue_pdb_occupancy_to_1_q not in self.residues: - self.input_error = True - print_error_message = ( - "Error: Please ensure that all the residue names in the " - "set_residue_pdb_occupancy_to_1 list are also in the residues list." - ) - raise ValueError(print_error_message) - - if self.bead_to_atom_name_dict is not None and not isinstance( - self.bead_to_atom_name_dict, dict - ): - self.input_error = True - print_error_message = ( - "ERROR: Please enter the a bead type to atom in the dictionary " - "(bead_to_atom_name_dict) so GOMC can properly evaluate the unique atom names" - ) - raise TypeError(print_error_message) - - if isinstance(self.bead_to_atom_name_dict, dict): - dict_list = [] - for key in self.bead_to_atom_name_dict.keys(): - dict_list.append(key) - - for dict_lis_i in dict_list: - if not isinstance(dict_lis_i, str) or not isinstance( - self.bead_to_atom_name_dict[dict_lis_i], str - ): - print_error_message = "ERROR: Please enter the bead_to_atom_name_dict with only string inputs." - raise TypeError(print_error_message) - - print("******************************") - print("") - - self.sub_1_for_base_52 = 1 - - if self.structure_box_1: - self.boxes_for_simulation = 2 - else: - self.boxes_for_simulation = 1 - - # write the Force fields - self.combined_1_4_lj_dict_per_residue = {} - self.combined_1_4_coul_dict_per_residue = {} - - if self.structure_box_1: - print( - "GOMC FF writing each residues FF as a group for structure_box_0" - ) - [ - self.structure_box_0_ff, - self.coulomb14scalar_dict_box_0, - self.LJ14scalar_dict_box_0, - self.residues_applied_list_box_0, - ] = specific_ff_to_residue( - self.structure_box_0, - forcefield_selection=self.forcefield_selection, - residues=self.residues, - reorder_res_in_pdb_psf=self.reorder_res_in_pdb_psf, - boxes_for_simulation=self.boxes_for_simulation, - ) - - print( - "GOMC FF writing each residues FF as a group for structure_box_1" - ) - [ - self.structure_box_1_ff, - self.coulomb14scalar_dict_box_1, - self.LJ14scalar_dict_box_1, - self.residues_applied_list_box_1, - ] = specific_ff_to_residue( - self.structure_box_1, - forcefield_selection=self.forcefield_selection, - residues=self.residues, - reorder_res_in_pdb_psf=self.reorder_res_in_pdb_psf, - boxes_for_simulation=self.boxes_for_simulation, - ) - - self.structure_box_0_and_1_ff = ( - self.structure_box_0_ff + self.structure_box_1_ff - ) - self.combined_1_4_lj_dict_per_residue.update( - self.LJ14scalar_dict_box_0 - ) - self.combined_1_4_lj_dict_per_residue.update( - self.LJ14scalar_dict_box_1 - ) - self.combined_1_4_coul_dict_per_residue.update( - self.coulomb14scalar_dict_box_0 - ) - self.combined_1_4_coul_dict_per_residue.update( - self.coulomb14scalar_dict_box_1 - ) - - self.residues_applied_list_box_0_and_1 = ( - self.residues_applied_list_box_0 - ) - for res_iter in self.residues_applied_list_box_1: - if res_iter not in self.residues_applied_list_box_0: - self.residues_applied_list_box_0_and_1.append(res_iter) - - for res_iter_0_1 in self.residues_applied_list_box_0_and_1: - if res_iter_0_1 not in self.residues: - self.input_error = True - print_error_message = "ERROR: All the residues were not used from the forcefield_selection " - "string or dictionary. There may be residues below other specified " - "residues in the mbuild.Compound hierarchy. If so, the residues " - "acquire the residue's force fields, which is at the top of the " - "hierarchy. Alternatively, residues that are not in the structure " - r"may have been specified." - raise ValueError(print_error_message) - - for res_iter_0_1 in self.residues: - if res_iter_0_1 not in self.residues_applied_list_box_0_and_1: - self.input_error = True - print_error_message = ( - "ERROR: All the residues were not used from the forcefield_selection " - "string or dictionary. There may be residues below other specified " - "residues in the mbuild.Compound hierarchy. If so, the residues " - "acquire the residue's force fields, which is at the top of the " - "hierarchy. Alternatively, residues that are not in the structure " - "may have been specified." - ) - raise ValueError(print_error_message) - - total_charge = sum( - [atom.charge for atom in self.structure_box_0_ff] - ) - if round(total_charge, 4) != 0.0: - warn( - "System is not charge neutral for structure_box_0. " - "Total charge is {}.".format(total_charge) - ) - - total_charge = sum( - [atom.charge for atom in self.structure_box_1_ff] - ) - if round(total_charge, 4) != 0.0: - warn( - "System is not charge neutral for structure_box_1. " - "Total charge is {}.".format(total_charge) - ) - - total_charge = sum( - [atom.charge for atom in self.structure_box_0_and_1_ff] - ) - if round(total_charge, 4) != 0.0: - warn( - "System is not charge neutral for structure_0_and_1. " - "Total charge is {}.".format(total_charge) - ) - - else: - print( - "GOMC FF writing each residues FF as a group for structure_box_0" - ) - [ - self.structure_box_0_ff, - self.coulomb14scalar_dict_box_0, - self.LJ14scalar_dict_box_0, - self.residues_applied_list_box_0, - ] = specific_ff_to_residue( - self.structure_box_0, - forcefield_selection=self.forcefield_selection, - residues=self.residues, - reorder_res_in_pdb_psf=self.reorder_res_in_pdb_psf, - boxes_for_simulation=self.boxes_for_simulation, - ) - - self.combined_1_4_lj_dict_per_residue.update( - self.LJ14scalar_dict_box_0 - ) - self.combined_1_4_coul_dict_per_residue.update( - self.coulomb14scalar_dict_box_0 - ) - - for res_iter_0 in self.residues_applied_list_box_0: - if res_iter_0 not in self.residues: - self.input_error = True - print_error_message = ( - "ERROR: All the residues were not used from the forcefield_selection " - "string or dictionary. There may be residues below other specified " - "residues in the mbuild.Compound hierarchy. If so, the residues " - "acquire the residue's force fields, which is at the top of the " - "hierarchy. Alternatively, residues that are not in the structure " - "may have been specified." - ) - raise ValueError(print_error_message) - - for res_iter_0 in self.residues: - if res_iter_0 not in self.residues_applied_list_box_0: - self.input_error = True - print_error_message = ( - "ERROR: All the residues were not used from the forcefield_selection " - "string or dictionary. There may be residues below other specified " - "residues in the mbuild.Compound hierarchy. If so, the residues " - "acquire the residue's force fields, which is at the top of the " - "hierarchy. Alternatively, residues that are not in the structure " - "may have been specified." - ) - raise ValueError(print_error_message) - - total_charge = sum( - [atom.charge for atom in self.structure_box_0_ff] - ) - if round(total_charge, 4) != 0.0: - warn( - "System is not charge neutral for structure_box_0. " - "Total charge is {}.".format(total_charge) - ) - - print( - "forcefield type from compound = " + str(self.forcefield_selection) - ) - print( - "coulomb14scale from compound = " - + str(self.combined_1_4_coul_dict_per_residue) - ) - print( - "lj14scale from compound = " - + str(self.combined_1_4_lj_dict_per_residue) - ) - - # lock the atom_style and unit_style for GOMC. Can be inserted into variables - # once more functionality is built in - self.atom_style = "full" - self.unit_style = "real" - # functional form type default. Can be inserted into variables once more functionality is built in - use_rb_torsions = True - use_dihedrals = False - use_urey_bradleys = False - - # Convert coordinates to real or other units (real only current option) - if self.unit_style == "real": - self.sigma_conversion_factor = 1 - self.epsilon_conversion_factor = 1 - self.mass_conversion_factor = 1 - - if self.structure_box_1: - self.types = np.array( - [ - atom.type + "_" + str(atom.residue.name) - for atom in self.structure_box_0_and_1_ff.atoms - ] - ) - - else: - self.types = np.array( - [ - atom.type + "_" + str(atom.residue.name) - for atom in self.structure_box_0_ff.atoms - ] - ) - - self.unique_types = list(set(self.types)) - self.unique_types.sort(key=natural_sort) - - if self.structure_box_1: - self.masses = ( - np.array( - [atom.mass for atom in self.structure_box_0_and_1_ff.atoms] - ) - / self.mass_conversion_factor - ) - self.mass_dict = dict( - [ - (self.unique_types.index(atom_type) + 1, mass) - for atom_type, mass in zip(self.types, self.masses) - ] - ) - - else: - self.masses = ( - np.array([atom.mass for atom in self.structure_box_0_ff.atoms]) - / self.mass_conversion_factor - ) - self.mass_dict = dict( - [ - (self.unique_types.index(atom_type) + 1, mass) - for atom_type, mass in zip(self.types, self.masses) - ] - ) - - # added an index so the atom types can be converted to numbers as the type name is to long for insertion into - # the pdb and psf files - self.atom_types_to_index_value_dict = dict( - [ - ( - self.unique_types[self.unique_types.index(atom_type)], - self.unique_types.index(atom_type), - ) - for atom_type, mass in zip(self.types, self.masses) - ] - ) - - # normalize by sigma - self.box_0 = Box( - lengths=np.array( - [ - (0.1 * val) / self.sigma_conversion_factor - for val in self.structure_box_0_ff.box[0:3] - ] - ), - angles=self.structure_box_0_ff.box[3:6], - ) - - # create box 0 vector list and convert from nm to Ang and round to 6 decimals. - # note mbuild standard lengths are in nm, so round to 6+1 = 7 then mutlipy by 10 - box_0_lengths_ang = ( - self.box_0.lengths[0] * 10, - self.box_0.lengths[1] * 10, - self.box_0.lengths[2] * 10, - ) - self.box_0_vectors = _lengths_angles_to_vectors( - box_0_lengths_ang, self.box_0.angles, precision=6 - ) - - # Internally use nm - if self.structure_box_1: - self.box_1 = Box( - lengths=np.array( - [ - (0.1 * val) / self.sigma_conversion_factor - for val in self.structure_box_1_ff.box[0:3] - ] - ), - angles=self.structure_box_1_ff.box[3:6], - ) - - # create box 1 vector list and convert from nm to Ang and round to 6 decimals. - # note mbuild standard lengths are in nm, so round to 6+1 = 7 then mutlipy by 10 - box_1_lengths_ang = ( - self.box_1.lengths[0] * 10, - self.box_1.lengths[1] * 10, - self.box_1.lengths[2] * 10, - ) - self.box_1_vectors = _lengths_angles_to_vectors( - box_1_lengths_ang, self.box_1.angles, precision=6 - ) - - # if self.structure_box_1 != None: - if self.structure_box_1: - self.structure_selection = self.structure_box_0_and_1_ff - else: - self.structure_selection = self.structure_box_0_ff - - # Non-Bonded forces - epsilons = ( - np.array([atom.epsilon for atom in self.structure_selection.atoms]) - / self.epsilon_conversion_factor - ) - sigmas = ( - np.array([atom.sigma for atom in self.structure_selection.atoms]) - / self.sigma_conversion_factor - ) - forcefields = [ - atom.type + "_" + atom.residue.name - for atom in self.structure_selection.atoms - ] - residues_all_list = [ - atom.residue.name for atom in self.structure_selection.atoms - ] - - self.epsilon_dict = dict( - [ - (self.unique_types.index(atom_type), epsilon) - for atom_type, epsilon in zip(self.types, epsilons) - ] - ) - self.sigma_dict = dict( - [ - (self.unique_types.index(atom_type), sigma) - for atom_type, sigma in zip(self.types, sigmas) - ] - ) - self.LJ_1_4_dict = dict( - [ - ( - self.unique_types.index(atom_type), - self.combined_1_4_lj_dict_per_residue[residues_all_list], - ) - for atom_type, residues_all_list in zip( - self.types, residues_all_list - ) - ] - ) - self.forcefield_dict = dict( - [ - (self.unique_types.index(atom_type), forcefield) - for atom_type, forcefield in zip(self.types, forcefields) - ] - ) - - # ensure all 1,4-coulombic scaling factors are the same - coul_1_4_List = [] - for p in self.combined_1_4_coul_dict_per_residue.values(): - coul_1_4_List.append(p) - coul_1_4_set = set(coul_1_4_List) - if len(coul_1_4_set) > 1: - self.input_error = True - print_error_message = ( - "ERROR: There are multiple 1,4-coulombic scaling factors " - "GOMC will only accept a singular input for the 1,4-coulombic " - "scaling factors." - ) - raise ValueError(print_error_message) - else: - self.coul_1_4 = list(coul_1_4_set)[0] - - # get all the unique atom name to check for the MEMC move in the gomc_conf_writer - self.all_individual_atom_names_list = [] - self.all_residue_names_List = [] - if self.structure_box_1: - list_of_structures = [ - self.structure_box_0_ff, - self.structure_box_1_ff, - ] - stuct_only = [self.structure_box_0_ff, self.structure_box_1_ff] - else: - list_of_structures = [self.structure_box_0_ff] - stuct_only = [self.structure_box_0_ff] - - for q_i in range(0, len(list_of_structures)): - stuct_only_iteration = stuct_only[q_i] - - # caluculate the atom name and unique atom names - residue_data_list = [] - residue_names_list = [] - for k, atom in enumerate(stuct_only_iteration.atoms): - residue_data_list.append(str(atom.residue)) - residue_names_list.append(atom.residue.name) - - unique_residue_data_dict = {} - unique_residue_data_list = [] - residue_data_name_list = [] - - for m, residue in enumerate(stuct_only_iteration.residues): - unique_residue_data_list.append( - str(stuct_only_iteration.residues[m]) - ) - unique_residue_data_dict.update( - {unique_residue_data_list[m]: m + 1} - ) - residue_data_name_list.append( - stuct_only_iteration.residues[m].name - ) - - self.max_residue_no = 9999 - self.max_resname_char = 4 - - res_no_chain_iter_corrected = [] - residue_id_list = [] - residue_id_adder_fixed_struct_wo_bonds = ( - 0 # for example zeolite used as fixed atoms wo bonds - ) - for f, PSF_atom_iteration_0 in enumerate( - stuct_only_iteration.atoms - ): - if f > 0: - if ( - PSF_atom_iteration_0.residue.chain - == previous_residue_chain - and len(PSF_atom_iteration_0.bonds) == 0 - ): - residue_id_adder_fixed_struct_wo_bonds += 1 - - previous_residue_chain = PSF_atom_iteration_0.residue.chain - - residue_id_int = int( - unique_residue_data_dict[residue_data_list[f]] - + residue_id_adder_fixed_struct_wo_bonds - ) - - res_id_adder = int( - (residue_id_int % self.max_residue_no) % self.max_residue_no - ) - if int(res_id_adder) == 0: - res_no_iteration_corrected = int(self.max_residue_no) - else: - res_no_iteration_corrected = res_id_adder - - res_no_chain_iter_corrected.append(res_no_iteration_corrected) - residue_id_list.append(residue_id_int) - - # This converts the atom name in the GOMC psf and pdb files to unique atom names - [ - unique_individual_atom_names_dict_iter, - individual_atom_names_list_iter, - missing_bead_to_atom_name_iter, - ] = unique_atom_naming( - stuct_only_iteration, - residue_id_list, - residue_names_list, - bead_to_atom_name_dict=self.bead_to_atom_name_dict, - ) - - if q_i == 0: - self.all_individual_atom_names_list = ( - individual_atom_names_list_iter - ) - - self.all_residue_names_List = residue_names_list - else: - self.all_individual_atom_names_list = ( - self.all_individual_atom_names_list - + individual_atom_names_list_iter - ) - - self.all_residue_names_List = ( - self.all_residue_names_List + residue_names_list - ) - - # put the self.all_individual_atom_names_list and self.all_residue_names_List in a list to match - # the the atom name with a residue and find the unique matches - if None in [ - unique_individual_atom_names_dict_iter, - individual_atom_names_list_iter, - missing_bead_to_atom_name_iter, - ]: - self.input_error = True - print_error_message = ( - "ERROR: The unique_atom_naming function failed while " - "running the charmm_writer function. Ensure the proper inputs are " - "in the bead_to_atom_name_dict." - ) - raise ValueError(print_error_message) - - else: - self.all_res_unique_atom_name_dict = {} - for res_i in range(0, len(self.all_individual_atom_names_list)): - try: - if ( - self.all_individual_atom_names_list[res_i] - not in self.all_res_unique_atom_name_dict[ - self.all_residue_names_List[res_i] - ] - ): - self.all_res_unique_atom_name_dict.setdefault( - self.all_residue_names_List[res_i], [] - ).append(self.all_individual_atom_names_list[res_i]) - except: - self.all_res_unique_atom_name_dict.setdefault( - self.all_residue_names_List[res_i], [] - ).append(self.all_individual_atom_names_list[res_i]) - - print( - "all_res_unique_atom_name_dict = {}".format( - self.all_res_unique_atom_name_dict - ) - ) - - def write_inp(self): - """This write_inp function writes the Charmm style parameter (force field) file, which can be utilized - in the GOMC and NAMD engines.""" - print("******************************") - print("") - print( - "The charmm force field file writer (the write_inp function) is running" - ) - - if self.ff_filename is None: - self.input_error = True - print_error_message = ( - "ERROR: The force field file name was not specified and in the " - "Charmm object. " - "Therefore, the force field file (.inp) can not be written. " - "Please use the force field file name when building the Charmm object, " - "then use the write_inp function." - ) - raise TypeError(print_error_message) - else: - print("******************************") - print("") - print( - "The charmm force field file writer (the write_inp function) is running" - ) - print("******************************") - print("") - print("writing the GOMC force field file ") - date_time = datetime.datetime.today() - - unique_residue_data_dict = {} - unique_residue_data_list = [] - residue_data_name_list = [] - - # if self.structure_box_1 != None: - if self.structure_box_1: - residue_iterate = 0 - for m, residue in enumerate(self.structure_box_0_ff.residues): - residue_iterate = residue_iterate + 1 - unique_residue_data_list.append( - str(self.structure_box_0_ff.residues[m]) - ) - unique_residue_data_dict.update( - {unique_residue_data_list[m]: m + 1} - ) - residue_data_name_list.append( - self.structure_box_0_ff.residues[m].name - ) - - for m, residue in enumerate(self.structure_box_1_ff.residues): - unique_residue_data_list.append( - str(self.structure_box_1_ff.residues[m]) - ) - unique_residue_data_dict.update( - {unique_residue_data_list[m]: m + 1 + residue_iterate} - ) - residue_data_name_list.append( - self.structure_box_1_ff.residues[m].name - ) - - else: - for m, residue in enumerate(self.structure_box_0_ff.residues): - unique_residue_data_list.append( - str(self.structure_box_0_ff.residues[m]) - ) - unique_residue_data_dict.update( - {unique_residue_data_list[m]: m + 1} - ) - residue_data_name_list.append( - self.structure_box_0_ff.residues[m].name - ) - - for n in range(0, len(residue_data_name_list)): - if residue_data_name_list[n] not in self.residues: - print( - "residue_data_name_list = " - + str(residue_data_name_list) - ) - self.input_error = True - print_error_message = "ERROR: Please specifiy all residues (residues) in a list" - raise ValueError(print_error_message) - - with open(self.ff_filename, "w") as data: - # Syntax which can change based on the functional form - # Infer functional form based on the properties of the residue_id_list or structure_box_0_ff - if self.detect_forcefield_style: - # Check angles - if len(self.structure_selection.urey_bradleys) > 0: - print("Urey bradley terms detected") - data.write( - "! Urey bradley terms detected, will use angle_style self" - ) - data.write( - "! POTENTIAL ERROR: GOMC does no support the Urey bradley terms" - ) - use_urey_bradleys = True - else: - print( - "No urey bradley terms detected, will use angle_style harmonic" - ) - use_urey_bradleys = False - - # Check dihedrals - if len(self.structure_selection.rb_torsions) > 0: - print( - "will use CHARMM_torsions = K0 + K1 * (1 + Cos[n1*(t) - (d1)] ) + " - + "K2 * (1 + Cos[n2*(t) - (d2)] ) + K3 * (1 + Cos[n3*(t) - (d3)] ) + " - + "K4 * (1 + Cos[n4*(t) - (d4)] ) + K5 * (1 + Cos[n5*(t) - (d5)] ) " - ) - use_rb_torsions = True - - else: - use_rb_torsions = False - - if len(self.structure_selection.dihedrals) > 0: - print( - "Charmm dihedrals detected, will use dihedral_style charmm" - ) - # this will need tested with a standard charmm input format before releasing it - use_dihedrals = True - self.input_error = True - print_error_message = ( - "ERROR: use_dihedrals = {} " - "Charmm dihedrals not yet supported.".format( - use_dihedrals - ) - ) - raise ValueError(print_error_message) - else: - use_dihedrals = False - - if use_rb_torsions and use_dihedrals: - warn( - "Multiple dihedral styles detected, check your Forcefield XML and structure_selection" - ) - - # Check impropers - for dihedral in self.structure_selection.dihedrals: - if dihedral.improper: - warn( - "Amber-style impropers are currently not supported" - ) - - bonds = [ - [bond.atom1.idx + 1, bond.atom2.idx + 1] - for bond in self.structure_selection.bonds - ] - angles = [ - [ - angle.atom1.idx + 1, - angle.atom2.idx + 1, - angle.atom3.idx + 1, - ] - for angle in self.structure_selection.angles - ] - if use_rb_torsions: - dihedrals = [ - [ - dihedral.atom1.idx + 1, - dihedral.atom2.idx + 1, - dihedral.atom3.idx + 1, - dihedral.atom4.idx + 1, - ] - for dihedral in self.structure_selection.rb_torsions - ] - elif use_dihedrals: - dihedrals = [ - [ - dihedral.atom1.idx + 1, - dihedral.atom2.idx + 1, - dihedral.atom3.idx + 1, - dihedral.atom4.idx + 1, - ] - for dihedral in self.structure_selection.dihedrals - ] - else: - dihedrals = [] - impropers = [ - [ - improper.atom1.idx + 1, - improper.atom2.idx + 1, - improper.atom3.idx + 1, - improper.atom4.idx + 1, - ] - for improper in self.structure_selection.impropers - ] - - if bonds: - if len(self.structure_selection.bond_types) == 0: - bond_types = np.ones(len(bonds), dtype=int) - else: - bond_types, unique_bond_types = _get_bond_types( - self.structure_selection, - self.sigma_conversion_factor, - self.epsilon_conversion_factor, - ) - - if angles: - angle_types, unique_angle_types = _get_angle_types( - self.structure_selection, - self.sigma_conversion_factor, - self.epsilon_conversion_factor, - use_urey_bradleys=use_urey_bradleys, - ) - - if dihedrals: - dihedral_types, unique_dihedral_types = _get_dihedral_types( - self.structure_selection, - use_rb_torsions, - use_dihedrals, - self.epsilon_conversion_factor, - ) - - if impropers: - improper_types, unique_improper_types = _get_impropers( - self.structure_selection, self.epsilon_conversion_factor - ) - - # if self.structure_box_1 != None: - if self.structure_box_1: - data.write( - "* " - + self.filename_box_0 - + " and " - + self.filename_box_1 - + " - created by MoSDeF-GOMC using the on " - + str(date_time) - + "\n" - ) - else: - data.write( - "* " - + self.filename_box_0 - + " - created by MoSDeF-GOMC using the on " - + str(date_time) - + "\n" - ) - - data.write( - "* " - + "parameters from the " - + str(self.forcefield_selection) - + " force field(s) via MoSDef\n" - ) - data.write( - "* 1-4 coulombic scaling = " - + str(self.combined_1_4_coul_dict_per_residue) - + ", and 1-4 LJ scaling = " - + str(self.combined_1_4_lj_dict_per_residue) - + "\n\n" - ) - data.write( - "* " - + "{:d} atoms\n".format(len(self.structure_selection.atoms)) - ) - - if self.atom_style in ["full", "molecular"]: - data.write("* " + "{:d} bonds\n".format(len(bonds))) - data.write("* " + "{:d} angles\n".format(len(angles))) - data.write( - "* " + "{:d} dihedrals\n".format(len(dihedrals)) - ) - data.write( - "* " + "{:d} impropers\n\n".format(len(impropers)) - ) - - data.write( - "* " + "{:d} atom types\n".format(len(set(self.types))) - ) - if self.atom_style in ["full", "molecular"]: - if bonds: - data.write( - "* " - + "{:d} bond types\n".format( - len(set(unique_bond_types)) - ) - ) - if angles: - data.write( - "* " - + "{:d} angle types\n".format( - len(set(unique_angle_types)) - ) - ) - if dihedrals: - data.write( - "* " - + "{:d} dihedral types\n".format( - len(set(unique_dihedral_types)) - ) - ) - if impropers: - data.write( - "* " - + "{:d} improper types\n".format( - len(set(unique_improper_types)) - ) - ) - - data.write("\n") - - data.write("\n* masses\n\n") - data.write( - "!atom_types \tmass \t\t atomTypeForceFieldName_ResidueName " - + "(i.e., atoms_type_per_utilized_FF) \n" - ) - for atom_type, mass in self.mass_dict.items(): - mass_format = "* {}\t\t{:.6f}\t! {}\n" - data.write( - mass_format.format( - base10_to_base52_alph( - atom_type - self.sub_1_for_base_52 - ), - mass, - self.unique_types[atom_type - 1], - ) - ) - - # Bond coefficients - if bonds: - data.write("\n") - data.write("BONDS * harmonic\n") - data.write("!\n") - data.write("!V(bond) = Kb(b - b0)**2\n") - data.write("!\n") - data.write("!Kb: kcal/mole/A**2\n") - data.write("!b0: A\n") - data.write( - "!Kb (kcal/mol) = Kb_K (K) * Boltz. const.; (9999999999 if no stretching)\n" - ) - data.write("!\n") - - if self.unit_style == "real": - data.write( - "!atom_types \t Kb\t\tb0 \t\t atoms_types_per_utilized_FF\n" - ) - for params, idx in unique_bond_types.items(): - bond_format = "{}\t{}\t{}\t{}\t\t! {}\t{}\n" - if ( - (self.gomc_fix_bonds_angles is not None) - and ( - (params[3] and params[4]) - in self.gomc_fix_bonds_angles - ) - ) or ( - ( - (self.gomc_fix_bonds is not None) - and ( - (params[3] and params[4]) - in self.gomc_fix_bonds - ) - ) - ): - fix_bond_k_value = "999999999999" - data.write( - bond_format.format( - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[2][0] + "_" + str(params[3]) - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[2][1] + "_" + str(params[4]) - ] - ), - fix_bond_k_value, - params[1], - params[2][0] + "_" + str(params[3]), - params[2][1] + "_" + str(params[4]), - ) - ) - - else: - data.write( - bond_format.format( - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[2][0] + "_" + str(params[3]) - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[2][1] + "_" + str(params[4]) - ] - ), - params[0], - params[1], - params[2][0] + "_" + str(params[3]), - params[2][1] + "_" + str(params[4]), - ) - ) - - # Angle coefficients - if angles: - if use_urey_bradleys: - data.write( - "\n! Urey Bradley terms detected but not written," - + "since they are currently not compatible with GOMC\n" - ) - - data.write("\nANGLES * harmonic\n") - data.write("!\n") - data.write("!V(angle) = Ktheta(Theta - Theta0)**2\n") - data.write("!\n") - data.write("!Ktheta: kcal/mole/rad**2\n") - data.write("!Theta0: degrees\n") - data.write("!\n") - data.write( - "! Ktheta (kcal/mol) = Ktheta_K (K) * Boltz. const.\t\t\n" - ) - data.write("!\n") - data.write( - "!atom_types \t\tKtheta\t\tTheta0\t\t\t atoms_types_per_utilized_FF\n" - ) - for params, idx in unique_angle_types.items(): - if ( - (self.gomc_fix_bonds_angles is not None) - and ((params[4] and params[5] and params[6])) - in self.gomc_fix_bonds_angles - ) or ( - (self.gomc_fix_angles is not None) - and ((params[4] and params[5] and params[6])) - in self.gomc_fix_angles - ): - fix_angle_k_value = "999999999999" - angle_format = ( - "{}\t{}\t{}\t{}\t\t{:.5f}\t\t! {}\t{}\t{}\n" - ) - data.write( - angle_format.format( - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[3][0] + "_" + params[4] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[2] + "_" + params[5] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[3][1] + "_" + params[6] - ] - ), - fix_angle_k_value, - params[1], - params[3][0] + "_" + params[4], - params[2] + "_" + params[5], - params[3][1] + "_" + params[6], - ) - ) - - else: - data.write( - "{}\t{}\t{}\t{}\t\t{:.5f}\t\t! {}\t{}\t{}\n".format( - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[3][0] + "_" + params[4] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[2] + "_" + params[5] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[3][1] + "_" + params[6] - ] - ), - params[0], - params[1], - params[3][0] + "_" + params[4], - params[2] + "_" + params[5], - params[3][1] + "_" + params[6], - ) - ) - - # Dihedral coefficients - if dihedrals: - if use_rb_torsions: - list_if_large_error_dihedral_overall = [] - - list_if_largest_error_abs_values_for_dihedral_overall = ( - [] - ) - list_dihedral_overall_error = [] - - list_if_abs_max_values_for_dihedral_overall = [] - list_dihedral_atoms_all_dihedral_overall = [] - - data.write("\nDIHEDRALS * CHARMM\n") - data.write("!\n") - data.write( - "!V(dihedral) = Kchi(1 + cos(n(chi) - delta))\n" - ) - data.write("!\n") - data.write("!Kchi: kcal/mole\n") - data.write("!n: multiplicity\n") - data.write("!delta: degrees\n") - data.write("!\n") - data.write( - "! Kchi (kcal/mol) = Kchi_K (K) * Boltz. const.\n" - ) - data.write( - "! Boltzmann = 0.0019872041 kcal / (mol * K)\n" - ) - data.write("!\n") - if self.unit_style == "real": - data.write( - "!atom_types \t\t\tKchi\t\tn\tdelta\t\t atoms_types_per_utilized_FF\n" - ) - - for params, idx in unique_dihedral_types.items(): - charmm_coeffs = RB_to_CHARMM( - params[0], - params[1], - params[2], - params[3], - params[4], - params[5], - ) - - # check the error between the convertions of RB_tortions to CHARMM DIHEDRALS (start) - rb_to_charmm_abs_diff = [] - no_pi = np.pi - dihedral_steps = 2 * 10 ** (-3) - dihedral_range = 4 * no_pi - dihedral_no_steps = ( - int(dihedral_range / dihedral_steps) + 1 - ) - - for i in range(0, dihedral_no_steps + 1): - t = i * dihedral_steps - - rb_dihedral_calc = ( - params[0] - + params[1] * (np.cos(t - no_pi)) ** 1 - + params[2] * (np.cos(t - no_pi)) ** 2 - + params[3] * (np.cos(t - no_pi)) ** 3 - + params[4] * (np.cos(t - no_pi)) ** 4 - + params[5] * (np.cos(t - no_pi)) ** 5 - ) - """CHARMM_torsions - = K0 * (1 + Cos[n0 * (t) - (d0)]) + K1 * (1 + Cos[n1 * (t) - (d1)]) + K2 * ( - # 1 + Cos[n2 * (t) - (d2)]) - + K3 * (1 + Cos[n3 * (t) - (d3)]) + K4 * (1 + Cos[n4 * (t) - (d4)]) + K5 * ( - # 1 + Cos[n5 * (t) - (d5)]) - - = K0 + K1 * (1 + Cos[n1 * (t) - (d1)]) + K2 * (1 + Cos[n2 * (t) - (d2)]) - + K3 * (1 + Cos[n3 * (t) - (d3)]) + K4 * (1 + Cos[n4 * (t) - (d4)]) + K5 * ( - # 1 + Cos[n5 * (t) - (d5)]). """ - - rb_to_charmm_calc = ( - charmm_coeffs[0, 0] - * ( - 1 - + np.cos( - int(charmm_coeffs[0, 1]) * t - - charmm_coeffs[0, 2] * no_pi / 180 - ) - ) - + charmm_coeffs[1, 0] - * ( - 1 - + np.cos( - int(charmm_coeffs[1, 1]) * t - - charmm_coeffs[1, 2] * no_pi / 180 - ) - ) - + charmm_coeffs[2, 0] - * ( - 1 - + np.cos( - int(charmm_coeffs[2, 1]) * t - - charmm_coeffs[2, 2] * no_pi / 180 - ) - ) - + charmm_coeffs[3, 0] - * ( - 1 - + np.cos( - int(charmm_coeffs[3, 1]) * t - - charmm_coeffs[3, 2] * no_pi / 180 - ) - ) - + charmm_coeffs[4, 0] - * ( - 1 - + np.cos( - int(charmm_coeffs[4, 1]) * t - - charmm_coeffs[4, 2] * no_pi / 180 - ) - ) - + charmm_coeffs[5, 0] - * ( - 1 - + np.cos( - int(charmm_coeffs[5, 1]) * t - - charmm_coeffs[5, 2] * no_pi / 180 - ) - ) - ) - - rb_to_charmm_absolute_difference = np.absolute( - rb_dihedral_calc - rb_to_charmm_calc - ) - rb_to_charmm_abs_diff.append( - rb_to_charmm_absolute_difference - ) - - list_if_large_error_dihedral_iteration = [] - list_abs_max_dihedral_iteration = [] - - if max(rb_to_charmm_abs_diff) > 10 ** (-10): - list_if_large_error_dihedral_iteration.append(1) - list_abs_max_dihedral_iteration.append( - max(rb_to_charmm_abs_diff) - ) - - list_if_large_error_dihedral_overall.append(1) - list_if_largest_error_abs_values_for_dihedral_overall.append( - max(rb_to_charmm_abs_diff) - ) - list_dihedral_overall_error.append( - str(params[8]) - + ", " - + str(params[9]) - + ", " - + str(params[10]) - + ", " - + str(params[11]) - ) - - else: - list_if_large_error_dihedral_iteration.append(0) - - list_if_abs_max_values_for_dihedral_overall.append( - max(rb_to_charmm_abs_diff) - ) - list_dihedral_atoms_all_dihedral_overall.append( - str(params[8]) - + ", " - + str(params[9]) - + ", " - + str(params[10]) - + ", " - + str(params[11]) - ) - - # ************************************** - # check the error between the convertions of RB_tortions to CHARMM DIHEDRALS (end) - # ************************************** - dihedral_format = "{}\t{}\t{}\t{}\t{:.6f}\t{}\t{}\t\t! {}\t{}\t{}\t{}\n" - - # Note the Charmm C0 or K0 dihedral term is not printed as it is used/read - # as a harmonic potential in the Charmm format - - data.write( - dihedral_format.format( - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[8] + "_" + params[12] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[9] + "_" + params[13] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[10] + "_" + params[14] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[11] + "_" + params[15] - ] - ), - charmm_coeffs[1, 0], - int(charmm_coeffs[1, 1]), - charmm_coeffs[1, 2], - params[8] + "_" + params[12], - params[9] + "_" + params[13], - params[10] + "_" + params[14], - params[11] + "_" + params[15], - ) - ) - data.write( - dihedral_format.format( - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[8] + "_" + params[12] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[9] + "_" + params[13] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[10] + "_" + params[14] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[11] + "_" + params[15] - ] - ), - charmm_coeffs[2, 0], - int(charmm_coeffs[2, 1]), - charmm_coeffs[2, 2], - params[8] + "_" + params[12], - params[9] + "_" + params[13], - params[10] + "_" + params[14], - params[11] + "_" + params[15], - ) - ) - data.write( - dihedral_format.format( - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[8] + "_" + params[12] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[9] + "_" + params[13] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[10] + "_" + params[14] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[11] + "_" + params[15] - ] - ), - charmm_coeffs[3, 0], - int(charmm_coeffs[3, 1]), - charmm_coeffs[3, 2], - params[8] + "_" + params[12], - params[9] + "_" + params[13], - params[10] + "_" + params[14], - params[11] + "_" + params[15], - ) - ) - data.write( - dihedral_format.format( - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[8] + "_" + params[12] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[9] + "_" + params[13] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[10] + "_" + params[14] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[11] + "_" + params[15] - ] - ), - charmm_coeffs[4, 0], - int(charmm_coeffs[4, 1]), - charmm_coeffs[4, 2], - params[8] + "_" + params[12], - params[9] + "_" + params[13], - params[10] + "_" + params[14], - params[11] + "_" + params[15], - ) - ) - data.write( - dihedral_format.format( - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[8] + "_" + params[12] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[9] + "_" + params[13] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[10] + "_" + params[14] - ] - ), - base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - params[11] + "_" + params[15] - ] - ), - charmm_coeffs[5, 0], - int(charmm_coeffs[5, 1]), - charmm_coeffs[5, 2], - params[8] + "_" + params[12], - params[9] + "_" + params[13], - params[10] + "_" + params[14], - params[11] + "_" + params[15], - ) - ) - - if sum(list_if_large_error_dihedral_overall) > 0: - list_max_error_abs_dihedral_overall = max( - list_if_largest_error_abs_values_for_dihedral_overall - ) - info_if_dihedral_error_too_large = ( - "! WARNING: RB-torsion to CHARMM " - "dihedral conversion error" - " is to large [error > 10^(-10)] \n" - "! WARNING: Maximum( " - "|(RB-torsion calc)-(CHARMM dihedral calc)| ) = " - + str(list_max_error_abs_dihedral_overall) - + "\n" - ) - warn( - "! WARNING: RB-torsion to CHARMM dihedral conversion error" - "is to large [error > 10^(-10)] \n" - "! WARNING: Maximum( |(RB-torsion calc)-(CHARMM dihedral calc)| ) = " - + str(list_max_error_abs_dihedral_overall) - + "\n" - ) - data.write(info_if_dihedral_error_too_large) - print(info_if_dihedral_error_too_large) - else: - list_if_abs_max_values_for_dihedral_overall_max = ( - max(list_if_abs_max_values_for_dihedral_overall) - ) - info_if_dihedral_error_ok = ( - "! RB-torsion to CHARMM dihedral conversion error is OK " - "[error <= 10^(-10)]\n" - + "! Maximum( |(RB-torsion calc)-(CHARMM dihedral calc)| ) = " - + str( - list_if_abs_max_values_for_dihedral_overall_max - ) - + "\n" - ) - data.write(info_if_dihedral_error_ok) - print(info_if_dihedral_error_ok) - - elif use_dihedrals: - data.write( - "ERROR: not set up to use to use_dihedrals form for data input from the xml file" - ) - - # Improper coefficients - if impropers: - data.write( - "ERROR: GOMC is not currently able to use improper in its calculations" - ) - - # Pair coefficients - print( - "NBFIX_Mixing not used or no mixing used for the non-bonded potentials out" - ) - print("self.non_bonded_type = " + str(self.non_bonded_type)) - if self.non_bonded_type == "LJ": - data.write("\n") - data.write("NONBONDED\n") - data.write("!\n") - data.write( - "!V(Lennard-Jones) = Eps,i,j[(Rmin,i,j/ri,j)**12 - 2(Rmin,i,j/ri,j)**6]\n" - ) - data.write("!\n") - - if self.unit_style == "real": - data.write( - "!atype \tignored\tepsilon \tRmin/2 \t\tignored\teps,1-4\t\tRmin/2,1-4\t\t" - + " atom_type_per_utilized_FF\n" - ) - - print("forcefield_dict = " + str(self.forcefield_dict)) - - for idx, epsilon in self.epsilon_dict.items(): - nb_format = "{}\t{:.2f}\t{:.9f}\t{:.11f}\t{:.2f}\t{:.9f}\t{:.11f}\t\t! {}\t{}\n" - data.write( - nb_format.format( - base10_to_base52_alph(idx), - 0, - -epsilon, - self.sigma_dict[idx] * (2 ** (1 / 6)) / 2, - 0, - float(self.LJ_1_4_dict[idx]) * (-epsilon), - self.sigma_dict[idx] * (2 ** (1 / 6)) / 2, - self.forcefield_dict[idx], - self.forcefield_dict[idx], - ) - ) - - elif self.non_bonded_type == "Mie": - data.write( - "ERROR: Currently the Mie potential (non_bonded_type) is not supported in this MoSDeF " - "GOMC parameter writer\n" - ) - print_error_message = ( - "ERROR: Currently the Mie potential (non_bonded_type) is not " - "supported in this MoSDeF GOMC parameter writer." - ) - raise ValueError(print_error_message) - else: - data.write( - "ERROR: Currently this potential (non_bonded_type) is not supported in " - "this MoSDeF GOMC parameter writer\n" - ) - print_error_message = ( - "ERROR: Currently this potential (non_bonded_type) is not supported in " - "this MoSDeF GOMC parameter writer." - ) - raise ValueError(print_error_message) - - # writing end in file - data.write("\nEND\n") - - # ********************************** - # ********************************** - # FF writer (end) - # ********************************** - # ********************************** - - def write_psf(self): - """This write_psf function writes the Charmm style PSF (topology) file, which can be utilized - in the GOMC and NAMD engines.""" - # ********************************** - # ********************************** - # psf writer (start) - # ********************************** - # ********************************** - - print("******************************") - print("") - print( - "The charmm X-plor format psf writer (the write_psf function) is running" - ) - - date_time = datetime.datetime.today() - - print( - "write_psf: forcefield_selection = {}, residues = {}".format( - self.forcefield_selection, self.residues - ) - ) - - print("******************************") - print("") - - if self.structure_box_1: - list_of_structures = [ - self.structure_box_0_ff, - self.structure_box_1_ff, - ] - list_of_file_names = [self.filename_box_0, self.filename_box_1] - stuct_only = [self.structure_box_0_ff, self.structure_box_1_ff] - else: - list_of_structures = [self.structure_box_0_ff] - list_of_file_names = [self.filename_box_0] - stuct_only = [self.structure_box_0_ff] - - for q in range(0, len(list_of_structures)): - stuct_iteration = list_of_structures[q] - file_name_iteration = list_of_file_names[q] - output = str(file_name_iteration) + ".psf" - stuct_only_iteration = stuct_only[q] - # Lammps syntax depends on the functional form - # Infer functional form based on the properties of the stuct_iteration - if self.detect_forcefield_style: - # Check for angles - if len(stuct_iteration.urey_bradleys) > 0: - print( - "Warning: Urey bradley terms detected. GOMC does no support the Urey-Bradley terms" - ) - warn( - "warning: Urey bradley terms detected. " - "GOMC does no support the Urey-Bradley terms" - ) - use_urey_bradleys = True - else: - print("No urey bradley terms detected") - use_urey_bradleys = False - - # Check for dihedrals - if len(stuct_iteration.rb_torsions) > 0: - print( - "RB Torsions detected, will converted to CHARMM Dihedrals" - ) - use_rb_torsions = True - dihedrals_list = stuct_iteration.rb_torsions - dihedrals = [ - [ - dihedral.atom1.idx + 1, - dihedral.atom2.idx + 1, - dihedral.atom3.idx + 1, - dihedral.atom4.idx + 1, - ] - for dihedral in stuct_iteration.rb_torsions - ] - else: - use_rb_torsions = False - - if len(stuct_iteration.dihedrals) > 0: - print( - "Charmm dihedrals detected, so CHARMM Dihedrals will remain" - ) - use_dihedrals = True - dihedrals_list = stuct_iteration.dihedrals - dihedrals = [ - [ - dihedral.atom1.idx + 1, - dihedral.atom2.idx + 1, - dihedral.atom3.idx + 1, - dihedral.atom4.idx + 1, - ] - for dihedral in stuct_iteration.dihedrals - ] - else: - use_dihedrals = False - if (use_rb_torsions is False) and (use_dihedrals is False): - dihedrals_list = [] - dihedrals = [] - if use_rb_torsions and use_dihedrals: - warn( - "Multiple dihedral styles detected, check your " - "Forcefield XML and structure files" - ) - - # Check for impropers - for dihedral in stuct_iteration.dihedrals: - if dihedral.improper: - warn( - "ERROR: Amber-style impropers are currently not supported in GOMC" - ) - - impropers_list = stuct_iteration.impropers - impropers = [ - [ - improper.atom1.idx + 1, - improper.atom2.idx + 1, - improper.atom3.idx + 1, - improper.atom4.idx + 1, - ] - for improper in stuct_iteration.impropers - ] - - no_atoms = len(stuct_iteration.atoms) - no_bonds = len(stuct_iteration.bonds) - no_angles = len(stuct_iteration.angles) - - no_dihedrals = len(dihedrals) - no_impropers = len(impropers) - - no_donors = len(stuct_iteration.donors) - no_acceptors = len(stuct_iteration.acceptors) - no_groups = len(stuct_iteration.groups) - - # psf printing (start) - - residue_data_list = [] - residue_names_list = [] - for k, atom in enumerate(stuct_only_iteration.atoms): - residue_data_list.append(str(atom.residue)) - residue_names_list.append(atom.residue.name) - - unique_residue_data_dict = {} - unique_residue_data_list = [] - residue_data_name_list = [] - - for m, residue in enumerate(stuct_only_iteration.residues): - unique_residue_data_list.append( - str(stuct_only_iteration.residues[m]) - ) - unique_residue_data_dict.update( - {unique_residue_data_list[m]: m + 1} - ) - residue_data_name_list.append( - stuct_only_iteration.residues[m].name - ) - - res_no_chain_iter_corrected = [] - residue_id_list = [] - residue_id_adder_fixed_struct_wo_bonds = 0 - for f, PSF_atom_iteration_0 in enumerate( - stuct_only_iteration.atoms - ): - if f > 0: - if ( - PSF_atom_iteration_0.residue.chain - == previous_residue_chain - and len(PSF_atom_iteration_0.bonds) == 0 - ): - residue_id_adder_fixed_struct_wo_bonds += 1 - - previous_residue_chain = PSF_atom_iteration_0.residue.chain - - residue_id_int = int( - unique_residue_data_dict[residue_data_list[f]] - + residue_id_adder_fixed_struct_wo_bonds - ) - res_id_adder = int( - (residue_id_int % self.max_residue_no) % self.max_residue_no - ) - if int(res_id_adder) == 0: - res_no_iteration_corrected = int(self.max_residue_no) - else: - res_no_iteration_corrected = res_id_adder - - res_no_chain_iter_corrected.append(res_no_iteration_corrected) - residue_id_list.append(residue_id_int) - - output_write = genopen(output, "w") - - first_indent = "%8s" - psf_formating = ( - "%8s %-4s %-4s %-4s %-4s %4s %10.6f %13.4f" + 11 * " " - ) - - output_write.write("PSF ") - output_write.write("\n\n") - - no_of_remarks = 3 - output_write.write(first_indent % no_of_remarks + " !NTITLE\n") - output_write.write( - " REMARKS this file " - + file_name_iteration - + " - created by MoSDeF-GOMC using the" - + "\n" - ) - output_write.write( - " REMARKS parameters from the " - + str(self.forcefield_selection) - + " force field via MoSDef\n" - ) - output_write.write( - " REMARKS created on " + str(date_time) + "\n\n\n" - ) - - # This converts the atom name in the GOMC psf and pdb files to unique atom names - print( - "bead_to_atom_name_dict = {}".format( - self.bead_to_atom_name_dict - ) - ) - [ - unique_individual_atom_names_dict, - individual_atom_names_list, - missing_bead_to_atom_name, - ] = unique_atom_naming( - stuct_only_iteration, - residue_id_list, - residue_names_list, - bead_to_atom_name_dict=self.bead_to_atom_name_dict, - ) - - if None in [ - unique_individual_atom_names_dict, - individual_atom_names_list, - missing_bead_to_atom_name, - ]: - self.input_error = True - print_error_message = ( - "ERROR: The unique_atom_naming function failed while " - "running the charmm_writer function. Ensure the proper inputs are " - "in the bead_to_atom_name_dict." - ) - raise ValueError(print_error_message) - - # ATOMS: Calculate the atom data - # psf_formating is conducted for the for CHARMM format (i.e., atom types are base 52, letters only) - output_write.write(first_indent % no_atoms + " !NATOM\n") - for i_atom, PSF_atom_iteration_1 in enumerate( - stuct_iteration.atoms - ): - segment_id = PSF_atom_iteration_1.residue.segid or "SYS" - atom_type_iter = base10_to_base52_alph( - self.atom_types_to_index_value_dict[ - PSF_atom_iteration_1.type - + "_" - + PSF_atom_iteration_1.residue.name - ] - ) - - atom_lines_iteration = psf_formating % ( - i_atom + 1, - segment_id, - res_no_chain_iter_corrected[i_atom], - str(residue_names_list[i_atom])[: self.max_resname_char], - individual_atom_names_list[i_atom], - atom_type_iter, - PSF_atom_iteration_1.charge, - PSF_atom_iteration_1.mass, - ) - - output_write.write("%s\n" % atom_lines_iteration) - - output_write.write("\n") - - # BONDS: Calculate the bonding data - output_write.write(first_indent % no_bonds + " !NBOND: bonds\n") - for i_bond, PSF_bond_iteration_1 in enumerate( - stuct_iteration.bonds - ): - output_write.write( - (first_indent * 2) - % ( - PSF_bond_iteration_1.atom1.idx + 1, - PSF_bond_iteration_1.atom2.idx + 1, - ) - ) - - if (i_bond + 1) % 4 == 0: - output_write.write("\n") - - if no_bonds % 4 == 0: - output_write.write("\n") - else: - output_write.write("\n\n") - - if no_bonds == 0: - output_write.write("\n") - - # ANGLES: Calculate the angle data - output_write.write(first_indent % no_angles + " !NTHETA: angles\n") - for i_angle, angle_iteration in enumerate(stuct_iteration.angles): - output_write.write( - (first_indent * 3) - % ( - angle_iteration.atom1.idx + 1, - angle_iteration.atom2.idx + 1, - angle_iteration.atom3.idx + 1, - ) - ) - - if (i_angle + 1) % 3 == 0: - output_write.write("\n") - - if no_angles % 3 == 0: - output_write.write("\n") - else: - output_write.write("\n\n") - - if no_angles == 0: - output_write.write("\n") - - # DIHEDRALS: Calculate the dihedral data - output_write.write( - first_indent % no_dihedrals + " !NPHI: dihedrals\n" - ) - for i_dihedral, dihedral_iter in enumerate(dihedrals_list): - ( - dihedral_atom_1, - dihedral_atom_2, - dihedral_atom_3, - dihedral_atom_4, - ) = ( - dihedral_iter.atom1, - dihedral_iter.atom2, - dihedral_iter.atom3, - dihedral_iter.atom4, - ) - - output_write.write( - (first_indent * 4) - % ( - dihedral_atom_1.idx + 1, - dihedral_atom_2.idx + 1, - dihedral_atom_3.idx + 1, - dihedral_atom_4.idx + 1, - ) - ) - - if (i_dihedral + 1) % 2 == 0: - output_write.write("\n") - - if no_dihedrals % 2 == 0: - output_write.write("\n") - else: - output_write.write("\n\n") - - if no_dihedrals == 0: - output_write.write("\n") - - # IMPROPERS: Calculate the improper data - output_write.write( - first_indent % no_impropers + " !NIMPHI: impropers\n" - ) - for i_improper, improper_iter in enumerate(impropers_list): - ( - improper_atom_1, - improper_atom_2, - improper_atom_3, - improper_atom_4, - ) = ( - improper_iter.atom1, - improper_iter.atom2, - improper_iter.atom3, - improper_iter.atom4, - ) - - output_write.write( - (first_indent * 4) - % ( - improper_atom_1.idx + 1, - improper_atom_2.idx + 1, - improper_atom_3.idx + 1, - improper_atom_4.idx + 1, - ) - ) - - if (i_improper + 1) % 2 == 0: - output_write.write("\n") - - if no_impropers % 2 == 0: - output_write.write("\n") - else: - output_write.write("\n\n") - - if no_impropers == 0: - output_write.write("\n") - - # DONOR: calculate the donor data - output_write.write(first_indent % no_donors + " !NDON: donors\n") - for donor_i, donor_iter in enumerate(stuct_iteration.donors): - output_write.write( - (first_indent * 2) - % (donor_iter.atom1.idx + 1, donor_iter.atom2.idx + 1) - ) - if (donor_i + 1) % 4 == 0: - output_write.write("\n") - - if no_donors % 4 == 0: - output_write.write("\n") - else: - output_write.write("\n\n") - - if no_donors == 0: - output_write.write("\n") - - # ACCEPTOR: calculate the acceptor data - output_write.write( - first_indent % no_acceptors + " !NACC: acceptors\n" - ) - for acceptor_i, acceptor_iter in enumerate( - stuct_iteration.acceptors - ): - output_write.write( - (first_indent * 2) - % (acceptor_iter.atom1.idx + 1, acceptor_iter.atom2.idx + 1) - ) - if (acceptor_i + 1) % 4 == 0: - output_write.write("\n") - - if no_acceptors % 4 == 0: - output_write.write("\n") - else: - output_write.write("\n\n") - - if no_acceptors == 0: - output_write.write("\n") - - # NNB: calculate the NNB data - output_write.write(first_indent % 0 + " !NNB\n\n") - for nbb_i, atoms_iter in enumerate(stuct_iteration.atoms): - output_write.write(first_indent % 0) - if (nbb_i + 1) % 8 == 0: - output_write.write("\n") - - if no_atoms % 8 == 0: - output_write.write("\n") - else: - output_write.write("\n\n") - - if no_atoms == 0: - output_write.write("\n") - - # GROUP: calculate the group data - try: - group_data = stuct_iteration.groups.nst2 - except AttributeError: - group_data = 0 - output_write.write( - (first_indent * 2) % (no_groups or 1, group_data) + " !NGRP \n" - ) - if stuct_iteration.groups is True: - for group_i, group_iter in enumerate(stuct_iteration.groups): - output_write.write( - (first_indent * 3) - % ( - group_iter.atom.idx, - group_iter.type, - group_iter.move, - ) - ) - if (group_i + 1) % 3 == 0: - output_write.write("\n") - - if no_groups % 3 == 0: - output_write.write("\n") - else: - output_write.write("\n\n") - - if no_groups == 0: - output_write.write("\n") - - else: - structure_abs_charge_value = abs( - sum( - atom_charge_iter.charge - for atom_charge_iter in stuct_iteration.atoms - ) - ) - if structure_abs_charge_value < 1.0e-4: - group_type = 1 - else: - group_type = 2 - output_write.write((first_indent * 3) % (0, group_type, 0)) - output_write.write("\n") - - output_write.write("\n") - output_write.close() - # ********************************** - # ********************************** - # psf writer (end) - # ********************************** - # ********************************** - - def write_pdb(self): - """This write_psf function writes the Charmm style PDB (coordinate file), which can be utilized - in the GOMC and NAMD engines.""" - # ********************************** - # ********************************** - # pdb writer (start) - # ********************************** - # ********************************** - date_time = datetime.datetime.today() - print("******************************") - print("") - print("The charmm pdb writer (the write_pdb function) is running") - print("write_charmm_pdb: residues == {}".format(self.residues)) - print("fix_residue = {}".format(self.fix_residue)) - print("fix_residue_in_box = {}".format(self.fix_residue_in_box)) - print( - "set_residue_pdb_occupancy_to_1 = {}".format( - self.set_residue_pdb_occupancy_to_1 - ) - ) - print("bead_to_atom_name_dict = {}".format(self.bead_to_atom_name_dict)) - - if self.fix_residue is None and self.fix_residue_in_box is None: - print( - "INFORMATION: No atoms are fixed in this pdb file for the GOMC simulation engine. " - ) - else: - warn( - "Some atoms are fixed in this pdb file for the GOMC simulation engine. " - ) - - print("******************************") - print("") - - if self.structure_box_1: - list_of_structures = [ - self.structure_box_0_ff, - self.structure_box_1_ff, - ] - list_of_file_names = [self.filename_box_0, self.filename_box_1] - stuct_only = [self.structure_box_0_ff, self.structure_box_1_ff] - else: - list_of_structures = [self.structure_box_0_ff] - list_of_file_names = [self.filename_box_0] - stuct_only = [self.structure_box_0_ff] - - for q in range(0, len(list_of_structures)): - file_name_iteration = list_of_file_names[q] - output = str(file_name_iteration) + ".pdb" - stuct_only_iteration = stuct_only[q] - - output_write = genopen(output, "w") - # output_write.write( - #'REMARK this file ' + file_name_iteration +' - created by using MoSDeF-GOMC.' + '\n') - # output_write.write( - #'REMARK parameters from the ' + str(self.forcefield_selection) + ' force field via MoSDef\n') - # output_write.write('REMARK created on ' + str(date_time) + '\n') - - unique_residue_data_dict = {} - unique_residue_data_list = [] - residue_data_name_list = [] - for m, residue in enumerate(stuct_only_iteration.residues): - unique_residue_data_list.append( - str(stuct_only_iteration.residues[m]) - ) - unique_residue_data_dict.update( - {unique_residue_data_list[m]: m + 1} - ) - residue_data_name_list.append( - stuct_only_iteration.residues[m].name - ) - - for n in range(0, len(residue_data_name_list)): - if residue_data_name_list[n] not in self.residues: - self.input_error = True - print_error_message = "ERROR: Please specifiy all residues (residues) in a list" - raise ValueError(print_error_message) - - residue_data_list = [] - for k, atom in enumerate(stuct_only_iteration.atoms): - residue_data_list.append(str(atom.residue)) - - if (self.fix_residue is not None) and ( - self.fix_residue_in_box is not None - ): - for n in range(0, len(self.fix_residue)): - if self.fix_residue[n] in self.fix_residue_in_box: - self.input_error = True - print_error_message = ( - "ERROR: residue type can not be specified to both " - "fix_residue and fix_residue_in_box" - ) - raise ValueError(print_error_message) - - occupancy_values_atoms_list = [] - residue_names_list = [] - fix_atoms_list = [] - for k, atom in enumerate(stuct_only_iteration.atoms): - residue_names_list.append(atom.residue.name) - if (self.fix_residue is not None) and ( - atom.residue.name in self.fix_residue - ): - beta_iteration = 1.00 - elif (self.fix_residue_in_box is not None) and ( - atom.residue.name in self.fix_residue_in_box - ): - beta_iteration = 2.00 - else: - beta_iteration = 0.00 - fix_atoms_list.append(beta_iteration) - - if (self.set_residue_pdb_occupancy_to_1 is not None) and ( - atom.residue.name in self.set_residue_pdb_occupancy_to_1 - ): - occupancy_iteration = 1.00 - else: - occupancy_iteration = 0.00 - occupancy_values_atoms_list.append(occupancy_iteration) - - if stuct_only_iteration.box is not None: - output_write.write( - "CRYST1%9.3f%9.3f%9.3f%7.2f%7." - "2f%7.2f %-11s%4s\n" - % ( - stuct_only_iteration.box[0], - stuct_only_iteration.box[1], - stuct_only_iteration.box[2], - stuct_only_iteration.box[3], - stuct_only_iteration.box[4], - stuct_only_iteration.box[5], - stuct_only_iteration.space_group, - "", - ) - ) - - all_atom_coordinates = stuct_only_iteration.get_coordinates("all") - if all_atom_coordinates is None: - self.input_error = True - print_error_message = ( - "ERROR: the submitted structure has no PDB coordinates, " - "so the PDB writer has terminated. " - ) - raise ValueError(print_error_message) - - pdb_atom_line_format = "ATOM %5s %-4s%1s%-4s%1s%4d%1s %8.3f%8.3f%8.3f%6.2f%6.2f %-4s%2s%-2s\n" - - atom_alternate_location_list = [] - residue_code_insertion_list = [] - x_list = [] - y_list = [] - z_list = [] - atom_occupancy_list = [] - atom_bfactor_list = [] - element_list = [] - - # lock occupany factor at 1 (instead of: atom.occupancy) - locked_occupany_factor = 1.00 - max_no_atoms_in_base10 = 99999 # 99,999 for atoms in psf/pdb - - res_no_chain_iter_corrected = [] - res_chain_iteration_corrected_list = [] - residue_id_list = [] - residue_id_adder_fixed_struct_wo_bonds = ( - 0 # for example zeolite used as fixed atoms wo bonds - ) - for i, atom_iter in enumerate(stuct_only_iteration.atoms): - if i > 0: - if ( - atom_iter.residue.chain == previous_residue_chain - and len(atom_iter.bonds) == 0 - ): - residue_id_adder_fixed_struct_wo_bonds += 1 - - previous_residue_chain = atom_iter.residue.chain - residue_id_int = int( - unique_residue_data_dict[residue_data_list[i]] - + residue_id_adder_fixed_struct_wo_bonds - ) - res_chain_iteration_corrected_list.append( - base10_to_base26_alph( - int(residue_id_int / (self.max_residue_no + 1)) - )[-1:] - ) - res_id_adder = int( - (residue_id_int % self.max_residue_no) % self.max_residue_no - ) - if int(res_id_adder) == 0: - res_no_chain_iter_corrected.append(int(self.max_residue_no)) - else: - res_no_chain_iter_corrected.append(res_id_adder) - - residue_id_list.append(residue_id_int) - - # This converts the atom name in the CHARMM psf and pdb files to unique atom names - [ - unique_individual_atom_names_dict, - individual_atom_names_list, - missing_bead_to_atom_name, - ] = unique_atom_naming( - stuct_only_iteration, - residue_id_list, - residue_names_list, - bead_to_atom_name_dict=self.bead_to_atom_name_dict, - ) - - if None in [ - unique_individual_atom_names_dict, - individual_atom_names_list, - missing_bead_to_atom_name, - ]: - self.input_error = True - print_error_message = ( - "ERROR: The unique_atom_naming function failed while " - "running the charmm_writer function. Ensure the proper inputs are " - "in the bead_to_atom_name_dict." - ) - - raise ValueError(print_error_message) - - for coord_iter, atom_coordinates in enumerate(all_atom_coordinates): - for PDB_residue_count in stuct_only_iteration.residues: - segment_id = "" - atom_iteration = sorted( - PDB_residue_count.atoms, key=lambda atom: atom.number - ) - for atom_iteration_2 in atom_iteration: - x, y, z = atom_coordinates[atom_iteration_2.idx] - atom_alternate_location_list.append( - atom_iteration_2.altloc - ) - residue_code_insertion_list.append( - PDB_residue_count.insertion_code[:1] - ) - x_list.append(x) - y_list.append(y) - z_list.append(z) - atom_occupancy_list.append(atom_iteration_2.occupancy) - atom_bfactor_list.append(atom_iteration_2.bfactor) - element_list.append( - Element[atom_iteration_2.atomic_number].upper() - ) - - for v, atom_iter_1 in enumerate(stuct_only_iteration.atoms): - if v + 1 > max_no_atoms_in_base10: - atom_number = base10_to_base16_alph_num(v + 1) - - else: - atom_number = v + 1 - - output_write.write( - pdb_atom_line_format - % ( - atom_number, - individual_atom_names_list[v], - atom_alternate_location_list[v], - str(residue_names_list[v])[: self.max_resname_char], - res_chain_iteration_corrected_list[v], - res_no_chain_iter_corrected[v], - residue_code_insertion_list[v], - x_list[v], - y_list[v], - z_list[v], - occupancy_values_atoms_list[v], - fix_atoms_list[v], - segment_id, - element_list[v], - "", - ) - ) - - output_write.write("%-80s\n" % "END") - - output_write.close() - - # ********************************** - # ********************************** - # pdb writer (end) - # ********************************** - # ********************************** + # depreciation error that charmm_writer has been depreciated + depreciation_error = ( + "The mosdef_gomc 'charmm_writer.py' has been depreciated, and the entire 'charmm_writer.py' " + "file will be removed/deleted soon." + "The this only effects the mosdef-gomc 'charmm_writer' parmed version. The GMSO version, " + "'gmso_charmm_writer.py', has replaced it with more features, so please use this GMSO version." + ) + raise ModuleNotFoundError(depreciation_error) diff --git a/mosdef_gomc/formats/gomc_conf_writer.py b/mosdef_gomc/formats/gomc_conf_writer.py index 87ba4bef..b52fb27e 100644 --- a/mosdef_gomc/formats/gomc_conf_writer.py +++ b/mosdef_gomc/formats/gomc_conf_writer.py @@ -1,7983 +1,35 @@ -import datetime -import os -from warnings import warn - -import mosdef_gomc.formats.charmm_writer as mf_charmm - - -def dict_keys_to_list(dict): - """ - Converts the dictionary keys into a list - - Parameters - ---------- - dict : dict - A provided dictionary - - Returns - --------- - list : list - list of keys from the provided dictionary - """ - return [key for key in dict.keys()] - - -def print_valid_required_input_variables(description=False): - """ - Prints the valid required input, which is necessary to write the GOMC control file. - - Parameters - ---------- - description : bool, default = False - If True, it prints the descriptions of the input_variables (i.e. dict), - If False, it only prints the input_variables without the descriptions (i.e. list) - - Returns - --------- - Prints out the valid input variables (user optional) on the screen, - which can be entered in the GOMC writer. These are the valid input - variables for all ensembles. - """ - - valid_args = _get_all_possible_input_variables(description=description) - for arg, description in valid_args.items(): - print("{:10s}: {}".format(arg, description)) - - -def _get_required_data(description=False): - """ - Provides a list of the required inputs for all possible ensembles. - - Parameters - ---------- - description : bool, default = False. - If True, it prints the descriptions of the input_variables (i.e. dict), - If False, it only prints the input_variables without the descriptions (i.e. list) - - Returns - --------- - required_data : dict or list, default = list. - If the description = True then a dict is provided with the key and value. - if the description = False then a list of the dict keys is provided. - - Note: - Variables and text extracted with permission from the GOMC manual version 2.60. - Some of the text was modified from its original version. - Cite: Potoff, Jeffrey; Schwiebert, Loren; et al. GOMC Documentation. - https://raw.githubusercontent.com/GOMC-WSU/GOMC/master/GOMC_Manual.pdf, 2021. - """ - - required_data = { - "charmm_object": "Charmm object, " - "A Charmm object, which by definition has been parameterized " - "from the selected force field.", - "ensemble_type": "Required files or System Info (all ensembles): str, " - "(valid strings are 'NVT', 'NPT', 'GEMC_NPT', 'GCMC-NVT', or 'GCMC'), " - "the ensemble type for the simulation.", - "RunSteps": "Required files or System Info (all ensembles): int (> 0), " - "The number or run steps for the simulation.", - "Temperature": "Required files or System Info (all ensembles): float or integer (> 0), " - "Temperature of system in Kelvin (K)", - "ff_psf_pdb_file_directory": "str (optional), default=None (i.e., the current directory). " - "The full or relative directory added to the force field, psf, and pdb " - "file names, created via the Charmm object.", - "check_input_files_exist": "Required to check if files exist (all ensembles): bool (default=True), " - "Check if the force field, psf, and pdb files exist. " - "If the files are checked and do not exist, the writer will throw " - "a ValueError. " - "True, check if the force field, psf, and pdb files exist. " - "False, do not check if the force field, psf, and pdb files exist.", - "Restart": "Required for restarting (all ensembles): boolean (default=False), " - "Determines whether to restart the simulation " - "from restart file (*_restart.pdb and *_restart.psf) or not.", - "RestartCheckpoint": "Required for optimal restarting (all ensembles): boolean (default=False)," - "Determines whether to restart the simulation with the " - "checkpoint file (checkpoint.dat) or not. Restarting the " - "simulation with checkpoint.dat would result in an identical outcome, " - "as if previous simulation was continued.", - "Parameters": "Required for alternate force field file (all ensembles): " - "str, (default=None), " - "Override all other force field directory and filename input with the correct extension (.inp or .par). " - "Note: the default directory is the current directory with the Charmm object file name.", - "Coordinates_box_0": "Required for alternate box 0 .pdb file (all ensembles): " - "str, (default=None), " - "Override all other box 0 pdb directory and filename inputs. " - "Note: the default directory is the current directory with the Charmm object file name.", - "Structure_box_0": "Required for alternate box 0 .psf file (all ensembles): " - "str, (default=None), " - "Override all other box 0 psf directory and filename inputs. " - "Note: the default directory is the current directory with the Charmm object file name.", - "Coordinates_box_1": "Required for alternate box 1 .pdb file (all ensembles): " - "str, (default=None), " - "Override all other box 1 pdb directory and filename inputs. " - "Note: the default directory is the current directory with the Charmm object file name.", - "Structure_box_1": "Required for alternate box 1 .psf file (all ensembles): " - "str, (default=None), " - "Override all other box 1 psf directory and filename inputs. " - "Note: the default directory is the current directory with the Charmm object file name.", - "binCoordinates_box_0": "Required for alternate box 0 .coor file (all ensembles): " - "str, (default=None), " - "The box 0 binary coordinate file is used only for restarting " - "a GOMC simulation, which provides increased numerical accuracy.", - "extendedSystem_box_0": "Required for alternate box 0 .xsc file (all ensembles): " - "str, (default=None), " - "The box 0 vectors and origin file is used only for restarting a " - "GOMC simulation. ", - "binVelocities_box_0": "Required for alternate box 0 .vel file (all ensembles): " - "str, (default=None), " - "The box 0 binary velocity file is used only for " - "restarting a GOMC simulation, which provides increased " - "numerical accuracy. These velocities are only passed thru " - "GOMC since Monte Carlo simulations do not utilize any " - "velocity information. ", - "binCoordinates_box_1": "Required for alternate box 1 .coor file (all ensembles): " - "str, (default=None), " - "The box 1 binary coordinate file is used only for restarting a " - "GOMC simulation, which provides increased numerical accuracy. ", - "extendedSystem_box_1": "Required for alternate box 1 .coor file (all ensembles): " - "str, (default=None), " - "The box 1 vectors and origin file is used " - "only for restarting a GOMC simulation. ", - "binVelocities_box_1": "Required for alternate box 1 .vel file (all ensembles): " - "str, (default=None), " - "The box 1 binary velocity file is used only for restarting a " - "GOMC simulation, which provides increased numerical accuracy. " - "These velocities are only passed thru GOMC since Monte Carlo " - "simulations do not utilize any velocity information.", - } - - if description: - return required_data - else: - return list(required_data.keys()) - - -def _get_all_possible_input_variables(description=False): - """ - Provides a list of the variables inputs (user optional) for all possible ensembles. - - Parameters - ---------- - description : bool, default = False. - If True, it prints the descriptions of the input_variables (i.e. dict), - If False, it only prints the input_variables without the descriptions (i.e. list) - - Returns - --------- - valid_input_variables : dict or list, default = list. - If the description = True then a dict is provided with the key and value. - if the description = False then a list of the dict keys is provided. - - Note: - Variables and text extracted with permission from the GOMC manual version 2.60. - Some of the text was modified from its original version. - Cite: Potoff, Jeffrey; Schwiebert, Loren; et. al. GOMC Documentation. - https://raw.githubusercontent.com/GOMC-WSU/GOMC/master/GOMC_Manual.pdf, 2021. - """ - - valid_input_variables = { - # ****************************************************************************************************** - # Definitions in this function are copied to a large extent from the GOMC manual release version 2.60 (start) - # insert citation here: - # ****************************************************************************************************** - "PRNG": 'Simulation info (all ensembles): string or int (>= 0) ("RANDOM" or integer), default = {}. ' - "PRNG = Pseudo-Random Number Generator (PRNG). " - 'There are two (2) options, entering the string, "RANDOM", or a integer. \n' - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "RANDOM", which selects a random seed number. ' - 'This will enter the line "PRNG RANDOM" in the gomc configuration file. \n' - "\t\t\t\t\t\t\t\t\t\t\t\t\t --- integer, which defines the integer seed number " - "for the simulation. " - "This is equivalent to entering the following two lines in the configuration file: " - "line 1 = PRNG INTSEED, " - "line 2 = Random_Seed user_selected_integer. " - 'Example 1: for a random seed enter the string "RANDOM. ' - "Example 2: for a specific seed number enter a integer of your choosing. " - "".format(_get_default_variables_dict()["PRNG"]), - "ParaTypeCHARMM": "Simulation info (all ensembles): boolean, default = {}. " - "True if a CHARMM forcefield, False otherwise." - "".format(_get_default_variables_dict()["ParaTypeCHARMM"]), - "ParaTypeMie": "Simulation info (all ensembles): boolean, default = {}. " - "True if a Mie forcefield type, False otherwise." - "".format(_get_default_variables_dict()["ParaTypeMie"]), - "ParaTypeMARTINI": "Simulation info (all ensembles): boolean, default = {}. " - "True if a MARTINI forcefield, False otherwise." - "".format(_get_default_variables_dict()["ParaTypeMARTINI"]), - "RcutCoulomb_box_0": "Simulation info (all ensembles): int or float (>= 0), default = {}." - "Sets a specific radius in box 0 where the short-range " - "electrostatic energy will be calculated (i.e., The distance to truncate the " - "Note: if None, GOMC will default to the Rcut value" - "".format(_get_default_variables_dict()["RcutCoulomb_box_0"]), - "RcutCoulomb_box_1": "Simulation info (all ensembles): int or float (>= 0), default = {}." - "Sets a specific radius in box 1 where the short-range " - "electrostatic energy will be calculated. (i.e., The distance to truncate the " - "short-range electrostatic energy in box 1.)" - "Note: if None, GOMC will default to the Rcut value" - "".format(_get_default_variables_dict()["RcutCoulomb_box_1"]), - "Pressure": "Simulation info (only GEMC_NPT and NPT): int or float (>= 0), default = {}. " - "The pressure in bar utilized for the NPT " - "and GEMC_NPT simulations." - "".format(_get_default_variables_dict()["Pressure"]), - "Rcut": "Simulation info (all ensembles): int or float (>= 0 and RcutLow < Rswitch < Rcut), default = {}. " - "Sets a specific radius in Angstroms that non-bonded interaction " - "energy and force will be considered and calculated using defined potential function. " - "The distance in Angstoms to truncate the LJ, Mie, or other VDW type potential at. " - 'Note: Rswitch is only used when the "Potential" = SWITCH. ' - "".format(_get_default_variables_dict()["Rcut"]), - "RcutLow": "Simulation info (all ensembles): int or float (>= 0 and RcutLow < Rswitch < Rcut), default = {}. " - "Sets a specific minimum possible distance in Angstroms that reject " - "any move that places any atom closer than specified distance. The minimum possible " - "distance between any atoms. " - "Sets a specific radius in Angstroms that non-bonded interaction " - 'Note: Rswitch is only used when the "Potential" = SWITCH. ' - "WARNING: When using a molecule that has charge atoms with non-bonded epsilon values of zero (i.e., water), " - "the RcutLow need to be greater than zero, typically 1 angstrom. " - "WARNING: When using the free energy calculations, RcutLow needs to be set to zero (RcutLow=0);" - "otherwise, the free energy calculations can produce results that are slightly off or wrong. " - "".format(_get_default_variables_dict()["RcutLow"]), - "LRC": "Simulation info (all ensembles): boolean, default = {}. " - "If True, the simulation considers the long range tail corrections for the non-bonded VDW or " - "dispersion interactions. " - "Note: In case of using SHIFT or SWITCH potential functions, LRC will be ignored." - "".format(_get_default_variables_dict()["LRC"]), - "IPC": "Simulation info (all ensembles): boolean, default = {}. " - "If True, the simulation adds the impulse correction term to the pressure, " - "which considers to correct for the discontinuous Rcut potential " - "(i.e., a hard cutoff potential, meaning a potential without tail corrections) " - "the long range tail corrections for the non-bonded VDW or dispersion interactions. " - "If False, the impulse correction term to the pressure is not applied. " - "Note: This can not be used if LRC is True or the Potential is set to SWITCH, or SHIFT." - "".format(_get_default_variables_dict()["IPC"]), - "Exclude": "Simulation info (all ensembles): str " - '(The string inputs are "1-2", "1-3", or "1-4"), default = {}. ' - "Note: In CHARMM force field, the 1-4 interaction needs to be considered. " - 'Choosing "Excude 1-3", will modify 1-4 interaction based on 1-4 parameters ' - "in parameter file. If a kind force field is used, where " - '1-4 interaction needs to be ignored, such as TraPPE, either Exlcude "1-4" needs to be ' - "chosen or 1-4 parameter needs to be assigned to zero in the parameter file. \n" - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "1-2": All interaction pairs of bonded atoms, ' - "except the ones that separated with one bond, " - "will be considered and modified using 1-4 parameters defined in parameter file. \n" - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "1-3": All interaction pairs of bonded atoms, ' - "except the ones that separated with one or two " - "bonds, will be considered and modified using 1-4 parameters defined in parameter file. \n" - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "1-4": All interaction pairs of bonded atoms, ' - "except the ones that separated with one, " - "two or three bonds, will be considered using non-bonded parameters defined in parameter file." - "".format(_get_default_variables_dict()["Exclude"]), - "Potential": 'Simulation info (all ensembles): str, ["VDW", "EXP6", "SHIFT" or "SWITCH"], default = {}. ' - "Defines the potential function type to calculate non-bonded dispersion interaction " - "energy and force between atoms. \n" - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "VDW": Non-bonded dispersion interaction energy and force ' - "calculated based on n-6 (Lennard - Jones) equation. This function will be discussed " - "further in the Intermolecular energy and " - "Virial calculation section. \n" - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "EXP6": Non-bonded dispersion interaction energy and force ' - "calculated based on exp-6 (Buckingham potential) equation. \n" - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SHIFT": This option forces the potential energy to be ' - "zero at Rcut distance. \n" - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SWITCH": This option smoothly forces the potential ' - "energy to be zero at Rcut distance and starts modifying the potential at Rswitch " - "distance. Depending on force field type, specific potential function will be applied. " - "".format(_get_default_variables_dict()["Potential"]), - "Rswitch": "Simulation info (all ensembles): int or float (>= 0 and RcutLow < Rswitch < Rcut), default = {}. " - 'Note: Rswitch is only used when the SWITCH function is used (i.e., "Potential" = SWITCH). ' - "The Rswitch distance is in Angstrom. If the “SWITCH” function is chosen, " - "Rswitch needs to be defined, otherwise, the program will be terminated. When using " - 'choosing "SWITCH" as potential function, the Rswitch distance defines where the' - "non-bonded interaction energy modification is started, which is eventually truncated " - "smoothly at Rcut distance." - "".format(_get_default_variables_dict()["Rswitch"]), - "ElectroStatic": "Simulation info (all ensembles): boolean, default = {}. " - "Considers the coulomb interactions or not. " - "If True, coulomb interactions are considered and false if not. " - "Note: To simulate the polar molecule in MARTINI force field, ElectroStatic needs to be " - "turn on. The MARTINI force field uses short-range coulomb interaction with constant " - "Dielectric of 15.0." - "".format(_get_default_variables_dict()["ElectroStatic"]), - "Ewald": "Simulation info (all ensembles): boolean, default = {}. " - "Considers the standard Ewald summation method for electrostatic calculations. " - "If True, Ewald summation calculation needs to be considered and false if not. " - "Note: By default, GOMC will set ElectroStatic to True if Ewald summation " - "method was used to calculate coulomb interaction." - "".format(_get_default_variables_dict()["Ewald"]), - "CachedFourier": "Simulation info (all ensembles): boolean, default = {}. " - "Considers storing the reciprocal terms for Ewald summation " - "calculation in order to improve the code performance. This option would increase the code " - "performance with the cost of memory usage. If True, to store reciprocal terms of Ewald " - "summation calculation and False if not. " - "Warning: Monte Carlo moves, such as MEMC-1, MEMC-2, MEMC-3, " - "IntraMEMC-1, IntraMEMC-2, and IntraMEMC-3 are not support with CachedFourier." - "".format(_get_default_variables_dict()["CachedFourier"]), - "Tolerance": "Simulation info (all ensembles): float (0.0 < float < 1.0), default = {}. " - "Sets the accuracy in Ewald summation calculation. Ewald separation parameter and number " - "of reciprocal vectors for the Ewald summation are determined based on the accuracy parameter." - "".format(_get_default_variables_dict()["Tolerance"]), - "Dielectric": "Simulation info (all ensembles): int or float (>= 0.0), default = {}. " - "Sets dielectric value used in coulomb interaction when the Martini " - "force field is used. Note: In MARTINI force field, Dielectric needs to be set to 15.0." - "".format(_get_default_variables_dict()["Dielectric"]), - "PressureCalc": "Simulation info (all ensembles): list [bool , int (> 0)] or [bool , step_frequency], " - "default = {} or [{} , set via formula based on the number of RunSteps or {} max]. " - "Calculate the system pressure or not. bool = True, enables the pressure calculation " - "during the simulation, false disables the calculation. The int/step frequency sets the " - "frequency of calculating the pressure." - "".format( - _get_default_variables_dict()["PressureCalc"], - _get_default_variables_dict()["PressureCalc"][0], - _get_default_variables_dict()["PressureCalc"][1], - ), - "EqSteps": "Simulation info (all ensembles): int (> 0), " - "default = set via formula based on the number of RunSteps or {} max. " - "Sets the number of steps necessary to equilibrate the system. " - "Averaging will begin at this step. " - "Note: In GCMC simulations, the Histogram files will be outputed at EqSteps." - "".format(_get_default_variables_dict()["EqSteps"]), - "AdjSteps": "Simulation info (all ensembles): int (> 0), " - "default = set via formula based on the number of RunSteps or {} max. " - "Sets the number of steps per adjustment of the parameter associated with each move " - "(e.g. maximum translate distance, maximum rotation, maximum volume exchange, etc.)." - "".format(_get_default_variables_dict()["AdjSteps"]), - "VDWGeometricSigma": "Simulation info (all ensembles): boolean, default = {}. " - "Use geometric mean, as required by OPLS force field, " - "to combining Lennard-Jones sigma parameters for different atom types. " - "If set to True, GOMC uses geometric mean to combine Lennard-Jones or VDW sigmas. " - "Note: The default setting of VDWGeometricSigma is false, which uses the arithmetic " - "mean when combining Lennard-Jones or VDW sigma parameters for different atom types." - "".format(_get_default_variables_dict()["VDWGeometricSigma"]), - "useConstantArea": "Simulation info (only GEMC_NPT and NPT): boolean: default = {}. " - "Changes the volume of the simulation box by fixing the cross-sectional " - "area (x-y plane). If true, the volume will change only in z axis, If False, " - "the volume of the box will change in a way to maintain the constant axis ratio. " - "".format(_get_default_variables_dict()["useConstantArea"]), - "FixVolBox0": "Simulation info (only GEMC_NPT): boolean, default = {}. " - "Changing the volume of fluid phase (Box 1) to maintain the constant imposed pressure and " - "Temperature, while keeping the volume of adsorbed phase (Box 0) fixed. Note: By default, " - "GOMC will set useConstantArea to False if no value was set. It means, the volume of the " - "box will change in a way to maintain the constant axis ratio." - "".format(_get_default_variables_dict()["FixVolBox0"]), - # GCMC only properties - "ChemPot": "Simulation info (only GCMC): dict {str (4 dig limit) , int or float}, " - + "default = {} ".format(_get_default_variables_dict()["ChemPot"]) - + "(i.e., the user must set this variable as there is no working default)." - "The chemical potentials in GOMC units of energy, K. " - "There is a 4 character limit for the string/residue name since the PDB/PSF " - "files have a 4 character limitation and require and exact match in the conf file. " - "Note: These strings must match the residue in the psf and psb files or it will fail. " - "The name of the residues and their corresponding chemical potential must specified " - 'for every residue in the system (i.e., {"residue_name" : chemical_potential}). ' - "Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY " - "OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. " - 'Example 1 (system with only water): {"H2O" : -4000} . ' - 'Example 2 (system with water and ethanol): {"H2O" : -4000, "ETH" : -8000} ', - "Fugacity": "Simulation info (only GCMC): dict {str , int or float (>= 0)}, " - + "default = {} ".format(_get_default_variables_dict()["Fugacity"]) - + "(i.e., the user must set this variable as there is no working default). " - "The fugacity in GOMC units of pressure, bar. " - "There is a 4 character limit for the string/residue name since the PDB/PSF " - "files have a 4 character limitation and require and exact match in the conf file. " - "Note: These strings must match the residue in the psf and psb files or it will fail. " - "The name of the residues and their corresponding fugacity must specified " - 'for every residue in the system (i.e., {"residue_name" : fugacity}). ' - "Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY " - "OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. " - 'Example 1 (system with only water): {"H2O" : 1} . ' - 'Example 2 (system with water and ethanol): {"H2O" : 0.5, "ETH" : 10} ', - # CBMC inputs - "CBMC_First": "CBMC inputs (all ensembles): int (>= 0), default = {}, " - "The number of CD-CBMC trials to choose the first atom position" - "(Lennard-Jones trials for first seed growth)." - "".format(_get_default_variables_dict()["CBMC_First"]), - "CBMC_Nth": "CBMC inputs (all ensembles): int (>= 0), default = {}, " - "The number of CD-CBMC trials to choose the later atom positions " - "(Lennard-Jones trials for first seed growth)." - "".format(_get_default_variables_dict()["CBMC_Nth"]), - "CBMC_Ang": "CBMC inputs (all ensembles): int (>= 0), default = {}, " - "The number of CD-CBMC bending angle trials to perform for geometry " - "(per the coupled-decoupled CBMC scheme)." - "".format(_get_default_variables_dict()["CBMC_Ang"]), - "CBMC_Dih": "CBMC inputs (all ensembles): int (>= 0), default = {}, " - "The number of CD-CBMC dihedral angle trials to perform for geometry " - "(per the coupled-decoupled CBMC scheme)." - "".format(_get_default_variables_dict()["CBMC_Dih"]), - # Control file (.conf file ) output controls/parameters - "OutputName": "Output Frequency (all ensembles): str (NO SPACES), default = {}. " - "The UNIQUE STRING NAME, WITH NO SPACES, which is used for the " - "output block average, PDB, and PSF file names." - "".format(_get_default_variables_dict()["OutputName"]), - "CoordinatesFreq": "PDB Output Frequency (all ensembles): list [bool , int (> 0)] or " - "[Generate_data_bool , steps_per_data_output_int], " - "default = {} or [{} , set via formula based on the number of RunSteps or {} max]. " - "Controls output of PDB file (coordinates). " - "If bool is True, this enables outputting the coordinate files at the " - "integer frequency (set steps_per_data_output_int), " - 'while "False" disables outputting the coordinates.' - "".format( - _get_default_variables_dict()["CoordinatesFreq"], - _get_default_variables_dict()["CoordinatesFreq"][0], - _get_default_variables_dict()["CoordinatesFreq"][1], - ), - "DCDFreq": "DCD Output Frequency (all ensembles): list [bool , int (> 0)] or " - "[Generate_data_bool , steps_per_data_output_int], " - "default = {} or [{} , set via formula based on the number of RunSteps or {} max]. " - "Controls output of DCD file (coordinates). " - "If bool is True, this enables outputting the coordinate files at the " - "integer frequency (set steps_per_data_output_int), " - 'while "False" disables outputting the coordinates.' - "".format( - _get_default_variables_dict()["DCDFreq"], - _get_default_variables_dict()["DCDFreq"][0], - _get_default_variables_dict()["DCDFreq"][1], - ), - "RestartFreq": "Output Frequency (all ensembles): list [bool , int (> 0)] or " - "[Generate_data_bool , steps_per_data_output_int], " - "default = {} or [{} , set via formula based on the number of RunSteps or {} max]. " - "This creates the PDB and PSF (coordinate and topology) files for restarting the system " - "at the set steps_per_data_output_int (frequency) " - "If bool is True, this enables outputting the PDB/PSF restart files at the " - "integer frequency (set steps_per_data_output_int), " - "while “false” disables outputting the PDB/PSF restart files. " - "".format( - _get_default_variables_dict()["RestartFreq"], - _get_default_variables_dict()["RestartFreq"][0], - _get_default_variables_dict()["RestartFreq"][1], - ), - "CheckpointFreq": "Output Frequency (all ensembles): list [bool , int (> 0)] or " - "[Generate_data_bool , steps_per_data_output_int], " - "default = {} or [{} , set via formula based on the number of RunSteps or {} max]. " - "Controls the output of the last state of simulation at a specified step, in a " - "binary file format (checkpoint.dat). Checkpoint file contains the following " - "information in full precision: " - "(1) Last simulation step that saved into checkpoint file " - "(2) Simulation cell dimensions and angles " - "(3) Maximum amount of displacement (Å), rotation (δ), and volume (Å^3) that is used in " - "the Displacement, Rotation, MultiParticle, and Volume moves " - "(4) Number of Monte Carlo move trial and acceptance " - "(5) All molecule’s coordinates " - "(6) Random number sequence " - "If bool is True, this enables outputting the checkpoint file at the " - "integer frequency (set steps_per_data_output_int), " - 'while "False" disables outputting the checkpoint file.' - "".format( - _get_default_variables_dict()["CheckpointFreq"], - _get_default_variables_dict()["CheckpointFreq"][0], - _get_default_variables_dict()["CheckpointFreq"][1], - ), - "ConsoleFreq": "Output Frequency (all ensembles): list [bool , int (> 0)] or " - "[Generate_data_bool , steps_per_data_output_int], " - "default = {} or [{} , set via formula based on the number of RunSteps or {} max]. " - 'Controls the output to the "console” or log file, which prints the ' - "acceptance statistics, and run timing info. In addition, instantaneously-selected" - "thermodynamic properties will be output to this file. If bool is True, " - "this enables outputting the console data at the integer frequency " - '(set steps_per_data_output_int), while "False" disables outputting the console ' - "data file. " - "".format( - _get_default_variables_dict()["ConsoleFreq"], - _get_default_variables_dict()["ConsoleFreq"][0], - _get_default_variables_dict()["ConsoleFreq"][1], - ), - "BlockAverageFreq": "Output Frequency (all ensembles): list [bool , int (> 0)] or " - "[Generate_data_bool , steps_per_data_output_int], " - "default = {} or [{} , set via formula based on the number of RunSteps or {} max]. " - "Controls the block averages output of selected thermodynamic properties. " - "Block averages are averages of thermodynamic values of interest for chunks of the " - "simulation (for post-processing of averages or std. dev. in those values)." - "If bool is True, this enables outputting the block averaging data/file at the " - "integer frequency (set steps_per_data_output_int), " - 'while "False" disables outputting the block averaging data/file.' - "".format( - _get_default_variables_dict()["BlockAverageFreq"], - _get_default_variables_dict()["BlockAverageFreq"][0], - _get_default_variables_dict()["BlockAverageFreq"][1], - ), - "HistogramFreq": "Output Frequency (all ensembles): list [bool , int (> 0)] or " - "[Generate_data_bool , steps_per_data_output_int], " - "default = {} or [{} , set via formula based on the number of RunSteps or {} max]. " - "Controls the histograms. Histograms are a binned listing of observation frequency " - "for a specific thermodynamic variable. In the GOMC code, they also control the output " - "of a file containing energy/molecule samples, " - 'which is only used for the "GCMC" ensemble simulations for histogram reweighting purposes.' - "If bool is True, this enables outputting the data to the histogram data at the " - "integer frequency (set steps_per_data_output_int), " - 'while "False" disables outputting the histogram data.' - "".format( - _get_default_variables_dict()["HistogramFreq"], - _get_default_variables_dict()["HistogramFreq"][0], - _get_default_variables_dict()["HistogramFreq"][1], - ), - # Histogram data - "DistName": "Histogram Output (all ensembles): str (NO SPACES), default = {}. " - "Short phrase which will be combined with RunNumber and RunLetter " - "to use in the name of the binned histogram for molecule distribution." - "".format(_get_default_variables_dict()["DistName"]), - "HistName": "Histogram Output (all ensembles): str (NO SPACES), default = {}. " - "Short phrase, which will be combined with RunNumber and RunLetter, " - "to use in the name of the energy/molecule count sample file." - "".format(_get_default_variables_dict()["HistName"]), - "RunNumber": "Histogram Output (all ensembles): int ( > 0 ), default = {}. " - "Sets a number, which is a part of DistName and HistName file name." - "".format(_get_default_variables_dict()["RunNumber"]), - "RunLetter": "Histogram Output (all ensembles): str (1 alphabetic character only), default = {}. " - "Sets a letter, which is a part of DistName and HistName file name." - "".format(_get_default_variables_dict()["RunLetter"]), - "SampleFreq": "Histogram Output (all ensembles): int ( > 0 ), default = {}. " - "The number of steps per histogram sample or frequency." - "".format(_get_default_variables_dict()["SampleFreq"]), - # Data output for the console and bulk properties calculations - "OutEnergy": "Output Data (all ensembles): [bool, bool], default = {}. " - "The list provides the booleans to [block_averages_bool, console_output_bool]. " - "This outputs the energy data into the block averages and console output/log files." - "".format(_get_default_variables_dict()["OutEnergy"]), - "OutPressure": "Output Data (all ensembles): [bool, bool], default = {}. " - "The list provides the booleans to [block_averages_bool, console_output_bool]. " - "This outputs the pressure data into the block averages and console output/log files." - "".format(_get_default_variables_dict()["OutPressure"]), - "OutMolNum": "Output Data (all ensembles): [bool, bool], default = {}. " - "The list provides the booleans to [block_averages_bool, console_output_bool]. " - "This outputs the number of molecules data into the block averages and console " - "output/log files." - "".format(_get_default_variables_dict()["OutMolNum"]), - "OutDensity": "Output Data (all ensembles): [bool, bool], default = {}. " - "The list provides the booleans to [block_averages_bool, console_output_bool]. " - "This outputs the density data into the block averages and console output/log files." - "".format(_get_default_variables_dict()["OutDensity"]), - "OutVolume": "Output Data (all ensembles): [bool, bool], default = {}. " - "The list provides the booleans to [block_averages_bool, console_output_bool]. " - "This outputs the volume data into the block averages and console output/log files." - "".format(_get_default_variables_dict()["OutVolume"]), - "OutSurfaceTension": "Output Data (all ensembles): [bool, bool], default = {}. " - "The list provides the booleans to [block_averages_bool, console_output_bool]. " - "This outputs the surface tension data into the block averages and console " - "output/log files." - "".format(_get_default_variables_dict()["OutSurfaceTension"]), - # free energy calculation in NVT and NPT ensembles. - "FreeEnergyCalc": "Free Energy Calcs (NVT and NPT only): list [bool , int (> 0)] or " - "[Generate_data_bool , steps_per_data_output_int], default = {}. " - "bool = True enabling free energy calculation during the simulation, false disables " - "the calculation. The int/step frequency sets the frequency of calculating the free energy." - "WARNING: When using the free energy calculations, RcutLow needs to be set to zero (RcutLow=0);" - "otherwise, the free energy calculations can produce results that are slightly off or wrong." - "".format(_get_default_variables_dict()["FreeEnergyCalc"]), - "MoleculeType": "Free Energy Calcs (NVT and NPT only): list [str , int (> 0)] or " - '["residue_name" , residue_ID], ' - "The user must set this variable as there is no working default (default = {}). " - 'Note: ONLY 4 characters can be used for the string (i.e., "residue_name"). ' - "Sets the solute molecule kind (residue name) and molecule number (residue ID), " - "which absolute solvation free will be calculated for." - "".format(_get_default_variables_dict()["MoleculeType"]), - "InitialState": "Free Energy Calcs (NVT and NPT only): int (>= 0), " - "The user must set this variable as there is no working default (default = {}). " - "The index of LambdaCoulomb and LambdaVDW vectors. Sets the index of the" - "LambdaCoulomb and LambdaVDW vectors, to determine the simulation lambda value for" - "VDW and Coulomb interactions. " - "WARNING : This must an integer within the vector count of the LambdaVDW and LambdaCoulomb, " - "in which the counting starts at 0. " - "".format(_get_default_variables_dict()["InitialState"]), - "LambdaVDW": "Free Energy Calcs (NVT and NPT only): list of floats (0 <= floats <= 1), " - "The user must set this variable as there is no working default (default = {}). " - "Lambda values for VDW interaction in ascending order. Sets the intermediate " - "lambda states to which solute-solvent VDW interactions are scaled. " - 'WARNING : This list must be the same length as the "LambdaCoulomb" list length.' - "WARNING : All lambda values must be stated in the ascending order, " - "starting with 0.0 and ending with 1.0; otherwise, the program will terminate." - "Example of ascending order 1: [0.0, 0.1, 1.0] " - "Example of ascending order 2: [0.0, 0.1, 0.2, 0.4, 0.9, 1.0] " - "".format(_get_default_variables_dict()["LambdaVDW"]), - "LambdaCoulomb": "Free Energy Calcs (NVT and NPT only): list of floats (0 <= floats <= 1), " - "The user must set this variable as there is no working default (default = {}). " - "Lambda values for Coulombic interaction in ascending order. Sets the intermediate " - "lambda states to which solute-solvent Coulombic interactions are scaled. " - 'GOMC defauts to the "LambdaVDW" values for the Coulombic interaction ' - 'if no "LambdaCoulomb" variable is set. ' - 'WARNING : This list must be the same length as the "LambdaVDW" list length.' - "WARNING : All lambda values must be stated in the ascending order, " - "starting with 0.0 and ending with 1.0; otherwise, the program will terminate." - "Example of ascending order 1: [0.0, 0.1, 1.0] " - "Example of ascending order 2: [0.0, 0.1, 0.2, 0.4, 0.9, 1.0] " - "".format(_get_default_variables_dict()["LambdaCoulomb"]), - "ScaleCoulomb": "Free Energy Calcs (NVT and NPT only): bool, default = {}, " - "Determines to scale the Coulombic interaction non-linearly (soft-core scheme) or not. " - "True if the Coulombic interaction needs to be scaled non-linearly. " - "False if the Coulombic interaction needs to be scaled linearly. " - "".format(_get_default_variables_dict()["ScaleCoulomb"]), - "ScalePower": "Free Energy Calcs (NVT and NPT only): int (>= 0), default = {}, " - "The p value in the soft-core scaling scheme, where the distance between " - "solute and solvent is scaled non-linearly." - "".format(_get_default_variables_dict()["ScalePower"]), - "ScaleAlpha": "Free Energy Calcs (NVT and NPT only): int or float (>= 0), default = {}, " - "The alpha value in the soft-core scaling scheme, where the distance " - "between solute and solvent is scaled non-linearly." - "".format(_get_default_variables_dict()["ScaleAlpha"]), - "MinSigma": "Free Energy Calcs (NVT and NPT only): int or float (>= 0), default = {}, " - "The minimum sigma value in the soft-core scaling scheme, where the " - "distance between solute and solvent is scaled non-linearly." - "".format(_get_default_variables_dict()["MinSigma"]), - # moves without MEMC - "DisFreq": "Std. MC moves (all ensembles) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which the displacement move will occur " - "(i.e., fraction of displacement moves). Note: all of the move types" - "are not available in for every ensemble. Note: all of the move fractions" - "must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["DisFreq"]), - "RotFreq": "Std. MC moves (all ensembles) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which the rotation move will occur " - "(i.e., fraction of rotation moves). Note: all of the move types" - "are not available in for every ensemble. Note: all of the move fractions" - "must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["RotFreq"]), - "IntraSwapFreq": "Std. MC moves (all ensembles) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which the molecule will be removed from a " - "box and inserted into the same box using coupled-decoupled configurational-bias" - "algorithm. (i.e., fraction of intra-molecule swap moves). Note: all of the move types" - "are not available in for every ensemble. Note: all of the move fractions" - "must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["IntraSwapFreq"]), - "SwapFreq": "Std. MC moves (only GEMC_NPT, GEMC_NVT, and GCMC) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "For Gibbs and Grand Canonical (GC) ensemble runs only: Fractional " - "percentage at which molecule swap move will occur using coupled-decoupled " - "configurational-bias. (i.e., fraction of molecule swaps moves). Note: all of the move types" - "are not available in for every ensemble. Note: all of the move fractions" - "must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["SwapFreq"]), - "RegrowthFreq": "Std. MC moves (all ensembles) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which part of the molecule will be " - "deleted and then regrown using coupled- decoupled configurational-bias algorithm " - "(i.e., fraction of molecular growth moves). Note: all of the move types" - "are not available in for every ensemble. Note: all of the move fractions" - "must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["RegrowthFreq"]), - "CrankShaftFreq": "Std. MC moves (all ensembles) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which crankshaft move will occur. " - "In this move, two atoms that are forming angle or dihedral are selected randomly and " - "form a shaft. Then any atoms or group that are within these two selected atoms, will " - "rotate around the shaft to sample intra-molecular degree of freedom " - "(i.e., fraction of crankshaft moves). Note: all of the move types" - "are not available in for every ensemble. Note: all of the move fractions" - "must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["CrankShaftFreq"]), - "VolFreq": "Std. MC moves (only GEMC_NPT and NPT ) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which a volume move will occur " - "(i.e., fraction of Volume moves). " - "Note: all of the move types are not available in for every ensemble. " - "Note: all of the move fractions must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["VolFreq"]), - "MultiParticleFreq": "Std. MC moves (all ensembles) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which multi-particle move will " - "occur. In this move, all molecules in the selected simulation box will be rigidly " - "rotated or displaced simultaneously, along the calculated torque or force " - "respectively (i.e., fraction of multi-particle moves). Note: all of the move types" - "are not available in for every ensemble. Note: all of the move fractions" - "must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["MultiParticleFreq"]), - # MEMC moves - "IntraMEMC-1Freq": "MEMC MC moves (all ensembles) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which specified number of small molecule kind will be " - "exchanged with a specified large molecule kind in defined sub-volume within " - "same simulation box. This move need additional information such as " - "ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, and ExchangeLargeKind." - "Note: all of the move types are not available in for every ensemble." - "Note: all of the move fractions must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["IntraMEMC-1Freq"]), - "MEMC-1Freq": "MEMC MC moves (only GEMC_NPT, GEMC_NVT, and GCMC) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which specified number of small molecule kind will be exchanged " - "with a specified large molecule kind in defined sub-volume, between simulation boxes. " - "This move needs additional information such as ExchangeVolumeDim, ExchangeRatio, " - "ExchangeSmallKind, and ExchangeLargeKind." - "Note: all of the move types are not available in for every ensemble." - "Note: all of the move fractions must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["MEMC-1Freq"]), - "IntraMEMC-2Freq": "MEMC MC moves (all ensembles) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which specified number of small molecule kind " - "will be exchanged with a specified large molecule kind in defined sub-volume " - "within same simulation box. Backbone of small and large molecule kind will be " - "used to insert the large molecule more efficiently. This move need additional " - "information such as ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, " - "ExchangeLargeKind, SmallKindBackBone, and LargeKindBackBone. " - "Note: all of the move types are not available in for every ensemble." - "Note: all of the move fractions must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["IntraMEMC-2Freq"]), - "MEMC-2Freq": "MEMC MC moves (only GEMC_NPT, GEMC_NVT, and GCMC) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which specified number of small molecule kind will be " - "exchanged with a specified large molecule kind in defined sub-volume, between" - "simulation boxes. Backbone of small and large molecule kind will be used to insert " - "the large molecule more efficiently. " - "This move needs additional information such as ExchangeVolumeDim, ExchangeRatio, " - "ExchangeSmallKind, ExchangeLargeKind, SmallKindBackBone, and LargeKindBackBone. " - "Note: all of the move types are not available in for every ensemble." - "Note: all of the move fractions must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["MEMC-2Freq"]), - "IntraMEMC-3Freq": "MEMC MC moves (all ensembles) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which specified number of small molecule kind will be " - "exchanged with a specified large molecule kind in defined sub-volume within same " - "simulation box. Specified atom of the large molecule kind will be used to insert " - "the large molecule using coupled-decoupled configurational-bias. This move needs " - "additional information such as ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, " - "ExchangeLargeKind, and LargeKindBackBone. " - "Note: all of the move types are not available in for every ensemble." - "Note: all of the move fractions must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["IntraMEMC-3Freq"]), - "MEMC-3Freq": "MEMC MC moves (only GEMC_NPT, GEMC_NVT, and GCMC) : " - "int or float (0 <= value <= 1), default are specific for each ensemble {}. " - "Fractional percentage at which specified number of small molecule kind will be exchanged " - "with a specified large molecule kind in defined sub-volume, between simulation boxes. " - "Specified atom of the large molecule kind will be used to insert the large molecule " - "using coupled-decoupled configurational-bias. This move need additional information " - "such as ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, ExchangeLargeKind, " - "and LargeKindBackBone. " - "Note: all of the move types are not available in for every ensemble." - "Note: all of the move fractions must sum to 1, or the control file writer will fail. " - "".format(_get_default_variables_dict()["MEMC-3Freq"]), - # MEMC move parameters - "ExchangeVolumeDim": "MEMC parameters (all ensembles) : " - "list of 3 floats or integers " - "[int or float (> 0), int or float (> 0), int or float (> 0)]" - " or [X-dimension, Y-dimension, Z-dimension)], default = {}. " - "To use all variation of MEMC and Intra-MEMC Monte Carlo moves, the exchange " - "subvolume must be defined. The exchange sub-volume is defined as an orthogonal box " - "with x, y, and z-dimensions, where small molecule/molecules kind will be selected " - "from to be exchanged with a large molecule kind. " - "Note: Currently, the X and Y dimension cannot be set independently (X = Y = max(X, Y)). " - "Note: A heuristic for setting good values of the x, y, and z-dimensions is to use " - "the geometric size of the large molecule plus 1-2 Å in each dimension. " - "Note: In case of exchanging 1 small molecule kind with 1 large molecule kind in " - "IntraMEMC-2, IntraMEMC-3, MEMC-2, MEMC-3 Monte Carlo moves, the sub-volume " - "dimension has no effect on acceptance rate. " - "".format(_get_default_variables_dict()["ExchangeVolumeDim"]), - "MEMC_DataInput": "MEMC parameters (availablity based on selelection): nested lists, " - + "default = {}. ".format( - _get_default_variables_dict()["MEMC_DataInput"] - ) - + "Enter data as a list with some sub-lists as follows: " - "[[ExchangeRatio_int (> 0), ExchangeLargeKind_str, " - "[LargeKindBackBone_atom_1_str_or_NONE, LargeKindBackBone_atom_2_str_or_NONE ], " - "ExchangeSmallKind_str, " - "[SmallKindBackBone_atom_1_str_or_NONE, SmallKindBackBone_atom_2_str_or_NONE ]], ..., " - "[ExchangeRatio_int (> 0), ExchangeLargeKind_str, " - "[LargeKindBackBone_atom_1_str_or_NONE, LargeKindBackBone_atom_2_str_or_NONE ], " - "ExchangeSmallKind_str, " - "[SmallKindBackBone_atom_1_str_or_NONE, SmallKindBackBone_atom_2_str_or_NONE ]. " - "NOTE: CURRENTLY ALL THESE INPUTS NEED TO BE SPECIFIED, REGARDLESS OF THE MEMC TYPE " - "SELECTION. IF THE SmallKindBackBone or LargeKindBackBone IS NOT REQUIRED FOR THE " - "MEMC TYPE, None CAN BE USED IN PLACE OF A STRING. " - "Note: These strings must match the residue in the psf and psb files or it will fail. " - "It is recommended that the user print the Charmm object psf and pdb files " - "and review the residue names that match the atom name before using the in " - "the MEMC_DataInput variable input." - "Note: see the below data explanations for the ExchangeRatio, ExchangeSmallKind, " - "ExchangeLargeKind, LargeKindBackBone, SmallKindBackBone. " - "Example 1 (MEMC-1) : [ [1, 'WAT', [None, None], 'wat', [None, None]] , " - "[1, 'WAT', [None, None], 'wat', [None, None]] . " - "Example 2 (MEMC-2): [ [1, 'WAT', ['O1', 'H1'], 'wat', ['O1', 'H1' ]] , " - "[1, 'WAT', ['H1', 'H2'], 'wat', ['H1', 'H2' ]] . " - "Example 3 (MEMC-3) : [ [2, 'WAT', 'O1', 'H1'], 'wat', [None, None]] , " - "[2, 'WAT', ['H1', 'H2'], 'wat', [None, None]] .\n" - "\t\t\t\t\t\t\t\t\t\t\t\t\t --- ExchangeRatio = MEMC parameters (all ensembles): " - "int (> 0), default = None. The Ratio of exchanging " - "small molecule/molecules with 1 large molecule. " - "To use all variation of MEMC and Intra-MEMC Monte Carlo moves, " - "the exchange ratio must be defined. " - "The exchange ratio defines how many small molecule will be " - "exchanged with 1 large molecule. For each large-small molecule pairs, " - "one exchange ratio must be defined. \n" - "\t\t\t\t\t\t\t\t\t\t\t\t\t --- ExchangeSmallKind = MEMC parameters (all ensembles): " - "str, default = None. The small molecule " - "kind (resname) to be exchanged. " - "Note: ONLY 4 characters can be used for the strings. " - "To use all variation of MEMC and Intra-MEMC Monte Carlo moves, " - "the small molecule kind to be exchanged with a large molecule " - "kind must be defined. Multiple small molecule kind can be specified. \n" - "\t\t\t\t\t\t\t\t\t\t\t\t\t --- ExchangeLargeKind = MEMC parameters (all ensembles): " - "str, default = None. The large molecule " - "kind (resname) to be exchanged. " - "Note: ONLY 4 characters can be used for the strings. " - "To use all variations of MEMC and Intra-MEMC Monte Carlo moves, " - "the large molecule kind to be exchanged with small molecule " - "kind must be defined. Multiple large molecule kind can be specified. \n" - "\t\t\t\t\t\t\t\t\t\t\t\t\t --- LargeKindBackBone = MEMC parameters (all ensembles): " - "list [str, str] or [None, None], default = None " - "Note: ONLY 4 characters can be used for the strings. " - "The [None, None] values can only be used if that MEMC type does not require them. " - "The strings for the the atom name 1 and atom name 2 that belong to the large " - "molecule’s backbone (i.e., [str_for_atom_name_1, str_for_atom_name_2]) " - "To use MEMC-2, MEMC-3, IntraMEMC-2, and IntraMEMC-3 Monte Carlo moves, the " - "large molecule backbone must be defined. The backbone of the molecule is defined " - "as a vector that connects two atoms belong to the large molecule. The large " - "molecule backbone will be used to align the sub-volume in MEMC-2 and IntraMEMC-2 " - "moves, while in MEMC-3 and IntraMEMC-3 moves, it uses the atom name to start " - "growing the large molecule using coupled-decoupled configurational-bias. For " - "each large-small molecule pairs, two atom names must be defined. " - "Note: all atom names in the molecule must be unique. " - "Note: In MEMC-3 and IntraMEMC-3 Monte Carlo moves, both atom names must be same, " - "otherwise program will be terminated. " - "Note: If the large molecule has only one atom (mono atomic molecules), " - "same atom name must be used for str_for_atom_name_1 and str_for_atom_name_2 " - "of the LargeKindBackBone. \n" - "\t\t\t\t\t\t\t\t\t\t\t\t\t --- SmallKindBackBone = MEMC parameters (all ensembles): " - " list [str, str] or [None, None], default = None " - "Note: ONLY 4 characters can be used for the strings. " - "The [None, None] values can only be used if that MEMC type does not require them." - "The strings for the the atom name 1 and atom name 2 that belong to the small " - "molecule’s backbone (i.e., [str_for_atom_name_1, str_for_atom_name_2]) " - "To use MEMC-2, and IntraMEMC-2 Monte Carlo moves, the small molecule backbone " - "must be defined. The backbone of the molecule is defined as a vector that " - "connects two atoms belong to the small molecule and will be used to align the " - "sub-volume. For each large-small molecule pairs, two atom names must be defined. " - "Note: all atom names in the molecule must be unique. " - "Note: If the small molecule has only one atom (mono atomic molecules), same atom " - "name must be used str_for_atom_name_1 and str_for_atom_name_2 " - "of the SmallKindBackBone. ", - "TargetedSwapFreq": "int or float (0 <= value <= 1), default are specific for each ensemble " - "{'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0} " - "Fractional percentage at which targeted swap move will occur. " - "Note: This is only usable with the 'GCMC', 'GEMC_NVT', and 'GEMC_NPT' ensembles., " - "Note: This is used in conjunction with the 'TargetedSwap_DataInput' variables. ", - "IntraTargetedSwapFreq": "int or float (0 <= value <= 1), default are specific for each ensemble " - "{'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0} " - 'Note: This is used in conjunction with the "TargetedSwap_DataInput" variables. ', - "TargetedSwap_DataInput": "dict, default=None. " - "A dictionary which can contain one or several targeted swap regions, each designated with " - "their own tag ID number (aka, subvolume number). " - "A few examples for TargetedSwap_DataInput input is provided below. " - "NOTE: MULTIPLE SIMULATION BOXES CAN BE UTILIZED BY SETTING MULTIPLE tag_ID_integer VALUES (INTEGERS VALUES), " - 'NOTE: THIS IS REQUIRED WHEN USING EITHER THE "TargetedSwapFreq" OR "IntraTargetedSwapFreq" MC MOVES. ' - "WARNING: THE tag_ID_integer VALUES MUST BE UNIQUE FOR EACH SUBVOLUME, " - "OR THE DICTIONARY WILL OVERWRITE THE PREVIOUS SUBVOLUME (tag_ID_integer) SECTION " - "WITH THE CURRENT tag_ID_integer AND ITS RESPECTIVE VALUES. " - 'The details of each key and value for the "TargetedSwap_DataInput" are provided below. ' - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumeType" : str ("static" or "dynamic"), No default is provided. ' - "The type of targeted swap box (subvolume) that will be created. " - 'The "static" type will maintain the box (subvolume) in a fixed location during the whole simulation, ' - "with the center of the box determined by the coordinates set in the " - '"SubvolumeCenter" parameter. ' - 'The "dynamic" type will allow for dynamic movement of the box (subvolume) based atom indices ' - 'provided in the SubvolumeCenterList variable. For the "dynamic" type, the user must define a ' - 'list of atom indices using "SubVolumeCenterList" keyword; the geometric center of the ' - "provided atom indices will be used as the center of subVolume. User must ensure that the " - "atoms defined in the atom list remain in the simulation box (by setting the Beta value to 2 in PDB file). " - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumeBox" : int (0 or 1), No default is provided. ' - "The simulation box in which the targeted swap subvolume will be applied. " - "NOTE: Only box zero (0) can be used for the GCMC, NPT, and NVT ensembles. " - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumeCenter" : list of three (3) int or float, [x-axis, y-axis, z-axis], ' - "No default is provided. " - "The simulation box is centered on this x, y, and z-axis points (in Angstroms), which is only " - 'utilized when "SubVolumeType" is set to "static". ' - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumeCenterList" : list of int and/or str (>=0), ' - "[atom_index, ..., atom_index], No default is provided. " - "The simulation box subVolume is centered on the geometric center of the provided atom indices, which is " - 'only used when the "SubVolumeType" is set to "dynamic". For example, ["0-10", 12, 15] means that ' - "atom indices 0 to 10, 12 and 15 are used as the geometric center of the simulation box subVolume. " - 'NOTE: THE ATOM INDICES RANGES MUST BE A STRING IN THE FORM "2-20", WITH THE FIRST ATOM INDICES BEING ' - 'SMALLER THAN THE SECOND (i.e, "a-b", where a < b). ALL SINGULAR ATOM INDICES MUST BE INTEGERS. ' - "NOTE: THE SAME ATOM INDICES CAN BE USED 2, 3 OR X TIMES TO WEIGHT that atom 2, 3, OR X TIMES MORE " - "IN THE GEOMETRIC CENTERING CALCULATION. " - "NOTE: THE ATOM INDICES START AT ZERO (0), WHILE THE PDB AND PSF FILES START AT ONE (1). " - "THEREFORE, YOU NEED TO BE CAREFUL WHEN SETTING THE INDICES FROM THE PDB OR PSF VALUES AS THEY ARE " - "ONE (1) NUMBER OFF. " - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumeDim" : list of three (3) int or float (>0), ' - "[x-axis, y-axis, z-axis], No default is provided. " - "This sets the size of the simulation box (subVolume) in the x, y, and z-axis (in Angstroms). " - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumeResidueKind" : str or list of str, "ALL" or "residue" ' - 'or ["ALL"] or [residue_str, ..., residue_str], No default is provided. ' - 'The residues that will be used in the "TargetedSwap_DataInput" subvolume. ' - 'Alternatively, the user can just set the value to ["ALL"] or "ALL", which covers all the residues. ' - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumeRigidSwap" : bool, ' - + "default = {} ".format( - _get_default_variables_dict()["SubVolumeRigidSwap".lower()] - ) - + "Choose whether to use a rigid or flexible molecule insertion using CD-CBMC for the subVolume. " - "True uses a rigid molecule insertion, while False uses a flexible molecule insertion " - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumePBC" : str ("X", "XY", "XZ", "XYZ", "Y", "YZ", or "Z"), ' - + "default = {} ".format( - _get_default_variables_dict()["SubVolumePBC".lower()] - ) - + "Apply periodic boundary condition (PBC) in selected axes for the subVolume. " - 'Example 1, "X" applies PBC only in the X axis. Example 2, "XY" applies PBC only in the X and Y axes. ' - 'Example 3, "XYZ" applies PBC in the X, Y, and Z axes. ' - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumeChemPot" : dict {str (4 dig limit) , int or float}, ' - "No default is provided. " - "The chemical potentials in GOMC units of energy, K. If no SubVolumeChemPot is provided " - "the default system chemical potential values are used. " - "There is a 4 character limit for the string/residue name since the PDB/PSF " - "files have a 4 character limitation and require an exact match in the conf file. " - "Note: These strings must match the residue in the psf and psb files or it will fail. " - "The name of the residues and their corresponding chemical potential must be specified " - 'for every residue in the system (i.e., {"residue_name" : chemical_potential}). ' - "Note: THIS IS ONLY REQUIRED FOR THE GCMC ENSEMBLE. " - "Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY " - "OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. " - 'Note: ONLY THE "SubVolumeChemPot" OR THE "SubVolumeFugacity" CAN BE USED FOR ALL THE ' - 'TARGET SWAP BOXES (SUBVOLUMES). IF MIX OF "SubVolumeChemPot" AND "SubVolumeFugacity" ARE ' - "USED THE CONTROL FILE WRITER WILL THROW AN ERROR. " - '\t\t\t\t\t\t\t\t\t\t\t\t\t --- "SubVolumeFugacity" : dict {str , int or float (>= 0)}, ' - "No default is provided. " - 'The fugacity in GOMC units of pressure, bar. If no "SubVolumeFugacity" is provided ' - "the default system fugacity values are used. " - "There is a 4 character limit for the string/residue name since the PDB/PSF " - "files have a 4 character limitation and require an exact match in the conf file. " - "Note: These strings must match the residue in the psf and psb files or it will fail. " - "The name of the residues and their corresponding fugacity must be specified " - 'for every residue in the system (i.e., {"residue_name" : fugacity}). ' - "Note: THIS IS ONLY REQUIRED FOR THE GCMC ENSEMBLE. " - "Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY " - "OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. " - 'Note: ONLY THE "SubVolumeChemPot" OR THE "SubVolumeFugacity" CAN BE USED FOR ALL THE ' - 'TARGET SWAP BOXES (SUBVOLUMES). IF MIX OF "SubVolumeChemPot" AND "SubVolumeFugacity" ARE ' - "USED THE CONTROL FILE WRITER WILL THROW AN ERROR. ", - # ****************************************************************************************************** - # Definitions in this function are copied to a large extent from the GOMC manual release version 2.60 (end) - # insert citation here: - # ****************************************************************************************************** - } - if description: - return valid_input_variables - else: - return list(valid_input_variables.keys()) - - -def _get_default_variables_dict(): - """ - Provides a dictionary of the default variables inputs and their default settings (user optional). - - Returns - --------- - default_input_variables_dict : dict - Provides a dict of the default variables inputs (user optional) - - """ - - default_input_variables_dict = { - "PRNG": "RANDOM", - "ParaTypeCHARMM": True, - "ParaTypeMie": False, - "ParaTypeMARTINI": False, - "RcutCoulomb_box_0": None, - "RcutCoulomb_box_1": None, - "Pressure": 1.01325, - "Rcut": 10, - "RcutLow": 0, - "LRC": True, - "IPC": False, - "Exclude": "1-3", - "coul_1_4_scaling": None, - "Potential": "VDW", - "Rswitch": 9, - "ElectroStatic": True, - "Ewald": True, - "CachedFourier": False, - "Tolerance": 0.00001, - "Dielectric": 15, - "PressureCalc": [True, 10000], - "EqSteps": 1000000, - "AdjSteps": 1000, - "VDWGeometricSigma": False, - "useConstantArea": False, - "FixVolBox0": False, - # GCMC only properties - "ChemPot": None, - "Fugacity": None, - # CBMC inputs - "CBMC_First": 12, - "CBMC_Nth": 10, - "CBMC_Ang": 50, - "CBMC_Dih": 50, - # Control file (.conf file ) output controls/parameters - "OutputName": "Output_data", - "CoordinatesFreq": [True, 1000000], - "DCDFreq": [ - False, - 1000000, - ], # set to False until this is in the new official GOMC software release - "RestartFreq": [True, 1000000], - "CheckpointFreq": [True, 1000000], - "ConsoleFreq": [True, 10000], - "BlockAverageFreq": [True, 10000], - "HistogramFreq": [True, 10000], - # Histogram data - "DistName": "dis", - "HistName": "his", - "RunNumber": 1, - "RunLetter": "a", - "SampleFreq": 500, - # Data output for the console and bulk properties calculations - "OutEnergy": [True, True], - "OutPressure": [True, True], - "OutMolNum": [True, True], - "OutDensity": [True, True], - "OutVolume": [True, True], - "OutSurfaceTension": [False, False], - # free energy calculation in NVT and NPT ensembles. - "FreeEnergyCalc": None, - "MoleculeType": None, - "InitialState": None, - "LambdaVDW": None, - "LambdaCoulomb": None, - "ScaleCoulomb": False, - "ScalePower": 2, - "ScaleAlpha": 0.5, - "MinSigma": 3, - # MEMC move info - "ExchangeVolumeDim": [1.0, 1.0, 1.0], - "MEMC_DataInput": None, - "TargetedSwap_DataInput": None, - # TargetedSwap_DataInput default values (these need to be all lower case) - "subvolumerigidswap": True, - "subvolumepbc": "XYZ", - # moves without MEMC - "DisFreq": { - "NVT": 0.15, - "NPT": 0.15, - "GEMC_NVT": 0.20, - "GEMC_NPT": 0.19, - "GCMC": 0.15, - }, - "RotFreq": { - "NVT": 0.15, - "NPT": 0.15, - "GEMC_NVT": 0.20, - "GEMC_NPT": 0.20, - "GCMC": 0.15, - }, - "IntraSwapFreq": { - "NVT": 0.30, - "NPT": 0.29, - "GEMC_NVT": 0.10, - "GEMC_NPT": 0.10, - "GCMC": 0.10, - }, - "SwapFreq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.20, - "GEMC_NPT": 0.20, - "GCMC": 0.35, - }, - "RegrowthFreq": { - "NVT": 0.30, - "NPT": 0.30, - "GEMC_NVT": 0.20, - "GEMC_NPT": 0.20, - "GCMC": 0.15, - }, - "CrankShaftFreq": { - "NVT": 0.10, - "NPT": 0.10, - "GEMC_NVT": 0.10, - "GEMC_NPT": 0.10, - "GCMC": 0.10, - }, - "VolFreq": { - "NVT": 0.00, - "NPT": 0.01, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.01, - "GCMC": 0.00, - }, - "MultiParticleFreq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.00, - "GCMC": 0.00, - }, - # MEMC moves - "IntraMEMC-1Freq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.00, - "GCMC": 0.00, - }, - "MEMC-1Freq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.00, - "GCMC": 0.00, - }, - "IntraMEMC-2Freq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.00, - "GCMC": 0.00, - }, - "MEMC-2Freq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.00, - "GCMC": 0.00, - }, - "IntraMEMC-3Freq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.00, - "GCMC": 0.00, - }, - "MEMC-3Freq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.00, - "GCMC": 0.00, - }, - "TargetedSwapFreq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.00, - "GCMC": 0.00, - }, - "IntraTargetedSwapFreq": { - "NVT": 0.00, - "NPT": 0.00, - "GEMC_NVT": 0.00, - "GEMC_NPT": 0.00, - "GCMC": 0.00, - }, - } - - return default_input_variables_dict - - -def print_required_input(description=False): - """ - Prints the required ensemble arguments with an optional description based on the ensemble type - - Parameters - ---------- - description : bool, default = False. - If True, it prints the descriptions of the required ensemble inputs (i.e. dict), - If False, it only prints the required ensemble inputs without the descriptions (i.e. list) - - Returns - --------- - Prints the required ensemble arguments with an optional description based on the ensemble type - """ - - required_data_dict = _get_required_data(description=True) - required_data_list = _get_required_data(description=False) - ensemble_has_all_valid_required_data = True - required_data = _get_required_data() - - for iter in range(0, len(required_data_list)): - if required_data_list[iter] not in required_data: - ensemble_has_all_valid_required_data = False - - if ensemble_has_all_valid_required_data: - for iter_2 in range(0, len(required_data_list)): - required_data_iter = required_data_list[iter_2] - if description is False: - print( - "{:10s}: {}".format(str(iter_2), str(required_data_iter)) - ) - elif description is True: - print( - "{:10s}: {:30s} {}".format( - str(iter_2), - str(required_data_iter), - str(required_data_dict[required_data_iter]), - ) - ) - else: - print( - "ERROR: Some files in this ensemble are not in the required file list" - ) - - -def check_valid_ensemble_input_variables( - ensemble_type, testing_input_variables_list -): - """ - Checks if all the input variables (user optional) inputs are valid for the given - ensemble, and provides a list of the bad variables in the printed output. - - Parameters - ---------- - ensemble_type : str, valid options are 'NVT', 'NPT', 'GEMC_NVT', 'GEMC_NPT', 'GCMC' - The ensemble type of the simulation. - testing_input_variables_list : list - List containing the optional ensemble input variables which will be - tested for to see if they are valid. - - Returns - --------- - bool: - Returns a bool (True or False) depending on if all variables - are valid or not. - """ - - bad_key_inputs_list = [] - - valid_input_variables_list = _get_possible_ensemble_input_variables( - ensemble_type - ) - ensemble_has_valid_input_variables_list = True - for iter in range(0, len(testing_input_variables_list)): - if testing_input_variables_list[iter] not in valid_input_variables_list: - bad_key_inputs_list.append(testing_input_variables_list[iter]) - ensemble_has_valid_input_variables_list = False - - if ensemble_has_valid_input_variables_list: - return [True, bad_key_inputs_list] - - else: - return [False, bad_key_inputs_list] - - -def print_valid_ensemble_input_variables(ensemble_type, description=False): - """ - Prints the arguments for optional variables brief description based on the ensemble type - - Parameters - ---------- - ensemble_type = str, valid options are 'NVT', 'NPT', 'GEMC_NVT', 'GEMC_NPT', 'GCMC' - The ensemble type of the simulation. - description = bool, default = False. - If True, it prints the descriptions of the optional variable ensemble inputs (i.e. dict), - If False, it only prints the optional variable ensemble inputs without the - descriptions (i.e. list) - - Returns - --------- - Prints the arguments for optional variables brief description based on the ensemble type - """ - - valid_input_variables_dict = _get_all_possible_input_variables( - description=True - ) - ensemble_has_all_valid_input_variables = True - all_valid_input_variables = _get_all_possible_input_variables() - - valid_input_variables_list = _get_possible_ensemble_input_variables( - ensemble_type - ) - - for iter in range(0, len(valid_input_variables_list)): - if valid_input_variables_list[iter] not in all_valid_input_variables: - ensemble_has_all_valid_input_variables = False - - if ensemble_has_all_valid_input_variables: - for iter_2 in range(0, len(valid_input_variables_list)): - ensemble_kwarg_iter = valid_input_variables_list[iter_2] - if description is False: - print( - "{:10s}: {}".format( - str(iter_2), str(ensemble_kwarg_iter) - ) - ) - elif description is True: - print( - "{:10s}: {:30s} {}".format( - str(iter_2), - str(ensemble_kwarg_iter), - str(valid_input_variables_dict[ensemble_kwarg_iter]), - ) - ) - else: - print( - "ERROR: Some input_variables in the ensemble are not in the main input_variables list" - ) - - -def _get_possible_ensemble_input_variables(ensemble_type): - """ - Provides list of the possible optional input variables based on the ensemble type - - Parameters - ---------- - ensemble_type : str, valid options are 'NVT', 'NPT', 'GEMC_NVT', 'GEMC_NPT', 'GCMC' - The ensemble type of the simulation. - - Returns - --------- - valid_input_variables_list : list - A list possible optional input variables for the provided ensemble type. - """ - histogram_output_variables_list = [ - "DistName", - "HistName", - "RunNumber", - "RunLetter", - "SampleFreq", - ] - - cbmc_variables_list = ["CBMC_First", "CBMC_Nth", "CBMC_Ang", "CBMC_Dih"] - - output_freq_variables_list = [ - "OutputName", - "CoordinatesFreq", - "DCDFreq", - "RestartFreq", - "CheckpointFreq", - "ConsoleFreq", - "BlockAverageFreq", - "HistogramFreq", - ] - - output_data_variables_list = [ - "OutEnergy", - "OutPressure", - "OutMolNum", - "OutDensity", - "OutVolume", - "OutSurfaceTension", - ] - - std_mc_moves_variables_list = [ - "DisFreq", - "RotFreq", - "IntraSwapFreq", - "SwapFreq", - "RegrowthFreq", - "CrankShaftFreq", - "VolFreq", - "MultiParticleFreq", - "TargetedSwapFreq", - "IntraTargetedSwapFreq", - ] - - memc_target_swap_mc_moves_variables_list = [ - "IntraMEMC-1Freq", - "MEMC-1Freq", - "IntraMEMC-2Freq", - "MEMC-2Freq", - "IntraMEMC-3Freq", - "MEMC-3Freq", - "ExchangeVolumeDim", - "MEMC_DataInput", - "TargetedSwap_DataInput", - ] - - basic_sim_info_variables_list = [ - "PRNG", - "ParaTypeCHARMM", - "ParaTypeMie", - "ParaTypeMARTINI", - "RcutCoulomb_box_0", - "Pressure", - "Rcut", - "RcutLow", - "LRC", - "IPC", - "Exclude", - "Potential", - "Rswitch", - "ElectroStatic", - "Ewald", - "CachedFourier", - "Tolerance", - "Dielectric", - "PressureCalc", - "EqSteps", - "AdjSteps", - "VDWGeometricSigma", - "useConstantArea", - ] - - if ensemble_type in ["NPT", "NVT"]: - extra_sim_info_variables_list = [] - - free_energy_variables_list = [ - "FreeEnergyCalc", - "MoleculeType", - "InitialState", - "LambdaVDW", - "LambdaCoulomb", - "ScaleCoulomb", - "ScalePower", - "ScaleAlpha", - "MinSigma", - ] - - elif ensemble_type in ["GEMC_NPT", "GEMC_NVT"]: - extra_sim_info_variables_list = ["RcutCoulomb_box_1", "FixVolBox0"] - - free_energy_variables_list = [] # always empty for GEMC - - elif ensemble_type == "GCMC": - extra_sim_info_variables_list = ["ChemPot", "Fugacity"] - - free_energy_variables_list = [] # always empty for GCMC - - if ensemble_type in ["NPT", "NVT", "GEMC_NPT", "GEMC_NVT", "GCMC"]: - valid_input_variables_list = ( - basic_sim_info_variables_list - + extra_sim_info_variables_list - + cbmc_variables_list - + output_freq_variables_list - + histogram_output_variables_list - + output_data_variables_list - + free_energy_variables_list - + std_mc_moves_variables_list - + memc_target_swap_mc_moves_variables_list - ) - else: - warn( - "WARNING: The ensemble_type selected for the _get_possible_ensemble_input_variables " - "function is not valid." - ) - valid_input_variables_list = None - - return valid_input_variables_list - - -class GOMCControl: - """ - Constructs the GOMC control file with user selected variables. - The selected variables and Class attributes are mostly or nearly identical to the - GOMC command names. For many ensembles, the user may use the default input_variables_dict - variables, unless they are required for the specific ensemble (Example: - the GCMC ensemble requires the user to input the Chempot or Fugacity variables, - or the build will fail.) - - Default settings for the GOMC configuration files are based upon - an educated guess, which should result in appropriate sampling for a - given ensemble/simulation type. However, there is no guarantee that - the default setting will provide the best or adequate sampling for - the selected system. The user can modify the configuration/control files - based on the simulation specifics or optimize the system beyond the standard - settings. These override options are available via the keyword arguments - in input_variable_dict. - - Parameters - ---------- - charmm_object : Charmm object - Charmm object is has been parameterized from the selected force field., - ensemble_typ : str, ['NVT', 'NPT', 'GEMC_NPT', 'GCMC-NVT', 'GCMC'] - The ensemble type of the simulation. - RunSteps : int (>0), must be an integer greater than zero. - Sets the total number of simulation steps. - Temperature : float or int (>0), must be an integer greater than zero. - Temperature of system in Kelvin (K) - ff_psf_pdb_file_directory : str (optional), default=None (i.e., the current directory). - The full or relative directory added to the force field, psf, and pdb - file names, created via the Charmm object. - check_input_files_exist : bool, (default=True) - Check if the force field, psf, and pdb files exist. - If the files are checked and do not exist, the writer will throw a ValueError. - True, check if the force field, psf, and pdb files exist. - False, do not check if the force field, psf, and pdb files exist. - Restart : boolean, default = False - Determines whether to restart the simulation from restart file - (``*_restart.pdb`` and ``*_restart.psf``) or not. - RestartCheckpoint : boolean, default = False - Determines whether to restart the simulation with the checkpoint - file (checkpoint.dat) or not. Restarting the simulation with checkpoint.dat - would result in an identical outcome, as if previous simulation was continued. - ExpertMode : boolean, default = False - This allows the move ratios to be any value, regardless of the ensemble, - provided all the move ratios sum to 1. For example, this mode is utilized - to easily equilibrate a GCMC or GEMC ensemble in a pseudo NVT mode by removing - the requirement that the volume and swap moves must be non-zero. - In other words, when the volume and swap moves are zero, the GCMC and GEMC - ensembles will run pseudo NVT simulations in 1 and 2 simulation boxes, respectively. - The simulation's output and restart files will keep their original output structure - for the selected ensemble, which is advantageous when automating a workflow. - Parameters : str, (default=None) - Override all other force field directory and filename input with the correct extension (.inp or .par). - Note: the default directory is the current directory with the Charmm object file name. - Coordinates_box_0 : str, (default=None) - Override all other box 0 pdb directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Structure_box_0 : str, (default=None) - Override all other box 0 psf directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Coordinates_box_1 : str, (default=None) - Override all other box 1 pdb directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Structure_box_1 : str, (default=None) - Override all other box 1 psf directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - binCoordinates_box_0 : str, (default=None) - The box 0 binary coordinate file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. - extendedSystem_box_0 : str, (default=None) - The box 0 vectors and origin file is used only for restarting a GOMC simulation. - binVelocities_box_0 : str, (default=None) - The box 0 binary velocity file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. These velocities are only passed thru - GOMC since Monte Carlo simulations do not utilize any velocity information. - binCoordinates_box_1 : str, (default=None) - The box 1 binary coordinate file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. - extendedSystem_box_1 : str, (default=None) - The box 1 vectors and origin file is used only for restarting a GOMC simulation. - binVelocities_box_1 : str, (default=None) - The box 1 binary velocity file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. These velocities are only passed thru - GOMC since Monte Carlo simulations do not utilize any velocity information. - input_variables_dict: dict, default = None - These input variables are optional and override the default settings. - Changing these variables likely required for more advanced systems. - The details of the acceptable input variables for the selected - ensembles can be found by running the code below in python, - >>> print_valid_ensemble_input_variables('GCMC', description = True) - which prints the input_variables with their subsection description - for the selected 'GCMC' ensemble (other ensembles can be set as well). - - Example : input_variables_dict = {'PRNG' : 123, - 'ParaTypeCHARMM' : True } - - # ******************************************************************* - # input_variables_dict options (keys and values) - (start) - # Note: the input_variables_dict keys are also attributes - # ******************************************************************* - PRNG : string or int (>= 0) ("RANDOM" or int), default = "RANDOM" - PRNG = Pseudo-Random Number Generator (PRNG). There are two (2) options, entering - the string, "RANDOM", or a integer. - - --- "RANDOM": selects a random seed number. This will enter the line - "PRNG RANDOM" in the gomc configuration file. - - --- integer: which defines the integer seed number for the simulation. This is - equivalent to entering the following two lines in the configuration file - - line 1 = PRNG INTSEED - - line 2 = Random_Seed user_selected_integer. - - Example 1: for a random seed enter the string "RANDOM". - - Example 2: for a specific seed number enter a integer of your choosing. - - ParaTypeCHARMM : boolean, default = True - True if a CHARMM forcefield, False otherwise. - ParaTypeMie : boolean, default = False - True if a Mie forcefield type, False otherwise. - ParaTypeMARTINI : boolean, default = False - True if a MARTINI forcefield, False otherwise. - RcutCoulomb_box_0 : int or float (>= 0), default = None - Sets a specific radius in box 0 where the short-range electrostatic - energy will be calculated (i.e., The distance to truncate the - short-range electrostatic energy in box 0.) - Note: if None, GOMC will default to the Rcut value - RcutCoulomb_box_1 : int or float (>= 0), default = None - Sets a specific radius in box 1 where the short-range electrostatic - energy will be calculated (i.e., The distance to truncate the - short-range electrostatic energy in box 0.) - Note: if None, GOMC will default to the Rcut value - Pressure : int or float (>= 0), default = 1.01325 - The pressure in bar utilized for the NPT and GEMC_NPT simulations. - Rcut : int or float (>= 0 and RcutLow < Rswitch < Rcut), default = 10 - Sets a specific radius in Angstroms that non-bonded interaction - energy and force will be considered and calculated using defined potential function. - The distance in Angstoms to truncate the LJ, Mie, or other VDW type potential at. - Note: Rswitch is only used when the "Potential" = SWITCH. - RcutLow : int or float (>= 0 and RcutLow < Rswitch < Rcut), default = 0 - Sets a specific minimum possible distance in Angstroms that reject - any move that places any atom closer than specified distance. - The minimum possible distance between any atoms. - Sets a specific radius in Angstroms that non-bonded interaction - Note: Rswitch is only used when the "Potential" = SWITCH. - WARNING: When using a molecule that has charge atoms with non-bonded epsilon values of zero (i.e., water), - the RcutLow need to be greater than zero, typically 1 angstrom. - WARNING: When using the free energy calculations, RcutLow needs to be set to zero (RcutLow=0); - otherwise, the free energy calculations can produce results that are slightly off or wrong. - LRC : boolean, default = True - If True, the simulation considers the long range tail corrections for the - non-bonded VDW or dispersion interactions. - Note: In case of using SHIFT or SWITCH potential functions, LRC will be ignored. - IPC : boolean, default = False - If True, the simulation adds the impulse correction term to the pressure, - which considers to correct for the discontinuous Rcut potential - (i.e., a hard cutoff potential, meaning a potential without tail corrections) - the long range tail corrections for the non-bonded VDW or dispersion interactions. - If False, the impulse correction term to the pressure is not applied. - Note: This can not be used if LRC is True or the Potential is set to SWITCH, or SHIFT. - Exclude : str ["1-2", "1-3", or "1-4"], default = "1-3" - Note: In CHARMM force field, the 1-4 interaction needs to be considered. - Choosing "Excude 1-3", will modify 1-4 interaction based on 1-4 parameters - in parameter file. If a kind force field is used, where 1-4 interaction - needs to be ignored, such as TraPPE, either Exclude "1-4" needs to be - chosen or 1-4 parameter needs to be assigned to zero in the parameter file. - - --- "1-2": All interaction pairs of bonded atoms, except the ones that - separated with one bond, will be considered and modified using 1-4 - parameters defined in parameter file. - - --- "1-3": All interaction pairs of bonded atoms, except the ones that - separated with one or two bonds, will be considered and modified using - 1-4 parameters defined in parameter file. - - --- "1-4": All interaction pairs of bonded atoms, except the ones that - separated with one, two or three bonds, will be considered using - non-bonded parameters defined in parameter file. - - Potential : str, ["VDW", "EXP6", "SHIFT" or "SWITCH"], default = "VDW" - Defines the potential function type to calculate non-bonded dispersion - interaction energy and force between atoms. - - --- "VDW": Non-bonded dispersion interaction energy and force - calculated based on n-6 (Lennard - Jones) equation. This - function will be discussed further in the Intermolecular energy - and Virial calculation section. - - --- "EXP6": Non-bonded dispersion interaction energy and force calculated - based on exp-6 (Buckingham potential) equation. - - --- "SHIFT": This option forces the potential energy to be zero at Rcut distance. - - --- "SWITCH": This option smoothly forces the potential energy to be zero at - Rcut distance and starts modifying the potential at Rswitch - distance. Depending on force field type, specific potential - function will be applied. - - Rswitch : int or float (>= 0 and RcutLow < Rswitch < Rcut), default = 9 - Note: Rswitch is only used when the SWITCH function is used - (i.e., "Potential" = SWITCH). The Rswitch distance is in Angstrom. If the - “SWITCH” function is chosen, Rswitch needs to be defined, otherwise, the - program will be terminated. When using choosing "SWITCH" as potential function, - the Rswitch distance defines where the non-bonded interaction energy - modification is started, which is eventually truncated smoothly at Rcut - distance. - ElectroStatic : boolean, default = True - Considers the coulomb interactions or not. If True, coulomb interactions are - considered and false if not. Note: To simulate the polar molecule in MARTINI - force field, ElectroStatic needs to be turn on (i.e., True). The MARTINI force - field uses short-range coulomb interaction with constant Dielectric of 15.0. - Ewald : boolean, default = True - Considers the standard Ewald summation method for electrostatic calculations. - If True, Ewald summation calculation needs to be considered and false if not. - Note: By default, GOMC will set ElectroStatic to True if Ewald summation - method was used to calculate coulomb interaction. - CachedFourier : boolean, default = False - Considers storing the reciprocal terms for Ewald summation calculation in - order to improve the code performance. This option would increase the code - performance with the cost of memory usage. If True, to store reciprocal - terms of Ewald summation calculation and False if not. - Warning: Monte Carlo moves, such as MEMC-1, MEMC-2, MEMC-3, - IntraMEMC-1, IntraMEMC-2, and IntraMEMC-3 are not support with CachedFourier. - Tolerance : float (0.0 < float < 1.0), default = 1e-05 - Sets the accuracy in Ewald summation calculation. Ewald separation parameter - and number of reciprocal vectors for the Ewald summation are determined - based on the accuracy parameter. - Dielectric : int or float (>= 0.0), default = 15 - Sets dielectric value used in coulomb interaction when the Martini - force field is used. Note: In MARTINI force field, Dielectric needs to - be set to 15.0. - PressureCalc : list [bool , int (> 0)] or [bool , step_frequency], - default = [True, 10k] or [True , set via formula based on the number of RunSteps or 10k max] - Calculate the system pressure or not. bool = True, enables the pressure calculation - during the simulation, false disables the calculation. The int/step frequency sets the - frequency of calculating the pressure. - EqSteps : int (> 0), default = set via formula based on the number of RunSteps or 1M max - Sets the number of steps necessary to equilibrate the system. - Averaging will begin at this step. - Note: In GCMC simulations, the Histogram files will be outputed at EqSteps. - AdjSteps : int (> 0), default = set via formula based on the number of RunSteps or 1k max - Sets the number of steps per adjustment of the parameter associated with each move - (e.g. maximum translate distance, maximum rotation, maximum volume exchange, etc.). - VDWGeometricSigma: boolean, default = False - Use geometric mean, as required by OPLS force field, to combining - Lennard-Jones sigma parameters for different atom types. - If set to True, GOMC uses geometric mean to combine Lennard-Jones or VDW sigmas. - Note: The default setting of VDWGeometricSigma is false, which uses the arithmetic - mean when combining Lennard-Jones or VDW sigma parameters for different atom types. - useConstantArea : boolean, default = False - Changes the volume of the simulation box by fixing the cross-sectional - area (x-y plane). If True, the volume will change only in z axis, - If False, the volume of the box will change in a way to maintain the constant - axis ratio. - FixVolBox0 : boolean, default = False - Changing the volume of fluid phase (Box 1) to maintain the constant imposed - pressure and Temperature, while keeping the volume of adsorbed phase (Box 0) fixed. - Note: By default, GOMC will set useConstantArea to False if no value was set. - It means, the volume of the box will change in a way to maintain the constant - axis ratio. - ChemPot : dict {str (4 dig limit) , int or float}, default = None - The chemical potentials in GOMC units of energy, K. - There is a 4 character limit for the string/residue name since the PDB/PSF - files have a 4 character limitation and require and exact match in the conf file. - Note: These strings must match the residue in the psf and psb files or it will fail. - The name of the residues and their corresponding chemical potential must specified - for every residue in the system (i.e., {"residue_name" : chemical_potential}). - Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY - OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. - - Example 1 (system with only water): {"H2O" : -4000} - - Example 2 (system with water and ethanol): {"H2O" : -4000, "ETH" : -8000} - - Fugacity : dict {str , int or float (>= 0)}, default = None - The fugacity in GOMC units of pressure, bar. - There is a 4 character limit for the string/residue name since the PDB/PSF - files have a 4 character limitation and require and exact match in the conf file. - Note: These strings must match the residue in the psf and psb files or it will fail. - The name of the residues and their corresponding fugacity must specified - for every residue in the system (i.e., {"residue_name" : fugacity}). - Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY - OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. - - Example 1 (system with only water): {"H2O" : 1} - - Example 2 (system with water and ethanol): {"H2O" : 0.5, "ETH" : 10} - - CBMC_First : int (>= 0), default = 12 - The number of CD-CBMC trials to choose the first atom position - (Lennard-Jones trials for first seed growth). - CBMC_Nth : int (>= 0), default = 10 - The Number of CD-CBMC trials to choose the later atom positions - (Lennard-Jones trials for first seed growth). - CBMC_Ang : int (>= 0), default = 50 - The Number of CD-CBMC bending angle trials to perform for geometry - (per the coupled-decoupled CBMC scheme). - CBMC_Dih : int (>= 0), default = 50 - The Number of CD-CBMC dihedral angle trials to perform for geometry - (per the coupled-decoupled CBMC scheme). - OutputName : str (NO SPACES), , default = "Output_data", default = [True, 1M] or - [True , set via formula based on the number of RunSteps or 1M max] - The UNIQUE STRING NAME, WITH NO SPACES, which is used for the - output block average, PDB, and PSF file names. - CoordinatesFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 1M] or [True , set via formula based on the number of RunSteps or M max] - Controls output of PDB file (coordinates). If bool is True, this - enables outputting the coordinate files at the integer frequency - (set steps_per_data_output_int), while "False" disables outputting - the coordinates. - DCDFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 1M] or [True , set via formula based on the number of RunSteps or M max] - Controls output of DCD file (coordinates). If bool is True, this - enables outputting the coordinate files at the integer frequency - (set steps_per_data_output_int), while "False" disables outputting - the coordinates. - RestartFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 1M] or [True , set via formula based on the number of RunSteps or 1M max] - This creates the PDB and PSF (coordinate and topology) files for - restarting the system at the set steps_per_data_output_int (frequency) - If bool is True, this enables outputting the PDB/PSF restart files at the - integer frequency (set steps_per_data_output_int), while “false” - disables outputting the PDB/PSF restart files. - CheckpointFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 1M] or [True , set via formula based on the number of RunSteps or 1M max] - Controls the output of the last state of simulation at a specified step, - in a binary file format (checkpoint.dat). Checkpoint file contains the - following information in full precision: - - (1) Last simulation step that saved into checkpoint file - - (2) Simulation cell dimensions and angles - - (3) Maximum amount of displacement (Å), rotation (δ), and volume (Å^3) - that is used in the Displacement, Rotation, MultiParticle, and Volume moves - - (4) Number of Monte Carlo move trial and acceptance - - (5) All molecule’s coordinates - - (6) Random number sequence - - If bool is True, this enables outputing the checkpoint file at the - integer frequency (set steps_per_data_ouput_int), - while "False" disables outputting the checkpoint file. - ConsoleFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 10k] or [True , set via formula based on the number of RunSteps or 10k max] - Controls the output to the "console" or log file, which prints the - acceptance statistics, and run timing info. In addition, instantaneously-selected - thermodynamic properties will be output to this file. If bool is True, - this enables outputting the console data at the integer frequency - (set steps_per_data_output_int), while "False" disables outputting the console - data file. - BlockAverageFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 10k] or [True , set via formula based on the number of RunSteps or 10k max] - Controls the block averages output of selected thermodynamic properties. - Block averages are averages of thermodynamic values of interest for chunks of the - simulation (for post-processing of averages or std. dev. in those values). - If bool is True, this enables outputting the block averaging data/file at the - integer frequency (set steps_per_data_output_int), while "False" - disables outputting the block averaging data/file. - HistogramFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 10k] or [True , set via formula based on the number of RunSteps or 10k max] - Controls the histograms. Histograms are a binned listing of observation frequency - for a specific thermodynamic variable. In the GOMC code, they also control the output - of a file containing energy/molecule samples, which is only used for the "GCMC" - ensemble simulations for histogram reweighting purposes. If bool is True, this - enables outputting the data to the histogram data at the integer frequency - (set steps_per_data_output_int), while "False" disables outputting the histogram - data. - DistName : str (NO SPACES), default = "dis" - Short phrase which will be combined with RunNumber and RunLetter - to use in the name of the binned histogram for molecule distribution. - HistName : str (NO SPACES), default = "his" - Short phrase, which will be combined with RunNumber and RunLetter, - to use in the name of the energy/molecule count sample file. - RunNumber : int ( > 0 ), default = 1 - Sets a number, which is a part of DistName and HistName file name. - RunLetter : str (1 alphabetic character only), default = "a" - Sets a letter, which is a part of DistName and HistName file name. - SampleFreq : int ( > 0 ), default = 500 - The number of steps per histogram sample or frequency. - OutEnergy : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the energy data into the block averages and console output/log - OutPressure : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the pressure data into the block averages and console output/log files. - OutMolNum : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the number of molecules data into the block averages and console - output/log files. - OutDensity : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the density data into the block averages and console output/log files. - OutVolume : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the volume data into the block averages and console output/log files. - OutSurfaceTension : [bool, bool], default = [False, False] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the surface tension data into the block averages and console - output/log files. - FreeEnergyCalc : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = None - bool = True enabling free energy calculation during the simulation, false disables - the calculation. The int/step frequency sets the frequency of calculating the free energy. - WARNING: When using the free energy calculations, RcutLow needs to be set to zero (RcutLow=0); - otherwise, the free energy calculations can produce results that are slightly off or wrong. - MoleculeType : list [str , int (> 0)] or ["residue_name" , residue_ID], default = None - The user must set this variable as there is no working default. - Note: ONLY 4 characters can be used for the string (i.e., "residue_name"). - Sets the solute molecule kind (residue name) and molecule number (residue ID), - which absolute solvation free will be calculated for. - InitialState : int (>= 0), default = None - The user must set this variable as there is no working default. - The index of LambdaCoulomb and LambdaVDW vectors. Sets the index of the - LambdaCoulomb and LambdaVDW vectors, to determine the simulation lambda value for - VDW and Coulomb interactions. - WARNING : This must an integer within the vector count of the LambdaVDW and LambdaCoulomb, - in which the counting starts at 0. - LambdaVDW : list of floats (0 <= floats <= 1), default = None - The user must set this variable as there is no working default (default = {}). - Lambda values for VDW interaction in ascending order. Sets the intermediate - lambda states to which solute-solvent VDW interactions are scaled. - - WARNING : This list must be the same length as the "LambdaCoulomb" list length. - - WARNING : All lambda values must be stated in the ascending order, - starting with 0.0 and ending with 1.0; otherwise, the program will terminate. - - Example of ascending order 1: [0.0, 0.1, 1.0] - - Example of ascending order 2: [0.0, 0.1, 0.2, 0.4, 0.9, 1.0] - - LambdaCoulomb : list of floats (0 <= floats <= 1), default = None - Lambda values for Coulombic interaction in ascending order. Sets the intermediate - lambda states to which solute-solvent Coulombic interactions are scaled. - GOMC defauts to the "LambdaVDW" values for the Coulombic interaction - if no "LambdaCoulomb" variable is set. - - WARNING : This list must be the same length as the "LambdaVDW" list length. - - WARNING : All lambda values must be stated in the ascending order, - starting with 0.0 and ending with 1.0; otherwise, the program will terminate. - - Example of ascending order 1: [0.0, 0.1, 1.0] - - Example of ascending order 2: [0.0, 0.1, 0.2, 0.4, 0.9, 1.0] - - ScaleCoulomb : bool, default = False - Determines to scale the Coulombic interaction non-linearly - (soft-core scheme) or not. - True if the Coulombic interaction needs to be scaled non-linearly. - False if the Coulombic interaction needs to be scaled linearly. - ScalePower : int (>= 0), default = 2 - The p value in the soft-core scaling scheme, where the distance - between solute and solvent is scaled non-linearly. - ScaleAlpha : int or float (>= 0), default = 0.5 - The alpha value in the soft-core scaling scheme, where the distance - between solute and solvent is scaled non-linearly. - MinSigma : int or float (>= 0), default = 3 - The minimum sigma value in the soft-core scaling scheme, where the - distance between solute and solvent is scaled non-linearly. - DisFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.15, 'NPT': 0.15, 'GEMC_NVT': 0.2, 'GEMC_NPT': 0.19, 'GCMC': 0.15} - Fractional percentage at which the displacement move will occur - (i.e., fraction of displacement moves). - RotFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.15, 'NPT': 0.15, 'GEMC_NVT': 0.2, 'GEMC_NPT': 0.2, 'GCMC': 0.15} - Fractional percentage at which the rotation move will occur. - (i.e., fraction of rotation moves). - IntraSwapFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.3, 'NPT': 0.29, 'GEMC_NVT': 0.1, 'GEMC_NPT': 0.1, 'GCMC': 0.1} - Fractional percentage at which the molecule will be removed from a - box and inserted into the same box using coupled-decoupled configurational-bias - algorithm. (i.e., fraction of intra-molecule swap moves). - SwapFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.2, 'GEMC_NPT': 0.2, 'GCMC': 0.35} - For Gibbs and Grand Canonical (GC) ensemble runs only: Fractional - percentage at which molecule swap move will occur using coupled-decoupled - configurational-bias. (i.e., fraction of molecule swaps moves). - RegrowthFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.3, 'NPT': 0.3, 'GEMC_NVT': 0.2, 'GEMC_NPT': 0.2, 'GCMC': 0.15} - Fractional percentage at which part of the molecule will be deleted and - then regrown using coupled- decoupled configurational-bias algorithm - (i.e., fraction of molecular growth moves). - CrankShaftFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.1, 'NPT': 0.1, 'GEMC_NVT': 0.1, 'GEMC_NPT': 0.1, 'GCMC': 0.1} - Fractional percentage at which crankshaft move will occur. - In this move, two atoms that are forming angle or dihedral are selected - randomly and form a shaft. Then any atoms or group that are within these - two selected atoms, will rotate around the shaft to sample intra-molecular - degree of freedom (i.e., fraction of crankshaft moves). - VolFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.01, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.01, 'GCMC': 0.0} - For isobaric-isothermal (NPT) ensemble and Gibbs ensemble - (GEMC_NPT and GEMC_NVT) runs only: Fractional percentage at - which a volume move will occur (i.e., fraction of Volume moves). - MultiParticleFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which multi-particle move will occur. - In this move, all molecules in the selected simulation box will be rigidly - rotated or displaced simultaneously, along the calculated torque or force - respectively (i.e., fraction of multi-particle moves). - IntraMEMC-1Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will be - exchanged with a specified large molecule kind in defined sub-volume within - same simulation box. This move need additional information such as - ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, and ExchangeLargeKind. - MEMC-1Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will - be exchanged with a specified large molecule kind in defined sub-volume, - between simulation boxes. This move need additional information such as - ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, and ExchangeLargeKind. - IntraMEMC-2Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind - will be exchanged with a specified large molecule kind in defined sub-volume - within same simulation box. Backbone of small and large molecule kind will be - used to insert the large molecule more efficiently. This move need additional - information such as ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, - ExchangeLargeKind, SmallKindBackBone, and LargeKindBackBone. - MEMC-2Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will be - exchanged with a specified large molecule kind in defined sub-volume, - between simulation boxes. Backbone of small and large molecule kind will be - used to insert the large molecule more efficiently. This move need additional - information such as ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, - ExchangeLargeKind, SmallKindBackBone, and LargeKindBackBone. - IntraMEMC-3Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will be - exchanged with a specified large molecule kind in defined sub-volume within same - simulation box. Specified atom of the large molecule kind will be used to insert - the large molecule using coupled-decoupled configurational-bias. This move need - additional information such as ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, - ExchangeLargeKind, and LargeKindBackBone. - MEMC-3Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will be - exchanged with a specified large molecule kind in defined sub-volume, - between simulation boxes. Specified atom of the large molecule kind will be - used to insert the large molecule using coupled-decoupled configurational-bias. - This move need additional information such as ExchangeVolumeDim, - ExchangeRatio, ExchangeSmallKind, ExchangeLargeKind, and LargeKindBackBone. - TargetedSwapFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0} - Fractional percentage at which targeted swap move will occur. - Note: This is only usable with the 'GCMC', 'GEMC_NVT', and 'GEMC_NPT' ensembles. - Note: This is used in conjunction with the "TargetedSwap_DataInput" variables. - IntraTargetedSwapFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0} - Note: This is used in conjunction with the "TargetedSwap_DataInput" variables. - TargetedSwap_DataInput : dict, default=None - A dictionary which can contain one or several targeted swap regions, each designated with - their own tag ID number (aka, subvolume number). - A few examples for TargetedSwap_DataInput input is provided below. - NOTE: MULTIPLE SIMULATION BOXES CAN BE UTILIZED BY SETTING MULTIPLE tag_ID_integer VALUES (INTEGERS VALUES), - NOTE: THIS IS REQUIRED WHEN USING EITHER THE "TargetedSwapFreq" OR "IntraTargetedSwapFreq" MC MOVES. - WARNING: THE tag_ID_integer VALUES MUST BE UNIQUE FOR EACH SUBVOLUME, - OR THE DICTIONARY WILL OVERWRITE THE PREVIOUS SUBVOLUME (tag_ID_integer) SECTION - WITH THE CURRENT tag_ID_integer AND ITS RESPECTIVE VALUES. - - Example 1 - input_variables_dict={"TargetedSwap_DataInput": {tag_ID_integer: {"SubVolumeType": "dynamic", - "SubVolumeBox": 0, "SubVolumeCenterList": ['0-10', 12, 15, '22-40'], "SubVolumeDim": [1, 2, 3], - "SubVolumeResidueKind": "ALL", "SubVolumeRigidSwap": False, "SubVolumePBC": "XY", - "SubVolumeChemPot": {"MET": -21, "met": -31}}} - - Example 2 - input_variables_dict={"TargetedSwap_DataInput": {tag_ID_integer: {"SubVolumeType": "static", - "SubVolumeBox": 0, "SubVolumeCenter": [1, 12, 15], "SubVolumeDim": [3, 3, 3], - "SubVolumeResidueKind": ["MET", "met"], "SubVolumeRigidSwap": False, "SubVolumePBC": "XYZ", - "SubVolumeFugacity": {"MET": 0.1, "met": 1}}} - - The details of each key and value for the "TargetedSwap_DataInput" are provided below. - - --- "SubVolumeType" : str ("static" or "dynamic"), No default is provided. - The type of targeted swap box (subvolume) that will be created. - The "static" type will maintain the box (subvolume) in a fixed location during the whole simulation, - with the center of the box determined by the coordinates set in the - "SubvolumeCenter" parameter. - The "dynamic" type will allow for dynamic movement of the box (subvolume) based atom indices - provided in the SubvolumeCenterList variable. For the "dynamic" type, the user must define a - list of atom indices using "SubVolumeCenterList" keyword; the geometric center of the - provided atom indices will be used as the center of subVolume. User must ensure that the - atoms defined in the atom list remain in the simulation box (by setting the Beta value to 2 in PDB file). - - --- "SubVolumeBox" : int (0 or 1), No default is provided. - The simulation box in which the targeted swap subvolume will be applied. - NOTE: Only box zero (0) can be used for the GCMC, NPT, and NVT ensembles. - - --- "SubVolumeCenter" : list of three (3) int or float, [x-axis, y-axis, z-axis], No default is provided. - The simulation box is centered on this x, y, and z-axis points (in Angstroms), which is only - utilized when "SubVolumeType" is set to "static". - - --- "SubVolumeCenterList" : list of int and/or str (>=0), [atom_index, ..., atom_index], No default is provided. - The simulation box subVolume is centered on the geometric center of the provided atom indices, which is - only used when the "SubVolumeType" is set to "dynamic". For example, [0-10', 12, 15] means that - atom indices 0 to 10, 12 and 15 are used as the geometric center of the simulation box subVolume. - NOTE: THE ATOM INDICES RANGES MUST BE A STRING IN THE FORM '2-20', WITH THE FIRST ATOM INDICES BEING - SMALLER THAN THE SECOND (i.e, 'a-b', where a < b). ALL SINGULAR ATOM INDICES MUST BE INTEGERS. - NOTE: THE SAME ATOM INDICES CAN BE USED 2, 3 OR X TIMES TO WEIGHT that atom 2, 3, OR X TIMES MORE - IN THE GEOMETRIC CENTERING CALCULATION. - NOTE: THE ATOM INDICES START AT ZERO (0), WHILE THE PDB AND PSF FILES START AT ONE (1). - THEREFORE, YOU NEED TO BE CAREFUL WHEN SETTING THE INDICES FROM THE PDB OR PSF VALUES AS THEY ARE - ONE (1) NUMBER OFF. - - --- "SubVolumeDim" : list of three (3) int or float (>0), [x-axis, y-axis, z-axis], No default is provided. - This sets the size of the simulation box (subVolume) in the x, y, and z-axis (in Angstroms). - - --- "SubVolumeResidueKind" : str or list of str, "ALL" or "residue" - or ["ALL"] or [residue_str, ..., residue_str], No default is provided. - The residues that will be used in the "TargetedSwap_DataInput" subvolume. - Alternatively, the user can just set the value to ["ALL"] or "ALL", which covers all the residues. - - --- "SubVolumeRigidSwap" : bool, default = True - Choose whether to use a rigid or flexible molecule insertion using CD-CBMC for the subVolume. - True uses a rigid molecule insertion, while False uses a flexible molecule insertion - - --- "SubVolumePBC" : str ('X', 'XY', 'XZ', 'XYZ', 'Y', 'YZ', or 'Z'), default = 'XYZ'. - Apply periodic boundary condition (PBC) in selected axes for the subVolume. - Example 1, 'X' applies PBC only in the X axis. Example 2, 'XY' applies PBC only in the X and Y axes. - Example 3, 'XYZ' applies PBC in the X, Y, and Z axes. - - --- "SubVolumeChemPot" : dict {str (4 dig limit) , int or float}, No default is provided. - The chemical potentials in GOMC units of energy, K. If no SubVolumeChemPot is provided - the default system chemical potential values are used. - There is a 4 character limit for the string/residue name since the PDB/PSF - files have a 4 character limitation and require an exact match in the conf file. - Note: These strings must match the residue in the psf and psb files or it will fail. - The name of the residues and their corresponding chemical potential must be specified - for every residue in the system (i.e., {"residue_name" : chemical_potential}). - Note: THIS IS ONLY REQUIRED FOR THE GCMC ENSEMBLE. - Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY - OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. - Note: ONLY THE "SubVolumeChemPot" OR THE "SubVolumeFugacity" CAN BE USED FOR ALL THE - TARGET SWAP BOXES (SUBVOLUMES). IF MIX OF "SubVolumeChemPot" AND "SubVolumeFugacity" ARE - USED THE CONTROL FILE WRITER WILL THROW AN ERROR. - - --- "SubVolumeFugacity" : dict {str , int or float (>= 0)}, No default is provided. - The fugacity in GOMC units of pressure, bar. If no "SubVolumeFugacity" is provided - the default system fugacity values are used. - There is a 4 character limit for the string/residue name since the PDB/PSF - files have a 4 character limitation and require an exact match in the conf file. - Note: These strings must match the residue in the psf and psb files or it will fail. - The name of the residues and their corresponding fugacity must be specified - for every residue in the system (i.e., {"residue_name" : fugacity}). - Note: THIS IS ONLY REQUIRED FOR THE GCMC ENSEMBLE. - Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY - OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. - Note: ONLY THE "SubVolumeChemPot" OR THE "SubVolumeFugacity" CAN BE USED FOR ALL THE - TARGET SWAP BOXES (SUBVOLUMES). IF MIX OF "SubVolumeChemPot" AND "SubVolumeFugacity" ARE - USED THE CONTROL FILE WRITER WILL THROW AN ERROR. - - ExchangeVolumeDim : list of 3 floats or integers or [X-dimension, Y-dimension, Z-dimension], - default = [1.0, 1.0, 1.0] - To use all variations of MEMC and Intra-MEMC Monte Carlo moves, the exchange - subvolume must be defined. The exchange sub-volume is defined as an orthogonal box - with x, y, and z-dimensions, where small molecule/molecules kind will be selected - from to be exchanged with a large molecule kind. - Note: Currently, the X and Y dimension cannot be set independently (X = Y = max(X, Y)). - Note: A heuristic for setting good values of the x, y, and z-dimensions is to use - the geometric size of the large molecule plus 1-2 Å in each dimension. - Note: In case of exchanging 1 small molecule kind with 1 large molecule kind in - IntraMEMC-2, IntraMEMC-3, MEMC-2, MEMC-3 Monte Carlo moves, the sub-volume - dimension has no effect on acceptance rate. - MEMC_DataInput : nested lists, default = None - Enter data as a list with some sub-lists as follows: - [[ExchangeRatio_int (> 0), ExchangeLargeKind_str, - [LargeKindBackBone_atom_1_str_or_NONE, LargeKindBackBone_atom_2_str_or_NONE ], - ExchangeSmallKind_str, [SmallKindBackBone_atom_1_str_or_NONE, SmallKindBackBone_atom_2_str_or_NONE ]], - ..., - [ExchangeRatio_int (> 0), ExchangeLargeKind_str, - [LargeKindBackBone_atom_1_str_or_NONE, LargeKindBackBone_atom_2_str_or_NONE ], - ExchangeSmallKind_str, [SmallKindBackBone_atom_1_str_or_NONE, SmallKindBackBone_atom_2_str_or_NONE ]. - NOTE: CURRENTLY ALL THESE INPUTS NEED TO BE SPECIFIED, REGARDLESS OF THE MEMC TYPE - SELECTION. IF THE SmallKindBackBone or LargeKindBackBone IS NOT REQUIRED FOR THE - MEMC TYPE, None CAN BE USED IN PLACE OF A STRING. - - Note: These strings must match the residue in the psf and psb files or it will fail. - It is recommended that the user print the Charmm object psf and pdb files - and review the residue names that match the atom name before using the in - the MEMC_DataInput variable input. - - Note: see the below data explanations for the ExchangeRatio, ExchangeSmallKind, - ExchangeLargeKind, LargeKindBackBone, SmallKindBackBone. - - Example 1 (MEMC-1) : [ [1, 'WAT', [None, None], 'wat', [None, None]] , - [1, 'WAT', [None, None], 'wat', [None, None]] - - Example 2 (MEMC-2): [ [1, 'WAT', ['O1', 'H1'], 'wat', ['O1', 'H1' ]] , - [1, 'WAT', ['H1', 'H2'], 'wat', ['H1', 'H2' ]] - - Example 3 (MEMC-3) : [ [2, 'WAT', 'O1', 'H1'], 'wat', [None, None]] , - [2, 'WAT', ['H1', 'H2'], 'wat', [None, None]] - - --- ExchangeRatio = MEMC parameters (all ensembles): int (> 0), default = None - The Ratio of exchanging small molecule/molecules with 1 large molecule. - To use all variation of MEMC and Intra-MEMC Monte Carlo moves, - the exchange ratio must be defined. The exchange ratio defines how - many small molecule will be exchanged with 1 large molecule. For each - large-small molecule pairs, one exchange ratio must be defined. - - --- ExchangeSmallKind = MEMC parameters (all ensembles): str, default = None - The small molecule kind (resname) to be exchanged. - Note: ONLY 4 characters can be used for the strings. - To use all variation of MEMC and Intra-MEMC Monte Carlo moves, - the small molecule kind to be exchanged with a large molecule - kind must be defined. Multiple small molecule kind can be specified. - - --- ExchangeLargeKind = MEMC parameters (all ensembles): str, default = None - The large molecule kind (resname) to be exchanged. - Note: ONLY 4 characters can be used for the strings. - To use all variation of MEMC and Intra-MEMC Monte Carlo moves, - the large molecule kind to be exchanged with small molecule - kind must be defined. Multiple large molecule kind can be specified. - - --- LargeKindBackBone = MEMC parameters (all ensembles): list [str, str] or [None, None], default = None - Note: ONLY 4 characters can be used for the strings. - The [None, None] values can only be used if that MEMC type does - not require them. The strings for the the atom name 1 and atom name 2 - that belong to the large molecule’s backbone - (i.e., [str_for_atom_name_1, str_for_atom_name_2]) - To use MEMC-2, MEMC-3, IntraMEMC-2, and IntraMEMC-3 Monte Carlo moves, the - large molecule backbone must be defined. The backbone of the molecule is defined - as a vector that connects two atoms belong to the large molecule. The large - molecule backbone will be used to align the sub-volume in MEMC-2 and IntraMEMC-2 - moves, while in MEMC-3 and IntraMEMC-3 moves, it uses the atom name to start - growing the large molecule using coupled-decoupled configurational-bias. For - each large-small molecule pairs, two atom names must be defined. - Note: all atom names in the molecule must be unique. - Note: In MEMC-3 and IntraMEMC-3 Monte Carlo moves, both atom names must be same, - otherwise program will be terminated. - Note: If the large molecule has only one atom (mono atomic molecules), - same atom name must be used for str_for_atom_name_1 and str_for_atom_name_2 - of the LargeKindBackBone. - - --- SmallKindBackBone = MEMC parameters (all ensembles): list [str, str] or [None, None], default = None - Note: ONLY 4 characters can be used for the strings. - The [None, None] values can only be used if that MEMC type does not - require them. The strings for the the atom name 1 and atom name 2 that - belong to the small molecule’s backbone - (i.e., [str_for_atom_name_1, str_for_atom_name_2]) - To use MEMC-2, and IntraMEMC-2 Monte Carlo moves, the small molecule backbone - must be defined. The backbone of the molecule is defined as a vector that - connects two atoms belong to the small molecule and will be used to align the - sub-volume. For each large-small molecule pairs, two atom names must be defined. - Note: all atom names in the molecule must be unique. - Note: If the small molecule has only one atom (mono atomic molecules), same atom - name must be used str_for_atom_name_1 and str_for_atom_name_2 - of the SmallKindBackBone. - - # ******************************************************************* - # input_variables_dict options (keys and values) - (end) - # Note: the input_variables_dict keys are also attributes - # ******************************************************************* - - Attributes - ---------- - input_error : bool - This error is typically incurred from an error in the user input values. - However, it could also be due to a bug, provided the user is inputting - the data as this Class intends. - all_failed_input_List : list - A list of all the inputs that failed, but there may be some inputs that - are not possible to put on this list. - ensemble_typ : str, ['NVT', 'NPT', 'GEMC_NPT', 'GCMC-NVT', 'GCMC'] - The ensemble type of the simulation. - RunSteps : int (>0), must be an integer greater than zero. - Sets the total number of simulation steps. - Temperature : float or int (>0), must be an integer greater than zero. - Temperature of system in Kelvin (K) - ff_psf_pdb_file_directory : str (optional), default=None (i.e., the current directory). - The full or relative directory added to the force field, psf, and pdb - file names, created via the Charmm object. - check_input_files_exist : bool, (default=True) - Check if the force field, psf, and pdb files exist. - If the files are checked and do not exist, the writer will throw a ValueError. - True, check if the force field, psf, and pdb files exist. - False, do not check if the force field, psf, and pdb files exist. - Restart : boolean, default = False - Determines whether to restart the simulation from restart file - (``*_restart.pdb`` and ``*_restart.psf``) or not. - RestartCheckpoint : boolean, default = False - Determines whether to restart the simulation with the checkpoint - file (checkpoint.dat) or not. Restarting the simulation with checkpoint.dat - would result in an identical outcome, as if previous simulation was continued. - Parameters : str, (default=None) - Override all other force field directory and filename input with the correct extension (.inp or .par). - Note: the default directory is the current directory with the Charmm object file name. - Coordinates_box_0 : str, (default=None) - Override all other box 0 pdb directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Structure_box_0 : str, (default=None) - Override all other box 0 psf directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Coordinates_box_1 : str, (default=None) - Override all other box 1 pdb directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Structure_box_1 : str, (default=None) - Override all other box 1 psf directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - binCoordinates_box_0 : str, (default=None) - The box 0 binary coordinate file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. - extendedSystem_box_0 : str, (default=None) - The box 0 vectors and origin file is used only for restarting a GOMC simulation. - binVelocities_box_0 : str, (default=None) - The box 0 binary velocity file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. These velocities are only passed thru - GOMC since Monte Carlo simulations do not utilize any velocity information. - binCoordinates_box_1 : str, (default=None) - The box 1 binary coordinate file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. - extendedSystem_box_1 : str, (default=None) - The box 1 vectors and origin file is used only for restarting a GOMC simulation. - binVelocities_box_1 : str, (default=None) - The box 1 binary velocity file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. These velocities are only passed thru - GOMC since Monte Carlo simulations do not utilize any velocity information. - input_variables_dict: dict, default = None - These input variables are optional and override the default settings. - Changing these variables likely required for more advanced systems. - The details of the acceptable input variables for the selected - ensembles can be found by running the code below in python, - >>> print_valid_ensemble_input_variables('GCMC', description = True) - which prints the input_variables with their subsection description - for the selected 'GCMC' ensemble (other ensembles can be set as well). - Example : input_variables_dict = {'PRNG' : 123, - 'ParaTypeCHARMM' : True } - conf_filename : str - The name of the GOMC contol file, which will be created. The extension - of the GOMC control file can be .conf, or no extension can be provided. - If no extension is provided, this writer will automatically add the - .conf extension to the provided string. - box_0_vectors : numpy.ndarray, [[float float float], [float float float], [float float float]] - Three (3) sets vectors for box 0 each with 3 float values, which represent - the vectors for the Charmm-style systems (units in Angstroms (Ang)) - box_1_vectors : numpy.ndarray, [[float float float], [float float float], [float float float]] - Three (3) sets vectors for box 1 each with 3 float values, which represent - the vectors for the Charmm-style systems (units in Angstroms (Ang)) - coul_1_4 : float or int - The non-bonded 1-4 coulombic scaling factor, which is the - same for all the residues/molecules, regardless if - differenct force fields are utilized. - residues : list, [str, ..., str] - Labels of unique residues in the Compound. Residues are assigned by - checking against Compound.name. Only supply residue names as 4 character - strings, as the residue names are truncated to 4 characters to fit in the - psf and pdb file. - all_res_unique_atom_name_dict : dict, {str : [str, ..., str]} - A dictionary that provides the residue names (keys) and a list - of the unique atom names in the residue (value), for the - combined structures (box 0 and box 1 (if supplied)). - any input_variables_dict key : varies (see each input_variables_dict key and value) - Any of the input variables keys is also an Attribute and can be called - the same way. Please see the input_variables_dict keys in the - Parameters section above for all the available attributes. - - Notes - ------- - The user input variables (input_variables_dict) and the specific - ensembles. - - The details of the required inputs for the selected - ensembles can be found by running this python workbook, - - >>> print_valid_required_input_variables('NVT', description = True) - - which prints the required inputs with their subsection description - for the selected 'NVT' ensemble (other ensembles can be set as well). - - The details of the input variables for the selected - ensembles can be found by running this python workbook, - - >>> print_valid_ensemble_input_variables('NPT', description = True) - - which prints the input variables with their subsection description - for the selected 'NPT' ensemble (other ensembles can be set as well). - - Note: The box units imported are in nm (standard MoSDeF units). - The units for this writer are auto-scaled to Angstroms, so they - can be directly used in the GOMC or NAMD engines. - - Note: all of the move types are not available in for every ensemble. - - Note: all of the move fractions must sum to 1, or the control file - writer will fail. - - The input variables (input_variables_dict) and text extracted with permission from - the GOMC manual version 2.60. Some of the text was modified from its original version. - Cite: Potoff, Jeffrey; Schwiebert, Loren; et. al. GOMC Documentation. - https://raw.githubusercontent.com/GOMC-WSU/GOMC/master/GOMC_Manual.pdf, 2021. - """ - - def __init__( - self, - charmm_object, - ensemble_type, - RunSteps, - Temperature, - ff_psf_pdb_file_directory=None, - check_input_files_exist=True, - Restart=False, - RestartCheckpoint=False, - ExpertMode=False, - Parameters=None, - Coordinates_box_0=None, - Structure_box_0=None, - Coordinates_box_1=None, - Structure_box_1=None, - binCoordinates_box_0=None, - extendedSystem_box_0=None, - binVelocities_box_0=None, - binCoordinates_box_1=None, - extendedSystem_box_1=None, - binVelocities_box_1=None, - input_variables_dict=None, - ): - # depreciation warning that gomc_conf_writer will be depreciated soon - depreciation_warning = ( - "The mosdef_gomc gomc_conf_writer.py will be depreciated soon (by the end of 2022 or sooner). " - "The this only effects the mosdef-gomc charmm_writer parmed version. The GMSO version, " - "gmso_gomc_conf_writer.py, will replace it." - ) - warn(depreciation_warning, DeprecationWarning) - - # set this to check and see if all the input pass - self.input_error = False - - # set this to check and see if all the input pass - self.all_failed_input_List = [] - - # Check if charmm_object is really a Charmm() object - if not isinstance(charmm_object, mf_charmm.Charmm): - self.input_error = True - print_error_message = ( - "ERROR: The variable supplied is a ({}), not a charmm_object ({})" - "".format(type(charmm_object), type(mf_charmm.Charmm)) - ) - raise TypeError(print_error_message) - - # check ensemble is a correct type - if ensemble_type in ["GEMC_NVT", "GEMC-NVT"]: - ensemble_type = "GEMC_NVT" - elif ensemble_type in ["GEMC_NPT", "GEMC-NPT"]: - ensemble_type = "GEMC_NPT" - print("INFO: ensemble_type = " + str(ensemble_type)) - if ensemble_type in ["NPT", "NVT", "GCMC", "GEMC_NVT", "GEMC_NPT"]: - self.ensemble_type = ensemble_type - print( - "INFO: All the ensemble (ensemble_type) input passed the initial error checking" - ) - else: - self.input_error = True - print_error_message = ( - "ERROR: The ensemble type selection of '{}' is not a valid ensemble option. " - "Please choose the 'NPT', 'NVT', 'GEMC_NVT', 'GEMC_NPT', or 'GCMC' " - "ensembles".format(ensemble_type) - ) - raise ValueError(print_error_message) - - # check if check_input_files_exist is a boolean - _check_if_bool("check_input_files_exist", check_input_files_exist) - - # set and check valid inputs for the Restart attribute - _check_if_bool("Restart", Restart) - self.Restart = Restart - - # set and check valid inputs for the RestartCheckpoint attribute - _check_if_bool("RestartCheckpoint", RestartCheckpoint) - self.RestartCheckpoint = RestartCheckpoint - - # set ExpertMode - _check_if_bool("ExpertMode", ExpertMode) - self.ExpertMode = ExpertMode - - self.binCoordinates_box_0 = binCoordinates_box_0 - self.extendedSystem_box_0 = extendedSystem_box_0 - self.binVelocities_box_0 = binVelocities_box_0 - self.binCoordinates_box_1 = binCoordinates_box_1 - self.extendedSystem_box_1 = extendedSystem_box_1 - self.binVelocities_box_1 = binVelocities_box_1 - - # check if the binary restart files are provided correctly - if self.Restart and self.ensemble_type in ["NVT", "NPT"]: - if ( - self.binCoordinates_box_0 is not None - or self.extendedSystem_box_0 is not None - ) and ( - self.binCoordinates_box_0 is None - or self.extendedSystem_box_0 is None - ): - print_error_message = ( - "ERROR: To restart a simulation with the binary files both the coor and " - "xsc files for box 0 must be provided." - ) - raise ValueError(print_error_message) - - elif self.binVelocities_box_0 is not None and ( - self.binCoordinates_box_0 is None - or self.extendedSystem_box_0 is None - ): - print_error_message = ( - 'ERROR: To restart a "NVT", "NPT" simulation with the ' - "velocity binary files, the velocity files for box 0 " - "must be provided." - ) - raise ValueError(print_error_message) - - if self.Restart is True and self.ensemble_type in [ - "GEMC_NPT", - "GEMC_NVT", - "GCMC", - ]: - if ( - self.binCoordinates_box_0 is not None - or self.extendedSystem_box_0 is not None - or self.binCoordinates_box_1 is not None - or self.extendedSystem_box_1 is not None - ) and ( - self.binCoordinates_box_0 is None - or self.extendedSystem_box_0 is None - or self.binCoordinates_box_1 is None - or self.extendedSystem_box_1 is None - ): - print_error_message = ( - "ERROR: To restart a simulation with the binary files both the coor and " - "xsc files for box 0 and box 1 must be provided." - ) - raise ValueError(print_error_message) - - elif ( - self.binVelocities_box_0 is not None - or self.binVelocities_box_1 is not None - ) and ( - self.binVelocities_box_0 is None - or self.binVelocities_box_1 is None - ): - print_error_message = ( - 'ERROR: To restart a "GEMC_NPT", "GEMC_NVT", "GCMC" simulation with the ' - "velocity binary files, both the velocity files for box 0 and box 1 " - "must be provided." - ) - raise ValueError(print_error_message) - - elif ( - self.binVelocities_box_0 is not None - or self.binVelocities_box_1 is not None - ) and ( - self.binCoordinates_box_0 is None - or self.extendedSystem_box_0 is None - or self.binCoordinates_box_1 is None - or self.extendedSystem_box_1 is None - ): - print_error_message = ( - 'ERROR: To restart a "GEMC_NPT", "GEMC_NVT", "GCMC" simulation with the ' - "velocity binary files, both the coor and xsc files files for box 0 " - "and box 1 must be provided." - ) - raise ValueError(print_error_message) - - self.RunSteps = RunSteps - self.Temperature = Temperature - self.ff_psf_pdb_file_directory = ff_psf_pdb_file_directory - if ( - not isinstance(self.ff_psf_pdb_file_directory, str) - and self.ff_psf_pdb_file_directory is not None - ): - _check_if_string_and_extension( - "ff_psf_pdb_file_directory", - self.ff_psf_pdb_file_directory, - "force field, pdb, and psf", - expected_file_extension=None, - ) - - if ( - charmm_object.ff_filename is not None - and isinstance(charmm_object.ff_filename, str) is True - ): - if Parameters is not None: - _check_if_string_and_extension( - "Parameters", - Parameters, - "force field", - expected_file_extension=[".inp", ".par"], - ) - self.ff_filename = Parameters - elif self.ff_psf_pdb_file_directory is None: - self.ff_filename = charmm_object.ff_filename - else: - self.ff_filename = "{}/{}".format( - self.ff_psf_pdb_file_directory, - charmm_object.ff_filename, - ) - # check if the FF file exist: - _check_if_input_files_exist( - self.ff_filename, - "force field file or parameter file", - check_input_files_exist=check_input_files_exist, - ) - elif ( - charmm_object.ff_filename is None - or isinstance(charmm_object.ff_filename, str) is False - ): - self.input_error = True - print_error_message = ( - "The force field file name was not specified and in the Charmm object ({})." - "Therefore, the force field file (.inp) can not be written, and thus, the " - "GOMC control file (.conf) can not be created. Please use the force field file " - "name when building the Charmm object".format( - type(mf_charmm.Charmm) - ) - ) - raise ValueError(print_error_message) - - if ( - charmm_object.filename_box_0 is not None - and isinstance(charmm_object.filename_box_0, str) is True - ): - if Coordinates_box_0 is not None: - _check_if_string_and_extension( - "Coordinates_box_0", - Coordinates_box_0, - "pdb", - expected_file_extension=[".pdb"], - ) - self.Coordinates_box_0 = Coordinates_box_0 - elif self.ff_psf_pdb_file_directory is None: - self.Coordinates_box_0 = "{}.pdb".format( - charmm_object.filename_box_0 - ) - else: - self.Coordinates_box_0 = "{}/{}.pdb".format( - self.ff_psf_pdb_file_directory, charmm_object.filename_box_0 - ) - - if Structure_box_0 is not None: - _check_if_string_and_extension( - "Structure_box_0", - Structure_box_0, - "psf", - expected_file_extension=[".psf"], - ) - self.Structure_box_0 = Structure_box_0 - elif self.ff_psf_pdb_file_directory is None: - self.Structure_box_0 = "{}.psf".format( - charmm_object.filename_box_0 - ) - else: - self.Structure_box_0 = "{}/{}.psf".format( - self.ff_psf_pdb_file_directory, charmm_object.filename_box_0 - ) - - _check_if_input_files_exist( - self.Coordinates_box_0, - "box 0 pdb file", - check_input_files_exist=check_input_files_exist, - ) - _check_if_input_files_exist( - self.Structure_box_0, - "box 0 psf file", - check_input_files_exist=check_input_files_exist, - ) - - # Box 0 restarting files with increased accuracy (coor, xsc) and a velocity passing input - if ( - self.binCoordinates_box_0 is not None - and self.extendedSystem_box_0 is not None - ): - _check_if_string_and_extension( - "binCoordinates_box_0", - self.binCoordinates_box_0, - "coor", - expected_file_extension=[".coor"], - ) - _check_if_string_and_extension( - "extendedSystem_box_0", - self.extendedSystem_box_0, - "xsc", - expected_file_extension=[".xsc"], - ) - _check_if_input_files_exist( - self.binCoordinates_box_0, - "box 0 coor file", - check_input_files_exist=check_input_files_exist, - ) - _check_if_input_files_exist( - self.extendedSystem_box_0, - "box 0 xsc file", - check_input_files_exist=check_input_files_exist, - ) - - if self.binVelocities_box_0 is not None: - _check_if_string_and_extension( - "binVelocities_box_0", - self.binVelocities_box_0, - "velocity", - expected_file_extension=[".vel"], - ) - _check_if_input_files_exist( - self.binVelocities_box_0, - "box 0 velocity file", - check_input_files_exist=check_input_files_exist, - ) - - if ( - charmm_object.filename_box_1 is not None - and isinstance(charmm_object.filename_box_1, str) is True - ): - if Coordinates_box_1 is not None: - _check_if_string_and_extension( - "Coordinates_box_1", - Coordinates_box_1, - "pdb", - expected_file_extension=[".pdb"], - ) - self.Coordinates_box_1 = Coordinates_box_1 - - elif self.ff_psf_pdb_file_directory is None: - self.Coordinates_box_1 = "{}.pdb".format( - charmm_object.filename_box_1 - ) - - else: - self.Coordinates_box_1 = "{}/{}.pdb".format( - self.ff_psf_pdb_file_directory, charmm_object.filename_box_1 - ) - - if Structure_box_1 is not None: - _check_if_string_and_extension( - "Structure_box_1", - Structure_box_1, - "psf", - expected_file_extension=[".psf"], - ) - self.Structure_box_1 = Structure_box_1 - elif self.ff_psf_pdb_file_directory is None: - self.Structure_box_1 = "{}.psf".format( - charmm_object.filename_box_1 - ) - else: - self.Structure_box_1 = "{}/{}.psf".format( - self.ff_psf_pdb_file_directory, charmm_object.filename_box_1 - ) - - _check_if_input_files_exist( - self.Coordinates_box_1, - "box 1 pdb file", - check_input_files_exist=check_input_files_exist, - ) - _check_if_input_files_exist( - self.Structure_box_1, - "box 1 psf file", - check_input_files_exist=check_input_files_exist, - ) - - # Box 1 restarting files with increased accuracy (coor, xsc) and a velocity passing input - if ( - self.binCoordinates_box_1 is not None - and self.extendedSystem_box_1 is not None - ): - _check_if_string_and_extension( - "binCoordinates_box_1", - self.binCoordinates_box_1, - "coor", - expected_file_extension=[".coor"], - ) - _check_if_string_and_extension( - "extendedSystem_box_1", - self.extendedSystem_box_1, - "xsc", - expected_file_extension=[".xsc"], - ) - _check_if_input_files_exist( - self.binCoordinates_box_1, - "box 1 coor file", - check_input_files_exist=check_input_files_exist, - ) - _check_if_input_files_exist( - self.extendedSystem_box_1, - "box 1 xsc file", - check_input_files_exist=check_input_files_exist, - ) - - if self.binVelocities_box_1 is not None: - _check_if_string_and_extension( - "binVelocities_box_1", - self.binVelocities_box_1, - "velocity", - expected_file_extension=[".vel"], - ) - _check_if_input_files_exist( - self.binVelocities_box_1, - "box 0 velocity file", - check_input_files_exist=check_input_files_exist, - ) - - else: - self.Coordinates_box_1 = None - self.Structure_box_1 = None - - self.coul_1_4 = charmm_object.coul_1_4 - self.input_variables_dict = input_variables_dict - self.residues = charmm_object.residues - self.all_residues_unique_atom_name_dict = ( - charmm_object.all_res_unique_atom_name_dict - ) - - # Get and test and make sure vectors are not too large for the 16 spaces allotted - box_vectors_char_limit = 16 - self.box_0_vectors = charmm_object.box_0_vectors - - box_0_vectors_char_ok = _check_box_vectors_char_limit( - self.box_0_vectors, box_vectors_char_limit - ) - - if box_0_vectors_char_ok == False: - self.input_error = True - print_error_message = ( - "ERROR: At lease one of the individual box {} vectors are too large " - "or greater than {} characters." - "".format( - 0, - box_vectors_char_limit, - ) - ) - raise ValueError(print_error_message) - if self.ensemble_type in ["GEMC_NVT", "GEMC_NPT", "GCMC"]: - if ( - charmm_object.filename_box_1 is not None - and isinstance(charmm_object.filename_box_1, str) is True - ): - self.box_1_vectors = charmm_object.box_1_vectors - - box_1_vectors_char_ok = _check_box_vectors_char_limit( - self.box_1_vectors, box_vectors_char_limit - ) - - if box_1_vectors_char_ok == False: - self.input_error = True - print_error_message = ( - "ERROR: At lease one of the individual box {} vectors are too large " - "or greater than {} characters." - "".format( - 1, - box_vectors_char_limit, - ) - ) - raise ValueError(print_error_message) - else: - self.box_1_vectors = None - - # check if the ensembles have the correct number of boxes in the charmm object - if ( - self.ensemble_type in ["NVT", "NPT"] - and self.Coordinates_box_1 is not None - and self.Structure_box_1 is not None - ): - self.input_error = True - print_error_message = ( - "ERROR: The ensemble type selection of {} is using a Charmm " - "object with two simulation boxes, and the {} ensemble only accepts " - "one box (box 0)." - "".format(ensemble_type, ensemble_type) - ) - raise ValueError(print_error_message) - - if ( - self.ensemble_type in ["GEMC_NVT", "GEMC_NPT", "GCMC"] - and self.Coordinates_box_1 is None - and self.Structure_box_1 is None - ): - self.input_error = True - print_error_message = ( - "ERROR: The ensemble type selection of {} is using a Charmm " - "object with one simulation boxes, and the {} ensemble only accepts " - "two boxes (box 0 and box 1)." - "".format(ensemble_type, ensemble_type) - ) - raise ValueError(print_error_message) - - # the future control file name is entered now as None - self.conf_filename = None - - # list of bad variable inputs - bad_input_variables_values_list = [] - - # set all the other variable initally to None (they are corrected to their set or default values later) - default_input_variables_dict = _get_default_variables_dict() - - self.PRNG = default_input_variables_dict["PRNG"] - self.ParaTypeCHARMM = default_input_variables_dict["ParaTypeCHARMM"] - self.ParaTypeMie = default_input_variables_dict["ParaTypeMie"] - self.ParaTypeMARTINI = default_input_variables_dict["ParaTypeMARTINI"] - self.RcutCoulomb_box_0 = default_input_variables_dict[ - "RcutCoulomb_box_0" - ] - self.RcutCoulomb_box_1 = default_input_variables_dict[ - "RcutCoulomb_box_1" - ] - self.Pressure = default_input_variables_dict["Pressure"] - self.Rcut = default_input_variables_dict["Rcut"] - self.RcutLow = default_input_variables_dict["RcutLow"] - self.LRC = default_input_variables_dict["LRC"] - self.IPC = default_input_variables_dict["IPC"] - self.Exclude = default_input_variables_dict["Exclude"] - self.Potential = default_input_variables_dict["Potential"] - self.Rswitch = default_input_variables_dict["Rswitch"] - self.ElectroStatic = default_input_variables_dict["ElectroStatic"] - self.Ewald = default_input_variables_dict["Ewald"] - self.CachedFourier = default_input_variables_dict["CachedFourier"] - self.Tolerance = default_input_variables_dict["Tolerance"] - self.Dielectric = default_input_variables_dict["Dielectric"] - self.VDWGeometricSigma = default_input_variables_dict[ - "VDWGeometricSigma" - ] - self.useConstantArea = default_input_variables_dict["useConstantArea"] - self.FixVolBox0 = default_input_variables_dict["FixVolBox0"] - self.ChemPot = default_input_variables_dict["ChemPot"] - self.Fugacity = default_input_variables_dict["Fugacity"] - self.CBMC_First = default_input_variables_dict["CBMC_First"] - self.CBMC_Nth = default_input_variables_dict["CBMC_Nth"] - self.CBMC_Ang = default_input_variables_dict["CBMC_Ang"] - self.CBMC_Dih = default_input_variables_dict["CBMC_Dih"] - self.OutputName = default_input_variables_dict["OutputName"] - self.DistName = default_input_variables_dict["DistName"] - self.HistName = default_input_variables_dict["HistName"] - self.RunNumber = default_input_variables_dict["RunNumber"] - self.RunLetter = default_input_variables_dict["RunLetter"] - self.OutEnergy = default_input_variables_dict["OutEnergy"] - self.OutPressure = default_input_variables_dict["OutPressure"] - self.OutMolNum = default_input_variables_dict["OutMolNum"] - self.OutDensity = default_input_variables_dict["OutDensity"] - self.OutVolume = default_input_variables_dict["OutVolume"] - self.OutSurfaceTension = default_input_variables_dict[ - "OutSurfaceTension" - ] - self.FreeEnergyCalc = default_input_variables_dict["FreeEnergyCalc"] - self.MoleculeType = default_input_variables_dict["MoleculeType"] - self.InitialState = default_input_variables_dict["InitialState"] - self.LambdaVDW = default_input_variables_dict["LambdaVDW"] - self.LambdaCoulomb = default_input_variables_dict["LambdaCoulomb"] - self.ScaleCoulomb = default_input_variables_dict["ScaleCoulomb"] - self.ScalePower = default_input_variables_dict["ScalePower"] - self.ScaleAlpha = default_input_variables_dict["ScaleAlpha"] - self.MinSigma = default_input_variables_dict["MinSigma"] - - # standard moves - self.DisFreq = default_input_variables_dict["DisFreq"][ - self.ensemble_type - ] - self.RotFreq = default_input_variables_dict["RotFreq"][ - self.ensemble_type - ] - self.IntraSwapFreq = default_input_variables_dict["IntraSwapFreq"][ - self.ensemble_type - ] - self.SwapFreq = default_input_variables_dict["SwapFreq"][ - self.ensemble_type - ] - self.RegrowthFreq = default_input_variables_dict["RegrowthFreq"][ - self.ensemble_type - ] - self.CrankShaftFreq = default_input_variables_dict["CrankShaftFreq"][ - self.ensemble_type - ] - self.VolFreq = default_input_variables_dict["VolFreq"][ - self.ensemble_type - ] - self.MultiParticleFreq = default_input_variables_dict[ - "MultiParticleFreq" - ][self.ensemble_type] - - self.IntraMEMC_1Freq = default_input_variables_dict["IntraMEMC-1Freq"][ - self.ensemble_type - ] - self.MEMC_1Freq = default_input_variables_dict["MEMC-1Freq"][ - self.ensemble_type - ] - self.IntraMEMC_2Freq = default_input_variables_dict["IntraMEMC-2Freq"][ - self.ensemble_type - ] - self.MEMC_2Freq = default_input_variables_dict["MEMC-2Freq"][ - self.ensemble_type - ] - self.IntraMEMC_3Freq = default_input_variables_dict["IntraMEMC-3Freq"][ - self.ensemble_type - ] - self.MEMC_3Freq = default_input_variables_dict["MEMC-3Freq"][ - self.ensemble_type - ] - self.TargetedSwapFreq = default_input_variables_dict[ - "TargetedSwapFreq" - ][self.ensemble_type] - self.IntraTargetedSwapFreq = default_input_variables_dict[ - "IntraTargetedSwapFreq" - ][self.ensemble_type] - - # MEMC data input - self.ExchangeVolumeDim = default_input_variables_dict[ - "ExchangeVolumeDim" - ] - self.MEMC_DataInput = default_input_variables_dict["MEMC_DataInput"] - self.TargetedSwap_DataInput = default_input_variables_dict[ - "TargetedSwap_DataInput" - ] - - # auto calculate the best EqSteps (number of Equilbrium Steps) and Adj_Steps (number of AdjSteps Steps) - self.EqSteps = _scale_gen_freq_for_run_steps_int( - "EqSteps", default_input_variables_dict["EqSteps"], self.RunSteps - ) - - self.AdjSteps = _scale_gen_freq_for_run_steps_int( - "AdjSteps", default_input_variables_dict["AdjSteps"], self.RunSteps - ) - - # auto calculate the best RestartFreq for the number of self.RunSteps - self.RestartFreq = _scale_gen_freq_for_run_steps_list_bool_int( - "RestartFreq", - default_input_variables_dict["RestartFreq"], - self.RunSteps, - ) - - # auto calculate the best CheckpointFreq for the number of self.RunSteps - self.CheckpointFreq = _scale_gen_freq_for_run_steps_list_bool_int( - "CheckpointFreq", - default_input_variables_dict["CheckpointFreq"], - self.RunSteps, - ) - - # auto calculate the best CoordinatesFreq for the number of self.RunSteps - self.CoordinatesFreq = _scale_gen_freq_for_run_steps_list_bool_int( - "CoordinatesFreq", - default_input_variables_dict["CoordinatesFreq"], - self.RunSteps, - ) - - # auto calculate the best DCDFreq for the number of self.RunSteps - self.DCDFreq = _scale_gen_freq_for_run_steps_list_bool_int( - "DCDFreq", default_input_variables_dict["DCDFreq"], self.RunSteps - ) - - # auto calculate the best ConsoleFreq for the number of self.RunSteps - self.ConsoleFreq = _scale_gen_freq_for_run_steps_list_bool_int( - "ConsoleFreq", - default_input_variables_dict["ConsoleFreq"], - self.RunSteps, - ) - - # auto calculate the best PressureCalc for the number of self.RunSteps - self.PressureCalc = _scale_gen_freq_for_run_steps_list_bool_int( - "PressureCalc", - default_input_variables_dict["PressureCalc"], - self.RunSteps, - ) - - # auto calculate the best BlockAverageFreq for the number of self.RunSteps - self.BlockAverageFreq = _scale_gen_freq_for_run_steps_list_bool_int( - "BlockAverageFreq", - default_input_variables_dict["BlockAverageFreq"], - self.RunSteps, - ) - - # auto calculate the best HistogramFreq for the number of self.RunSteps - self.HistogramFreq = _scale_gen_freq_for_run_steps_list_bool_int( - "HistogramFreq", - default_input_variables_dict["HistogramFreq"], - self.RunSteps, - ) - - # auto calculate the best SampleFreq for the number of self.RunSteps - self.SampleFreq = _scale_gen_freq_for_run_steps_int( - "SampleFreq", - default_input_variables_dict["SampleFreq"], - self.RunSteps, - ) - - if input_variables_dict is None: - self.input_variables_dict = {} - elif isinstance(input_variables_dict, dict) is True: - self.input_variables_dict = input_variables_dict - else: - self.input_error = True - print_error_message = "ERROR: The input_variables_dict variable is not None or a dictionary." - raise ValueError(print_error_message) - - # Create all lower case spelled keywords, and return case specific keywords - # Also, creates a dict to convert the lower case keys to case sensitive keys - all_input_var_case_spec_list = _get_all_possible_input_variables( - description=False - ) - all_input_var_case_unspec_list = [] - all_input_var_case_unspec_to_spec_dict = {} - for var_i in all_input_var_case_spec_list: - all_input_var_case_unspec_list.append(var_i.lower()) - all_input_var_case_unspec_to_spec_dict.update( - {var_i.lower(): var_i} - ) - - # create/fix user case insensitive input variables (input_variables_dict) keys to case sensitive keys - input_var_dict_orig_keys_list = dict_keys_to_list( - self.input_variables_dict - ) - for z_j in range(0, len(input_var_dict_orig_keys_list)): - key_lower = input_var_dict_orig_keys_list[z_j].lower() - if key_lower in all_input_var_case_unspec_list: - input_variables_dict[ - all_input_var_case_unspec_to_spec_dict[key_lower] - ] = input_variables_dict.pop(input_var_dict_orig_keys_list[z_j]) - - # check that the coulombic 1-4 scalar is : 0 =< 1-4 scalar <=1 - if ( - ( - isinstance(self.coul_1_4, int) is False - and isinstance(self.coul_1_4, float) is False - ) - or self.coul_1_4 < 0 - or self.coul_1_4 > 1 - ): - self.input_error = True - print_error_message = ( - "ERROR: The selected 1-4 Coulombic scalar ({{) is not correct. " - "The 1-4 Coulombic scalar need to be an integer or float from " - "0 to 1.".format(self.coul_1_4) - ) - raise ValueError(print_error_message) - - # check that the Temperature is valid - if self.Temperature <= 1: - self.input_error = True - print_error_message = ( - "ERROR: The selected Temperature ({}) is equal to or less than 1 Kelvin. " - "Please select a valid Temperature".format(self.Temperature) - ) - raise ValueError(print_error_message) - else: - print( - "INFO: All the Temperature (Temperature) input passed the initial error checking" - ) - - # RunSteps - if not isinstance(self.RunSteps, int) or self.RunSteps <= 0: - self.input_error = True - print_error_message = ( - "ERROR: The selected run steps (RunSteps variable = {}) is not " - "an integer or is less than or equal to 0.".format( - self.RunSteps - ) - ) - raise ValueError(print_error_message) - - # create a list of the possible required files and check them based on the ensemble - required_data_list = [ - self.ff_filename, - self.Coordinates_box_0, - self.Structure_box_0, - ] - - if self.Coordinates_box_1 is not None: - required_data_list.append(self.Coordinates_box_1) - if self.Structure_box_1 is not None: - required_data_list.append(self.Structure_box_1) - - if self.ensemble_type in ["NVT", "NPT"]: - if ( - len(required_data_list) != 3 - or os.path.splitext(self.ff_filename)[1] not in [".inp", ".par"] - or os.path.splitext(self.Coordinates_box_0)[1] != ".pdb" - or os.path.splitext(self.Structure_box_0)[1] != ".psf" - ): - self.input_error = True - print_error_message = ( - "ERROR: The proper force field, PDB, and psf files were not provided, " - "or at least their extentions are not correct " - "(i.e., not .inp, .par, .pdb, or .psf). Or box 1 PSF and PDB files were " - "provided for the NVT or NPT simulations, which is not allowed" - ) - raise ValueError(print_error_message) - - else: - print( - "INFO: All the required force field, pdb, and psf files for box 0 (.inp, .pdb, and .psf) all " - "passed the intial error checking. Note: the file names and their existance is not confirmed." - ) - - if self.ensemble_type in ["GEMC_NVT", "GEMC_NPT", "GCMC"]: - if ( - len(required_data_list) != 5 - or os.path.splitext(self.ff_filename)[1] not in [".inp", ".par"] - or os.path.splitext(self.Coordinates_box_0)[1] != ".pdb" - or os.path.splitext(self.Structure_box_0)[1] != ".psf" - or os.path.splitext(self.Coordinates_box_1)[1] != ".pdb" - or os.path.splitext(self.Structure_box_1)[1] != ".psf" - ): - print_error_message = ( - "ERROR: The proper force field, PDB, and psf files were not provided, " - "or at least their extentions are not correct " - "(i.e., not .inp, .par, .pdb, or .psf). Or box 1 PSF and PDB files were not provided " - "for the GEMC_NVT, GEMC_NPT or GCMC simulations, which is not allowed" - ) - self.input_error = True - raise ValueError(print_error_message) - else: - print( - "INFO: All the required force field, pdb, and psf files for box 0 and 1 (.inp, .pdb, and .psf) all " - "passed the intial error checking. Note: the file names and their existance is not confirmed." - ) - - # verify all input variables keys are valid - input_variables_dict_keys_list = dict_keys_to_list( - self.input_variables_dict - ) - if ( - check_valid_ensemble_input_variables( - self.ensemble_type, input_variables_dict_keys_list - )[0] - is False - ): - returned_ck_bad_inputs_list = check_valid_ensemble_input_variables( - self.ensemble_type, input_variables_dict_keys_list - )[1] - self.input_error = True - print_error_message = ( - "ERROR: All the correct input variables where not provided for the {} " - "ensemble. Please be sure to check that the keys in the " - "input variables dictionary (input_variables_dict) is correct, and be aware " - "that added spaces before or after the variable in any keys " - "will also give this warning. The bad variable inputs " - "ensemble inputs = {}".format( - self.ensemble_type, returned_ck_bad_inputs_list - ) - ) - raise ValueError(print_error_message) - - # verify all input variable values are valid, for their keys - input_var_all_keys_list = dict_keys_to_list(self.input_variables_dict) - # sort to only values that are not None - input_var_keys_list = [] - for all_keys_i in input_var_all_keys_list: - if self.input_variables_dict[all_keys_i] is not None: - input_var_keys_list.append(all_keys_i) - - possible_ensemble_variables_list = ( - _get_possible_ensemble_input_variables(self.ensemble_type) - ) - - # check to make sure the VDW FF (ParaTypeCHARMM) is set true for multiple ones by the user - # (i.e., ParaTypeCHARMM, ParaTypeMie, ParaTypeMARTINI) - vdw_ck_list = [] - for vdw_ck_inter in range(0, len(input_var_keys_list)): - if ( - input_var_keys_list[vdw_ck_inter] - in ["ParaTypeCHARMM", "ParaTypeMie", "ParaTypeMARTINI"] - and self.input_variables_dict[input_var_keys_list[vdw_ck_inter]] - is True - ): - vdw_ck_list.append(True) - - if sum(vdw_ck_list) > 1: - self.input_error = True - print_error_message = ( - "ERROR: there can only be 1 VDW set to true. Please set only one of the " - "ParaTypeCHARMM, ParaTypeMie, ParaTypeMARTINI types to True in the " - "user variable input" - ) - raise ValueError(print_error_message) - - # check for MC move ratios and zero all of them if any are in the input variables - for var_iter in range(0, len(input_var_keys_list)): - # standard MC moves - key_move_list = [ - "DisFreq", - "RotFreq", - "IntraSwapFreq", - "SwapFreq", - "RegrowthFreq", - "CrankShaftFreq", - "VolFreq", - "MultiParticleFreq", - "IntraMEMC-1Freq", - "MEMC-1Freq", - "IntraMEMC-2Freq", - "MEMC-2Freq", - "IntraMEMC-3Freq", - "MEMC-3Freq", - "TargetedSwapFreq", - "IntraTargetedSwapFreq", - ] - - if input_var_keys_list[var_iter] in key_move_list: - self.DisFreq = 0.00 - self.RotFreq = 0.00 - self.IntraSwapFreq = 0.00 - self.SwapFreq = 0.00 - self.RegrowthFreq = 0.00 - self.CrankShaftFreq = 0.00 - self.VolFreq = 0.00 - self.MultiParticleFreq = 0.00 - self.IntraMEMC_1Freq = 0.00 - self.MEMC_1Freq = 0.00 - self.IntraMEMC_2Freq = 0.00 - self.MEMC_2Freq = 0.00 - self.IntraMEMC_3Freq = 0.00 - self.MEMC_3Freq = 0.00 - self.TargetedSwapFreq = 0.00 - self.IntraTargetedSwapFreq = 0.00 - - # set all the "RcutLow", "Rcut", "Rswitch" variable ahead of time so they can check the values - # relative to each other in the next interation, regardless of their user entered order - if input_var_keys_list[var_iter] == "Rcut": - self.Rcut = self.input_variables_dict["Rcut"] - - if input_var_keys_list[var_iter] == "RcutLow": - self.RcutLow = self.input_variables_dict["RcutLow"] - - if input_var_keys_list[var_iter] == "Rswitch": - self.Rswitch = self.input_variables_dict["Rswitch"] - - if input_var_keys_list[var_iter] == "Potential": - self.Potential = self.input_variables_dict["Potential"] - - # check for bad input variables and list the bad ones - for var_iter in range(0, len(input_var_keys_list)): - key = "PRNG" - if input_var_keys_list[var_iter] == key: - if ( - self.input_variables_dict[key] != "RANDOM" - and isinstance(self.input_variables_dict[key], int) - is not True - ): - bad_input_variables_values_list.append(key) - if isinstance(self.input_variables_dict[key], int) is True: - if self.input_variables_dict[key] < 0: - bad_input_variables_values_list.append(key) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.PRNG = self.input_variables_dict[key] - - key = "ParaTypeCHARMM" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ParaTypeCHARMM = self.input_variables_dict[key] - if self.input_variables_dict[key] is True: - self.ParaTypeMie = False - self.ParaTypeMARTINI = False - - key = "ParaTypeMie" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ParaTypeMie = self.input_variables_dict[key] - if self.input_variables_dict[key] is True: - self.ParaTypeCHARMM = False - - key = "ParaTypeMARTINI" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ParaTypeMARTINI = self.input_variables_dict[key] - if self.input_variables_dict[key] is True: - self.ParaTypeCHARMM = False - - key = "RcutCoulomb_box_0" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.RcutCoulomb_box_0 = self.input_variables_dict[key] - - key = "RcutCoulomb_box_1" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.RcutCoulomb_box_1 = self.input_variables_dict[key] - - key = "Pressure" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.Pressure = self.input_variables_dict[key] - - key = "Rcut" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.Rcut = self.input_variables_dict[key] - - key = "RcutLow" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - if isinstance( - self.input_variables_dict[key], float - ) or isinstance(self.input_variables_dict[key], int): - if self.input_variables_dict[key] > self.Rcut: - bad_input_variables_values_list.append(key) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.RcutLow = self.input_variables_dict[key] - - key = "LRC" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.LRC = self.input_variables_dict[key] - - key = "IPC" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.IPC = self.input_variables_dict[key] - - key = "Exclude" - if input_var_keys_list[var_iter] == key: - if ( - self.input_variables_dict[key] != "1-2" - and self.input_variables_dict[key] != "1-3" - and self.input_variables_dict[key] != "1-4" - ): - bad_input_variables_values_list.append(key) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.Exclude = self.input_variables_dict[key] - - key = "Potential" - if input_var_keys_list[var_iter] == key: - if ( - self.input_variables_dict[key] != "VDW" - and self.input_variables_dict[key] != "EXP6" - and self.input_variables_dict[key] != "SHIFT" - and self.input_variables_dict[key] != "SWITCH" - ): - bad_input_variables_values_list.append(key) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.Potential = self.input_variables_dict[key] - - key = "Rswitch" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - ( - isinstance(self.input_variables_dict[key], float) - or isinstance(self.input_variables_dict[key], int) - ) - and ( - isinstance(self.RcutLow, float) - or isinstance(self.RcutLow, int) - ) - and ( - isinstance(self.Rcut, float) - or isinstance(self.Rcut, int) - ) - and self.Potential == "SWITCH" - ): - if ( - self.input_variables_dict[key] <= self.RcutLow - or self.input_variables_dict[key] >= self.Rcut - ): - bad_input_variables_values_list.append(key) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.Rswitch = self.input_variables_dict[key] - - key = "ElectroStatic" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ElectroStatic = self.input_variables_dict[key] - - key = "Ewald" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.Ewald = self.input_variables_dict[key] - - key = "CachedFourier" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.CachedFourier = self.input_variables_dict[key] - - key = "Tolerance" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_float_greater_zero_less_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.Tolerance = self.input_variables_dict[key] - - key = "Dielectric" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.Dielectric = self.input_variables_dict[key] - - key = "PressureCalc" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_int_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.PressureCalc = self.input_variables_dict[key] - - key = "EqSteps" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.EqSteps = self.input_variables_dict[key] - - key = "AdjSteps" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.AdjSteps = self.input_variables_dict[key] - - key = "VDWGeometricSigma" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.VDWGeometricSigma = self.input_variables_dict[key] - - key = "useConstantArea" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.useConstantArea = self.input_variables_dict[key] - - key = "FixVolBox0" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.FixVolBox0 = self.input_variables_dict[key] - - # ChemPot and Fugacity are only for GCMC - key = "ChemPot" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_GCMC_dict_str_int_or_float( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ChemPot = self.input_variables_dict[key] - - key = "Fugacity" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_GCMC_dict_str_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.Fugacity = self.input_variables_dict[key] - - key = "CBMC_First" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.CBMC_First = self.input_variables_dict[key] - - key = "CBMC_Nth" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.CBMC_Nth = self.input_variables_dict[key] - - key = "CBMC_Ang" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.CBMC_Ang = self.input_variables_dict[key] - - key = "CBMC_Dih" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.CBMC_Dih = self.input_variables_dict[key] - - key = "OutputName" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_str_with_no_spaces( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.OutputName = self.input_variables_dict[key] - - key = "CoordinatesFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.CoordinatesFreq = self.input_variables_dict[key] - - key = "DCDFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.DCDFreq = self.input_variables_dict[key] - - key = "RestartFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.RestartFreq = self.input_variables_dict[key] - - key = "CheckpointFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.CheckpointFreq = self.input_variables_dict[key] - - key = "ConsoleFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ConsoleFreq = self.input_variables_dict[key] - - key = "BlockAverageFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.BlockAverageFreq = self.input_variables_dict[key] - - key = "HistogramFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.HistogramFreq = self.input_variables_dict[key] - - key = "DistName" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_str_with_no_spaces( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.DistName = self.input_variables_dict[key] - - key = "HistName" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_str_with_no_spaces( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.HistName = self.input_variables_dict[key] - - key = "RunNumber" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.RunNumber = self.input_variables_dict[key] - - key = "RunLetter" - if input_var_keys_list[var_iter] == key: - if isinstance(self.input_variables_dict[key], str) is not True: - bad_input_variables_values_list.append(key) - if isinstance(self.input_variables_dict[key], str) is True: - if len(self.input_variables_dict[key]) != 1: - bad_input_variables_values_list.append(key) - elif len(self.input_variables_dict[key]) == 1: - is_run_letter_alphabet_char = self.input_variables_dict[ - key - ].isalpha() - if is_run_letter_alphabet_char is False: - bad_input_variables_values_list.append(key) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.RunLetter = self.input_variables_dict[key] - - key = "SampleFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.SampleFreq = self.input_variables_dict[key] - - key = "OutEnergy" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_bool( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.OutEnergy = self.input_variables_dict[key] - - key = "OutPressure" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_bool( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.OutPressure = self.input_variables_dict[key] - - key = "OutMolNum" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_bool( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.OutMolNum = self.input_variables_dict[key] - - key = "OutDensity" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_bool( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.OutDensity = self.input_variables_dict[key] - - key = "OutVolume" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_bool( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.OutVolume = self.input_variables_dict[key] - - key = "OutSurfaceTension" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_bool( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.OutSurfaceTension = self.input_variables_dict[key] - - key = "FreeEnergyCalc" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_bool_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.FreeEnergyCalc = self.input_variables_dict[key] - - key = "MoleculeType" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_residue_str_int_greater_zero( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.MoleculeType = self.input_variables_dict[key] - - key = "InitialState" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.InitialState = self.input_variables_dict[key] - - key = "LambdaVDW" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_of_floats_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.LambdaVDW = self.input_variables_dict[key] - - key = "LambdaCoulomb" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_list_of_floats_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.LambdaCoulomb = self.input_variables_dict[key] - - key = "ScaleCoulomb" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_true_or_false( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ScaleCoulomb = self.input_variables_dict[key] - - key = "ScalePower" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ScalePower = self.input_variables_dict[key] - - key = "ScaleAlpha" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ScaleAlpha = self.input_variables_dict[key] - - key = "MinSigma" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_or_greater( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.MinSigma = self.input_variables_dict[key] - - # standard MC moves - key = "DisFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.DisFreq = self.input_variables_dict[key] - - key = "RotFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.RotFreq = self.input_variables_dict[key] - - key = "IntraSwapFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.IntraSwapFreq = self.input_variables_dict[key] - - key = "SwapFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.SwapFreq = self.input_variables_dict[key] - else: - self.VolFreq = 0.00 - - key = "RegrowthFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.RegrowthFreq = self.input_variables_dict[key] - - key = "CrankShaftFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.CrankShaftFreq = self.input_variables_dict[key] - - key = "VolFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.VolFreq = self.input_variables_dict[key] - else: - self.VolFreq = 0.00 - - key = "MultiParticleFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.MultiParticleFreq = self.input_variables_dict[key] - - # MEMC moves freqencies - key = "IntraMEMC-1Freq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.IntraMEMC_1Freq = self.input_variables_dict[key] - else: - self.IntraMEMC_1Freq = 0.00 - - key = "MEMC-1Freq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.MEMC_1Freq = self.input_variables_dict[key] - else: - self.MEMC_1Freq = 0.00 - - key = "IntraMEMC-2Freq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.IntraMEMC_2Freq = self.input_variables_dict[key] - else: - self.IntraMEMC_2Freq = 0.00 - - key = "MEMC-2Freq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.MEMC_2Freq = self.input_variables_dict[key] - else: - self.MEMC_2Freq = 0.00 - - key = "IntraMEMC-3Freq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.IntraMEMC_3Freq = self.input_variables_dict[key] - else: - self.IntraMEMC_3Freq = 0.00 - - key = "MEMC-3Freq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.MEMC_3Freq = self.input_variables_dict[key] - else: - self.MEMC_3Freq = 0.00 - - key = "ExchangeVolumeDim" - if input_var_keys_list[var_iter] == key: - if isinstance(self.input_variables_dict[key], list) is False: - bad_input_variables_values_list.append(key) - elif isinstance(self.input_variables_dict[key], list) is True: - if ( - len(self.input_variables_dict[key]) != 3 - or ( - isinstance(self.input_variables_dict[key][0], float) - is not True - and isinstance( - self.input_variables_dict[key][0], int - ) - is not True - ) - or ( - isinstance(self.input_variables_dict[key][1], float) - is not True - and isinstance( - self.input_variables_dict[key][1], int - ) - is not True - ) - or ( - isinstance(self.input_variables_dict[key][2], float) - is not True - and isinstance( - self.input_variables_dict[key][2], int - ) - is not True - ) - or str(self.input_variables_dict[key][0]) == str(True) - or str(self.input_variables_dict[key][0]) == str(False) - or str(self.input_variables_dict[key][1]) == str(True) - or str(self.input_variables_dict[key][1]) == str(False) - or str(self.input_variables_dict[key][2]) == str(True) - or str(self.input_variables_dict[key][2]) == str(False) - ): - bad_input_variables_values_list.append(key) - elif len(self.input_variables_dict[key]) == 3: - if ( - ( - isinstance( - self.input_variables_dict[key][0], float - ) - is True - or isinstance( - self.input_variables_dict[key][0], int - ) - is True - ) - and ( - isinstance( - self.input_variables_dict[key][1], float - ) - is True - or isinstance( - self.input_variables_dict[key][1], int - ) - is True - ) - and ( - isinstance( - self.input_variables_dict[key][2], float - ) - is True - or isinstance( - self.input_variables_dict[key][2], int - ) - is True - ) - ): - if ( - self.input_variables_dict[key][0] <= 0 - or self.input_variables_dict[key][1] <= 0 - or self.input_variables_dict[key][2] <= 0 - ): - bad_input_variables_values_list.append(key) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.ExchangeVolumeDim = self.input_variables_dict[key] - - key = "MEMC_DataInput" - if input_var_keys_list[var_iter] == key: - if isinstance(self.input_variables_dict[key], list) is False: - bad_input_variables_values_list.append(key) - elif isinstance(self.input_variables_dict[key], list) is True: - if len(self.input_variables_dict[key]) == 0: - bad_input_variables_values_list.append(key) - elif len(self.input_variables_dict[key]) > 0: - no_memc_combos = len(self.input_variables_dict[key]) - for MEMC_iter in range(0, no_memc_combos): - if ( - isinstance( - self.input_variables_dict[key][MEMC_iter], - list, - ) - is False - ): - bad_input_variables_values_list.append(key) - elif ( - isinstance( - self.input_variables_dict[key][MEMC_iter], - list, - ) - is True - and len( - self.input_variables_dict[key][MEMC_iter] - ) - == 5 - ): - if ( - isinstance( - self.input_variables_dict[key][ - MEMC_iter - ][2], - list, - ) - is False - or isinstance( - self.input_variables_dict[key][ - MEMC_iter - ][4], - list, - ) - is False - ): - bad_input_variables_values_list.append(key) - elif ( - isinstance( - self.input_variables_dict[key][ - MEMC_iter - ][2], - list, - ) - is True - and isinstance( - self.input_variables_dict[key][ - MEMC_iter - ][4], - list, - ) - is True - ): - if ( - len( - self.input_variables_dict[key][ - MEMC_iter - ][2] - ) - != 2 - or len( - self.input_variables_dict[key][ - MEMC_iter - ][4] - ) - != 2 - ): - bad_input_variables_values_list.append( - key - ) - elif ( - len( - self.input_variables_dict[key][ - MEMC_iter - ][2] - ) - == 2 - and len( - self.input_variables_dict[key][ - MEMC_iter - ][4] - ) - == 2 - ): - if ( - isinstance( - self.input_variables_dict[key][ - MEMC_iter - ][0], - int, - ) - is not True - or str( - self.input_variables_dict[key][ - MEMC_iter - ][0] - ) - == str(True) - or str( - self.input_variables_dict[key][ - MEMC_iter - ][0] - ) - == str(False) - or isinstance( - self.input_variables_dict[key][ - MEMC_iter - ][1], - str, - ) - is False - or ( - isinstance( - self.input_variables_dict[ - key - ][MEMC_iter][2][0], - str, - ) - is False - and self.input_variables_dict[ - key - ][MEMC_iter][2][0] - is not None - ) - or ( - isinstance( - self.input_variables_dict[ - key - ][MEMC_iter][2][1], - str, - ) - is False - and self.input_variables_dict[ - key - ][MEMC_iter][2][1] - is not None - ) - or isinstance( - self.input_variables_dict[key][ - MEMC_iter - ][3], - str, - ) - is False - or ( - isinstance( - self.input_variables_dict[ - key - ][MEMC_iter][4][0], - str, - ) - is False - and self.input_variables_dict[ - key - ][MEMC_iter][4][0] - is not None - ) - or ( - isinstance( - self.input_variables_dict[ - key - ][MEMC_iter][4][1], - str, - ) - is False - and self.input_variables_dict[ - key - ][MEMC_iter][4][1] - is not None - ) - ): - bad_input_variables_values_list.append( - key - ) - else: - bad_input_variables_values_list.append( - key - ) - - all_atom_names_and_res_pairs_keys_list = list( - self.all_residues_unique_atom_name_dict.keys() - ) - # check that the atom names match the residues that exist - if ( - self.input_variables_dict[key][ - MEMC_iter - ][1] - not in all_atom_names_and_res_pairs_keys_list - ): - bad_input_variables_values_list.append( - key - ) - - elif ( - self.input_variables_dict[key][ - MEMC_iter - ][1] - in all_atom_names_and_res_pairs_keys_list - ): - if ( - self.input_variables_dict[key][ - MEMC_iter - ][2][0] - not in self.all_residues_unique_atom_name_dict[ - self.input_variables_dict[key][ - MEMC_iter - ][1] - ] - ): - bad_input_variables_values_list.append( - key - ) - - if ( - self.input_variables_dict[key][ - MEMC_iter - ][2][1] - not in self.all_residues_unique_atom_name_dict[ - self.input_variables_dict[key][ - MEMC_iter - ][1] - ] - ): - bad_input_variables_values_list.append( - key - ) - - if ( - self.input_variables_dict[key][ - MEMC_iter - ][3] - not in all_atom_names_and_res_pairs_keys_list - ): - bad_input_variables_values_list.append( - key - ) - - elif ( - self.input_variables_dict[key][ - MEMC_iter - ][3] - in all_atom_names_and_res_pairs_keys_list - ): - if ( - self.input_variables_dict[key][ - MEMC_iter - ][4][0] - not in self.all_residues_unique_atom_name_dict[ - self.input_variables_dict[key][ - MEMC_iter - ][3] - ] - ): - bad_input_variables_values_list.append( - key - ) - - if ( - self.input_variables_dict[key][ - MEMC_iter - ][4][1] - not in self.all_residues_unique_atom_name_dict[ - self.input_variables_dict[key][ - MEMC_iter - ][3] - ] - ): - bad_input_variables_values_list.append( - key - ) - - if ( - isinstance( - self.input_variables_dict[key][ - MEMC_iter - ][0], - int, - ) - is True - ): - if ( - self.input_variables_dict[key][ - MEMC_iter - ][0] - <= 0 - ): - bad_input_variables_values_list.append( - key - ) - - else: - bad_input_variables_values_list.append(key) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.MEMC_DataInput = self.input_variables_dict[key] - - key = "TargetedSwapFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.TargetedSwapFreq = self.input_variables_dict[key] - else: - self.TargetedSwapFreq = 0.00 - - key = "IntraTargetedSwapFreq" - if input_var_keys_list[var_iter] == key: - self.ck_input_variable_int_or_float_zero_to_1( - self.input_variables_dict, - key, - bad_input_variables_values_list, - ) - - if ( - input_var_keys_list[var_iter] == key - and key in possible_ensemble_variables_list - ): - self.IntraTargetedSwapFreq = self.input_variables_dict[key] - else: - self.IntraTargetedSwapFreq = 0.00 - - key = "TargetedSwap_DataInput" - if input_var_keys_list[var_iter] == key: - # get all residues - all_residue_names_list = list( - self.all_residues_unique_atom_name_dict.keys() - ) - target_swap_dict = self.input_variables_dict[ - input_var_keys_list[var_iter] - ] - - target_swap_input_error = ( - "The TargetedSwap_DataInput is not formatted correctly as a dictionary" - " or has the wrong input keys, values, or types." - ) - if isinstance(target_swap_dict, dict): - for tag_i in list(target_swap_dict.keys()): - # check all tag ids are integers - if not isinstance(tag_i, int): - raise ValueError(target_swap_input_error) - for ts_dict_key_i in list( - target_swap_dict[tag_i].keys() - ): - # check all target swap data inputs keys are strings - if not isinstance(ts_dict_key_i, str): - raise ValueError(target_swap_input_error) - # force all keys to lower case - elif isinstance(ts_dict_key_i, str): - target_swap_dict[tag_i][ - ts_dict_key_i.lower() - ] = target_swap_dict[tag_i].pop(ts_dict_key_i) - # verify all Target swap keys are valid - valid_target_swap_keys = [ - "subvolumetype", - "subvolumebox", - "subvolumecenter", - "subvolumecenterlist", - "subvolumedim", - "subvolumeresiduekind", - "subvolumerigidswap", - "subvolumepbc", - "subvolumechempot", - "subvolumefugacity", - ] - if ( - ts_dict_key_i.lower() - not in valid_target_swap_keys - ): - raise ValueError(target_swap_input_error) - - # check the SubVolumeResidueKind is list of n length or convert string to list - # this SubVolumeResidueKind reformating needs done first before the other checks, - # specifically, the SubVolumeFugacity and SubVolumeChemPot - if ts_dict_key_i.lower() in [ - "subvolumeresiduekind" - ]: - if not isinstance( - target_swap_dict[tag_i][ - "subvolumeresiduekind" - ], - list, - ) and not isinstance( - target_swap_dict[tag_i][ - "subvolumeresiduekind" - ], - str, - ): - bad_input_variables_values_list.append( - "subvolumeresiduekind" - ) - elif ( - isinstance( - target_swap_dict[tag_i][ - "subvolumeresiduekind" - ], - list, - ) - and len( - target_swap_dict[tag_i][ - "subvolumeresiduekind" - ] - ) - >= 1 - ): - for ts_residue_i in target_swap_dict[tag_i][ - "subvolumeresiduekind" - ]: - if not isinstance(ts_residue_i, str): - bad_input_variables_values_list.append( - "subvolumeresiduekind" - ) - elif ( - ts_residue_i - not in all_residue_names_list - and ts_residue_i.lower() - not in ["all"] - ): - bad_input_variables_values_list.append( - "subvolumeresiduekind" - ) - elif ts_residue_i.lower() in ["all"]: - self.input_variables_dict[ - input_var_keys_list[var_iter] - ][tag_i]["subvolumeresiduekind"] = [ - "ALL" - ] - elif ( - target_swap_dict[tag_i][ - "subvolumeresiduekind" - ].lower() - == "all" - ): - self.input_variables_dict[ - input_var_keys_list[var_iter] - ][tag_i]["subvolumeresiduekind"] = ["ALL"] - elif ( - target_swap_dict[tag_i][ - "subvolumeresiduekind" - ] - in all_residue_names_list - ): - self.input_variables_dict[ - input_var_keys_list[var_iter] - ][tag_i]["subvolumeresiduekind"] = [ - target_swap_dict[tag_i][ - "subvolumeresiduekind" - ] - ] - else: - bad_input_variables_values_list.append( - "subvolumeresiduekind" - ) - else: - raise ValueError(target_swap_input_error) - - if isinstance(target_swap_dict, dict): - for tag_id_keys_i in list(target_swap_dict.keys()): - target_swap_tag_id_dict_key_data = target_swap_dict[ - tag_id_keys_i - ] - - for target_swap_dict_key_i_lower in list( - target_swap_tag_id_dict_key_data.keys() - ): - # check the SubVolumeType are either "Static", or "Dynamic" - if target_swap_dict_key_i_lower in [ - "subvolumetype" - ]: - if not isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumetype" - ], - str, - ): - bad_input_variables_values_list.append( - "subvolumetype" - ) - elif target_swap_tag_id_dict_key_data[ - "subvolumetype" - ].lower() not in ["static", "dynamic"]: - bad_input_variables_values_list.append( - "subvolumetype" - ) - - # check for the SubVolumeCenter if its a static box - elif target_swap_tag_id_dict_key_data[ - "subvolumetype" - ].lower() in ["static"]: - if ( - "subvolumecenter" - in target_swap_tag_id_dict_key_data - ): - if not isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumecenter" - ], - list, - ): - bad_input_variables_values_list.append( - "subvolumecenter" - ) - elif ( - isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumecenter" - ], - list, - ) - and len( - target_swap_tag_id_dict_key_data[ - "subvolumecenter" - ] - ) - == 3 - ): - for ( - x_y_z_dim_i - ) in target_swap_tag_id_dict_key_data[ - "subvolumecenter" - ]: - if not isinstance( - x_y_z_dim_i, (int, float) - ): - bad_input_variables_values_list.append( - "subvolumecenter" - ) - else: - bad_input_variables_values_list.append( - "subvolumecenter" - ) - else: - bad_input_variables_values_list.append( - "subvolumecenter" - ) - - # check for the SubVolumeCenterList if its a dynamic box - elif target_swap_tag_id_dict_key_data[ - "subvolumetype" - ].lower() in ["dynamic"]: - if ( - "subvolumecenterlist" - in target_swap_tag_id_dict_key_data - ): - if isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumecenterlist" - ], - list, - ): - for ( - atom_index_dim_i - ) in target_swap_tag_id_dict_key_data[ - "subvolumecenterlist" - ]: - if isinstance( - atom_index_dim_i, int - ): - if atom_index_dim_i < 0: - bad_input_variables_values_list.append( - "subvolumecenterlist" - ) - elif isinstance( - atom_index_dim_i, str - ): - atom_index_split_str = ( - atom_index_dim_i.split( - "-" - ) - ) - if ( - len( - atom_index_split_str - ) - == 2 - and atom_index_dim_i.find( - "." - ) - < 0 - ): - try: - if ( - not isinstance( - int( - atom_index_split_str[ - 0 - ] - ), - int, - ) - or not isinstance( - int( - atom_index_split_str[ - 1 - ] - ), - int, - ) - or int( - atom_index_split_str[ - 0 - ] - ) - >= int( - atom_index_split_str[ - 1 - ] - ) - or atom_index_split_str[ - 0 - ] - == "" - or atom_index_split_str[ - 1 - ] - == "" - ): - bad_input_variables_values_list.append( - "subvolumecenterlist" - ) - except: - bad_input_variables_values_list.append( - "subvolumecenterlist" - ) - else: - bad_input_variables_values_list.append( - "subvolumecenterlist" - ) - else: - bad_input_variables_values_list.append( - "subvolumecenterlist" - ) - else: - bad_input_variables_values_list.append( - "subvolumecenterlist" - ) - else: - bad_input_variables_values_list.append( - "subvolumecenterlist" - ) - - # check the SubVolumeBox is an interger of 0 or 1 - if target_swap_dict_key_i_lower in ["subvolumebox"]: - if isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumebox" - ], - int, - ): - if self.ensemble_type in [ - "GEMC_NVT", - "GEMC_NPT", - ]: - if ( - target_swap_tag_id_dict_key_data[ - "subvolumebox" - ] - != 0 - and target_swap_tag_id_dict_key_data[ - "subvolumebox" - ] - != 1 - ): - bad_input_variables_values_list.append( - "subvolumebox" - ) - elif self.ensemble_type in [ - "GCMC", - "NVT", - "NPT", - ]: - if ( - target_swap_tag_id_dict_key_data[ - "subvolumebox" - ] - != 0 - ): - bad_input_variables_values_list.append( - "subvolumebox" - ) - else: - bad_input_variables_values_list.append( - "subvolumebox" - ) - - # check the SubVolumeDim is list of length 3, [x-dim, y-dim, z-dim] - if target_swap_dict_key_i_lower in ["subvolumedim"]: - if not isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumedim" - ], - list, - ): - bad_input_variables_values_list.append( - "subvolumedim" - ) - elif ( - isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumedim" - ], - list, - ) - and len( - target_swap_tag_id_dict_key_data[ - "subvolumedim" - ] - ) - == 3 - ): - for ( - set_x_y_z_dim_i - ) in target_swap_tag_id_dict_key_data[ - "subvolumedim" - ]: - if not isinstance( - set_x_y_z_dim_i, (int, float) - ): - bad_input_variables_values_list.append( - "subvolumedim" - ) - elif set_x_y_z_dim_i <= 0: - bad_input_variables_values_list.append( - "subvolumedim" - ) - else: - bad_input_variables_values_list.append( - "subvolumedim" - ) - - # check the SubVolumeRigidSwap is bool - if target_swap_dict_key_i_lower in [ - "subvolumerigidswap" - ]: - if not isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumerigidswap" - ], - bool, - ): - bad_input_variables_values_list.append( - "subvolumerigidswap" - ) - - # check the SubVolumePBC is str of only 'X' 'XY' or 'XYZ' - if target_swap_dict_key_i_lower in ["subvolumepbc"]: - if not isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumepbc" - ], - str, - ): - bad_input_variables_values_list.append( - "subvolumepbc" - ) - elif isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumepbc" - ], - str, - ) and target_swap_tag_id_dict_key_data[ - "subvolumepbc" - ].upper() in [ - "X", - "XY", - "XZ", - "XYZ", - "Y", - "YZ", - "Z", - ]: - self.input_variables_dict[ - input_var_keys_list[var_iter] - ][tag_id_keys_i][ - "subvolumepbc" - ] = target_swap_tag_id_dict_key_data[ - "subvolumepbc" - ].upper() - else: - bad_input_variables_values_list.append( - "subvolumepbc" - ) - - # check the SubVolumeChempot and is dict {'resname_str': value} - if target_swap_dict_key_i_lower in [ - "subvolumechempot" - ]: - if not isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumechempot" - ], - dict, - ): - bad_input_variables_values_list.append( - "subvolumechempot" - ) - - elif isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumechempot" - ], - dict, - ): - self.ck_input_variable_GCMC_dict_str_int_or_float( - target_swap_tag_id_dict_key_data, - "subvolumechempot", - bad_input_variables_values_list, - ) - for res_in_sub_chempot_i in list( - target_swap_tag_id_dict_key_data[ - "subvolumechempot" - ].keys() - ): - if ( - res_in_sub_chempot_i - not in all_residue_names_list - ): - bad_input_variables_values_list.append( - "subvolumechempot" - ) - - if "subvolumeresiduekind" in list( - target_swap_tag_id_dict_key_data.keys() - ): - if isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumeresiduekind" - ], - list, - ): - subvolumechempot_res_list = list( - target_swap_tag_id_dict_key_data[ - "subvolumechempot" - ].keys() - ) - subvolumeresiduekind_res_list = list( - target_swap_tag_id_dict_key_data[ - "subvolumeresiduekind" - ] - ) - - for ( - subvolumechempot_res_iter - ) in subvolumechempot_res_list: - if ( - subvolumechempot_res_iter - not in subvolumeresiduekind_res_list - and subvolumeresiduekind_res_list - != ["ALL"] - and subvolumechempot_res_iter - in all_residue_names_list - ): - bad_input_variables_values_list.append( - "subvolumeresiduekind" - ) - - # check the SubVolumefugacity and is dict {'resname_str': value} - if target_swap_dict_key_i_lower in [ - "subvolumefugacity" - ]: - if not isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumefugacity" - ], - dict, - ): - bad_input_variables_values_list.append( - "subvolumefugacity" - ) - - elif isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumefugacity" - ], - dict, - ): - self.ck_input_variable_GCMC_dict_str_int_or_float_zero_or_greater( - target_swap_tag_id_dict_key_data, - "subvolumefugacity", - bad_input_variables_values_list, - ) - - for res_in_sub_chempot_i in list( - target_swap_tag_id_dict_key_data[ - "subvolumefugacity" - ].keys() - ): - if ( - res_in_sub_chempot_i - not in all_residue_names_list - ): - bad_input_variables_values_list.append( - "subvolumefugacity" - ) - - if "subvolumeresiduekind" in list( - target_swap_tag_id_dict_key_data.keys() - ): - if isinstance( - target_swap_tag_id_dict_key_data[ - "subvolumeresiduekind" - ], - list, - ): - subvolumefugacity_res_list = list( - target_swap_tag_id_dict_key_data[ - "subvolumefugacity" - ].keys() - ) - subvolumeresiduekind_res_list = list( - target_swap_tag_id_dict_key_data[ - "subvolumeresiduekind" - ] - ) - - for ( - subvolumefugacity_res_iter - ) in subvolumefugacity_res_list: - if ( - subvolumefugacity_res_iter - not in subvolumeresiduekind_res_list - and subvolumeresiduekind_res_list - != ["ALL"] - and subvolumefugacity_res_iter - in all_residue_names_list - ): - bad_input_variables_values_list.append( - "subvolumeresiduekind" - ) - - self.TargetedSwap_DataInput = self.input_variables_dict[key] - # if not a dict - else: - bad_input_variables_values_list.append(key) - - # Error out and print the bad input values - if len(bad_input_variables_values_list) > 0: - self.input_error = True - # create unique list - bad_input_variables_values_set = set( - bad_input_variables_values_list - ) - bad_unique_input_variables_values_list = list( - bad_input_variables_values_set - ) - print_error_message = ( - "ERROR: The following input variables have " - "bad values (check spelling and for empty spaces in the keys or that " - "the values are in the correct form with the acceptable values): " - "{}".format(bad_unique_input_variables_values_list) - ) - raise ValueError(print_error_message) - - else: - print( - "INFO: All the input variable passed the initial error checking" - ) - - # For the impulse correction term (IPC) is True, check and make sure the LRC is False - # and the potenial is set to VDW or EXP6, otherwise error out. - # If the impulse correction term (IPC) is True and the potenial is set to - # "SHIFT", "SWITCH", or the LRC is True, then error out. - if self.IPC is True and ( - self.LRC is True or (self.Potential in ["SHIFT", "SWITCH"]) - ): - print_error_message = ( - "ERROR: The impulse correction term (IPC) can not be set as True " - "if the LRC=True or the Potential is SHIFT or SWITCH." - ) - raise ValueError(print_error_message) - - if ( - self.IPC is False - and self.LRC is False - and (self.Potential in ["VDW", "EXP6"]) - ): - print_warning_message = ( - "WARNING: The impulse correction term (IPC) is False, but likely needs to be True, " - "as the LRC=False when the Potential is VDW or EXP6." - ) - warn(print_warning_message) - - # check to make sure the VDW FF (ParaTypeCHARMM) is not true for multiple ones - # (i.e., ParaTypeCHARMM, ParaTypeMie, ParaTypeMARTINI) - if ( - (self.ParaTypeCHARMM is True and self.ParaTypeMie is True) - or (self.ParaTypeCHARMM is True and self.ParaTypeMARTINI is True) - or self.ParaTypeMie is True - and self.ParaTypeMARTINI is True - ): - self.input_error = True - print_error_message = ( - "ERROR: there can only be 1 VDW type set to true. Please set only one of the " - "ParaTypeCHARMM = {}, ParaTypeMie = {}, ParaTypeMARTINI = {} types " - "to True".format( - self.ParaTypeCHARMM, self.ParaTypeMie, self.ParaTypeMARTINI - ) - ) - raise ValueError(print_error_message) - elif ( - self.ParaTypeCHARMM is True - or self.ParaTypeMie is True - or self.ParaTypeMARTINI is True - ): - if self.ParaTypeCHARMM is True: - self.VDW_type = "ParaTypeCHARMM" - elif self.ParaTypeMie is True: - self.VDW_type = "ParaTypeMie" - elif self.ParaTypeMARTINI is True: - self.VDW_type = "ParaTypeMARTINI" - else: - self.input_error = True - print_error_message = ( - "ERROR: There no VDW types that are set as True. Please set only one of the " - "ParaTypeCHARMM = {}, ParaTypeMie = {}, ParaTypeMARTINI = {} types " - "to True".format( - self.ParaTypeCHARMM, self.ParaTypeMie, self.ParaTypeMARTINI - ) - ) - raise ValueError(print_error_message) - - # check to see if the moves sum up to 1 - if ensemble_type in ["NVT", "GCMC"]: - if self.VolFreq != 0 and self.ExpertMode is False: - self.input_error = True - print_error_message = ( - "ERROR: The input variable VolFreq is non-zero (0). " - 'VolFreq must be zero (0) for the "NVT", "GEMC_NVT", and "GCMC" ensembles.' - ) - raise ValueError(print_error_message) - - if ensemble_type in ["NVT", "NPT"]: - if ( - self.SwapFreq != 0 - or self.MEMC_1Freq != 0 - or self.MEMC_2Freq != 0 - or self.MEMC_3Freq != 0 - ): - self.input_error = True - print_error_message = ( - "ERROR: All the MC move input variables must be non-zero (0) for the " - "SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq. " - "The SwapFreq, MEMC-1Freq, MEMC-2Freq, " - 'and MEMC-3Freq need to be zero (0) for the "NVT" and "NPT" ensembles.' - ) - raise ValueError(print_error_message) - - moves_list = [ - self.DisFreq, - self.RotFreq, - self.IntraSwapFreq, - self.SwapFreq, - self.RegrowthFreq, - self.CrankShaftFreq, - self.VolFreq, - self.MultiParticleFreq, - self.IntraMEMC_1Freq, - self.MEMC_1Freq, - self.IntraMEMC_2Freq, - self.MEMC_2Freq, - self.IntraMEMC_3Freq, - self.MEMC_3Freq, - self.TargetedSwapFreq, - self.IntraTargetedSwapFreq, - ] - - if sum(moves_list) <= 1 + 10 ** (-13) and sum(moves_list) >= 1 - 10 ** ( - -13 - ): - print( - "INFO: The sum of the Monte Carlo move ratios = " - + str("{:.12f}".format(sum(moves_list))) - ) - - else: - print( - "INFO: sum(moves_list) = " - + str("{:.12f}".format(sum(moves_list))) - ) - print("\t DisFreq = " + str(self.DisFreq)) - print("\t RotFreq = " + str(self.RotFreq)) - print("\t IntraSwapFreq = " + str(self.IntraSwapFreq)) - print("\t SwapFreq = " + str(self.SwapFreq)) - print("\t RegrowthFreq = " + str(self.RegrowthFreq)) - print("\t CrankShaftFreq = " + str(self.CrankShaftFreq)) - print("\t VolFreq = " + str(self.VolFreq)) - print("\t MultiParticleFreq = " + str(self.MultiParticleFreq)) - print("\t IntraMEMC-1Freq = " + str(self.IntraMEMC_1Freq)) - print("\t MEMC-1Freq = " + str(self.MEMC_1Freq)) - print("\t IntraMEMC-2Freq = " + str(self.IntraMEMC_2Freq)) - print("\t MEMC-2Freq = " + str(self.MEMC_2Freq)) - print("\t IntraMEMC-3Freq = " + str(self.IntraMEMC_3Freq)) - print("\t MEMC-3Freq = " + str(self.MEMC_3Freq)) - print("\t TargetedSwapFreq = " + str(self.TargetedSwapFreq)) - print( - "\t IntraTargetedSwapFreq = " + str(self.IntraTargetedSwapFreq) - ) - self.input_error = True - print_error_message = ( - "ERROR: The sum of the Monte Carlo move ratios does not equal 1. " - "Note: The sum that was manually entered may equal 1, but some " - "moves may not be valid for the provided ensemble. The moves " - "that are invalid for a given ensemble are set to zero. If " - "the default moves are not being used, all the move frequencies " - "which do not have default values of zero will need to be set manually " - "so the sum equals (DisFreq, RotFreq, IntraSwapFreq, SwapFreq, " - "RegrowthFreq, CrankShaftFreq, and VolFreq)." - ) - raise ValueError(print_error_message) - - # Check that RunSteps > EqSteps >= AdjSteps - print("self.RunSteps = " + str(self.RunSteps)) - if ( - self.RunSteps <= self.EqSteps - or self.RunSteps < self.AdjSteps - or self.EqSteps < self.AdjSteps - ) and self.Restart is False: - self.input_error = True - print_error_message = ( - "ERROR: When starting a simulation, the values must be in this order RunSteps > EqSteps >= AdjSteps " - "({} > {} >= {})".format( - self.RunSteps, self.EqSteps, self.AdjSteps - ) - ) - raise ValueError(print_error_message) - - elif (self.RunSteps <= self.EqSteps) and self.Restart is True: - self.input_error = True - print_error_message = ( - "ERROR: When restarting a simulation, this must be true RunSteps > EqSteps " - "({} > {})".format(self.RunSteps, self.EqSteps) - ) - raise ValueError(print_error_message) - - # check if both the ChemPot and Fugacity are not set to None. Only one can be used - if ( - self.Fugacity is not None - and self.ChemPot is not None - and self.ensemble_type == "GCMC" - ): - self.input_error = True - print_error_message = ( - "ERROR: In the GCMC ensemble, both Fugacity and ChemPot are provided. " - "Add a dictionary for either the Fugacity or ChemPot and set the other " - "variable to None. Note: Both the Fugacity or ChemPot and set to None by default" - ) - raise ValueError(print_error_message) - - # check that both the ChemPot and Fugacity are set to None. Only one can be used - if ( - self.Fugacity is None - and self.ChemPot is None - and self.ensemble_type == "GCMC" - ): - warn( - "ERROR: In the GCMC ensemble, neither Fugacity and ChemPot are provided (i.e., both are None). " - "Add a dictionary for either the Fugacity or ChemPot and set the other variable to None. " - "Note: Both the Fugacity or ChemPot and set to None by default" - ) - self.input_error = True - print_error_message = ( - "ERROR: In the GCMC ensemble, neither Fugacity and ChemPot are provided " - "(i.e., both are None). Add a dictionary for either the Fugacity or " - "ChemPot and set the other variable to None. " - "Note: Both the Fugacity or ChemPot and set to None by default" - ) - raise ValueError(print_error_message) - - # check that TargetedSwap_DataInput values are provided if self.TargetedSwapFreq - # and self.IntraTargetedSwapFreq is not zero - if self.TargetedSwap_DataInput is None and ( - self.TargetedSwapFreq != 0 or self.IntraTargetedSwapFreq != 0 - ): - self.input_error = True - print_error_message = ( - "ERROR: The TargetedSwap_DataInput variable is equal to None, " - "but the TargetedSwapFreq or IntraTargetedSwapFreq move ratio is non-zero." - ) - raise ValueError(print_error_message) - - # check that either the ChemPot or Fugacity are set for the Target swap moves - # only ChemPot or Fugacity can be set - if isinstance(self.TargetedSwap_DataInput, dict): - chempot_used = False - fugacity_used = False - for tag_id_keys_j in list(self.TargetedSwap_DataInput.keys()): - target_swap_tag_id_dict_key_data = self.TargetedSwap_DataInput[ - tag_id_keys_j - ] - - for target_swap_dict_key_j_lower in list( - target_swap_tag_id_dict_key_data.keys() - ): - if target_swap_dict_key_j_lower in ["subvolumechempot"]: - chempot_used = True - - if target_swap_dict_key_j_lower in ["subvolumefugacity"]: - fugacity_used = True - - if chempot_used is True and fugacity_used is True: - print_error_message = ( - "Both ChemPot and Fugacity were used in the " - "TargetedSwap_DataInput dictionaries. " - "However, only ChemPot or Fugacity may be used, not both." - ) - raise ValueError(print_error_message) - - if (chempot_used is True and self.Fugacity is not None) or ( - fugacity_used is True and self.ChemPot is not None - ): - print_error_message = ( - "Both ChemPot and Fugacity were used in the " - "TargetedSwap_DataInput dictionaries " - "and in the standard GOMC swap inputs. " - "However, only ChemPot or Fugacity may be used, not both." - ) - raise ValueError(print_error_message) - - if ( - chempot_used is True or fugacity_used is True - ) and self.ensemble_type in ["NPT", "NVT", "GEMC_NVT", "GEMC_NPT"]: - print_error_message = ( - "Either the ChemPot and Fugacity were used in the " - "TargetedSwap_DataInput dictionaries, " - "which can not be used for the 'NPT', 'NVT', 'GEMC_NVT', " - "or 'GEMC_NPT' ensembles." - ) - raise ValueError(print_error_message) - - # check if every TargetedSwap_DataInput has all the required values - required_ts_datainput_keys_main = [ - "subvolumetype", - "subvolumebox", - "subvolumedim", - "subvolumeresiduekind", - "subvolumerigidswap", - "subvolumepbc", - ] - required_ts_datainput_keys_static_adder = ["subvolumecenter"] - required_ts_datainput_keys_dynamic_adder = ["subvolumecenterlist"] - required_ts_datainput_keys_GCMC_chempot_adder = ["subvolumechempot"] - required_ts_datainput_keys_GCMC_fugacity_adder = [ - "subvolumefugacity" - ] - - for ts_tag_i in list(self.TargetedSwap_DataInput.keys()): - all_potential_keys = ( - required_ts_datainput_keys_main - + required_ts_datainput_keys_static_adder - + required_ts_datainput_keys_dynamic_adder - + required_ts_datainput_keys_GCMC_chempot_adder - + required_ts_datainput_keys_GCMC_fugacity_adder - ) - print_error_message = ( - f"The TargetedSwap_DataInput dictionaries do not have all the required " - f"keys or inputs per the subvolumetype and specified ensemble. " - f"Remember that the 'subvolumetype' values are 'static' and 'dynamic', " - f"which must only have the cooresponding " - f"'subvolumecenter' and 'subvolumecenterlist' values, respectively," - f" in each subvolume." - ) - - required_ts_datainput_total = [] - if "subvolumetype" in self.TargetedSwap_DataInput[ts_tag_i]: - if ( - self.TargetedSwap_DataInput[ts_tag_i]["subvolumetype"] - == "dynamic" - ): - required_ts_datainput_total = ( - required_ts_datainput_keys_main - + required_ts_datainput_keys_dynamic_adder - ) - elif ( - self.TargetedSwap_DataInput[ts_tag_i]["subvolumetype"] - == "static" - ): - required_ts_datainput_total = ( - required_ts_datainput_keys_main - + required_ts_datainput_keys_static_adder - ) - - if self.ensemble_type in ["GCMC"]: - if ( - "subvolumefugacity" - in self.TargetedSwap_DataInput[ts_tag_i] - ): - required_ts_datainput_total += ( - required_ts_datainput_keys_GCMC_fugacity_adder - ) - elif ( - "subvolumechempot" - in self.TargetedSwap_DataInput[ts_tag_i] - ): - required_ts_datainput_total += ( - required_ts_datainput_keys_GCMC_chempot_adder - ) - - # fail build if all subvolume keys are not provided, - # set default values of SubVolumeRigidSwap and SubVolumePBC if not found - for subvolume_keys_j in required_ts_datainput_total: - if subvolume_keys_j not in list( - self.TargetedSwap_DataInput[ts_tag_i].keys() - ): - # set default values of SubVolumeRigidSwap or SubVolumePBC to - # default value, if not provided - if subvolume_keys_j in [ - "subvolumerigidswap", - "subvolumepbc", - ]: - self.TargetedSwap_DataInput[ts_tag_i].update( - { - subvolume_keys_j: _get_default_variables_dict()[ - subvolume_keys_j - ] - } - ) - else: - raise ValueError(print_error_message) - - else: - raise ValueError(print_error_message) - - # check that MEMC moves rations are > 0 if MEMC_DataInput is used - if self.MEMC_DataInput is not None and ( - self.MEMC_1Freq == 0 - and self.MEMC_2Freq == 0 - and self.MEMC_3Freq == 0 - and self.IntraMEMC_1Freq == 0 - and self.IntraMEMC_2Freq == 0 - and self.IntraMEMC_3Freq == 0 - ): - self.input_error = True - print_error_message = ( - "ERROR: The MEMC_DataInput variable is not equal to None, " - "but all the MEMC move ratios are " - "zero (IntraMEMC-1Freq, MEMC-1Freq, IntraMEMC-2Freq, MEMC-2Freq, " - "IntraMEMC-3Freq, and MEMC-3Freq)." - ) - raise ValueError(print_error_message) - - if self.MEMC_DataInput is None and ( - self.MEMC_1Freq != 0 - or self.MEMC_2Freq != 0 - or self.MEMC_3Freq != 0 - or self.IntraMEMC_1Freq != 0 - or self.IntraMEMC_2Freq != 0 - or self.IntraMEMC_3Freq != 0 - ): - self.input_error = True - print_error_message = ( - "ERROR: The MEMC_DataInput variable is equal to None, " - "but at least one of the MEMC move ratios are " - "all non-zero (IntraMEMC-1Freq, MEMC-1Freq, IntraMEMC-2Freq, MEMC-2Freq, " - "IntraMEMC-3Freq, and MEMC-3Freq)." - ) - raise ValueError(print_error_message) - - # ensure the LargeKindBackBone and SmallKindBackBones are provided as appropriate for MEMC-1, MEMC-2, MEMC-3 - if self.MEMC_DataInput is not None and ( - self.MEMC_2Freq > 0 or self.IntraMEMC_2Freq > 0 - ): - for MEMC_2_i in range(0, len(self.MEMC_DataInput)): - if ( - self.MEMC_DataInput[MEMC_2_i][2][0] is None - or self.MEMC_DataInput[MEMC_2_i][2][1] is None - or self.MEMC_DataInput[MEMC_2_i][4][0] is None - or self.MEMC_DataInput[MEMC_2_i][4][1] is None - ): - self.input_error = True - print_error_message = ( - "ERROR: The LargeKindBackBone and SmallKindBackBones unique " - "atom names, strings, both must be provided when using the " - "IntraMEMC-2Freq or MEMC-2Freq moves " - "(i.e., the LargeKindBackBone and SmallKindBackBones can not be None). " - ) - raise ValueError(print_error_message) - - if self.MEMC_DataInput is not None and ( - self.MEMC_3Freq > 0 or self.IntraMEMC_3Freq > 0 - ): - for MEMC_3_i in range(0, len(self.MEMC_DataInput)): - if ( - self.MEMC_DataInput[MEMC_3_i][2][0] is None - or self.MEMC_DataInput[MEMC_3_i][2][1] is None - ): - self.input_error = True - print_error_message = ( - "ERROR: The LargeKindBackBone unique atom names, strings, " - "both must be provided when using the IntraMEMC-3Freq or MEMC-3Freq moves " - "(i.e., the LargeKindBackBone can not be None)." - ) - raise ValueError(print_error_message) - - # check that all required free energy values are provided and RcutLow is zero (0) - if ( - self.FreeEnergyCalc is not None - or self.MoleculeType is not None - or self.InitialState is not None - or self.LambdaVDW is not None - ): - if ( - self.FreeEnergyCalc is None - or self.MoleculeType is None - or self.InitialState is None - or self.LambdaVDW is None - ): - self.input_error = True - print_error_message = ( - "ERROR: To utilize the free energy calculations all the following " - "variables need to be set, and not equal to None: " - "FreeEnergyCalc, MoleculeType, InitialState, LambdaVDW." - ) - raise ValueError(print_error_message) - - if self.RcutLow != 0: - print_warning_message = ( - "WARNING: The free energy calculations are being used when RcutLow is not zero (0), " - "which can produce free energy results that are slightly off or wrong. " - "Please set RcutLow to zero (RcutLow=0) when using the free energy calculations." - ) - warn(print_warning_message) - - if ( - self.LambdaVDW is not None - and self.LambdaCoulomb is not None - and isinstance(self.LambdaVDW, list) is True - and (isinstance(self.LambdaCoulomb, list)) is True - ): - if len(self.LambdaVDW) == len(self.LambdaCoulomb): - if self.InitialState + 1 <= len(self.LambdaVDW): - for lam_i in range(1, len(self.LambdaVDW)): - if self.LambdaVDW[lam_i] < self.LambdaVDW[lam_i - 1]: - self.input_error = True - print_error_message = "ERROR: The LambdaVDW list is not in accending order." - raise ValueError(print_error_message) - if ( - self.LambdaCoulomb[lam_i] - < self.LambdaCoulomb[lam_i - 1] - ): - self.input_error = True - print_error_message = "ERROR: The LambdaCoulomb list is not in accending order." - raise ValueError(print_error_message) - else: - self.input_error = True - print_error_message = ( - "ERROR: The InitialState integer is greater than the LambdaVDW and " - "LambdaCoulomb list length. Note: the InitialState integer starts at 0." - ) - raise ValueError(print_error_message) - else: - self.input_error = True - print_error_message = "ERROR: The LambdaVDW and LambdaCoulomb list must be of equal length." - raise ValueError(print_error_message) - - # check self.LambdaVDW and LambdaCoulomb last value is 1.0 - if self.ensemble_type in ["NVT", "NPT"]: - if isinstance(self.LambdaVDW, list): - if len(self.LambdaVDW) > 0: - if self.LambdaVDW[-1] != 1.0: - print_error_message = "ERROR: The last value in the LambdaVDW variable list must be a 1.0" - raise ValueError(print_error_message) - if self.LambdaVDW[0] != 0.0: - print_error_message = "ERROR: The first value in the LambdaVDW variable list must be a 0.0" - raise ValueError(print_error_message) - if isinstance(self.LambdaCoulomb, list): - if len(self.LambdaCoulomb) > 0: - if self.LambdaCoulomb[-1] != 1.0: - print_error_message = "ERROR: The last value in the LambdaCoulomb variable list must be a 1.0" - raise ValueError(print_error_message) - if self.LambdaCoulomb[0] != 0.0: - print_error_message = "ERROR: The first value in the LambdaCoulomb variable list must be a 0.0" - raise ValueError(print_error_message) - - # write the control file - def write_conf_file(self, conf_filename): - """ - Writes the GOMC control file. - - Parameters - ---------- - conf_filename: str - The path and file name for the control file name, with - the .conf extension, or no extension. If no extension is provided, the - code will add the .conf extension to the provided file name. - - Returns - --------- - Writes the GOMC control file with the name provided via conf_filename - If completed without errors: str, "PASSED - If completed with errors : None - """ - - # check to see if it is OK to proceed writing the control file - if self.input_error is True: - print_error_message = ( - "ERROR: The control file was not written as at least 1 input to the " - "control file writer was bad." - ) - raise ValueError(print_error_message) - - date_time = datetime.datetime.today() - - self.conf_filename = conf_filename - - if ( - isinstance(self.conf_filename, str) is False - or isinstance(self.conf_filename, str) is None - ): - self.input_error = True - print_error_message = "ERROR: The control file name (conf_filename) is not provided as a string. " - raise ValueError(print_error_message) - - if os.path.splitext(self.conf_filename)[1] == ".conf": - self.conf_filename = conf_filename - print( - "INFO: the correct extension for the control file was provided in the file name, .conf " - "with control file name = " + str(self.conf_filename) - ) - elif os.path.splitext(self.conf_filename)[1] == "": - self.conf_filename = self.conf_filename + ".conf" - print( - "INFO: No extension name was provided for the control file. Therefore, the proper " - "extension, .conf, was added. The new total control file name = {}".format( - self.conf_filename - ) - ) - else: - self.input_error = True - print_error_message = ( - "ERROR: No extension name or the wrong extension name was provided. " - "Please enter a proper extension name, .conf or no extension in the conf_filename " - "The control file as provided name = {}".format( - self.conf_filename - ) - ) - raise ValueError(print_error_message) - - # get and open the control file file - data_control_file = open(self.conf_filename, "w") - - data_control_file.write( - "#######################################################" - "#########################################\n" - ) - data_control_file.write( - "## This file ({}) - was created by MoSDeF-GOMC " - "using the on {}\n".format(self.conf_filename, date_time) - ) - data_control_file.write( - "#######################################################" - "#########################################\n" - ) - data_control_file.write("\n") - data_control_file.write( - "############################################################################\n" - ) - data_control_file.write( - "# ---------------------------- INPUT ------------------------------------- \n" - ) - data_control_file.write( - "############################################################################\n" - ) - data_control_file.write(" \n") - data_control_file.write("####################################\n") - data_control_file.write("# enable, step\n") - data_control_file.write("####################################\n") - data_control_file.write("{:25s} {}\n".format("Restart", self.Restart)) - data_control_file.write("\n") - data_control_file.write( - "{:25s} {}\n".format("RestartCheckpoint", self.RestartCheckpoint) - ) - data_control_file.write("\n") - data_control_file.write( - "{:25s} {}\n".format("ExpertMode", self.ExpertMode) - ) - data_control_file.write("\n") - data_control_file.write("####################################\n") - data_control_file.write("# kind {RESTART, RANDOM, INTSEED}\n") - data_control_file.write("####################################\n") - if self.PRNG == "RANDOM": - data_control_file.write("{:25s} {}\n".format("PRNG", self.PRNG)) - elif isinstance(self.PRNG, int): - data_control_file.write("PRNG \t\t " + "INTSEED \n") - data_control_file.write( - "{:25s} {}\n".format("Random_Seed", self.PRNG) - ) - data_control_file.write(" \n") - data_control_file.write("####################################\n") - data_control_file.write("# FORCE FIELD\n") - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {}\n".format(str(self.VDW_type), str(True)) - ) - data_control_file.write(" \n") - data_control_file.write( - "{:25s} {}\n".format("Parameters", self.ff_filename) - ) - data_control_file.write("####################################\n") - data_control_file.write("# INPUT PDB FILES\n") - data_control_file.write("####################################\n") - if self.ensemble_type in ["NVT", "NPT", "GEMC_NPT", "GEMC_NVT", "GCMC"]: - data_control_file.write( - "{:25s} {}\n".format("Coordinates 0", self.Coordinates_box_0) - ) - if self.ensemble_type in ["GEMC_NPT", "GEMC_NVT", "GCMC"]: - data_control_file.write( - "{:25s} {}\n".format("Coordinates 1", self.Coordinates_box_1) - ) - data_control_file.write(" \n") - data_control_file.write("####################################\n") - data_control_file.write("# INPUT PSF FILES\n") - data_control_file.write("####################################\n") - if self.ensemble_type in ["NVT", "NPT", "GEMC_NPT", "GEMC_NVT", "GCMC"]: - data_control_file.write( - "{:25s} {}\n".format("Structure 0", self.Structure_box_0) - ) - if self.ensemble_type in ["GEMC_NPT", "GEMC_NVT", "GCMC"]: - data_control_file.write( - "{:25s} {}\n".format("Structure 1", self.Structure_box_1) - ) - - if ( - self.Restart is True - and self.binCoordinates_box_0 is not None - and self.extendedSystem_box_0 is not None - and self.ensemble_type - in ["NVT", "NPT", "GEMC_NPT", "GEMC_NVT", "GCMC"] - ): - data_control_file.write(" \n") - data_control_file.write("####################################\n") - data_control_file.write( - "# INPUT FILES FOR RESTARTING (COORDINATE, XSC, VELOCITY FILES)\n" - ) - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {}\n".format( - "binCoordinates 0", self.binCoordinates_box_0 - ) - ) - data_control_file.write( - "{:25s} {}\n".format( - "extendedSystem 0", self.extendedSystem_box_0 - ) - ) - if self.binVelocities_box_0 is not None: - data_control_file.write( - "{:25s} {}\n".format( - "binVelocities 0", self.binVelocities_box_0 - ) - ) - data_control_file.write(" \n") - - if ( - self.binCoordinates_box_1 is not None - and self.extendedSystem_box_1 is not None - and self.ensemble_type in ["GEMC_NPT", "GEMC_NVT", "GCMC"] - ): - data_control_file.write( - "{:25s} {}\n".format( - "binCoordinates 1", self.binCoordinates_box_1 - ) - ) - data_control_file.write( - "{:25s} {}\n".format( - "extendedSystem 1", self.extendedSystem_box_1 - ) - ) - if self.binVelocities_box_1 is not None: - data_control_file.write( - "{:25s} {}\n".format( - "binVelocities 1", self.binVelocities_box_1 - ) - ) - - data_control_file.write(" \n") - data_control_file.write( - "############################################################################\n" - ) - data_control_file.write( - "# ---------------------------- SYSTEM -------------------------------------\n" - ) - data_control_file.write( - "############################################################################ \n" - ) - data_control_file.write(" \n") - if self.ensemble_type in ["GEMC_NPT", "GEMC_NVT"]: - data_control_file.write("####################################\n") - data_control_file.write("# GEMC TYPE \n") - data_control_file.write("####################################\n") - if self.ensemble_type in "GEMC_NPT": - data_control_file.write("GEMC \t\t NPT \n") - elif self.ensemble_type in "GEMC_NVT": - data_control_file.write("GEMC \t\t NVT \n") - data_control_file.write(" \n") - data_control_file.write("####################################\n") - data_control_file.write("# SIMULATION CONDITION\n") - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {}\n".format("Temperature", self.Temperature) - ) - if self.ensemble_type in ["GEMC_NPT", "NPT"]: - data_control_file.write( - "{:25s} {}\n".format("Pressure", self.Pressure) - ) - data_control_file.write( - "{:25s} {}\n".format("useConstantArea", self.useConstantArea) - ) - - if self.ensemble_type in ["GEMC_NPT"] and self.FixVolBox0 is True: - data_control_file.write( - "{:25s} {}\n".format("FixVolBox0", self.FixVolBox0) - ) - - if ( - self.ensemble_type in ["GCMC"] - and self.ChemPot is not None - and self.Fugacity is None - ): - chem_pot_dict_key_list = dict_keys_to_list(self.ChemPot) - for chem_pot_iter in range(0, len(chem_pot_dict_key_list)): - chem_pot_residue_iter = chem_pot_dict_key_list[chem_pot_iter] - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "ChemPot", - chem_pot_residue_iter, - self.ChemPot[chem_pot_residue_iter], - ) - ) - - if ( - self.ensemble_type in ["GCMC"] - and self.Fugacity is not None - and self.ChemPot is None - ): - fugacity_iter_dict_key_list = dict_keys_to_list(self.Fugacity) - for fugacity_iter in range(0, len(fugacity_iter_dict_key_list)): - fugacity_residue_iter = fugacity_iter_dict_key_list[ - fugacity_iter - ] - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "Fugacity", - fugacity_residue_iter, - self.Fugacity[fugacity_residue_iter], - ) - ) - - data_control_file.write(" \n") - data_control_file.write( - "{:25s} {}\n".format("Potential", self.Potential) - ) - data_control_file.write("{:25s} {}\n".format("LRC", self.LRC)) - data_control_file.write("{:25s} {}\n".format("IPC", self.IPC)) - data_control_file.write("{:25s} {}\n".format("Rcut", self.Rcut)) - data_control_file.write("{:25s} {}\n".format("RcutLow", self.RcutLow)) - if self.Potential == "SWITCH": - data_control_file.write( - "{:25s} {}\n".format("Rswitch", self.Rswitch) - ) - data_control_file.write("{:25s} {}\n".format("Exclude", self.Exclude)) - data_control_file.write( - "{:25s} {}\n".format("VDWGeometricSigma", self.VDWGeometricSigma) - ) - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# ELECTROSTATIC \n") - data_control_file.write("####################################\n") - data_control_file.write("{:25s} {}\n".format("Ewald", self.Ewald)) - data_control_file.write( - "{:25s} {}\n".format("ElectroStatic", self.ElectroStatic) - ) - data_control_file.write( - "{:25s} {}\n".format("CachedFourier", self.CachedFourier) - ) - data_control_file.write( - "{:25s} {}\n".format("Tolerance", str(self.Tolerance)) - ) - if self.VDW_type in ["ParaTypeMARTINI"]: - data_control_file.write( - "{:25s} {}\n".format("Dielectric", format(self.Dielectric)) - ) - data_control_file.write( - "{:25s} {}\n".format("1-4scaling", self.coul_1_4) - ) - data_control_file.write(" \n") - if self.RcutCoulomb_box_0 is not None: - data_control_file.write( - "{:25s} {}\n".format("RcutCoulomb 0", self.RcutCoulomb_box_0) - ) - if self.RcutCoulomb_box_1 is not None and self.ensemble_type in [ - "GEMC_NPT", - "GEMC_NVT", - "GCMC", - ]: - data_control_file.write( - "{:25s} {}\n".format("RcutCoulomb 1", self.RcutCoulomb_box_1) - ) - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# PRESSURE CALCULATION\n") - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "PressureCalc", - str(self.PressureCalc[0]), - self.PressureCalc[1], - ) - ) - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# STEPS \n") - data_control_file.write("####################################\n") - data_control_file.write("{:25s} {}\n".format("RunSteps", self.RunSteps)) - data_control_file.write("{:25s} {}\n".format("EqSteps", self.EqSteps)) - data_control_file.write("{:25s} {}\n".format("AdjSteps", self.AdjSteps)) - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# MOVE FREQUENCY \n") - data_control_file.write("####################################\n") - mc_move_zero_error_tolerance = 10 ** (-14) - if self.DisFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("DisFreq", self.DisFreq) - ) - if self.RotFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("RotFreq", self.RotFreq) - ) - if self.IntraSwapFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("IntraSwapFreq", self.IntraSwapFreq) - ) - if self.SwapFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("SwapFreq", self.SwapFreq) - ) - if self.RegrowthFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("RegrowthFreq", self.RegrowthFreq) - ) - if self.CrankShaftFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("CrankShaftFreq", self.CrankShaftFreq) - ) - if self.VolFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("VolFreq", self.VolFreq) - ) - if self.MultiParticleFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format( - "MultiParticleFreq", self.MultiParticleFreq - ) - ) - if self.IntraMEMC_1Freq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("IntraMEMC-1Freq", self.IntraMEMC_1Freq) - ) - if self.MEMC_1Freq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("MEMC-1Freq", self.MEMC_1Freq) - ) - if self.IntraMEMC_2Freq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("IntraMEMC-2Freq", self.IntraMEMC_2Freq) - ) - if self.MEMC_2Freq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("MEMC-2Freq", self.MEMC_2Freq) - ) - if self.IntraMEMC_3Freq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("IntraMEMC-3Freq", self.IntraMEMC_3Freq) - ) - if self.MEMC_3Freq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("MEMC-3Freq", self.MEMC_3Freq) - ) - if self.TargetedSwapFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format("TargetedSwapFreq", self.TargetedSwapFreq) - ) - if self.IntraTargetedSwapFreq > mc_move_zero_error_tolerance: - data_control_file.write( - "{:25s} {}\n".format( - "IntraTargetedSwapFreq", self.IntraTargetedSwapFreq - ) - ) - data_control_file.write(" \n") - - # sort and print the MEMC data if MEMC is used for the simulation - if self.MEMC_DataInput is not None and ( - self.MEMC_1Freq > 0 - or self.MEMC_2Freq > 0 - or self.MEMC_3Freq > 0 - or self.IntraMEMC_1Freq > 0 - or self.IntraMEMC_2Freq > 0 - or self.IntraMEMC_3Freq > 0 - ): - ExchangeRatio_list = [] - ExchangeLargeKind_list = [] - LargeKindBackBone_list = [] - ExchangeSmallKind_list = [] - SmallKindBackBone_list = [] - - for memc_i in range(0, len(self.MEMC_DataInput)): - ExchangeRatio_list.append( - str("{:10s} \t".format(str(self.MEMC_DataInput[memc_i][0]))) - ) - ExchangeLargeKind_list.append( - "{:10s} \t".format(str(self.MEMC_DataInput[memc_i][1])) - ) - LargeKindBackBone_list.append( - "{:4s} {:4s} \t".format( - str(self.MEMC_DataInput[memc_i][2][0]), - str(self.MEMC_DataInput[memc_i][2][1]), - ) - ) - ExchangeSmallKind_list.append( - "{:10s} \t".format(str(self.MEMC_DataInput[memc_i][3])) - ) - SmallKindBackBone_list.append( - "{:4s} {:4s} \t".format( - str(self.MEMC_DataInput[memc_i][4][0]), - str(self.MEMC_DataInput[memc_i][4][1]), - ) - ) - - ExchangeRatio_str = "".join(ExchangeRatio_list) - ExchangeLargeKind_str = "".join(ExchangeLargeKind_list) - LargeKindBackBone_str = "".join(LargeKindBackBone_list) - ExchangeSmallKind_str = "".join(ExchangeSmallKind_list) - SmallKindBackBone_str = "".join(SmallKindBackBone_list) - - data_control_file.write("####################################\n") - data_control_file.write("# MEMC PARAMETER \n") - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {}\t{}\t{}\n".format( - "ExchangeVolumeDim", - self.ExchangeVolumeDim[0], - self.ExchangeVolumeDim[1], - self.ExchangeVolumeDim[2], - ) - ) - data_control_file.write( - "{:25s} {}\n".format("ExchangeRatio", ExchangeRatio_str) - ) - data_control_file.write( - "{:25s} {}\n".format("ExchangeLargeKind", ExchangeLargeKind_str) - ) - data_control_file.write( - "{:25s} {}\n".format("ExchangeSmallKind", ExchangeSmallKind_str) - ) - if self.MEMC_DataInput is not None and ( - self.MEMC_2Freq > 0 - or self.IntraMEMC_2Freq > 0 - or self.MEMC_3Freq > 0 - or self.IntraMEMC_3Freq > 0 - ): - data_control_file.write( - "{:25s} {}\n".format( - "LargeKindBackBone", LargeKindBackBone_str - ) - ) - if self.MEMC_DataInput is not None and ( - self.MEMC_2Freq > 0 or self.IntraMEMC_2Freq > 0 - ): - data_control_file.write( - "{:25s} {}\n".format( - "SmallKindBackBone", SmallKindBackBone_str - ) - ) - - data_control_file.write(" \n") - - if self.TargetedSwap_DataInput is not None: - data_control_file.write("####################################\n") - data_control_file.write( - "# TARGETED SWAP PARAMETERS (only available in the GCMC and NPT ensembles) \n" - ) - data_control_file.write("####################################\n") - for sub_vol_tag_id_i in list(self.TargetedSwap_DataInput.keys()): - data_control_file.write( - "{:30s} {:10s} {:10s}\n".format( - "SubVolumeBox", - str(sub_vol_tag_id_i), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumebox" - ] - ), - ) - ) - - if ( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumetype" - ] - == "static" - ): - data_control_file.write( - "{:30s} {:10s} {:10s} {:10s} {:10s}\n".format( - "SubVolumeCenter", - str(sub_vol_tag_id_i), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumecenter" - ][0] - ), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumecenter" - ][1] - ), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumecenter" - ][2] - ), - ) - ) - elif ( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumetype" - ] - == "dynamic" - ): - data_control_file.write( - "{:30s} {:10s} {:10s} {:10s} {:10s}\n".format( - "SubVolumeCenterList", - str(sub_vol_tag_id_i), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumecenterlist" - ][0] - ), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumecenterlist" - ][1] - ), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumecenterlist" - ][2] - ), - ) - ) - - # get the SubVolumeDim - data_control_file.write( - "{:30s} {:10s} {:10s} {:10s} {:10s}\n".format( - "SubVolumeDim", - str(sub_vol_tag_id_i), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumedim" - ][0] - ), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumedim" - ][1] - ), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumedim" - ][2] - ), - ) - ) - # get the length of the SubVolumeResidueKind, modify the print statment and print it - data_control_file.write( - "{:30s} {:10s}".format( - "SubVolumeResidueKind", - str(sub_vol_tag_id_i), - ) - ) - for res_i in range( - 0, - len( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumeresiduekind" - ] - ), - ): - data_control_file.write( - " {:10s}".format( - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumeresiduekind" - ][res_i] - ), - ) - ) - data_control_file.write( - "{}\n".format(""), - ) - - data_control_file.write( - "{:30s} {:10s} {:10s}\n".format( - "SubVolumeRigidSwap", - str(sub_vol_tag_id_i), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumerigidswap" - ] - ), - ) - ) - - data_control_file.write( - "{:30s} {:10s} {:10s}\n".format( - "SubVolumePBC", - str(sub_vol_tag_id_i), - str( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumepbc" - ] - ), - ) - ) - - # get the length of the SubVolumeChemPot, modify the print statment and print it - if "subvolumechempot" in list( - self.TargetedSwap_DataInput[sub_vol_tag_id_i].keys() - ): - for subvol_chempot_key_i in list( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumechempot" - ].keys() - ): - data_control_file.write( - "{:30s} {:10s} {:10s} {:30s}\n".format( - "SubVolumeChemPot", - str(sub_vol_tag_id_i), - str(subvol_chempot_key_i), - str( - self.TargetedSwap_DataInput[ - sub_vol_tag_id_i - ]["subvolumechempot"][subvol_chempot_key_i] - ), - ) - ) - - # get the length of the SubVolumeFugacity, modify the print statment and print it - if "subvolumefugacity" in list( - self.TargetedSwap_DataInput[sub_vol_tag_id_i].keys() - ): - for subvol_fugacity_key_i in list( - self.TargetedSwap_DataInput[sub_vol_tag_id_i][ - "subvolumefugacity" - ].keys() - ): - data_control_file.write( - "{:30s} {:10s} {:10s} {:30s}\n".format( - "SubVolumeFugacity", - str(sub_vol_tag_id_i), - str(subvol_fugacity_key_i), - str( - self.TargetedSwap_DataInput[ - sub_vol_tag_id_i - ]["subvolumefugacity"][ - subvol_fugacity_key_i - ] - ), - ) - ) - - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# BOX DIMENSION #, X, Y, Z \n") - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {:20s} {:20s} {:20s}\n".format( - "CellBasisVector1 0", - str(self.box_0_vectors[0][0]), - str(self.box_0_vectors[0][1]), - str(self.box_0_vectors[0][2]), - ) - ) - data_control_file.write( - "{:25s} {:20s} {:20s} {:20s}\n".format( - "CellBasisVector2 0", - str(self.box_0_vectors[1][0]), - str(self.box_0_vectors[1][1]), - str(self.box_0_vectors[1][2]), - ) - ) - data_control_file.write( - "{:25s} {:20s} {:20s} {:20s}\n".format( - "CellBasisVector3 0", - str(self.box_0_vectors[2][0]), - str(self.box_0_vectors[2][1]), - str(self.box_0_vectors[2][2]), - ) - ) - data_control_file.write(" \n") - if self.ensemble_type in ["GEMC_NPT", "GEMC_NVT", "GCMC"]: - data_control_file.write( - "{:25s} {:20s} {:20s} {:20s}\n".format( - "CellBasisVector1 1", - str(self.box_1_vectors[0][0]), - str(self.box_1_vectors[0][1]), - str(self.box_1_vectors[0][2]), - ) - ) - data_control_file.write( - "{:25s} {:20s} {:20s} {:20s}\n".format( - "CellBasisVector2 1", - str(self.box_1_vectors[1][0]), - str(self.box_1_vectors[1][1]), - str(self.box_1_vectors[1][2]), - ) - ) - data_control_file.write( - "{:25s} {:20s} {:20s} {:20s}\n".format( - "CellBasisVector3 1", - str(self.box_1_vectors[2][0]), - str(self.box_1_vectors[2][1]), - str(self.box_1_vectors[2][2]), - ) - ) - data_control_file.write(" \n") - - if ( - (self.ensemble_type in ["NPT", "NVT"]) - and self.FreeEnergyCalc is not None - and self.MoleculeType is not None - and self.InitialState is not None - and self.LambdaVDW is not None - ): - # make list for number of states, LambdaVDW, and Lambda_Coul, and convert the list to string for printing - Lambda_states_list = [] - Lambda_VDW_list = [] - Lambda_Coul_list = [] - for lamda_i in range(0, len(self.LambdaVDW)): - Lambda_states_list.append(str(lamda_i)) - Lambda_VDW_list.append(str(self.LambdaVDW[lamda_i])) - if self.LambdaCoulomb is not None: - Lambda_Coul_list.append(str(self.LambdaCoulomb[lamda_i])) - - Lambda_states_str = "\t".join(Lambda_states_list) - Lambda_VDW_str = "\t".join(Lambda_VDW_list) - if self.LambdaCoulomb is not None: - Lambda_Coul_str = "\t".join(Lambda_Coul_list) - - data_control_file.write("####################################\n") - data_control_file.write( - "# FREE ENERGY PARAMETERS (only available in NPT and NVT ensembles) \n" - ) - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "FreeEnergyCalc", - str(self.FreeEnergyCalc[0]), - self.FreeEnergyCalc[1], - ) - ) - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "MoleculeType", - str(self.MoleculeType[0]), - self.MoleculeType[1], - ) - ) - data_control_file.write( - "{:25s} {}\n".format("InitialState", self.InitialState) - ) - data_control_file.write( - "{:25s} {}\n".format("ScalePower", self.ScalePower) - ) - data_control_file.write( - "{:25s} {}\n".format("ScaleAlpha", self.ScaleAlpha) - ) - data_control_file.write( - "{:25s} {}\n".format("MinSigma", self.MinSigma) - ) - data_control_file.write( - "{:25s} {}\n".format("ScaleCoulomb", self.ScaleCoulomb) - ) - data_control_file.write( - "{:25s} {}\n".format("# States", Lambda_states_str) - ) - data_control_file.write( - "{:25s} {}\n".format("LambdaVDW", Lambda_VDW_str) - ) - - if self.LambdaCoulomb is not None: - data_control_file.write( - "{:25s} {}\n".format("LambdaCoulomb", Lambda_Coul_str) - ) - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# CBMC TRIALS \n") - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {}\n".format("CBMC_First", self.CBMC_First) - ) - data_control_file.write("{:25s} {}\n".format("CBMC_Nth", self.CBMC_Nth)) - data_control_file.write("{:25s} {}\n".format("CBMC_Ang", self.CBMC_Ang)) - data_control_file.write("{:25s} {}\n".format("CBMC_Dih", self.CBMC_Dih)) - data_control_file.write(" \n") - - data_control_file.write( - "############################################################################\n" - ) - data_control_file.write( - "# --------------------------- OUTPUT ------------------------------------- \n" - ) - data_control_file.write( - "############################################################################\n" - ) - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# statistics filename add\n") - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {}\n".format("OutputName", self.OutputName) - ) - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# enable, frequency \n") - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "RestartFreq", str(self.RestartFreq[0]), self.RestartFreq[1] - ) - ) - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "CheckpointFreq", - str(self.CheckpointFreq[0]), - self.CheckpointFreq[1], - ) - ) - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "CoordinatesFreq", - str(self.CoordinatesFreq[0]), - self.CoordinatesFreq[1], - ) - ) - # set this only true if use dcd is true, until the DCDFreq is in a official release of GOMC - if self.DCDFreq[0] is True: - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "DCDFreq", - str(self.DCDFreq[0]), - self.DCDFreq[1], - ) - ) - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "ConsoleFreq", str(self.ConsoleFreq[0]), self.ConsoleFreq[1] - ) - ) - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "BlockAverageFreq", - str(self.BlockAverageFreq[0]), - self.BlockAverageFreq[1], - ) - ) - data_control_file.write( - "{:25s} {:10s} {}\n".format( - "HistogramFreq", - str(self.HistogramFreq[0]), - self.HistogramFreq[1], - ) - ) - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# OutHistSettings \n") - data_control_file.write("####################################\n") - data_control_file.write("{:25s} {}\n".format("DistName", self.DistName)) - data_control_file.write("{:25s} {}\n".format("HistName", self.HistName)) - data_control_file.write( - "{:25s} {}\n".format("RunNumber", self.RunNumber) - ) - data_control_file.write( - "{:25s} {}\n".format("RunLetter", self.RunLetter) - ) - data_control_file.write( - "{:25s} {}\n".format("SampleFreq", self.SampleFreq) - ) - data_control_file.write(" \n") - - data_control_file.write("####################################\n") - data_control_file.write("# enable: blk avg., fluct. \n") - data_control_file.write("####################################\n") - data_control_file.write( - "{:25s} {:10s} {:10s}\n".format( - "OutEnergy", - str(self.OutEnergy[0]), - str(self.OutEnergy[1]), - ) - ) - data_control_file.write( - "{:25s} {:10s} {:10s}\n".format( - "OutPressure", - str(self.OutPressure[0]), - str(self.OutPressure[1]), - ) - ) - data_control_file.write( - "{:25s} {:10s} {:10s}\n".format( - "OutMolNum", - str(self.OutMolNum[0]), - str(self.OutMolNum[1]), - ) - ) - data_control_file.write( - "{:25s} {:10s} {:10s}\n".format( - "OutDensity", - str(self.OutDensity[0]), - str(self.OutDensity[1]), - ) - ) - data_control_file.write( - "{:25s} {:10s} {:10s}\n".format( - "OutVolume", - str(self.OutVolume[0]), - str(self.OutVolume[1]), - ) - ) - data_control_file.write( - "{:25s} {:10s} {:10s}\n".format( - "OutSurfaceTension", - str(self.OutSurfaceTension[0]), - str(self.OutSurfaceTension[1]), - ) - ) - data_control_file.write("\n") - data_control_file.write("\n") - - return "GOMC_CONTROL_FILE_WRITTEN" - - def ck_input_variable_true_or_false( - self, input_variables_dict, key, bad_user_variable_list - ): - """ - Checks if the input variable is either True for False. - If not either True or False, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_user_variable_list: list - A list to append with the bad dict_key user inputs - Note: This list is intented to be printed with all the bad input variables - so the user can fix them after upon a failed GOMC conf file writing attempt. - - Returns - --------- - bad_user_variable_list : list, - A list to append with the bad dict_key user inputs, - which is appended upon detecting a bad user input variable. - Note: This list is intented to be printed with all the bad input variables - so the user can fix them after upon a failed GOMC conf file writing attempt. - """ - - if ( - input_variables_dict[key] is not True - and input_variables_dict[key] is not False - or ( - str(input_variables_dict[key]) == str(True) - and str(input_variables_dict[key]) == str(False) - ) - ): - bad_user_variable_list.append(key) - - def ck_input_variable_int_or_float_zero_or_greater( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is an integer or float is zero or greater ( value >= 0 ). - If not, the provided list is appended with the bad with the dict_key. - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], int) is not True - and isinstance(input_variables_dict[key], float) is not True - or input_variables_dict[key] < 0 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_int_zero_or_greater( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is an integer is zero or greater ( value >= 0 ). - If not, the provided list is appended with the bad with the dict_key - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], int) is not True - or input_variables_dict[key] < 0 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_float_zero_or_greater( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a float is zero or greater ( value >= 0 ). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], float) is not True - or input_variables_dict[key] < 0 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_int_or_float_greater_zero( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is an integer or float is greater than zero ( value > 0). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], int) is not True - and isinstance(input_variables_dict[key], float) is not True - or input_variables_dict[key] <= 0 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_int_greater_zero( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is an integer greater than zero ( value > 0).. - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], int) is not True - or input_variables_dict[key] <= 0 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_float_greater_zero( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a float greater than zero ( value > 0). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], float) is not True - or input_variables_dict[key] <= 0 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_float_greater_zero_less_1( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a float greater than zero and less than 1 - ( 0 < value < 1). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], float) is not True - or input_variables_dict[key] <= 0 - or input_variables_dict[key] >= 1 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_int_or_float_zero_to_1( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is an integer or float from 0 to 1 ( 0 =< value <= 1). - If not, the provided list is appended with the bad with the dict_key - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], int) is not True - and isinstance(input_variables_dict[key], float) is not True - or input_variables_dict[key] < 0 - or input_variables_dict[key] > 1 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_float_zero_to_1( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a float from 0 to 1 ( 0 =< value <= 1). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], float) is not True - or input_variables_dict[key] < 0 - or input_variables_dict[key] > 1 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_int_zero_to_1( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is an integer from 0 to 1 ( 0 =< value <= 1). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], int) is not True - or input_variables_dict[key] < 0 - or input_variables_dict[key] > 1 - or str(input_variables_dict[key]) == str(True) - or str(input_variables_dict[key]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_list_bool_int_zero_or_greater( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a list with a bool and integer 0 or greater - ([bool, int >= 0 ]). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if isinstance(input_variables_dict[key], list) is False: - bad_input_variables_values_list.append(key) - elif isinstance(input_variables_dict[key], list) is True: - if ( - len(input_variables_dict[key]) != 2 - or ( - input_variables_dict[key][0] is not True - and input_variables_dict[key][0] is not False - ) - or isinstance(input_variables_dict[key][1], int) is not True - or input_variables_dict[key][1] < 0 - or ( - str(input_variables_dict[key][0]) != str(True) - and str(input_variables_dict[key][0]) != str(False) - ) - or str(input_variables_dict[key][1]) == str(True) - or str(input_variables_dict[key][1]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_list_bool_int_greater_zero( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a list with a bool and integer greater than zero - ([bool, int > 0 ]). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if isinstance(input_variables_dict[key], list) is False: - bad_input_variables_values_list.append(key) - elif isinstance(input_variables_dict[key], list) is True: - if ( - len(input_variables_dict[key]) != 2 - or ( - input_variables_dict[key][0] is not True - and input_variables_dict[key][0] is not False - ) - or isinstance(input_variables_dict[key][1], int) is not True - or input_variables_dict[key][1] <= 0 - or ( - str(input_variables_dict[key][0]) != str(True) - and str(input_variables_dict[key][0]) != str(False) - ) - or str(input_variables_dict[key][1]) == str(True) - or str(input_variables_dict[key][1]) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_list_residue_str_int_greater_zero( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a list with a str and integer greater than zero - ([str, int > 0 ]). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if isinstance(input_variables_dict[key], list) is False: - bad_input_variables_values_list.append(key) - elif isinstance(input_variables_dict[key], list) is True: - if len(input_variables_dict[key]) == 2: - if isinstance(input_variables_dict[key], list) is True: - if ( - isinstance(input_variables_dict[key][0], str) is False - or isinstance(input_variables_dict[key][1], int) - is False - ): - bad_input_variables_values_list.append(key) - elif isinstance(input_variables_dict[key][0], str) is True: - if ( - len(input_variables_dict[key][0]) > 4 - or input_variables_dict[key][0] not in self.residues - ): - bad_input_variables_values_list.append(key) - - if ( - isinstance(input_variables_dict[key][1], int) is True - and input_variables_dict[key][1] <= 0 - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_list_bool_bool( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a list with a 2 booleans ([bool, bool]). - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if isinstance(input_variables_dict[key], list) is False: - bad_input_variables_values_list.append(key) - elif isinstance(input_variables_dict[key], list) is True: - if ( - len(input_variables_dict[key]) != 2 - or ( - input_variables_dict[key][0] is not True - and input_variables_dict[key][0] is not False - ) - or ( - input_variables_dict[key][1] is not True - and input_variables_dict[key][1] is not False - ) - or ( - str(input_variables_dict[key][0]) != str(True) - and str(input_variables_dict[key][0]) != str(False) - ) - or ( - str(input_variables_dict[key][1]) != str(True) - and str(input_variables_dict[key][1]) != str(False) - ) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_list_of_floats_zero_to_1( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a list of floats between 0 and 1 ([0,0, 0.1, ..., 1.0]). - Note: the list can be of any length with 0.0 <= float <= 1.0 - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if input_variables_dict[key] is not None: - if isinstance(input_variables_dict[key], list) is False: - bad_input_variables_values_list.append(key) - elif isinstance(input_variables_dict[key], list) is True: - if len(input_variables_dict[key]) >= 1: - for Lambda_i in range(0, len(input_variables_dict[key])): - if ( - isinstance( - input_variables_dict[key][Lambda_i], float - ) - is False - ): - bad_input_variables_values_list.append(key) - elif ( - isinstance( - input_variables_dict[key][Lambda_i], float - ) - is True - ): - if ( - input_variables_dict[key][Lambda_i] < 0.0 - or input_variables_dict[key][Lambda_i] > 1.0 - ): - bad_input_variables_values_list.append(key) - else: - bad_input_variables_values_list.append(key) - - def ck_input_variable_GCMC_dict_str_int_or_float( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a dictionary with a key = string and - value = integer or float ({'str_1' : integer_1 or float_1, ...., - 'str_x' : integer_x or float_x }). - Note: the dictionary can be of any length - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], dict) is not True - ): - bad_input_variables_values_list.append(key) - - elif isinstance(input_variables_dict[key], dict) is True: - keys_list = dict_keys_to_list(input_variables_dict[key]) - for keys_iter_No in range(0, len(keys_list)): - key_iter = keys_list[keys_iter_No] - value_iter = input_variables_dict[key][key_iter] - - if key_iter not in self.residues: - bad_input_variables_values_list.append(key) - - if isinstance(key_iter, str) is False: - bad_input_variables_values_list.append(key) - elif isinstance(key_iter, str) is True: - if len(key_iter) > 4: - bad_input_variables_values_list.append(key) - - if ( - ( - isinstance(value_iter, int) is False - and isinstance(value_iter, float) is False - ) - or str(value_iter) == str(True) - or str(value_iter) == str(False) - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_GCMC_dict_str_int_or_float_zero_or_greater( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a dictionary with a key = string and - value = integer or float zero or greater ({'str_1' : integer_1 or float_1 (>= 0), ...., - 'str_x' : integer_x or float_x (>= 0)}). - Note: the dictionary can be of any length - If not, the provided list is appended with the bad with the dict_key - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if ( - input_variables_dict[key] is not None - and isinstance(input_variables_dict[key], dict) is not True - ): - bad_input_variables_values_list.append(key) - - elif isinstance(input_variables_dict[key], dict) is True: - keys_list = dict_keys_to_list(input_variables_dict[key]) - for keys_iter_No in range(0, len(keys_list)): - key_iter = keys_list[keys_iter_No] - value_iter = input_variables_dict[key][key_iter] - - if key_iter not in self.residues: - bad_input_variables_values_list.append(key) - - if isinstance(key_iter, str) is False: - bad_input_variables_values_list.append(key) - elif isinstance(key_iter, str) is True: - if len(key_iter) > 4: - bad_input_variables_values_list.append(key) - - if ( - ( - isinstance(value_iter, int) is False - and isinstance(value_iter, float) is False - ) - or str(value_iter) == str(True) - or str(value_iter) == str(False) - or value_iter < 0 - ): - bad_input_variables_values_list.append(key) - - def ck_input_variable_str_with_no_spaces( - self, input_variables_dict, key, bad_input_variables_values_list - ): - """ - Checks if the input variable is a string with no spaces. - If not, the provided list is appended with the bad with the dict_key. - - Parameters - ---------- - input_variables_dict: dict - The user input variable dictionary - key: str - Dictionary key for the user provided input variable list - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - - Returns - --------- - bad_input_variables_values_list: list - A list to append with the bad variable user inputs - so the user can see which variable input values are bad. - """ - - if isinstance(input_variables_dict[key], str) is True: - no_spaces_in_OutputName_string = " " in input_variables_dict[key] - if ( - isinstance(input_variables_dict[key], str) is not True - or no_spaces_in_OutputName_string is True - ): - bad_input_variables_values_list.append(key) - - -def _scale_gen_freq_for_run_steps_list_bool_int( - variable_name, charmm_variable, run_steps -): - """ - Scales the frequency of the output to a a more realistic value, - if the output frequency does not make sense based on the - total number of simulation run steps. - - Parameters - ---------- - variable_name, str - The variable name as a sting, which is used for printing error outputs. - charmm_variable : GOMCControl object variable list, [bool, int] - This only for the frequency output variables of the GOMCControl object - run_steps : int (>0), must be an integer greater than zero. - This is the GOMCControl object varaible which sets the total number of simulation steps. - This should be the RunSteps variable in the GOMCControl object. - - Returns - --------- - charmm_variable : GOMCControl object variable list [bool, int] - A rescaled and appropriate value for the frequency output variables of the - GOMCControl object, based on the RunSteps in the simulation. - """ - if not isinstance(charmm_variable, list): - print_error_message = "ERROR: The {} variable is not a list.".format( - variable_name - ) - raise ValueError(print_error_message) - - if len(charmm_variable) != 2: - print_error_message = ( - "ERROR: The {} variable list length is not 2.".format( - variable_name - ) - ) - raise ValueError(print_error_message) - - else: - if not isinstance(charmm_variable[0], bool): - print_error_message = ( - "ERROR: The {} variable is not a boolean.".format( - variable_name - ) - ) - raise ValueError(print_error_message) - - if not isinstance(charmm_variable[1], int): - print_error_message = ( - "ERROR: The {} variable is not a int.".format(variable_name) - ) - raise ValueError(print_error_message) - - set_max_steps_charmm_variable = charmm_variable[1] - - if run_steps / 10 >= set_max_steps_charmm_variable and run_steps / 10 >= 1: - charmm_variable[1] = int(set_max_steps_charmm_variable) - elif run_steps / 10 >= 1: - charmm_variable[1] = int(run_steps / 10) - else: - charmm_variable[1] = int(1) - - return charmm_variable - - -def _scale_gen_freq_for_run_steps_int( - variable_name, charmm_variable, run_steps -): - """ - Scales the frequency of the output to a a more realistic value, - if the output frequency does not make sense based on the - total number of simulation run steps. - - Parameters - ---------- - variable_name, str - The variable name as a sting, which is used for printing error outputs. - charmm_variable : GOMCControl object variable, int - This only for the frequency output variables of the GOMCControl object - run_steps : int (>0), must be an integer greater than zero. - This is the GOMCControl object varaible which sets the total number of simulation steps. - This should be the RunSteps variable in the GOMCControl object. - - Returns - --------- - charmm_variable : GOMCControl object variable list, int - A rescaled and appropriate value for the frequency output variables of the - GOMCControl object, based on the RunSteps in the simulation. - """ - if not isinstance(charmm_variable, int): - print_error_message = ( - "ERROR: The {} variable is not an interger.".format(variable_name) - ) - raise ValueError(print_error_message) - - set_max_steps_charmm_variable = charmm_variable - - if run_steps / 10 >= set_max_steps_charmm_variable and run_steps / 10 >= 1: - charmm_variable = int(set_max_steps_charmm_variable) - elif run_steps / 10 >= 1: - charmm_variable = int(run_steps / 10) - else: - charmm_variable = int(1) - - return charmm_variable - - -def ck_box_dim_is_float_or_int_greater_0( - charmm_box_dimension, dimension, box_no, ensemble_type -): - """ - Scales the frequency of the output to a a more realistic value, - if the output frequency does not make sense based on the - total number of simulation run steps. - - Parameters - ---------- - charmm_box_dimension : GOMCControl object box dimension variable - This is the variable that contains the box input x, y, or z dimensions for box 0 or 1. - dimension : str (Only enter 'x', 'y', or 'z') - This is the dimension of the charmm_box_dimension variable. - Only enter 'x', 'y', or 'z', but it will not error out if you do not. - box_no : int (only 0 or 1) - This is the box number which is defined in the mbuild.Charmm object - Only enter only 0 or 1, but it will not error out if you do not. - ensemble_type : str, valid options are 'NVT', 'NPT', 'GEMC_NVT', 'GEMC_NPT', 'GCMC' - The ensemble type of the simulation. - - Returns - --------- - If charmm_box_dimension is an int or float (>0) : None - If charmm_box_dimension is not an int or float (>0) : raise ValueError - - """ - - if ( - isinstance(charmm_box_dimension, int) is False - and isinstance(charmm_box_dimension, float) is False - ) or charmm_box_dimension <= 0: - print_error_message = "ERROR: The {}-dimension for box {} is, {} , not an integer, float, " - "or is <= 0.".format(dimension, box_no, charmm_box_dimension) - raise ValueError(print_error_message) - - if ( - (ensemble_type in ["GEMC_NVT", "GEMC_NPT", "GCMC"]) - and charmm_box_dimension is None - and box_no == 1 - ): - print_error_message = ( - "ERROR: The {}-dimension for box {} was not provided. " - "The {}-dimension for box {}, " - " is required to be an an integer, float, and be > 0.".format( - dimension, box_no, dimension, box_no - ) - ) - raise ValueError(print_error_message) - - return None - - -def _check_box_vectors_char_limit(vectors, char_limit): - """ - Checks to see if the vectors exceed the specified character limit - - Parameters - ---------- - vectors : numpy.ndarray, [[float, float, float], [float, float, float], [float, float, float]] - Three (3) sets vectors for box 0 each with 3 float values, which represent - the vectors for the Charmm-style systems (i.e, the CellBasisVectors). - char_limit : int - The specified number of allowable characters for each individual value in the vectors. - - Returns - ------- - bool: - True, if within the allowable character limit - False, if not within the allowable character limit - """ - - for x_i in range(0, 3): - for y_i in range(0, 3): - if len(str(vectors[x_i][y_i])) > char_limit: - return False - return True - - -def _check_if_input_files_exist( - file_directory_and_name, - type_of_file, - check_input_files_exist=True, -): - """ - Checks to see GOMC FF, pdb, and psf files exist - - Parameters - ---------- - file_directory_and_name : str - The file directory and name of the file. - type_of_file : str - A brief description of the file which is evaluated. - check_input_files_exist: bool (default=True) - Check if the force field, psf, and pdb files exist. - If the files are checked and do not exist, the writer will throw a ValueError. - True, check if the force field, psf, and pdb files exist. - False, do not check if the force field, psf, and pdb files exist. - - Returns - ------- - If the file exists : None - If the file does not exist : raise ValueError - """ - if ( - os.path.isfile(file_directory_and_name) is False - and check_input_files_exist is True - ): - print_error_message = ( - "The {} with the file directory and name {}, " - "does not exist.".format(type_of_file, file_directory_and_name) - ) - raise ValueError(print_error_message) - - -def _check_if_string_and_extension( - file_directory_and_name, - file_directory_and_name_variable, - type_of_file, - expected_file_extension=None, -): - """ - Checks to see GOMC FF, pdb, and psf files exist - - Parameters - ---------- - file_directory_and_name : str - The file directory and name of the file. - file_directory_and_name_variable : variable - The variable for the file directory and name of the file. - type_of_file : str - A brief description of the file which is evaluated (force file, psf, pdb). - expected_file_extension : list of strings (optional), [str, ..., str], default=None - The expected file extensions that are checked against the actual file extension. - - Returns - ------- - If the variable is a string : None - If the variable is not a string : raise TypeError - If the variable is a string and has the correct extension : None - If the variable is a string and has the wrong extension : raise TypeError - """ - if ( - not isinstance(file_directory_and_name_variable, str) - and file_directory_and_name_variable is not None +class GOMCControl: + def __init__( + self, + charmm_object, + ensemble_type, + RunSteps, + Temperature, + ff_psf_pdb_file_directory=None, + check_input_files_exist=True, + Restart=False, + RestartCheckpoint=False, + ExpertMode=False, + Parameters=None, + Coordinates_box_0=None, + Structure_box_0=None, + Coordinates_box_1=None, + Structure_box_1=None, + binCoordinates_box_0=None, + extendedSystem_box_0=None, + binVelocities_box_0=None, + binCoordinates_box_1=None, + extendedSystem_box_1=None, + binVelocities_box_1=None, + input_variables_dict=None, ): - print( - "file_directory_and_name_variable =" - + str(file_directory_and_name_variable) - ) - print_error_message = ( - r"ERROR: The {} variable for directly entering the " - r"{} file directory and name is a {} and not a string.".format( - file_directory_and_name, - type_of_file, - type(file_directory_and_name_variable), - ) - ) - raise TypeError(print_error_message) - - if expected_file_extension is not None: - acutal_file_extension = os.path.splitext( - file_directory_and_name_variable - )[-1] - if acutal_file_extension not in expected_file_extension: - print_error_message = ( - r"ERROR: The {} variable expects a file extension of {}, " - r'but the actual file extension is "{}". ' - r"".format( - file_directory_and_name, - expected_file_extension, - acutal_file_extension, - ) - ) - raise TypeError(print_error_message) - - -def _check_if_bool( - variable_as_a_string, - variable, -): - """ - Checks to see if the variable is a boolean. - - Parameters - ---------- - variable_as_a_string : str - The variable name as a string. - variable : variable - The variable to test if it is a boolean. - - Returns - ------- - If the variable is a bool : None - If the variable is not a bool : raise TypeError - """ - if not isinstance(variable, bool): - print_error_message = ( - "ERROR: The {} input is {} and needs to be a boolean (i.e., True or False)." - "".format(variable_as_a_string, type(variable)) + depreciation_error = ( + "The mosdef_gomc 'gomc_conf_writer.py' has been depreciated, and the entire 'gomc_conf_writer.py' " + "file will be removed/deleted soon." + "The this only effects the mosdef-gomc 'gomc_conf_writer' parmed version. The GMSO version, " + "'gmso_gomc_conf_writer.py', has replaced it with more features, so please use this GMSO version." ) - raise TypeError(print_error_message) + raise ModuleNotFoundError(depreciation_error) # user callable function to write the GOMC control file @@ -8005,911 +57,7 @@ def write_gomc_control_file( binVelocities_box_1=None, input_variables_dict=None, ): - """ - The usable command that creates the ``GOMCControl`` object and writes - the GOMC control file via the ``GOMCControl.write_conf_file`` function. - - Constructs the GOMC GOMCControl object with the defaults, - or adding additional data in the input_variable section. - Default setting for the GOMC configuraion files are based upon - an educated guess, which should result in reasonable sampling for a - given ensemble/simulation type. However, there is no guarantee that - the default setting will provide the best or adequate sampling for - the selected system. The user has the option to modify the - configuration/control files based on the simulation specifics or to - optimize the system beyond the standard settings. These override - options are available via the keyword arguments in input_variable_dict. - - Parameters - ---------- - charmm_object : Charmm object - Charmm object is has been parameterized from the selected force field. - ensemble_typ : str, ['NVT', 'NPT', 'GEMC_NPT', 'GCMC-NVT', 'GCMC'] - The ensemble type of the simulation. - RunSteps : int (>0), must be an integer greater than zero. - Sets the total number of simulation steps. - Temperature : float or int (>0), must be an integer greater than zero. - Temperature of system in Kelvin (K) - ff_psf_pdb_file_directory : str (optional), default=None (i.e., the current directory). - The full or relative directory added to the force field, psf, and pdb - file names, created via the Charmm object. - check_input_files_exist : bool, (default=True) - Check if the force field, psf, and pdb files exist. - If the files are checked and do not exist, the writer will throw a ValueError. - True, check if the force field, psf, and pdb files exist. - False, do not check if the force field, psf, and pdb files exist. - Restart : boolean, default = False - Determines whether to restart the simulation from restart file - (``*_restart.pdb`` and ``*_restart.psf``) or not. - RestartCheckpoint : boolean, default = False - Determines whether to restart the simulation with the checkpoint - file (checkpoint.dat) or not. Restarting the simulation with checkpoint.dat - would result in an identical outcome, as if previous simulation was continued. - ExpertMode : boolean, default = False - This allows the move ratios to be any value, regardless of the ensemble, - provided all the move ratios sum to 1. For example, this mode is utilized - to easily equilibrate a GCMC or GEMC ensemble in a pseudo NVT mode by removing - the requirement that the volume and swap moves must be non-zero. - In other words, when the volume and swap moves are zero, the GCMC and GEMC - ensembles will run pseudo NVT simulations in 1 and 2 simulation boxes, respectively. - The simulation's output and restart files will keep their original output structure - for the selected ensemble, which is advantageous when automating a workflow. - Parameters : str, (default=None) - Override all other force field directory and filename input with the correct extension (.inp or .par). - Note: the default directory is the current directory with the Charmm object file name. - Coordinates_box_0 : str, (default=None) - Override all other box 0 pdb directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Structure_box_0 : str, (default=None) - Override all other box 0 psf directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Coordinates_box_1 : str, (default=None) - Override all other box 1 pdb directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Structure_box_1 : str, (default=None) - Override all other box 1 psf directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - binCoordinates_box_0 : str, (default=None) - The box 0 binary coordinate file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. - extendedSystem_box_0 : str, (default=None) - The box 0 vectors and origin file is used only for restarting a GOMC simulation. - binVelocities_box_0 : str, (default=None) - The box 0 binary velocity file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. These velocities are only passed thru - GOMC since Monte Carlo simulations do not utilize any velocity information. - binCoordinates_box_1 : str, (default=None) - The box 1 binary coordinate file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. - extendedSystem_box_1 : str, (default=None) - The box 1 vectors and origin file is used only for restarting a GOMC simulation. - binVelocities_box_1 : str, (default=None) - The box 1 binary velocity file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. These velocities are only passed thru - GOMC since Monte Carlo simulations do not utilize any velocity information. - input_variables_dict: dict, default=None - These input variables are optional and override the default settings. - Changing these variables likely required for more advanced systems. - The details of the acceptable input variables for the selected - ensembles can be found by running the code below in python, - >>>print_valid_ensemble_input_variables('GCMC', description = True) - which prints the input_variables with their subsection description - for the selected 'GCMC' ensemble (other ensembles can be set as well). - - Example : input_variables_dict = {'PRNG' : 123, - 'ParaTypeCHARMM' : True } - - # ******************************************************************* - # input_variables_dict options (keys and values) - (start) - # Note: the input_variables_dict keys are also attributes - # ******************************************************************* - PRNG : string or int (>= 0) ("RANDOM" or int), default = "RANDOM" - PRNG = Pseudo-Random Number Generator (PRNG). There are two (2) options, entering - the string, "RANDOM", or a integer. - - --- "RANDOM": selects a random seed number. This will enter the line - "PRNG RANDOM" in the gomc configuration file. - - --- integer: which defines the integer seed number for the simulation. This is - equivalent to entering the following two lines in the configuration file - - line 1 = PRNG INTSEED - - line 2 = Random_Seed user_selected_integer. - - Example 1: for a random seed enter the string "RANDOM". - - Example 2: for a specific seed number enter a integer of your choosing. - - ParaTypeCHARMM : boolean, default = True - True if a CHARMM forcefield, False otherwise. - ParaTypeMie : boolean, default = False - True if a Mie forcefield type, False otherwise. - ParaTypeMARTINI : boolean, default = False - True if a MARTINI forcefield, False otherwise. - RcutCoulomb_box_0 : int or float (>= 0), default = None - Sets a specific radius in box 0 where the short-range electrostatic - energy will be calculated (i.e., The distance to truncate the - short-range electrostatic energy in box 0.) - Note: if None, GOMC will default to the Rcut value - RcutCoulomb_box_1 : int or float (>= 0), default = None - Sets a specific radius in box 1 where the short-range electrostatic - energy will be calculated (i.e., The distance to truncate the - short-range electrostatic energy in box 0.) - Note: if None, GOMC will default to the Rcut value - Pressure : int or float (>= 0), default = 1.01325 - The pressure in bar utilized for the NPT and GEMC_NPT simulations. - Rcut : int or float (>= 0 and RcutLow < Rswitch < Rcut), default = 10 - Sets a specific radius in Angstroms that non-bonded interaction - energy and force will be considered and calculated using defined potential function. - The distance in Angstoms to truncate the LJ, Mie, or other VDW type potential at. - Note: Rswitch is only used when the "Potential" = SWITCH. - RcutLow : int or float (>= 0 and RcutLow < Rswitch < Rcut), default = 0 - Sets a specific minimum possible distance in Angstroms that reject - any move that places any atom closer than specified distance. - The minimum possible distance between any atoms. - Sets a specific radius in Angstroms that non-bonded interaction - Note: Rswitch is only used when the "Potential" = SWITCH. - WARNING: When using a molecule that has charge atoms with non-bonded epsilon values of zero (i.e., water), - the RcutLow need to be greater than zero, typically 1 angstrom. - WARNING: When using the free energy calculations, RcutLow needs to be set to zero (RcutLow=0); - otherwise, the free energy calculations can produce results that are slightly off or wrong. - LRC : boolean, default = True - If True, the simulation considers the long range tail corrections for the - non-bonded VDW or dispersion interactions. - Note: In case of using SHIFT or SWITCH potential functions, LRC will be ignored. - IPC : boolean, default = False - If True, the simulation adds the impulse correction term to the pressure, - which considers to correct for the discontinuous Rcut potential - (i.e., a hard cutoff potential, meaning a potential without tail corrections) - the long range tail corrections for the non-bonded VDW or dispersion interactions. - If False, the impulse correction term to the pressure is not applied. - Note: This can not be used if LRC is True or the Potential is set to SWITCH, or SHIFT. - Exclude : str ["1-2", "1-3", or "1-4"], default = "1-3" - Note: In CHARMM force field, the 1-4 interaction needs to be considered. - Choosing "Excude 1-3", will modify 1-4 interaction based on 1-4 parameters - in parameter file. If a kind force field is used, where 1-4 interaction - needs to be ignored, such as TraPPE, either Exclude "1-4" needs to be - chosen or 1-4 parameter needs to be assigned to zero in the parameter file. - - --- "1-2": All interaction pairs of bonded atoms, except the ones that - separated with one bond, will be considered and modified using 1-4 - parameters defined in parameter file. - - --- "1-3": All interaction pairs of bonded atoms, except the ones that - separated with one or two bonds, will be considered and modified using - 1-4 parameters defined in parameter file. - - --- "1-4": All interaction pairs of bonded atoms, except the ones that - separated with one, two or three bonds, will be considered using - non-bonded parameters defined in parameter file. - - Potential : str, ["VDW", "EXP6", "SHIFT" or "SWITCH"], default = "VDW" - Defines the potential function type to calculate non-bonded dispersion - interaction energy and force between atoms. - - --- "VDW": Non-bonded dispersion interaction energy and force - calculated based on n-6 (Lennard - Jones) equation. This - function will be discussed further in the Intermolecular energy - and Virial calculation section. - - --- "EXP6": Non-bonded dispersion interaction energy and force calculated - based on exp-6 (Buckingham potential) equation. - - --- "SHIFT": This option forces the potential energy to be zero at Rcut distance. - - --- "SWITCH": This option smoothly forces the potential energy to be zero at - Rcut distance and starts modifying the potential at Rswitch - distance. Depending on force field type, specific potential - function will be applied. - - Rswitch : int or float (>= 0 and RcutLow < Rswitch < Rcut), default = 9 - Note: Rswitch is only used when the SWITCH function is used - (i.e., "Potential" = SWITCH). The Rswitch distance is in Angstrom. If the - “SWITCH” function is chosen, Rswitch needs to be defined, otherwise, the - program will be terminated. When using choosing "SWITCH" as potential function, - the Rswitch distance defines where the non-bonded interaction energy - modification is started, which is eventually truncated smoothly at Rcut - distance. - ElectroStatic : boolean, default = True - Considers the coulomb interactions or not. If True, coulomb interactions are - considered and false if not. Note: To simulate the polar molecule in MARTINI - force field, ElectroStatic needs to be turn on (i.e., True). The MARTINI force - field uses short-range coulomb interaction with constant Dielectric of 15.0. - Ewald : boolean, default = True - Considers the standard Ewald summation method for electrostatic calculations. - If True, Ewald summation calculation needs to be considered and false if not. - Note: By default, GOMC will set ElectroStatic to True if Ewald summation - method was used to calculate coulomb interaction. - CachedFourier : boolean, default = False - Considers storing the reciprocal terms for Ewald summation calculation in - order to improve the code performance. This option would increase the code - performance with the cost of memory usage. If True, to store reciprocal - terms of Ewald summation calculation and False if not. - Warning: Monte Carlo moves, such as MEMC-1, MEMC-2, MEMC-3, - IntraMEMC-1, IntraMEMC-2, and IntraMEMC-3 are not support with CachedFourier. - Tolerance : float (0.0 < float < 1.0), default = 1e-05 - Sets the accuracy in Ewald summation calculation. Ewald separation parameter - and number of reciprocal vectors for the Ewald summation are determined - based on the accuracy parameter. - Dielectric : int or float (>= 0.0), default = 15 - Sets dielectric value used in coulomb interaction when the Martini - force field is used. Note: In MARTINI force field, Dielectric needs to - be set to 15.0. - PressureCalc : list [bool , int (> 0)] or [bool , step_frequency], - default = [True, 10k] or [True , set via formula based on the number of RunSteps or 10k max] - Calculate the system pressure or not. bool = True, enables the pressure calculation - during the simulation, false disables the calculation. The int/step frequency sets the - frequency of calculating the pressure. - EqSteps : int (> 0), default = set via formula based on the number of RunSteps or 1M max - Sets the number of steps necessary to equilibrate the system. - Averaging will begin at this step. - Note: In GCMC simulations, the Histogram files will be outputed at EqSteps. - AdjSteps : int (> 0), default = set via formula based on the number of RunSteps or 1k max - Sets the number of steps per adjustment of the parameter associated with each move - (e.g. maximum translate distance, maximum rotation, maximum volume exchange, etc.). - VDWGeometricSigma: boolean, default = False - Use geometric mean, as required by OPLS force field, to combining - Lennard-Jones sigma parameters for different atom types. - If set to True, GOMC uses geometric mean to combine Lennard-Jones or VDW sigmas. - Note: The default setting of VDWGeometricSigma is false, which uses the arithmetic - mean when combining Lennard-Jones or VDW sigma parameters for different atom types. - useConstantArea : boolean, default = False - Changes the volume of the simulation box by fixing the cross-sectional - area (x-y plane). If True, the volume will change only in z axis, - If False, the volume of the box will change in a way to maintain the constant - axis ratio. - FixVolBox0 : boolean, default = False - Changing the volume of fluid phase (Box 1) to maintain the constant imposed - pressure and Temperature, while keeping the volume of adsorbed phase (Box 0) fixed. - Note: By default, GOMC will set useConstantArea to False if no value was set. - It means, the volume of the box will change in a way to maintain the constant - axis ratio. - ChemPot : dict {str (4 dig limit) , int or float}, default = None - The chemical potentials in GOMC units of energy, K. - There is a 4 character limit for the string/residue name since the PDB/PSF - files have a 4 character limitation and require and exact match in the conf file. - Note: These strings must match the residue in the psf and psb files or it will fail. - The name of the residues and their corresponding chemical potential must specified - for every residue in the system (i.e., {"residue_name" : chemical_potential}). - Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY - OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. - - Example 1 (system with only water): {"H2O" : -4000} - - Example 2 (system with water and ethanol): {"H2O" : -4000, "ETH" : -8000} - - Fugacity : dict {str , int or float (>= 0)}, default = None - The fugacity in GOMC units of pressure, bar. - There is a 4 character limit for the string/residue name since the PDB/PSF - files have a 4 character limitation and require and exact match in the conf file. - Note: These strings must match the residue in the psf and psb files or it will fail. - The name of the residues and their corresponding fugacity must specified - for every residue in the system (i.e., {"residue_name" : fugacity}). - Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY - OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. - - Example 1 (system with only water): {"H2O" : 1} - - Example 2 (system with water and ethanol): {"H2O" : 0.5, "ETH" : 10} - - CBMC_First : int (>= 0), default = 12 - The number of CD-CBMC trials to choose the first atom position - (Lennard-Jones trials for first seed growth). - CBMC_Nth : int (>= 0), default = 10 - The Number of CD-CBMC trials to choose the later atom positions - (Lennard-Jones trials for first seed growth). - CBMC_Ang : int (>= 0), default = 50 - The Number of CD-CBMC bending angle trials to perform for geometry - (per the coupled-decoupled CBMC scheme). - CBMC_Dih : int (>= 0), default = 50 - The Number of CD-CBMC dihedral angle trials to perform for geometry - (per the coupled-decoupled CBMC scheme). - OutputName : str (NO SPACES), , default = "Output_data", default = [True, 1M] or - [True , set via formula based on the number of RunSteps or 1M max] - The UNIQUE STRING NAME, WITH NO SPACES, which is used for the - output block average, PDB, and PSF file names. - CoordinatesFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 1M] or [True , set via formula based on the number of RunSteps or M max] - Controls output of PDB file (coordinates). If bool is True, this - enables outputting the coordinate files at the integer frequency - (set steps_per_data_output_int), while "False" disables outputting - the coordinates. - DCDFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 1M] or [True , set via formula based on the number of RunSteps or M max] - Controls output of DCD file (coordinates). If bool is True, this - enables outputting the coordinate files at the integer frequency - (set steps_per_data_output_int), while "False" disables outputting - the coordinates. - RestartFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 1M] or [True , set via formula based on the number of RunSteps or 1M max] - This creates the PDB and PSF (coordinate and topology) files for - restarting the system at the set steps_per_data_output_int (frequency) - If bool is True, this enables outputting the PDB/PSF restart files at the - integer frequency (set steps_per_data_output_int), while “false” - disables outputting the PDB/PSF restart files. - CheckpointFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 1M] or [True , set via formula based on the number of RunSteps or 1M max] - Controls the output of the last state of simulation at a specified step, - in a binary file format (checkpoint.dat). Checkpoint file contains the - following information in full precision: - - (1) Last simulation step that saved into checkpoint file - - (2) Simulation cell dimensions and angles - - (3) Maximum amount of displacement (Å), rotation (δ), and volume (Å^3) - that is used in the Displacement, Rotation, MultiParticle, and Volume moves - - (4) Number of Monte Carlo move trial and acceptance - - (5) All molecule’s coordinates - - (6) Random number sequence - - If bool is True, this enables outputing the checkpoint file at the - integer frequency (set steps_per_data_ouput_int), - while "False" disables outputting the checkpoint file. - ConsoleFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 10k] or [True , set via formula based on the number of RunSteps or 10k max] - Controls the output to the "console" or log file, which prints the - acceptance statistics, and run timing info. In addition, instantaneously-selected - thermodynamic properties will be output to this file. If bool is True, - this enables outputting the console data at the integer frequency - (set steps_per_data_output_int), while "False" disables outputting the console - data file. - BlockAverageFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 10k] or [True , set via formula based on the number of RunSteps or 10k max] - Controls the block averages output of selected thermodynamic properties. - Block averages are averages of thermodynamic values of interest for chunks of the - simulation (for post-processing of averages or std. dev. in those values). - If bool is True, this enables outputting the block averaging data/file at the - integer frequency (set steps_per_data_output_int), while "False" - disables outputting the block averaging data/file. - HistogramFreq : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = [True, 10k] or [True , set via formula based on the number of RunSteps or 10k max] - Controls the histograms. Histograms are a binned listing of observation frequency - for a specific thermodynamic variable. In the GOMC code, they also control the output - of a file containing energy/molecule samples, which is only used for the "GCMC" - ensemble simulations for histogram reweighting purposes. If bool is True, this - enables outputting the data to the histogram data at the integer frequency - (set steps_per_data_output_int), while "False" disables outputting the histogram - data. - DistName : str (NO SPACES), default = "dis" - Short phrase which will be combined with RunNumber and RunLetter - to use in the name of the binned histogram for molecule distribution. - HistName : str (NO SPACES), default = "his" - Short phrase, which will be combined with RunNumber and RunLetter, - to use in the name of the energy/molecule count sample file. - RunNumber : int ( > 0 ), default = 1 - Sets a number, which is a part of DistName and HistName file name. - RunLetter : str (1 alphabetic character only), default = "a" - Sets a letter, which is a part of DistName and HistName file name. - SampleFreq : int ( > 0 ), default = 500 - The number of steps per histogram sample or frequency. - OutEnergy : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the energy data into the block averages and console output/log - OutPressure : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the pressure data into the block averages and console output/log files. - OutMolNum : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the number of molecules data into the block averages and console - output/log files. - OutDensity : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the density data into the block averages and console output/log files. - OutVolume : [bool, bool], default = [True, True] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the volume data into the block averages and console output/log files. - OutSurfaceTension : [bool, bool], default = [False, False] - The list provides the booleans to [block_averages_bool, console_output_bool]. - This outputs the surface tension data into the block averages and console - output/log files. - FreeEnergyCalc : list [bool , int (> 0)] or [Generate_data_bool , steps_per_data_output_int], - default = None - bool = True enabling free energy calculation during the simulation, false disables - the calculation. The int/step frequency sets the frequency of calculating the free energy. - WARNING: When using the free energy calculations, RcutLow needs to be set to zero (RcutLow=0); - otherwise, the free energy calculations can produce results that are slightly off or wrong. - MoleculeType : list [str , int (> 0)] or ["residue_name" , residue_ID], default = None - The user must set this variable as there is no working default. - Note: ONLY 4 characters can be used for the string (i.e., "residue_name"). - Sets the solute molecule kind (residue name) and molecule number (residue ID), - which absolute solvation free will be calculated for. - InitialState : int (>= 0), default = None - The user must set this variable as there is no working default. - The index of LambdaCoulomb and LambdaVDW vectors. Sets the index of the - LambdaCoulomb and LambdaVDW vectors, to determine the simulation lambda value for - VDW and Coulomb interactions. - WARNING : This must an integer within the vector count of the LambdaVDW and LambdaCoulomb, - in which the counting starts at 0. - LambdaVDW : list of floats (0 <= floats <= 1), default = None - The user must set this variable as there is no working default (default = {}). - Lambda values for VDW interaction in ascending order. Sets the intermediate - lambda states to which solute-solvent VDW interactions are scaled. - - WARNING : This list must be the same length as the "LambdaCoulomb" list length. - - WARNING : All lambda values must be stated in the ascending order, - starting with 0.0 and ending with 1.0; otherwise, the program will terminate. - - Example of ascending order 1: [0.0, 0.1, 1.0] - - Example of ascending order 2: [0.0, 0.1, 0.2, 0.4, 0.9, 1.0] - - LambdaCoulomb : list of floats (0 <= floats <= 1), default = None - Lambda values for Coulombic interaction in ascending order. Sets the intermediate - lambda states to which solute-solvent Coulombic interactions are scaled. - GOMC defauts to the "LambdaVDW" values for the Coulombic interaction - if no "LambdaCoulomb" variable is set. - - WARNING : This list must be the same length as the "LambdaVDW" list length. - - WARNING : All lambda values must be stated in the ascending order, - starting with 0.0 and ending with 1.0; otherwise, the program will terminate. - - Example of ascending order 1: [0.0, 0.1, 1.0] - - Example of ascending order 2: [0.0, 0.1, 0.2, 0.4, 0.9, 1.0] - - ScaleCoulomb : bool, default = False - Determines to scale the Coulombic interaction non-linearly - (soft-core scheme) or not. - True if the Coulombic interaction needs to be scaled non-linearly. - False if the Coulombic interaction needs to be scaled linearly. - ScalePower : int (>= 0), default = 2 - The p value in the soft-core scaling scheme, where the distance - between solute and solvent is scaled non-linearly. - ScaleAlpha : int or float (>= 0), default = 0.5 - The alpha value in the soft-core scaling scheme, where the distance - between solute and solvent is scaled non-linearly. - MinSigma : int or float (>= 0), default = 3 - The minimum sigma value in the soft-core scaling scheme, where the - distance between solute and solvent is scaled non-linearly. - DisFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.15, 'NPT': 0.15, 'GEMC_NVT': 0.2, 'GEMC_NPT': 0.19, 'GCMC': 0.15} - Fractional percentage at which the displacement move will occur - (i.e., fraction of displacement moves). - RotFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.15, 'NPT': 0.15, 'GEMC_NVT': 0.2, 'GEMC_NPT': 0.2, 'GCMC': 0.15} - Fractional percentage at which the rotation move will occur. - (i.e., fraction of rotation moves). - IntraSwapFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.3, 'NPT': 0.29, 'GEMC_NVT': 0.1, 'GEMC_NPT': 0.1, 'GCMC': 0.1} - Fractional percentage at which the molecule will be removed from a - box and inserted into the same box using coupled-decoupled configurational-bias - algorithm. (i.e., fraction of intra-molecule swap moves). - SwapFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.2, 'GEMC_NPT': 0.2, 'GCMC': 0.35} - For Gibbs and Grand Canonical (GC) ensemble runs only: Fractional - percentage at which molecule swap move will occur using coupled-decoupled - configurational-bias. (i.e., fraction of molecule swaps moves). - RegrowthFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.3, 'NPT': 0.3, 'GEMC_NVT': 0.2, 'GEMC_NPT': 0.2, 'GCMC': 0.15} - Fractional percentage at which part of the molecule will be deleted and - then regrown using coupled- decoupled configurational-bias algorithm - (i.e., fraction of molecular growth moves). - CrankShaftFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.1, 'NPT': 0.1, 'GEMC_NVT': 0.1, 'GEMC_NPT': 0.1, 'GCMC': 0.1} - Fractional percentage at which crankshaft move will occur. - In this move, two atoms that are forming angle or dihedral are selected - randomly and form a shaft. Then any atoms or group that are within these - two selected atoms, will rotate around the shaft to sample intra-molecular - degree of freedom (i.e., fraction of crankshaft moves). - VolFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.01, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.01, 'GCMC': 0.0} - For isobaric-isothermal (NPT) ensemble and Gibbs ensemble - (GEMC_NPT and GEMC_NVT) runs only: Fractional percentage at - which a volume move will occur (i.e., fraction of Volume moves). - MultiParticleFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which multi-particle move will occur. - In this move, all molecules in the selected simulation box will be rigidly - rotated or displaced simultaneously, along the calculated torque or force - respectively (i.e., fraction of multi-particle moves). - IntraMEMC-1Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will be - exchanged with a specified large molecule kind in defined sub-volume within - same simulation box. This move need additional information such as - ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, and ExchangeLargeKind. - MEMC-1Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will - be exchanged with a specified large molecule kind in defined sub-volume, - between simulation boxes. This move need additional information such as - ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, and ExchangeLargeKind. - IntraMEMC-2Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind - will be exchanged with a specified large molecule kind in defined sub-volume - within same simulation box. Backbone of small and large molecule kind will be - used to insert the large molecule more efficiently. This move need additional - information such as ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, - ExchangeLargeKind, SmallKindBackBone, and LargeKindBackBone. - MEMC-2Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will be - exchanged with a specified large molecule kind in defined sub-volume, - between simulation boxes. Backbone of small and large molecule kind will be - used to insert the large molecule more efficiently. This move need additional - information such as ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, - ExchangeLargeKind, SmallKindBackBone, and LargeKindBackBone. - IntraMEMC-3Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will be - exchanged with a specified large molecule kind in defined sub-volume within same - simulation box. Specified atom of the large molecule kind will be used to insert - the large molecule using coupled-decoupled configurational-bias. This move need - additional information such as ExchangeVolumeDim, ExchangeRatio, ExchangeSmallKind, - ExchangeLargeKind, and LargeKindBackBone. - MEMC-3Freq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0.0} - Fractional percentage at which specified number of small molecule kind will be - exchanged with a specified large molecule kind in defined sub-volume, - between simulation boxes. Specified atom of the large molecule kind will be - used to insert the large molecule using coupled-decoupled configurational-bias. - This move need additional information such as ExchangeVolumeDim, - ExchangeRatio, ExchangeSmallKind, ExchangeLargeKind, and LargeKindBackBone. - TargetedSwapFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0} - Fractional percentage at which targeted swap move will occur. - Note: This is only usable with the 'GCMC', 'GEMC_NVT', and 'GEMC_NPT' ensembles. - Note: This is used in conjunction with the "TargetedSwap_DataInput" variables. - IntraTargetedSwapFreq : int or float (0 <= value <= 1), default are specific for each ensemble - {'NVT': 0.0, 'NPT': 0.0, 'GEMC_NVT': 0.0, 'GEMC_NPT': 0.0, 'GCMC': 0} - Note: This is used in conjunction with the "TargetedSwap_DataInput" variables. - TargetedSwap_DataInput : dict, default=None - A dictionary which can contain one or several targeted swap regions, each designated with - their own tag ID number (aka, subvolume number). - A few examples for TargetedSwap_DataInput input is provided below. - NOTE: MULTIPLE SIMULATION BOXES CAN BE UTILIZED BY SETTING MULTIPLE tag_ID_integer VALUES (INTEGERS VALUES), - NOTE: THIS IS REQUIRED WHEN USING EITHER THE "TargetedSwapFreq" OR "IntraTargetedSwapFreq" MC MOVES. - WARNING: THE tag_ID_integer VALUES MUST BE UNIQUE FOR EACH SUBVOLUME, - OR THE DICTIONARY WILL OVERWRITE THE PREVIOUS SUBVOLUME (tag_ID_integer) SECTION - WITH THE CURRENT tag_ID_integer AND ITS RESPECTIVE VALUES. - - Example 1 - input_variables_dict={"TargetedSwap_DataInput": {tag_ID_integer: {"SubVolumeType": "dynamic", - "SubVolumeBox": 0, "SubVolumeCenterList": ['0-10', 12, 15, '22-40'], "SubVolumeDim": [1, 2, 3], - "SubVolumeResidueKind": "ALL", "SubVolumeRigidSwap": False, "SubVolumePBC": "XY", - "SubVolumeChemPot": {"MET": -21, "met": -31}}} - - Example 2 - input_variables_dict={"TargetedSwap_DataInput": {tag_ID_integer: {"SubVolumeType": "static", - "SubVolumeBox": 0, "SubVolumeCenter": [1, 12, 15], "SubVolumeDim": [3, 3, 3], - "SubVolumeResidueKind": ["MET", "met"], "SubVolumeRigidSwap": False, "SubVolumePBC": "XYZ", - "SubVolumeFugacity": {"MET": 0.1, "met": 1}}} - - The details of each key and value for the "TargetedSwap_DataInput" are provided below. - - --- "SubVolumeType" : str ("static" or "dynamic"), No default is provided. - The type of targeted swap box (subvolume) that will be created. - The "static" type will maintain the box (subvolume) in a fixed location during the whole simulation, - with the center of the box determined by the coordinates set in the - "SubvolumeCenter" parameter. - The "dynamic" type will allow for dynamic movement of the box (subvolume) based atom indices - provided in the SubvolumeCenterList variable. For the "dynamic" type, the user must define a - list of atom indices using "SubVolumeCenterList" keyword; the geometric center of the - provided atom indices will be used as the center of subVolume. User must ensure that the - atoms defined in the atom list remain in the simulation box (by setting the Beta value to 2 in PDB file). - - --- "SubVolumeBox" : int (0 or 1), No default is provided. - The simulation box in which the targeted swap subvolume will be applied. - NOTE: Only box zero (0) can be used for the GCMC, NPT, and NVT ensembles. - - --- "SubVolumeCenter" : list of three (3) int or float, [x-axis, y-axis, z-axis], No default is provided. - The simulation box is centered on this x, y, and z-axis points (in Angstroms), which is only - utilized when "SubVolumeType" is set to "static". - - --- "SubVolumeCenterList" : list of int and/or str (>=0), [atom_index, ..., atom_index], No default is provided. - The simulation box subVolume is centered on the geometric center of the provided atom indices, which is - only used when the "SubVolumeType" is set to "dynamic". For example, [0-10', 12, 15] means that - atom indices 0 to 10, 12 and 15 are used as the geometric center of the simulation box subVolume. - NOTE: THE ATOM INDICES RANGES MUST BE A STRING IN THE FORM '2-20', WITH THE FIRST ATOM INDICES BEING - SMALLER THAN THE SECOND (i.e, 'a-b', where a < b). ALL SINGULAR ATOM INDICES MUST BE INTEGERS. - NOTE: THE SAME ATOM INDICES CAN BE USED 2, 3 OR X TIMES TO WEIGHT that atom 2, 3, OR X TIMES MORE - IN THE GEOMETRIC CENTERING CALCULATION. - NOTE: THE ATOM INDICES START AT ZERO (0), WHILE THE PDB AND PSF FILES START AT ONE (1). - THEREFORE, YOU NEED TO BE CAREFUL WHEN SETTING THE INDICES FROM THE PDB OR PSF VALUES AS THEY ARE - ONE (1) NUMBER OFF. - - --- "SubVolumeDim" : list of three (3) int or float (>0), [x-axis, y-axis, z-axis], No default is provided. - This sets the size of the simulation box (subVolume) in the x, y, and z-axis (in Angstroms). - - --- "SubVolumeResidueKind" : str or list of str, "ALL" or "residue" - or ["ALL"] or [residue_str, ..., residue_str], No default is provided. - The residues that will be used in the "TargetedSwap_DataInput" subvolume. - Alternatively, the user can just set the value to ["ALL"] or "ALL", which covers all the residues. - - --- "SubVolumeRigidSwap" : bool, default = True - Choose whether to use a rigid or flexible molecule insertion using CD-CBMC for the subVolume. - True uses a rigid molecule insertion, while False uses a flexible molecule insertion - - --- "SubVolumePBC" : str ('X', 'XY', 'XZ', 'XYZ', 'Y', 'YZ', or 'Z'), default = 'XYZ'. - Apply periodic boundary condition (PBC) in selected axes for the subVolume. - Example 1, 'X' applies PBC only in the X axis. Example 2, 'XY' applies PBC only in the X and Y axes. - Example 3, 'XYZ' applies PBC in the X, Y, and Z axes. - - --- "SubVolumeChemPot" : dict {str (4 dig limit) , int or float}, No default is provided. - The chemical potentials in GOMC units of energy, K. If no SubVolumeChemPot is provided - the default system chemical potential values are used. - There is a 4 character limit for the string/residue name since the PDB/PSF - files have a 4 character limitation and require an exact match in the conf file. - Note: These strings must match the residue in the psf and psb files or it will fail. - The name of the residues and their corresponding chemical potential must be specified - for every residue in the system (i.e., {"residue_name" : chemical_potential}). - Note: THIS IS ONLY REQUIRED FOR THE GCMC ENSEMBLE. - Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY - OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. - Note: ONLY THE "SubVolumeChemPot" OR THE "SubVolumeFugacity" CAN BE USED FOR ALL THE - TARGET SWAP BOXES (SUBVOLUMES). IF MIX OF "SubVolumeChemPot" AND "SubVolumeFugacity" ARE - USED THE CONTROL FILE WRITER WILL THROW AN ERROR. - - --- "SubVolumeFugacity" : dict {str , int or float (>= 0)}, No default is provided. - The fugacity in GOMC units of pressure, bar. If no "SubVolumeFugacity" is provided - the default system fugacity values are used. - There is a 4 character limit for the string/residue name since the PDB/PSF - files have a 4 character limitation and require an exact match in the conf file. - Note: These strings must match the residue in the psf and psb files or it will fail. - The name of the residues and their corresponding fugacity must be specified - for every residue in the system (i.e., {"residue_name" : fugacity}). - Note: THIS IS ONLY REQUIRED FOR THE GCMC ENSEMBLE. - Note: IF 2 KEYS WITH THE SAME STRING/RESIDUE ARE PROVIDED, ONE WILL BE AUTOMATICALLY - OVERWRITTEN AND NO ERROR WILL BE THROWN IN THIS CONTROL FILE WRITER. - Note: ONLY THE "SubVolumeChemPot" OR THE "SubVolumeFugacity" CAN BE USED FOR ALL THE - TARGET SWAP BOXES (SUBVOLUMES). IF MIX OF "SubVolumeChemPot" AND "SubVolumeFugacity" ARE - USED THE CONTROL FILE WRITER WILL THROW AN ERROR. - - ExchangeVolumeDim : list of 3 floats or integers or [X-dimension, Y-dimension, Z-dimension)], - default = [1.0, 1.0, 1.0] - To use all variations of MEMC and Intra-MEMC Monte Carlo moves, the exchange - subvolume must be defined. The exchange sub-volume is defined as an orthogonal box - with x, y, and z-dimensions, where small molecule/molecules kind will be selected - from to be exchanged with a large molecule kind. - Note: Currently, the X and Y dimension cannot be set independently (X = Y = max(X, Y)). - Note: A heuristic for setting good values of the x, y, and z-dimensions is to use - the geometric size of the large molecule plus 1-2 Å in each dimension. - Note: In case of exchanging 1 small molecule kind with 1 large molecule kind in - IntraMEMC-2, IntraMEMC-3, MEMC-2, MEMC-3 Monte Carlo moves, the sub-volume - dimension has no effect on acceptance rate. - MEMC_DataInput : nested lists, default = None - Enter data as a list with some sub-lists as follows: - [[ExchangeRatio_int (> 0), ExchangeLargeKind_str, - [LargeKindBackBone_atom_1_str_or_NONE, LargeKindBackBone_atom_2_str_or_NONE ], - ExchangeSmallKind_str, [SmallKindBackBone_atom_1_str_or_NONE, SmallKindBackBone_atom_2_str_or_NONE ]], - ..., - [ExchangeRatio_int (> 0), ExchangeLargeKind_str, - [LargeKindBackBone_atom_1_str_or_NONE, LargeKindBackBone_atom_2_str_or_NONE ], - ExchangeSmallKind_str, [SmallKindBackBone_atom_1_str_or_NONE, SmallKindBackBone_atom_2_str_or_NONE ]. - NOTE: CURRENTLY ALL THESE INPUTS NEED TO BE SPECIFIED, REGARDLESS OF THE MEMC TYPE - SELECTION. IF THE SmallKindBackBone or LargeKindBackBone IS NOT REQUIRED FOR THE - MEMC TYPE, None CAN BE USED IN PLACE OF A STRING. - - Note: These strings must match the residue in the psf and psb files or it will fail. - It is recommended that the user print the Charmm object psf and pdb files - and review the residue names that match the atom name before using the in - the MEMC_DataInput variable input. - - Note: see the below data explanations for the ExchangeRatio, ExchangeSmallKind, - ExchangeLargeKind, LargeKindBackBone, SmallKindBackBone. - - Example 1 (MEMC-1) : [ [1, 'WAT', [None, None], 'wat', [None, None]] , - [1, 'WAT', [None, None], 'wat', [None, None]] - - Example 2 (MEMC-2): [ [1, 'WAT', ['O1', 'H1'], 'wat', ['O1', 'H1' ]] , - [1, 'WAT', ['H1', 'H2'], 'wat', ['H1', 'H2' ]] - - Example 3 (MEMC-3) : [ [2, 'WAT', 'O1', 'H1'], 'wat', [None, None]] , - [2, 'WAT', ['H1', 'H2'], 'wat', [None, None]] - - --- ExchangeRatio = MEMC parameters (all ensembles): int (> 0), default = None - The Ratio of exchanging small molecule/molecules with 1 large molecule. - To use all variation of MEMC and Intra-MEMC Monte Carlo moves, - the exchange ratio must be defined. The exchange ratio defines how - many small molecule will be exchanged with 1 large molecule. For each - large-small molecule pairs, one exchange ratio must be defined. - - --- ExchangeSmallKind = MEMC parameters (all ensembles): str, default = None - The small molecule kind (resname) to be exchanged. - Note: ONLY 4 characters can be used for the strings. - To use all variation of MEMC and Intra-MEMC Monte Carlo moves, - the small molecule kind to be exchanged with a large molecule - kind must be defined. Multiple small molecule kind can be specified. - - --- ExchangeLargeKind = MEMC parameters (all ensembles): str, default = None - The large molecule kind (resname) to be exchanged. - Note: ONLY 4 characters can be used for the strings. - To use all variation of MEMC and Intra-MEMC Monte Carlo moves, - the large molecule kind to be exchanged with small molecule - kind must be defined. Multiple large molecule kind can be specified. - - --- LargeKindBackBone = MEMC parameters (all ensembles): list [str, str] or [None, None], default = None - Note: ONLY 4 characters can be used for the strings. - The [None, None] values can only be used if that MEMC type does - not require them. The strings for the the atom name 1 and atom name 2 - that belong to the large molecule’s backbone - (i.e., [str_for_atom_name_1, str_for_atom_name_2]) - To use MEMC-2, MEMC-3, IntraMEMC-2, and IntraMEMC-3 Monte Carlo moves, the - large molecule backbone must be defined. The backbone of the molecule is defined - as a vector that connects two atoms belong to the large molecule. The large - molecule backbone will be used to align the sub-volume in MEMC-2 and IntraMEMC-2 - moves, while in MEMC-3 and IntraMEMC-3 moves, it uses the atom name to start - growing the large molecule using coupled-decoupled configurational-bias. For - each large-small molecule pairs, two atom names must be defined. - Note: all atom names in the molecule must be unique. - Note: In MEMC-3 and IntraMEMC-3 Monte Carlo moves, both atom names must be same, - otherwise program will be terminated. - Note: If the large molecule has only one atom (mono atomic molecules), - same atom name must be used for str_for_atom_name_1 and str_for_atom_name_2 - of the LargeKindBackBone. - - --- SmallKindBackBone = MEMC parameters (all ensembles): list [str, str] or [None, None], default = None - Note: ONLY 4 characters can be used for the strings. - The [None, None] values can only be used if that MEMC type does not - require them. The strings for the the atom name 1 and atom name 2 that - belong to the small molecule’s backbone - (i.e., [str_for_atom_name_1, str_for_atom_name_2]) - To use MEMC-2, and IntraMEMC-2 Monte Carlo moves, the small molecule backbone - must be defined. The backbone of the molecule is defined as a vector that - connects two atoms belong to the small molecule and will be used to align the - sub-volume. For each large-small molecule pairs, two atom names must be defined. - Note: all atom names in the molecule must be unique. - Note: If the small molecule has only one atom (mono atomic molecules), same atom - name must be used str_for_atom_name_1 and str_for_atom_name_2 - of the SmallKindBackBone. - - # ******************************************************************* - # input_variables_dict options (keys and values) - (end) - # Note: the input_variables_dict keys are also attributes - # ******************************************************************* - - Attributes - ---------- - input_error : bool - This error is typically incurred from an error in the user input values. - However, it could also be due to a bug, provided the user is inputting - the data as this Class intends. - all_failed_input_List : list - A list of all the inputs that failed, but there may be some inputs that - ensemble_typ : str, ['NVT', 'NPT', 'GEMC_NPT', 'GCMC-NVT', 'GCMC'] - The ensemble type of the simulation. - RunSteps : int (>0), must be an integer greater than zero. - Sets the total number of simulation steps. - Temperature : float or int (>0), must be an integer greater than zero. - Temperature of system in Kelvin (K) - ff_psf_pdb_file_directory : str (optional), default=None (i.e., the current directory). - The full or relative directory added to the force field, psf, and pdb - file names, created via the Charmm object. - check_input_files_exist: bool (default=True) - Check if the force field, psf, and pdb files exist. - If the files are checked and do not exist, the writer will throw a ValueError. - True, check if the force field, psf, and pdb files exist. - False, do not check if the force field, psf, and pdb files exist. - Restart : boolean, default = False - Determines whether to restart the simulation from restart file - (``*_restart.pdb`` and ``*_restart.psf``) or not. - RestartCheckpoint : boolean, default = False - Determines whether to restart the simulation with the checkpoint - file (checkpoint.dat) or not. Restarting the simulation with checkpoint.dat - would result in an identical outcome, as if previous simulation was continued. - Parameters : str, (default=None) - Override all other force field directory and filename input with the correct extension (.inp or .par). - Note: the default directory is the current directory with the Charmm object file name. - Coordinates_box_0 : str, (default=None) - Override all other box 0 pdb directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Structure_box_0 : str, (default=None) - Override all other box 0 psf directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Coordinates_box_1 : str, (default=None) - Override all other box 1 pdb directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - Structure_box_1 : str, (default=None) - Override all other box 1 psf directory and filename inputs with the correct extension. - Note: the default directory is the current directory with the Charmm object file name. - binCoordinates_box_0 : str, (default=None) - The box 0 binary coordinate file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. - extendedSystem_box_0 : str, (default=None) - The box 0 vectors and origin file is used only for restarting a GOMC simulation. - binVelocities_box_0 : str, (default=None) - The box 0 binary velocity file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. These velocities are only passed thru - GOMC since Monte Carlo simulations do not utilize any velocity information. - binCoordinates_box_1 : str, (default=None) - The box 1 binary coordinate file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. - extendedSystem_box_1 : str, (default=None) - The box 1 vectors and origin file is used only for restarting a GOMC simulation. - binVelocities_box_1 : str, (default=None) - The box 1 binary velocity file is used only for restarting a GOMC simulation, - which provides increased numerical accuracy. These velocities are only passed thru - GOMC since Monte Carlo simulations do not utilize any velocity information. - input_variables_dict: dict, default = None - These input variables are optional and override the default settings. - Changing these variables likely required for more advanced systems. - The details of the acceptable input variables for the selected - ensembles can be found by running the code below in python, - >>> print_valid_ensemble_input_variables('GCMC', description = True) - which prints the input_variables with their subsection description - for the selected 'GCMC' ensemble (other ensembles can be set as well). - Example : input_variables_dict = {'PRNG' : 123, - 'ParaTypeCHARMM' : True } - conf_filename : str - The name of the GOMC contol file, which will be created. The extension - of the GOMC control file can be .conf, or no extension can be provided. - If no extension is provided, this writer will automatically add the - .conf extension to the provided string. - box_0_vectors : numpy.ndarray, [[float float float], [float float float], [float float float]] - Three (3) sets vectors for box 0 each with 3 float values, which represent - the vectors for the Charmm-style systems (units in Angstroms (Ang)) - box_1_vectors : numpy.ndarray, [[float float float], [float float float], [float float float]] - Three (3) sets vectors for box 1 each with 3 float values, which represent - the vectors for the Charmm-style systems (units in Angstroms (Ang)) - coul_1_4 : float or int - The non-bonded 1-4 coulombic scaling factor, which is the - same for all the residues/molecules, regardless if - differenct force fields are utilized. - residues : list, [str, ..., str] - Labels of unique residues in the Compound. Residues are assigned by - checking against Compound.name. Only supply residue names as 4 character - strings, as the residue names are truncated to 4 characters to fit in the - psf and pdb file. - all_res_unique_atom_name_dict : dict, {str : [str, ..., str]} - A dictionary that provides the residue names (keys) and a list - of the unique atom names in the residue (value), for the - combined structures (box 0 and box 1 (if supplied)). - any input_variables_dict key : varies (see each input_variables_dict key and value) - Any of the input variables keys is also an Attribute and can be called - the same way. Please see the input_variables_dict keys in the - Parameters section above for all the available attributes. - - Notes - ------- - The user input variables (input_variables_dict) and the specific - ensembles. - - The details of the required inputs for the selected - ensembles can be found by running this python workbook, - - >>> print_valid_required_input_variables('NVT', description = True) - - which prints the required inputs with their subsection description - for the selected 'NVT' ensemble (other ensembles can be set as well). - - The details of the input variables for the selected - ensembles can be found by running this python workbook, - - >>> print_valid_ensemble_input_variables('NPT', description = True) - - which prints the input variables with their subsection description - for the selected 'NPT' ensemble (other ensembles can be set as well). - - Note: The box units imported are in nm (standard MoSDeF units). - The units for this writer are auto-scaled to Angstroms, so they - can be directly used in the GOMC or NAMD engines. - - Note: all of the move types are not available in for every ensemble. - - Note: all of the move fractions must sum to 1, or the control file - writer will fail. - - The input variables (input_variables_dict) and text extracted with permission from - the GOMC manual version 2.60. Some of the text was modified from its original version. - Cite: Potoff, Jeffrey; Schwiebert, Loren; et. al. GOMC Documentation. - https://raw.githubusercontent.com/GOMC-WSU/GOMC/master/GOMC_Manual.pdf, 2021. - - Returns - ------- - If completed without errors: str - returns "GOMC_CONTROL_FILE_WRITTEN" when the GOMC input control file is writen - If completed with errors: None - """ - # write the control file and return a testable value - gomc_control = GOMCControl( + GOMCControl( charmm_object, ensemble_type, RunSteps, @@ -8932,14 +80,3 @@ def write_gomc_control_file( binVelocities_box_1=binVelocities_box_1, input_variables_dict=input_variables_dict, ) - test_gomc_control_write_conf_file = gomc_control.write_conf_file( - conf_filename - ) - - if ( - gomc_control.input_error is False - and test_gomc_control_write_conf_file == "GOMC_CONTROL_FILE_WRITTEN" - ): - return "GOMC_CONTROL_FILE_WRITTEN" - else: - return None diff --git a/mosdef_gomc/tests/test_charmm_writer.py b/mosdef_gomc/tests/test_charmm_writer.py deleted file mode 100644 index efa3761e..00000000 --- a/mosdef_gomc/tests/test_charmm_writer.py +++ /dev/null @@ -1,3619 +0,0 @@ -from collections import OrderedDict - -import mbuild as mb -import numpy as np -import pytest -from foyer.forcefields import forcefields -from mbuild import Box, Compound -from mbuild.lattice import load_cif -from mbuild.utils.io import get_fn, has_foyer - -from mosdef_gomc.formats import charmm_writer -from mosdef_gomc.formats.charmm_writer import Charmm -from mosdef_gomc.tests.base_test import BaseTest -from mosdef_gomc.utils.conversion import ( - base10_to_base16_alph_num, - base10_to_base26_alph, - base10_to_base52_alph, - base10_to_base62_alph_num, -) -from mosdef_gomc.utils.specific_ff_to_residue import specific_ff_to_residue - - -@pytest.mark.skipif(not has_foyer, reason="Foyer package not installed") -class TestCharmmWriterData(BaseTest): - def test_save(self, ethane_gomc): - Charmm( - ethane_gomc, - "ethane", - ff_filename="ethane", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - def test_save_charmm_gomc_ff(self, ethane_gomc): - charmm = Charmm( - ethane_gomc, - "charmm_data", - ff_filename="charmm_data", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - charmm.write_inp() - - with open("charmm_data.inp", "r") as fp: - masses_read = False - bonds_read = False - angles_read = False - dihedrals_read = False - nonbondeds_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if ( - "!atom_types" in line - and "mass" in line - and "atomTypeForceFieldName_ResidueName" in line - and "(i.e., atoms_type_per_utilized_FF)" in line - ): - masses_read = True - assert len(out_gomc[i + 1].split("!")[0].split()) == 3 - assert out_gomc[i + 1].split("!")[0].split()[0:3] == [ - "*", - "A", - "12.010780", - ] - assert len(out_gomc[i + 2].split("!")[0].split()) == 3 - assert out_gomc[i + 2].split("!")[0].split()[0:3] == [ - "*", - "B", - "1.007947", - ] - assert out_gomc[i + 1].split()[4:5] == ["opls_135_ETH"] - assert out_gomc[i + 2].split()[4:5] == ["opls_140_ETH"] - - elif ( - "!atom_types" in line - and "Kb" in line - and "b0" in line - and "atoms_types_per_utilized_FF" in line - ): - bonds_read = True - bond_types = [ - ["A", "B", "340.0", "1.09"], - ["A", "A", "268.0", "1.529"], - ] - assert len(out_gomc[i + 1].split("!")[0].split()) == 4 - assert len(out_gomc[i + 2].split("!")[0].split()) == 4 - if ( - out_gomc[i + 1].split("!")[0].split()[0:4] - == bond_types[0] - ): - assert ( - out_gomc[i + 1].split("!")[0].split()[0:4] - == bond_types[0] - ) - assert ( - out_gomc[i + 2].split("!")[0].split()[0:4] - == bond_types[1] - ) - elif ( - out_gomc[i + 1].split("!")[0].split()[0:4] - == bond_types[1] - ): - assert ( - out_gomc[i + 1].split("!")[0].split()[0:4] - == bond_types[1] - ) - assert ( - out_gomc[i + 2].split("!")[0].split()[0:4] - == bond_types[0] - ) - - elif ( - "!atom_types" in line - and "Ktheta" in line - and "Theta0" in line - and "atoms_types_per_utilized_FF" in line - ): - angles_read = True - angle_types = [ - ["A", "A", "B", "37.5", "110.70000"], - ["B", "A", "B", "33.0", "107.80000"], - ] - assert len(out_gomc[i + 1].split("!")[0].split()) == 5 - assert len(out_gomc[i + 2].split("!")[0].split()) == 5 - if ( - out_gomc[i + 1].split("!")[0].split()[0:5] - == angle_types[0] - ): - assert ( - out_gomc[i + 1].split("!")[0].split()[0:5] - == angle_types[0] - ) - assert ( - out_gomc[i + 2].split("!")[0].split()[0:5] - == angle_types[1] - ) - elif ( - out_gomc[i + 1].split("!")[0].split()[0:4] - == angle_types[1] - ): - assert ( - out_gomc[i + 1].split("!")[0].split()[0:5] - == angle_types[1] - ) - assert ( - out_gomc[i + 2].split("!")[0].split()[0:5] - == angle_types[0] - ) - - elif ( - "!atom_types" in line - and "Kchi" in line - and "n" in line - and "delta" in line - and "atoms_types_per_utilized_FF" in line - ): - dihedrals_read = True - dihed_types = [ - ["B", "A", "A", "B", "0.000000", "1", "180.0"], - ["B", "A", "A", "B", "0.000000", "2", "0.0"], - ["B", "A", "A", "B", "-0.150000", "3", "180.0"], - ["B", "A", "A", "B", "0.000000", "4", "0.0"], - ["B", "A", "A", "B", "0.000000", "5", "180.0"], - ] - for j in range(0, len(dihed_types)): - assert ( - len(out_gomc[i + 1 + j].split("!")[0].split()) == 7 - ) - assert ( - out_gomc[i + 1 + j].split("!")[0].split()[0:7] - == dihed_types[j] - ) - - elif ( - "!atype" in line - and "ignored epsilon" in line - and "Rmin/2" in line - and "ignored" in line - and "eps,1-4" in line - and "Rmin/2,1-4" in line - and "atom_type_per_utilized_FF" in line - ): - nonbondeds_read = True - nb_types = [ - [ - "A", - "0.00", - "-0.066000000", - "1.96430858454", - "0.00", - "-0.033000000", - "1.96430858454", - ], - [ - "B", - "0.00", - "-0.030000000", - "1.40307756039", - "0.00", - "-0.015000000", - "1.40307756039", - ], - ] - - for j in range(0, len(nb_types)): - assert ( - len(out_gomc[i + 1 + j].split("!")[0].split()) == 7 - ) - assert ( - out_gomc[i + 1 + j].split("!")[0].split()[0:7] - == nb_types[j] - ) - - else: - pass - - assert masses_read - assert bonds_read - assert angles_read - assert dihedrals_read - assert nonbondeds_read - - def test_save_charmm_psf(self, ethane_gomc): - charmm = Charmm( - ethane_gomc, - "charmm_data", - ff_filename="charmm_data", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - charmm.write_psf() - - with open("charmm_data.psf", "r") as fp: - charges_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "8 !NATOM" in line: - charges_read = True - atom_type_charge_etc_list = [ - [ - "1", - "SYS", - "1", - "ETH", - "C1", - "A", - "-0.180000", - "12.0108", - ], - [ - "2", - "SYS", - "1", - "ETH", - "C2", - "A", - "-0.180000", - "12.0108", - ], - [ - "3", - "SYS", - "1", - "ETH", - "H1", - "B", - "0.060000", - "1.0079", - ], - [ - "4", - "SYS", - "1", - "ETH", - "H2", - "B", - "0.060000", - "1.0079", - ], - [ - "5", - "SYS", - "1", - "ETH", - "H3", - "B", - "0.060000", - "1.0079", - ], - [ - "6", - "SYS", - "1", - "ETH", - "H4", - "B", - "0.060000", - "1.0079", - ], - [ - "7", - "SYS", - "1", - "ETH", - "H5", - "B", - "0.060000", - "1.0079", - ], - [ - "8", - "SYS", - "1", - "ETH", - "H6", - "B", - "0.060000", - "1.0079", - ], - ] - for j in range(0, len(atom_type_charge_etc_list)): - assert ( - out_gomc[i + 1 + j].split()[0:8] - == atom_type_charge_etc_list[j] - ) - - else: - pass - - assert charges_read - - def test_save_charmm_pdb(self, ethane_gomc): - charmm = Charmm( - ethane_gomc, - "charmm_data", - ff_filename="charmm_data", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - charmm.write_pdb() - - with open("charmm_data.pdb", "r") as fp: - pdb_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_read = True - atom_type_res_part_1_list = [ - ["ATOM", "1", "C1", "ETH", "A", "1"], - ["ATOM", "2", "C2", "ETH", "A", "1"], - ["ATOM", "3", "H1", "ETH", "A", "1"], - ["ATOM", "4", "H2", "ETH", "A", "1"], - ["ATOM", "5", "H3", "ETH", "A", "1"], - ["ATOM", "6", "H4", "ETH", "A", "1"], - ["ATOM", "7", "H5", "ETH", "A", "1"], - ["ATOM", "8", "H6", "ETH", "A", "1"], - ] - atom_type_res_part_2_list = [ - ["0.00", "0.00", "C"], - ["0.00", "0.00", "C"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ] - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert pdb_read - - def test_save_charmm_ua_gomc_ff(self, two_propanol_ua): - charmm = Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - ) - charmm.write_inp() - - with open("charmm_data_UA.inp", "r") as fp: - masses_read = False - bonds_read = False - angles_read = False - dihedrals_read = False - nonbondeds_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if ( - "!atom_types" in line - and "mass" in line - and "atomTypeForceFieldName_ResidueName" in line - and "(i.e., atoms_type_per_utilized_FF)" in line - ): - masses_read = True - atom_types_1 = [ - ["*", "A", "15.035000"], - ["*", "B", "13.019000"], - ["*", "D", "15.999430"], - ["*", "C", "1.007947"], - ] - atom_types_2 = [ - ["CH3_sp3_POL"], - ["CH_O_POL"], - ["O_POL"], - ["H_POL"], - ] - - for j in range(0, len(atom_types_1)): - assert ( - len(out_gomc[i + 1 + j].split("!")[0].split()) == 3 - ) - assert ( - out_gomc[i + 1 + j].split("!")[0].split()[0:3] - == atom_types_1[j] - ) - assert ( - out_gomc[i + 1 + j].split()[4:5] == atom_types_2[j] - ) - - elif ( - "!atom_types" in line - and "Kb" in line - and "b0" in line - and "atoms_types_per_utilized_FF" in line - ): - bonds_read = True - bond_types = [ - ["C", "D", "600.40152964", "0.945"], - ["B", "D", "600.40152964", "1.43"], - ["A", "B", "600.40152964", "1.54"], - ] - total_bonds_evaluated = [] - total_bonds_evaluated_reorg = [] - for j in range(0, len(bond_types)): - assert ( - len(out_gomc[i + 1 + j].split("!")[0].split()) == 4 - ) - if ( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - == bond_types[0] - or bond_types[1] - or bond_types[2] - ): - total_bonds_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - for k in range(0, len(bond_types)): - if bond_types[k] in total_bonds_evaluated: - total_bonds_evaluated_reorg.append(bond_types[k]) - assert total_bonds_evaluated_reorg == bond_types - - elif ( - "!atom_types" in line - and "Ktheta" in line - and "Theta0" in line - and "atoms_types_per_utilized_FF" in line in line - ): - angles_read = True - angle_types = [ - ["A", "B", "A", "62.10013026", "112.00007"], - ["A", "B", "D", "50.07754422", "109.46989"], - ["B", "D", "C", "55.04555449", "108.49987"], - ] - total_angles_evaluated = [] - total_angles_evaluated_reorg = [] - for j in range(0, len(angle_types)): - assert ( - len(out_gomc[i + 1 + j].split("!")[0].split()) == 5 - ) - if ( - out_gomc[i + 1 + j].split("!")[0].split()[0:5] - == angle_types[0] - or angle_types[1] - or angle_types[2] - ): - total_angles_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:5] - ) - for k in range(0, len(angle_types)): - if angle_types[k] in total_angles_evaluated: - total_angles_evaluated_reorg.append(angle_types[k]) - assert total_angles_evaluated_reorg == angle_types - - elif ( - "!atom_types" in line - and "Kchi" in line - and "n" in line - and "delta" in line - and "atoms_types_per_utilized_FF" in line - ): - dihedrals_read = True - dihedral_types = [ - ["A", "B", "D", "C", "-0.392135", "1", "180.0"], - ["A", "B", "D", "C", "-0.062518", "2", "0.0"], - ["A", "B", "D", "C", "0.345615", "3", "180.0"], - ["A", "B", "D", "C", "0.000000", "4", "0.0"], - ["A", "B", "D", "C", "0.000000", "5", "180.0"], - ] - for j in range(0, len(dihedral_types)): - assert ( - len(out_gomc[i + 1 + j].split("!")[0].split()) == 7 - ) - assert ( - out_gomc[i + 1 + j].split("!")[0].split()[0:7] - == dihedral_types[j] - ) - - elif ( - "!atype" in line - and "ignored epsilon" in line - and "Rmin/2" in line - and "ignored" in line - and "eps,1-4" in line - and "Rmin/2,1-4" in line - and "atom_type_per_utilized_FF" in line - ): - nonbondeds_read = True - nb_types = [ - [ - "A", - "0.00", - "-0.194745937", - "2.10461634058", - "0.00", - "-0.000000000", - "2.10461634058", - ], - [ - "B", - "0.00", - "-0.019872012", - "2.43013033459", - "0.00", - "-0.000000000", - "2.43013033459", - ], - [ - "D", - "0.00", - "-0.184809990", - "1.69491769295", - "0.00", - "-0.000000000", - "1.69491769295", - ], - [ - "C", - "0.00", - "-0.000000000", - "5.61231024155", - "0.00", - "-0.000000000", - "5.61231024155", - ], - ] - - for j in range(0, len(nb_types)): - assert ( - len(out_gomc[i + 1 + j].split("!")[0].split()) == 7 - ) - assert ( - out_gomc[i + 1 + j].split("!")[0].split()[0:7] - == nb_types[j] - ) - - else: - pass - - assert masses_read - assert bonds_read - assert angles_read - assert dihedrals_read - assert nonbondeds_read - - def test_save_charmm_ua_psf(self, two_propanol_ua): - charmm = Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - ) - charmm.write_psf() - - with open("charmm_data_UA.psf", "r") as fp: - read_psf = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "5 !NATOM" in line: - read_psf = True - atom_type_charge_etc_list = [ - [ - "1", - "SYS", - "1", - "POL", - "C1", - "A", - "0.000000", - "15.0350", - ], - [ - "2", - "SYS", - "1", - "POL", - "BD1", - "B", - "0.265000", - "13.0190", - ], - [ - "3", - "SYS", - "1", - "POL", - "O1", - "D", - "-0.700000", - "15.9994", - ], - [ - "4", - "SYS", - "1", - "POL", - "H1", - "C", - "0.435000", - "1.0079", - ], - [ - "5", - "SYS", - "1", - "POL", - "C2", - "A", - "0.000000", - "15.0350", - ], - ] - - for j in range(0, len(atom_type_charge_etc_list)): - assert ( - out_gomc[i + 1 + j].split()[0:8] - == atom_type_charge_etc_list[j] - ) - - else: - pass - - assert read_psf - - def test_save_charmm_ua_pdb(self, two_propanol_ua): - charmm = Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - ) - charmm.write_pdb() - - with open("charmm_data_UA.pdb", "r") as fp: - read_pdb = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - read_pdb = True - atom_type_res_part_1_list = [ - ["ATOM", "1", "C1", "POL", "A", "1"], - ["ATOM", "2", "BD1", "POL", "A", "1"], - ["ATOM", "3", "O1", "POL", "A", "1"], - ["ATOM", "4", "H1", "POL", "A", "1"], - ["ATOM", "5", "C2", "POL", "A", "1"], - ] - atom_type_res_part_2_list = [ - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "O"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "EP"], - ] - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert read_pdb - - def test_charmm_pdb_fix_angle_bond_fix_atoms( - self, ethane_gomc, ethanol_gomc - ): - test_box_ethane_propane = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[2.0, 2.0, 2.0], - ) - charmm = Charmm( - test_box_ethane_propane, - "Test_fixes_angle_bond_atoms", - ff_filename="Test_fixes_angle_bond_atoms", - residues=[ethanol_gomc.name, ethane_gomc.name], - forcefield_selection="oplsaa", - fix_residue=[ethane_gomc.name], - fix_residue_in_box=[ethanol_gomc.name], - gomc_fix_bonds_angles=[ethane_gomc.name], - ) - charmm.write_inp() - charmm.write_pdb() - - with open("Test_fixes_angle_bond_atoms.inp", "r") as fp: - masses_read = False - bonds_read = False - angles_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if ( - "!atom_types" in line - and "mass" in line - and "atomTypeForceFieldName_ResidueName" in line - and "(i.e., atoms_type_per_utilized_FF)" in line - ): - masses_read = True - mass_type_1 = [ - ["*", "A", "12.010780"], - ["*", "C", "1.007947"], - ["*", "B", "12.010780"], - ["*", "G", "12.010780"], - ["*", "E", "15.999430"], - ["*", "D", "1.007947"], - ["*", "F", "1.007947"], - ] - mass_type_2 = [ - ["opls_135_ETH"], - ["opls_140_ETH"], - ["opls_135_ETO"], - ["opls_157_ETO"], - ["opls_154_ETO"], - ["opls_140_ETO"], - ["opls_155_ETO"], - ] - - for j in range(0, len(mass_type_1)): - assert ( - len(out_gomc[i + 1 + j].split("!")[0].split()) == 3 - ) - assert ( - out_gomc[i + 1 + j].split("!")[0].split()[0:3] - == mass_type_1[j] - ) - assert ( - out_gomc[i + 1 + j].split()[4:5] == mass_type_2[j] - ) - - elif ( - "!atom_types" in line - and "Kb" in line - and "b0" in line - and "atoms_types_per_utilized_FF" in line - ): - bonds_read = True - bond_types = [ - ["D", "G", "340.0", "1.09"], - ["E", "G", "320.0", "1.41"], - ["E", "F", "553.0", "0.945"], - ["A", "C", "999999999999", "1.09"], - ["B", "D", "340.0", "1.09"], - ["A", "A", "999999999999", "1.529"], - ["B", "G", "268.0", "1.529"], - ] - total_bonds_evaluated = [] - total_fixed_bonds = [] - for j in range(0, 7): - total_bonds_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[2:3] == [ - "999999999999" - ]: - total_fixed_bonds.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert total_bonds_evaluated.sort() == bond_types.sort() - assert len(total_fixed_bonds) == 2 - - elif ( - "!atom_types" in line - and "Ktheta" in line - and "Theta0" in line - and "atoms_types_per_utilized_FF" in line in line - ): - angles_read = True - fixed_angle_types = [ - ["A", "A", "C", "999999999999", "110.70000"], - ["C", "A", "C", "999999999999", "107.80000"], - ] - total_angles_evaluated = [] - total_fixed_angles = [] - for j in range(0, 9): - if out_gomc[i + 1 + j].split("!")[0].split()[0:4] == ( - fixed_angle_types[0] or fixed_angle_types[1] - ): - total_angles_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[3:4] == [ - "999999999999" - ]: - total_fixed_angles.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert ( - fixed_angle_types.sort() - == total_angles_evaluated.sort() - ) - assert len(total_fixed_angles) == len(fixed_angle_types) - - else: - pass - - assert masses_read - assert bonds_read - assert angles_read - - with open("Test_fixes_angle_bond_atoms.pdb", "r") as fp: - read_pdb_part_1 = False - read_pdb_part_2 = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - read_pdb_part_1 = True - assert out_gomc[i].split()[0:7] == [ - "CRYST1", - "20.000", - "20.000", - "20.000", - "90.00", - "90.00", - "90.00", - ] - - if "CRYST1" in line: - read_pdb_part_2 = True - atom_type_res_part_1_list = [ - ["ATOM", "1", "C1", "ETH", "A", "1"], - ["ATOM", "2", "C2", "ETH", "A", "1"], - ["ATOM", "3", "H1", "ETH", "A", "1"], - ["ATOM", "4", "H2", "ETH", "A", "1"], - ["ATOM", "5", "H3", "ETH", "A", "1"], - ["ATOM", "6", "H4", "ETH", "A", "1"], - ["ATOM", "7", "H5", "ETH", "A", "1"], - ["ATOM", "8", "H6", "ETH", "A", "1"], - ["ATOM", "9", "C1", "ETO", "A", "2"], - ["ATOM", "10", "C2", "ETO", "A", "2"], - ["ATOM", "11", "O1", "ETO", "A", "2"], - ["ATOM", "12", "H1", "ETO", "A", "2"], - ["ATOM", "13", "H2", "ETO", "A", "2"], - ["ATOM", "14", "H3", "ETO", "A", "2"], - ["ATOM", "15", "H4", "ETO", "A", "2"], - ["ATOM", "16", "H5", "ETO", "A", "2"], - ["ATOM", "17", "H6", "ETO", "A", "2"], - ] - atom_type_res_part_2_list = [ - ["0.00", "1.00", "C"], - ["0.00", "1.00", "C"], - ["0.00", "1.00", "H"], - ["0.00", "1.00", "H"], - ["0.00", "1.00", "H"], - ["0.00", "1.00", "H"], - ["0.00", "1.00", "H"], - ["0.00", "1.00", "H"], - ["0.00", "2.00", "C"], - ["0.00", "2.00", "C"], - ["0.00", "2.00", "O"], - ["0.00", "2.00", "H"], - ["0.00", "2.00", "H"], - ["0.00", "2.00", "H"], - ["0.00", "2.00", "H"], - ["0.00", "2.00", "H"], - ["0.00", "2.00", "H"], - ] - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert read_pdb_part_1 - assert read_pdb_part_2 - - def test_charmm_pdb_set_residue_pdb_occupancy_to_1( - self, ethane_gomc, ethanol_gomc - ): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[2.0, 2.0, 2.0], - ) - charmm = Charmm( - test_box_ethane_ethanol, - "Test_set_residue_pdb_occupancy_to_1", - ff_filename="Test_set_residue_pdb_occupancy_to_1", - residues=[ethanol_gomc.name, ethane_gomc.name], - forcefield_selection="oplsaa", - fix_residue=None, - fix_residue_in_box=None, - set_residue_pdb_occupancy_to_1=[ethane_gomc.name], - gomc_fix_bonds_angles=None, - ) - charmm.write_pdb() - - with open("Test_set_residue_pdb_occupancy_to_1.pdb", "r") as fp: - read_pdb_part_1 = False - read_pdb_part_2 = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - read_pdb_part_1 = True - assert out_gomc[i].split()[0:7] == [ - "CRYST1", - "20.000", - "20.000", - "20.000", - "90.00", - "90.00", - "90.00", - ] - - if "CRYST1" in line: - read_pdb_part_2 = True - atom_type_res_part_1_list = [ - ["ATOM", "1", "C1", "ETH", "A", "1"], - ["ATOM", "2", "C2", "ETH", "A", "1"], - ["ATOM", "3", "H1", "ETH", "A", "1"], - ["ATOM", "4", "H2", "ETH", "A", "1"], - ["ATOM", "5", "H3", "ETH", "A", "1"], - ["ATOM", "6", "H4", "ETH", "A", "1"], - ["ATOM", "7", "H5", "ETH", "A", "1"], - ["ATOM", "8", "H6", "ETH", "A", "1"], - ["ATOM", "9", "C1", "ETO", "A", "2"], - ["ATOM", "10", "C2", "ETO", "A", "2"], - ["ATOM", "11", "O1", "ETO", "A", "2"], - ["ATOM", "12", "H1", "ETO", "A", "2"], - ["ATOM", "13", "H2", "ETO", "A", "2"], - ["ATOM", "14", "H3", "ETO", "A", "2"], - ["ATOM", "15", "H4", "ETO", "A", "2"], - ["ATOM", "16", "H5", "ETO", "A", "2"], - ["ATOM", "17", "H6", "ETO", "A", "2"], - ] - atom_type_res_part_2_list = [ - ["1.00", "0.00", "C"], - ["1.00", "0.00", "C"], - ["1.00", "0.00", "H"], - ["1.00", "0.00", "H"], - ["1.00", "0.00", "H"], - ["1.00", "0.00", "H"], - ["1.00", "0.00", "H"], - ["1.00", "0.00", "H"], - ["0.00", "0.00", "C"], - ["0.00", "0.00", "C"], - ["0.00", "0.00", "O"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ] - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert read_pdb_part_1 - assert read_pdb_part_2 - - def test_charmm_pdb_fix_bonds_only(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[2.0, 2.0, 2.0], - ) - charmm = Charmm( - test_box_ethane_ethanol, - "Test_fixes_bonds_only", - ff_filename="Test_fixes_bonds_only", - residues=[ethanol_gomc.name, ethane_gomc.name], - forcefield_selection="oplsaa", - gomc_fix_bonds=[ethane_gomc.name], - ) - charmm.write_inp() - - with open("Test_fixes_bonds_only.inp", "r") as fp: - bonds_read = False - angles_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if ( - "!atom_types" in line - and "Kb" in line - and "b0" in line - and "atoms_types_per_utilized_FF" in line - ): - bonds_read = True - bond_types = [ - ["D", "G", "340.0", "1.09"], - ["E", "G", "320.0", "1.41"], - ["E", "F", "553.0", "0.945"], - ["A", "C", "999999999999", "1.09"], - ["B", "D", "340.0", "1.09"], - ["A", "A", "999999999999", "1.529"], - ["B", "G", "268.0", "1.529"], - ] - total_bonds_evaluated = [] - total_fixed_bonds = [] - for j in range(0, 7): - total_bonds_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[2:3] == [ - "999999999999" - ]: - total_fixed_bonds.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert total_bonds_evaluated.sort() == bond_types.sort() - assert len(total_fixed_bonds) == 2 - - elif ( - "!atom_types" in line - and "Ktheta" in line - and "Theta0" in line - and "atoms_types_per_utilized_FF" in line - ): - angles_read = True - fixed_angle_types = [] - total_angles_evaluated = [] - total_fixed_angles = [] - for j in range(0, 9): - if len(fixed_angle_types) > 0: - if out_gomc[i + 1 + j].split("!")[0].split()[ - 0:4 - ] == (fixed_angle_types[0] or fixed_angle_types[1]): - total_angles_evaluated.append( - out_gomc[i + 1 + j] - .split("!")[0] - .split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[3:4] == [ - "999999999999" - ]: - total_fixed_angles.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert ( - fixed_angle_types.sort() - == total_angles_evaluated.sort() - ) - assert len(total_fixed_angles) == len(fixed_angle_types) - - else: - pass - - assert bonds_read - assert angles_read - - def test_charmm_pdb_fix_bonds_only_and_fix_bonds_angles( - self, ethane_gomc, ethanol_gomc - ): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[2.0, 2.0, 2.0], - ) - charmm = Charmm( - test_box_ethane_ethanol, - "Test_fixes_bonds_only_and_fix_bonds_angles", - ff_filename="Test_fixes_bonds_only_and_fix_bonds_angles", - residues=[ethanol_gomc.name, ethane_gomc.name], - forcefield_selection="oplsaa", - gomc_fix_bonds=[ethane_gomc.name], - gomc_fix_bonds_angles=[ethane_gomc.name], - ) - charmm.write_inp() - - with open("Test_fixes_bonds_only_and_fix_bonds_angles.inp", "r") as fp: - bonds_read = False - angles_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if ( - "!atom_types" in line - and "Kb" in line - and "b0" in line - and "atoms_types_per_utilized_FF" in line - ): - bonds_read = True - bond_types = [ - ["D", "G", "340.0", "1.09"], - ["E", "G", "320.0", "1.41"], - ["E", "F", "553.0", "0.945"], - ["A", "C", "999999999999", "1.09"], - ["B", "D", "340.0", "1.09"], - ["A", "A", "999999999999", "1.529"], - ["B", "G", "268.0", "1.529"], - ] - total_bonds_evaluated = [] - total_fixed_bonds = [] - for j in range(0, 7): - total_bonds_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[2:3] == [ - "999999999999" - ]: - total_fixed_bonds.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert total_bonds_evaluated.sort() == bond_types.sort() - assert len(total_fixed_bonds) == 2 - - elif ( - "!atom_types" in line - and "Ktheta" in line - and "Theta0" in line - and "atoms_types_per_utilized_FF" in line - ): - angles_read = True - fixed_angle_types = [ - ["A", "A", "C", "999999999999", "110.70000"], - ["C", "A", "C", "999999999999", "107.80000"], - ] - total_angles_evaluated = [] - total_fixed_angles = [] - for j in range(0, 9): - if out_gomc[i + 1 + j].split("!")[0].split()[0:4] == ( - fixed_angle_types[0] or fixed_angle_types[1] - ): - total_angles_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[3:4] == [ - "999999999999" - ]: - total_fixed_angles.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert ( - fixed_angle_types.sort() - == total_angles_evaluated.sort() - ) - assert len(total_fixed_angles) == len(fixed_angle_types) - - else: - pass - - assert bonds_read - assert angles_read - - def test_charmm_pdb_fix_angles_only(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[2.0, 2.0, 2.0], - ) - charmm = Charmm( - test_box_ethane_ethanol, - "Test_fixes_angles_only", - ff_filename="Test_fixes_angles_only", - residues=[ethanol_gomc.name, ethane_gomc.name], - forcefield_selection="oplsaa", - gomc_fix_angles=[ethane_gomc.name], - ) - charmm.write_inp() - - with open("Test_fixes_angles_only.inp", "r") as fp: - bonds_read = False - angles_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if ( - "!atom_types" in line - and "Kb" in line - and "b0" in line - and "atoms_types_per_utilized_FF" in line - ): - bonds_read = True - bond_types = [ - ["D", "G", "340.0", "1.09"], - ["E", "G", "320.0", "1.41"], - ["E", "F", "553.0", "0.945"], - ["A", "C", "340.0", "1.09"], - ["B", "D", "340.0", "1.09"], - ["A", "A", "268.0", "1.529"], - ["B", "G", "268.0", "1.529"], - ] - total_bonds_evaluated = [] - total_fixed_bonds = [] - for j in range(0, 7): - total_bonds_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[2:3] == [ - "999999999999" - ]: - total_fixed_bonds.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert total_bonds_evaluated.sort() == bond_types.sort() - assert len(total_fixed_bonds) == 0 - - elif ( - "!atom_types" in line - and "Ktheta" in line - and "Theta0" in line - and "atoms_types_per_utilized_FF" in line - ): - angles_read = True - fixed_angle_types = [ - ["A", "A", "C", "999999999999", "110.70000"], - ["C", "A", "C", "999999999999", "107.80000"], - ] - total_angles_evaluated = [] - total_fixed_angles = [] - for j in range(0, 9): - if out_gomc[i + 1 + j].split("!")[0].split()[0:4] == ( - fixed_angle_types[0] or fixed_angle_types[1] - ): - total_angles_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[3:4] == [ - "999999999999" - ]: - total_fixed_angles.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert ( - fixed_angle_types.sort() - == total_angles_evaluated.sort() - ) - assert len(total_fixed_angles) == len(fixed_angle_types) - - else: - pass - - assert bonds_read - assert angles_read - - def test_charmm_pdb_fix_angles_only_and_fix_bonds_angles( - self, ethane_gomc, ethanol_gomc - ): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[2.0, 2.0, 2.0], - ) - charmm = Charmm( - test_box_ethane_ethanol, - "Test_fixes_angles_only_and_fix_bonds_angles", - ff_filename="Test_fixes_angles_only_and_fix_bonds_angles", - residues=[ethanol_gomc.name, ethane_gomc.name], - forcefield_selection="oplsaa", - gomc_fix_angles=[ethane_gomc.name], - gomc_fix_bonds_angles=[ethane_gomc.name], - ) - charmm.write_inp() - - with open("Test_fixes_angles_only_and_fix_bonds_angles.inp", "r") as fp: - bonds_read = False - angles_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if ( - "!atom_types" in line - and "Kb" in line - and "b0" in line - and "atoms_types_per_utilized_FF" in line - ): - bonds_read = True - bond_types = [ - ["D", "G", "340.0", "1.09"], - ["E", "G", "320.0", "1.41"], - ["E", "F", "553.0", "0.945"], - ["A", "C", "999999999999", "1.09"], - ["B", "D", "340.0", "1.09"], - ["A", "A", "999999999999", "1.529"], - ["B", "G", "268.0", "1.529"], - ] - total_bonds_evaluated = [] - total_fixed_bonds = [] - for j in range(0, 7): - total_bonds_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[2:3] == [ - "999999999999" - ]: - total_fixed_bonds.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert total_bonds_evaluated.sort() == bond_types.sort() - assert len(total_fixed_bonds) == 2 - - elif ( - "!atom_types" in line - and "Ktheta" in line - and "Theta0" in line - and "atoms_types_per_utilized_FF" in line - ): - angles_read = True - fixed_angle_types = [ - ["A", "A", "C", "999999999999", "110.70000"], - ["C", "A", "C", "999999999999", "107.80000"], - ] - total_angles_evaluated = [] - total_fixed_angles = [] - for j in range(0, 9): - if out_gomc[i + 1 + j].split("!")[0].split()[0:4] == ( - fixed_angle_types[0] or fixed_angle_types[1] - ): - total_angles_evaluated.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - if out_gomc[i + 1 + j].split("!")[0].split()[3:4] == [ - "999999999999" - ]: - total_fixed_angles.append( - out_gomc[i + 1 + j].split("!")[0].split()[0:4] - ) - assert ( - fixed_angle_types.sort() - == total_angles_evaluated.sort() - ) - assert len(total_fixed_angles) == len(fixed_angle_types) - - else: - pass - - assert bonds_read - assert angles_read - - def test_charmm_pdb_no_differenc_1_4_coul_scalars( - self, two_propanol_ua, ethane_gomc - ): - test_box_ethane_two_propanol_ua = mb.fill_box( - compound=[two_propanol_ua, ethane_gomc], - n_compounds=[1, 1], - box=[2.0, 2.0, 2.0], - ) - - with pytest.raises( - ValueError, - match=r"ERROR: There are multiple 1,4-coulombic scaling factors " - "GOMC will only accept a singular input for the 1,4-coulombic " - "scaling factors", - ): - Charmm( - test_box_ethane_two_propanol_ua, - "residue_reorder_box_sizing_box_0", - structure_box_1=ethane_gomc, - filename_box_1="residue_reorder_box_sizing_box_1", - ff_filename="residue_reorder_box", - residues=[two_propanol_ua.name, ethane_gomc.name], - forcefield_selection={ - two_propanol_ua.name: "trappe-ua", - ethane_gomc.name: "oplsaa", - }, - fix_residue=None, - fix_residue_in_box=None, - gomc_fix_bonds_angles=None, - reorder_res_in_pdb_psf=False, - bead_to_atom_name_dict={"_CH3": "C"}, - ) - - def test_charmm_pdb_residue_reorder_and_ff_filename_box_sizing( - self, ethanol_gomc, ethane_gomc - ): - test_box_ethane_ethanol_gomc = mb.fill_box( - compound=[ethanol_gomc, ethane_gomc], - n_compounds=[1, 1], - box=[3, 3, 3], - ) - - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - charmm = Charmm( - test_box_ethane_ethanol_gomc, - "residue_reorder_box_sizing_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="residue_reorder_box_sizing_box_1", - ff_filename=None, - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection=str(forcefields.get_ff_path()[0]) - + "/xml/" - + "oplsaa.xml", - fix_residue=None, - fix_residue_in_box=None, - gomc_fix_bonds_angles=None, - reorder_res_in_pdb_psf=True, - bead_to_atom_name_dict={"_CH3": "C"}, - ) - charmm.write_pdb() - - with open("residue_reorder_box_sizing_box_0.pdb", "r") as fp: - pdb_box_0_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_box_0_read = True - assert out_gomc[i].split()[0:7] == [ - "CRYST1", - "30.000", - "30.000", - "30.000", - "90.00", - "90.00", - "90.00", - ] - - atom_type_res_part_1_list = [ - ["ATOM", "1", "C1", "ETH", "A", "1"], - ["ATOM", "2", "C2", "ETH", "A", "1"], - ["ATOM", "3", "H1", "ETH", "A", "1"], - ["ATOM", "4", "H2", "ETH", "A", "1"], - ["ATOM", "5", "H3", "ETH", "A", "1"], - ["ATOM", "6", "H4", "ETH", "A", "1"], - ["ATOM", "7", "H5", "ETH", "A", "1"], - ["ATOM", "8", "H6", "ETH", "A", "1"], - ["ATOM", "9", "C1", "ETO", "A", "2"], - ["ATOM", "10", "C2", "ETO", "A", "2"], - ["ATOM", "11", "O1", "ETO", "A", "2"], - ["ATOM", "12", "H1", "ETO", "A", "2"], - ["ATOM", "13", "H2", "ETO", "A", "2"], - ["ATOM", "14", "H3", "ETO", "A", "2"], - ["ATOM", "15", "H4", "ETO", "A", "2"], - ["ATOM", "16", "H5", "ETO", "A", "2"], - ["ATOM", "17", "H6", "ETO", "A", "2"], - ] - - atom_type_res_part_2_list = [ - ["0.00", "0.00", "C"], - ["0.00", "0.00", "C"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "C"], - ["0.00", "0.00", "C"], - ["0.00", "0.00", "O"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "H"], - ] - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert pdb_box_0_read - - with open("residue_reorder_box_sizing_box_1.pdb", "r") as fp: - pdb_box_1_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_box_1_read = True - assert out_gomc[i].split()[0:7] == [ - "CRYST1", - "40.000", - "40.000", - "40.000", - "90.00", - "90.00", - "90.00", - ] - else: - pass - - assert pdb_box_1_read - - # test utils base 10 to base 16 converter - def test_base_10_to_base_16(self): - list_base_10_and_16 = [ - [15, "f"], - [16, "10"], - [17, "11"], - [200, "c8"], - [1000, "3e8"], - [5000, "1388"], - [int(16**3 - 1), "fff"], - [int(16**3), "1000"], - ] - - for test_base_16_iter in range(0, len(list_base_10_and_16)): - test_10_iter = list_base_10_and_16[test_base_16_iter][0] - test_16_iter = list_base_10_and_16[test_base_16_iter][1] - assert str(base10_to_base16_alph_num(test_10_iter)) == str( - test_16_iter - ) - - unique_entries_base_16_list = [] - for test_unique_base_16 in range(0, 16**2): - unique_entries_base_16_list.append( - base10_to_base16_alph_num(test_unique_base_16) - ) - - verified_unique_entries_base_16_list = np.unique( - unique_entries_base_16_list - ) - assert len(verified_unique_entries_base_16_list) == len( - unique_entries_base_16_list - ) - - add_same_values_list = ["1", "a"] - for add_same_base_16 in range(0, len(add_same_values_list)): - verified_unique_entries_base_16_list = np.append( - verified_unique_entries_base_16_list, - add_same_values_list[add_same_base_16], - ) - assert len(verified_unique_entries_base_16_list) - len( - add_same_values_list - ) == len(unique_entries_base_16_list) - - # test utils base 10 to base 26 converter - def test_base_10_to_base_26(self): - list_base_10_and_26 = [ - [0, "A"], - [5, "F"], - [25, "Z"], - [26, "BA"], - [200, "HS"], - [1000, "BMM"], - [5000, "HKI"], - [int(26**3 - 1), "ZZZ"], - [int(26**3), "BAAA"], - ] - - for test_base_26_iter in range(0, len(list_base_10_and_26)): - test_10_iter = list_base_10_and_26[test_base_26_iter][0] - test_26_iter = list_base_10_and_26[test_base_26_iter][1] - assert str(base10_to_base26_alph(test_10_iter)) == str(test_26_iter) - - unique_entries_base_26_list = [] - for test_unique_base_26 in range(0, 26**2): - unique_entries_base_26_list.append( - base10_to_base26_alph(test_unique_base_26) - ) - - verified_unique_entries_base_26_list = np.unique( - unique_entries_base_26_list - ) - assert len(verified_unique_entries_base_26_list) == len( - unique_entries_base_26_list - ) - - add_same_values_list = ["1", "a"] - for add_same_base_26 in range(0, len(add_same_values_list)): - verified_unique_entries_base_26_list = np.append( - verified_unique_entries_base_26_list, - add_same_values_list[add_same_base_26], - ) - assert len(verified_unique_entries_base_26_list) - len( - add_same_values_list - ) == len(unique_entries_base_26_list) - - # test utils base 10 to base 52 converter - def test_base_10_to_base_52(self): - list_base_10_and_52 = [ - [17, "R"], - [51, "z"], - [52, "BA"], - [53, "BB"], - [200, "Ds"], - [1000, "TM"], - [5000, "BsI"], - [int(52**3 - 1), "zzz"], - [int(52**3), "BAAA"], - ] - - for test_base_52_iter in range(0, len(list_base_10_and_52)): - test_10_iter = list_base_10_and_52[test_base_52_iter][0] - test_52_iter = list_base_10_and_52[test_base_52_iter][1] - assert str(base10_to_base52_alph(test_10_iter)) == str(test_52_iter) - - unique_entries_base_52_list = [] - for test_unique_base_52 in range(0, 52**2): - unique_entries_base_52_list.append( - base10_to_base52_alph(test_unique_base_52) - ) - - verified_unique_entries_base_52_list = np.unique( - unique_entries_base_52_list - ) - assert len(verified_unique_entries_base_52_list) == len( - unique_entries_base_52_list - ) - - add_same_values_list = ["1", "a"] - for add_same_base_52 in range(0, len(add_same_values_list)): - verified_unique_entries_base_52_list = np.append( - verified_unique_entries_base_52_list, - add_same_values_list[add_same_base_52], - ) - assert len(verified_unique_entries_base_52_list) - len( - add_same_values_list - ) == len(unique_entries_base_52_list) - - # test utils base 10 to base 62 converter - def test_base_10_to_base_62(self): - list_base_10_and_62 = [ - [17, "H"], - [61, "z"], - [62, "10"], - [63, "11"], - [200, "3E"], - [1000, "G8"], - [5000, "1Ie"], - [int(62**3 - 1), "zzz"], - [int(62**3), "1000"], - ] - - for test_base_62_iter in range(0, len(list_base_10_and_62)): - test_10_iter = list_base_10_and_62[test_base_62_iter][0] - test_62_iter = list_base_10_and_62[test_base_62_iter][1] - assert str(base10_to_base62_alph_num(test_10_iter)) == str( - test_62_iter - ) - - unique_entries_base_62_list = [] - for test_unique_base_62 in range(0, 62**2): - unique_entries_base_62_list.append( - base10_to_base62_alph_num(test_unique_base_62) - ) - - verified_unique_entries_base_62_list = np.unique( - unique_entries_base_62_list - ) - assert len(verified_unique_entries_base_62_list) == len( - unique_entries_base_62_list - ) - - add_same_values_list = ["1", "a"] - for add_same_base_62 in range(0, len(add_same_values_list)): - verified_unique_entries_base_62_list = np.append( - verified_unique_entries_base_62_list, - add_same_values_list[add_same_base_62], - ) - assert len(verified_unique_entries_base_62_list) - len( - add_same_values_list - ) == len(unique_entries_base_62_list) - - # Tests for the mbuild.utils.specific_FF_to_residue.Specific_FF_to_residue() function - def test_specific_ff_ff_is_none(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"Please the force field selection \(forcefield_selection\) as a " - r"dictionary with all the residues specified to a force field " - '-> Ex: {"Water" : "oplsaa", "OCT": "path/trappe-ua.xml"}, ' - "Note: the file path must be specified the force field file " - "or by using the standard force field name provided the `foyer` package.", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection=None, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_ff_wrong_ff_extention(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"Please make sure you are entering the correct " - r"foyer FF name and not a path to a FF file. " - r"If you are entering a path to a FF file, " - r"please use the forcefield_files variable with the " - r"proper XML extension \(.xml\).", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa.pdb"}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_all_residue_not_input(self, ethane_gomc, ethanol_gomc): - with pytest.raises( - ValueError, - match=r"All the residues are not specified, or the residues " - r"entered does not match the residues that were found " - r"and built for structure.", - ): - box = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - box=[1, 1, 1], - n_compounds=[1, 1], - ) - - specific_ff_to_residue( - box, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=2, - ) - - def test_specific_ff_to_residue_ff_selection_not_dict(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"The force field selection \(forcefield_selection\) " - "is not a dictionary. Please enter a dictionary " - "with all the residues specified to a force field " - '-> Ex: {"Water" : "oplsaa", "OCT": "path/trappe-ua.xml"}, ' - "Note: the file path must be specified the force field file " - "or by using the standard force field name provided the `foyer` package.", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection="oplsaa", - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_ff_to_residue_is_none(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"Please enter the residues in the Specific_FF_to_residue function.", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=None, - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_ff_to_residue_reorder_not_true_or_false( - self, ethane_gomc - ): - with pytest.raises( - TypeError, - match=r"Please enter the reorder_res_in_pdb_psf " - r"in the Specific_FF_to_residue function \(i.e., True or False\).", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=None, - boxes_for_simulation=1, - ) - - def test_specific_ff_to_simulation_boxes_not_1_or_2(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"Please enter boxes_for_simulation equal the integer 1 or 2.", - ): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 3, 4] - ) - - specific_ff_to_residue( - test_box_ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=3, - ) - - def test_specific_ff_to_residue_ffselection_wrong_path(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"Please make sure you are entering the correct foyer FF path, " - r"including the FF file name.xml " - r"If you are using the pre-build FF files in foyer, " - r"only use the string name without any extension.", - ): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 5, 6] - ) - - specific_ff_to_residue( - test_box_ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa.xml"}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_ff_wrong_path(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"Please make sure you are entering the correct foyer FF path, " - r"including the FF file name.xml " - r"If you are using the pre-build FF files in foyer, " - r"only use the string name without any extension.", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa.xml"}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_ff_to_residue_input_string_as_compound(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: The structure expected to be of type: " - r" or , " - r"received: ", - ): - specific_ff_to_residue( - "ethane_gomc", - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_ff_to_residue_boxes_for_simulation_not_int( - self, ethane_gomc - ): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter boxes_for_simulation equal " - "the integer 1 or 2.", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1.1, - ) - - def test_specific_ff_to_residues_no_ff(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"The forcefield_selection variable are not provided, " - r"but there are residues provided.", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection={}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_ff_to_no_residues(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"The residues variable is an empty list but there are " - "forcefield_selection variables provided.", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_ff_wrong_foyer_name(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"Please make sure you are entering the correct foyer FF name, " - r"or the correct file extension \(i.e., .xml, if required\).", - ): - specific_ff_to_residue( - ethane_gomc, - forcefield_selection={ethane_gomc.name: "xxx"}, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_specific_ff_to_residue_ffselection_run(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 5, 6] - ) - - [ - test_value_0, - test_value_1, - test_value_2, - test_value_3, - ] = specific_ff_to_residue( - test_box_ethane_gomc, - forcefield_selection={ - ethane_gomc.name: forcefields.get_ff_path()[0] - + "/xml/" - + "oplsaa.xml" - }, - residues=[ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - assert test_value_1 == {"ETH": 0.5} - assert test_value_2 == {"ETH": 0.5} - assert test_value_3 == ["ETH"] - - def test_specific_ff_to_no_atoms_in_residue(self): - with pytest.raises( - ValueError, - match=r"The residues variable is an empty list but there " - r"are forcefield_selection variables provided.", - ): - empty_compound = mb.Compound() - - specific_ff_to_residue( - empty_compound, - forcefield_selection={"empty_compound": "oplsaa"}, - residues=[], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_charmm_methane_test_no_children(self, methane_ua_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: If you are not providing an empty box, " - r"you need to specify the atoms/beads as children in the mb.Compound. " - r"If you are providing and empty box, please do so by specifying and " - r"mbuild Box \({}\)".format(type(Box(lengths=[1, 1, 1]))), - ): - specific_ff_to_residue( - methane_ua_gomc, - forcefield_selection={methane_ua_gomc.name: "trappe-ua"}, - residues=[methane_ua_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_charmm_a_few_mbuild_layers(self, ethane_gomc, ethanol_gomc): - box_reservior_1 = mb.fill_box( - compound=[ethane_gomc], box=[1, 1, 1], n_compounds=[1] - ) - box_reservior_1.periodicity = (True, True, True) - box_reservior_2 = mb.fill_box( - compound=[ethanol_gomc], box=[1, 1, 1], n_compounds=[1] - ) - box_reservior_2.translate([0, 0, 1]) - box_reservior_1.add(box_reservior_2, inherit_periodicity=False) - - [ - test_value_0, - test_value_1, - test_value_2, - test_value_3, - ] = specific_ff_to_residue( - box_reservior_1, - forcefield_selection={ - ethanol_gomc.name: "oplsaa", - ethane_gomc.name: "oplsaa", - }, - residues=[ethanol_gomc.name, ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - assert ( - str(test_value_0) - == "" - ) - assert test_value_1 == {"ETO": 0.5, "ETH": 0.5} - assert test_value_2 == {"ETO": 0.5, "ETH": 0.5} - assert test_value_3 == ["ETH", "ETO"] - - def test_charmm_all_residues_not_in_dict(self, ethane_gomc, ethanol_gomc): - with pytest.raises( - ValueError, - match=r"All the residues were not used from the forcefield_selection " - r"string or dictionary. There may be residues below other " - r"specified residues in the mbuild.Compound hierarchy. " - r"If so, all the highest listed residues pass down the force " - r"fields through the hierarchy. Alternatively, residues that " - r"are not in the structure may have been specified. ", - ): - box_reservior_1 = mb.fill_box( - compound=[ethane_gomc], box=[1, 1, 1], n_compounds=[1] - ) - specific_ff_to_residue( - box_reservior_1, - forcefield_selection={ethanol_gomc.name: "oplsaa"}, - residues=[ethanol_gomc.name, ethane_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - def test_charmm_correct_residue_format(self, ethane_gomc): - test_value = Charmm( - ethane_gomc, - "box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename=None, - residues=[ethane_gomc.name], - forcefield_selection={ethane_gomc.name: "oplsaa"}, - ) - - assert test_value.input_error is False - - def test_charmm_residue_not_list(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the residues list \(residues\) in a list format.", - ): - Charmm( - ethane_gomc, - "box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename=None, - residues=ethane_gomc.name, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - ) - - def test_charmm_residue_string(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the residues list \(residues\) in a list format.", - ): - Charmm( - ethane_gomc, - "box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename=None, - residues="ethane_gomc.name", - forcefield_selection={ethane_gomc.name: "oplsaa"}, - ) - - def test_charmm_residue_is_none(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the residues list \(residues\)", - ): - Charmm( - ethane_gomc, - "box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename=None, - residues=None, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - ) - - def test_charmm_filename_0_is_not_string(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the filename_box_0 as a string.", - ): - Charmm( - ethane_gomc, - 0, - structure_box_1=None, - filename_box_1=None, - ff_filename=None, - residues=[ethane_gomc.name], - forcefield_selection={ethane_gomc.name: "oplsaa"}, - ) - - def test_charmm_filename_box_1_is_not_string(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the filename_box_1 as a string.", - ): - Charmm( - ethane_gomc, - "box_0", - structure_box_1=ethane_gomc, - filename_box_1=["box_0"], - ff_filename=None, - residues=[ethane_gomc.name], - forcefield_selection={ethane_gomc.name: "oplsaa"}, - ) - - def test_charmm_gomc_filename_not_string(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter GOMC force field name \(ff_filename\) as a string.", - ): - Charmm( - ethane_gomc, - "box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename=0, - residues=[ethane_gomc.name], - forcefield_selection={ethane_gomc.name: "oplsaa"}, - ) - - def test_charmm_gomc_filename_ext_not_dot_inp(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"ERROR: Please enter GOMC force field name without an " - "extention or the .inp extension.", - ): - Charmm( - ethane_gomc, - "box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="box.test", - residues=[ethane_gomc.name], - forcefield_selection={ethane_gomc.name: "oplsaa"}, - ) - - def test_charmm_ffselection_not_dict(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: The force field selection \(forcefield_selection\) " - "is not a string or a dictionary with all the residues specified " - 'to a force field. -> String Ex: "path/trappe-ua.xml" or Ex: "trappe-ua" ' - "Otherise provided a dictionary with all the residues specified " - "to a force field " - '->Dictionary Ex: {"Water" : "oplsaa", "OCT": "path/trappe-ua.xml"}, ' - "Note: the file path must be specified the force field file if " - "a standard foyer force field is not used.", - ): - Charmm( - ethane_gomc, - "box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="box_0", - residues=[ethane_gomc.name], - forcefield_selection=["oplsaa", "oplsaa"], - ) - - def test_charmm_ffselection_string(self, ethane_gomc): - test_value = Charmm( - ethane_gomc, - "box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="box_0", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - assert test_value.input_error is False - - def test_charmm_residue_name_not_in_residues(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"ERROR: All the residues are not specified, or " - "the residues entered does not match the residues that " - "were found and built for structure.", - ): - Charmm( - ethane_gomc, - "box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="box_0", - residues=["XXX"], - forcefield_selection="oplsaa", - ) - - def test_ffselection_string(self, two_propanol_ua): - charmm = Charmm( - two_propanol_ua, - "ffselection_string", - ff_filename="ffselection_string", - residues=[two_propanol_ua.name], - forcefield_selection=forcefields.get_ff_path()[0] - + "/xml/" - + "trappe-ua.xml", - bead_to_atom_name_dict={"_CH3": "C"}, - ) - charmm.write_pdb() - - with open("ffselection_string.pdb", "r") as fp: - pdb_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_read = True - atom_type_res_part_1_list = [ - ["ATOM", "1", "C1", "POL", "A", "1"], - ["ATOM", "2", "BD1", "POL", "A", "1"], - ["ATOM", "3", "O1", "POL", "A", "1"], - ["ATOM", "4", "H1", "POL", "A", "1"], - ["ATOM", "5", "C2", "POL", "A", "1"], - ] - atom_type_res_part_2_list = [ - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "O"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "EP"], - ] - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert pdb_read - - def test_ff_selection_list(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: The force field selection \(forcefield_selection\) " - "is not a string or a dictionary with all the residues specified " - 'to a force field. -> String Ex: "path/trappe-ua.xml" or Ex: "trappe-ua" ' - "Otherise provided a dictionary with all the residues specified " - "to a force field " - '->Dictionary Ex: {"Water" : "oplsaa", "OCT": "path/trappe-ua.xml"}, ' - "Note: the file path must be specified the force field file if " - "a standard foyer force field is not used.", - ): - Charmm( - two_propanol_ua, - "S", - ff_filename="S", - residues=[two_propanol_ua.name], - forcefield_selection=[ - str(forcefields.get_ff_path()[0]) - + "/xml/" - + "trappe-ua.xml" - ], - bead_to_atom_name_dict={"_CH3": "C"}, - ) - - def test_residues_not_a_string(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter a residues list " - r"\(residues\) with only string values.", - ): - Charmm( - two_propanol_ua, - "box_0", - ff_filename="box_0", - residues=[2], - forcefield_selection={two_propanol_ua.name: "trappe-ua"}, - bead_to_atom_name_dict={"_CH3": "C"}, - ) - - # charmm writer sub-function testing - def test_charmm_bond_reorder_angle_urey_bradleys( - self, two_propanol_gomc, ethanol_gomc - ): - box_reservior_0 = mb.fill_box( - compound=[two_propanol_gomc, ethanol_gomc], - box=[2, 2, 2], - n_compounds=[2, 2], - ) - - [ - structure_ff, - coulomb14scalar_dict, - lj14_scalar_dict, - residues_applied_list, - ] = specific_ff_to_residue( - box_reservior_0, - forcefield_selection={ - two_propanol_gomc.name: "oplsaa", - ethanol_gomc.name: "oplsaa", - }, - residues=[ethanol_gomc.name, two_propanol_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - sigma_conversion_factor = 1 - epsilon_conversion_factor = 1 - # reversed the bond order so it fixes itself - bonds_1 = [ - [bond.atom1.idx + 1, bond.atom2.idx + 1] - for bond in structure_ff.bonds - ] - bond_types_1, unique_bond_types_1 = charmm_writer._get_bond_types( - structure_ff, sigma_conversion_factor, epsilon_conversion_factor - ) - - bonds_2 = [ - [bond.atom2.idx + 1, bond.atom1.idx + 1] - for bond in structure_ff.bonds - ] - bond_types_2, unique_bond_types_2 = charmm_writer._get_bond_types( - structure_ff, sigma_conversion_factor, epsilon_conversion_factor - ) - - assert bonds_1 != bonds_2 - assert bond_types_1 == bond_types_2 - assert unique_bond_types_1 == unique_bond_types_2 - - # test for error if trying to use urey_bradleys in th angles - use_urey_bradleys = True - angle_types_1, unique_angle_types_1 = charmm_writer._get_angle_types( - structure_ff, - sigma_conversion_factor, - epsilon_conversion_factor, - use_urey_bradleys=use_urey_bradleys, - ) - - assert angle_types_1 is None - assert unique_angle_types_1 is None - - # test for error if trying to use use_dihedrals and impropers in the dihedrals (i.e. only RB torsion allowed) - def test_charmm_dihedral_reorder(self, ethyl_ether_gomc, methyl_ether_gomc): - box_reservior_0 = mb.fill_box( - compound=[ethyl_ether_gomc, methyl_ether_gomc], - box=[10, 10, 10], - n_compounds=[10, 10], - ) - - [ - structure_ff, - coulomb14scalar_dict, - lj14_scalar_dict, - residues_applied_list, - ] = specific_ff_to_residue( - box_reservior_0, - forcefield_selection={ - ethyl_ether_gomc.name: "oplsaa", - methyl_ether_gomc.name: "oplsaa", - }, - residues=[ethyl_ether_gomc.name, methyl_ether_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - use_rb_torsions_1 = False - use_dihedrals_1 = True - epsilon_conversion_factor = 1 - lj_unit = 1 / epsilon_conversion_factor - ( - dihedral_types_1, - unique_dihedral_types_1, - ) = charmm_writer._get_dihedral_types( - structure_ff, - use_rb_torsions_1, - use_dihedrals_1, - epsilon_conversion_factor, - ) - assert dihedral_types_1 is None - assert unique_dihedral_types_1 is None - - use_rb_torsions_2 = True - use_dihedrals_2 = False - - ( - dihedral_types_2, - unique_dihedral_types_2, - ) = charmm_writer._get_dihedral_types( - structure_ff, - use_rb_torsions_2, - use_dihedrals_2, - epsilon_conversion_factor, - ) - - unique_dih_typ_unsorted_2 = dict( - enumerate( - set( - [ - ( - round(dihedral.type.c0 * lj_unit, 3), - round(dihedral.type.c1 * lj_unit, 3), - round(dihedral.type.c2 * lj_unit, 3), - round(dihedral.type.c3 * lj_unit, 3), - round(dihedral.type.c4 * lj_unit, 3), - round(dihedral.type.c5 * lj_unit, 3), - round(dihedral.type.scee, 1), - round(dihedral.type.scnb, 1), - dihedral.atom1.type, - dihedral.atom2.type, - dihedral.atom3.type, - dihedral.atom4.type, - dihedral.atom1.residue.name, - dihedral.atom2.residue.name, - dihedral.atom3.residue.name, - dihedral.atom4.residue.name, - ) - for dihedral in structure_ff.rb_torsions - ] - ) - ) - ) - - unique_dih_typ_unsorted_2 = OrderedDict( - [(y, x + 1) for x, y in unique_dih_typ_unsorted_2.items()] - ) - - assert len(unique_dih_typ_unsorted_2) == 7 - assert len(unique_dihedral_types_2) == 5 - - # test for error if trying to use impropers in the dihedrals (currently impropers are found but not used in - # the output) - # ******** NOTE************************* - # ******** NOTE************************* - # These impropers are blank and will need filled in upon adding the improper functionallity. - # They are kept in the code to identify if there are any impropers in the system and count them - # ******** NOTE************************* - # ******** NOTE************************* - # ******** NOTE************************* - ( - improper_types_1, - unique_improper_types_1, - ) = charmm_writer._get_impropers( - structure_ff, epsilon_conversion_factor - ) - - assert str(improper_types_1) == "[]" - assert str(unique_improper_types_1) == "OrderedDict()" - - def test_charmm_angle_reorder(self, ethyl_ether_gomc, methyl_ether_gomc): - box_reservior_0 = mb.fill_box( - compound=[ethyl_ether_gomc, methyl_ether_gomc], - box=[10, 10, 10], - n_compounds=[10, 10], - ) - - [ - structure_ff, - coulomb14scalar_dict, - lj14_scalar_dict, - residues_applied_list, - ] = specific_ff_to_residue( - box_reservior_0, - forcefield_selection={ - ethyl_ether_gomc.name: "oplsaa", - methyl_ether_gomc.name: "oplsaa", - }, - residues=[ethyl_ether_gomc.name, methyl_ether_gomc.name], - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, - ) - - sigma_conversion_factor = 1 - epsilon_conversion_factor = 1 - use_urey_bradleys = False - angle_types_1, unique_angle_types_1 = charmm_writer._get_angle_types( - structure_ff, - sigma_conversion_factor, - epsilon_conversion_factor, - use_urey_bradleys, - ) - - # note this sorts all the possible combinations, so this should be the same as the double check (i.e, both 10) - unique_angle_types_1_unsorted = dict( - enumerate( - set( - [ - ( - round( - angle.type.k - * ( - sigma_conversion_factor**2 - / epsilon_conversion_factor - ), - 3, - ), - round(angle.type.theteq, 3), - angle.atom2.type, - tuple(sorted((angle.atom1.type, angle.atom3.type))), - angle.atom1.residue.name, - angle.atom2.residue.name, - angle.atom3.residue.name, - ) - for angle in structure_ff.angles - ] - ) - ) - ) - unique_angle_types_1_unsorted = OrderedDict( - [(y, x + 1) for x, y in unique_angle_types_1_unsorted.items()] - ) - - assert len(unique_angle_types_1_unsorted) == 10 - assert len(unique_angle_types_1) == 10 - - def test_bead_atomname_equal_3(self, two_propanol_ua): - # testing def unique_atom_naming in charmm_writer, expecting when failing - with pytest.raises( - ValueError, - match=r"ERROR: The unique_atom_naming function failed while " - "running the charmm_writer function. Ensure the proper inputs are " - "in the bead_to_atom_name_dict.", - ): - box_reservior_0 = mb.fill_box( - compound=[two_propanol_ua], box=[10, 10, 10], n_compounds=[10] - ) - - value_0 = Charmm( - box_reservior_0, - "test_bead_atomname_equal_3", - ff_filename="test_bead_atomname_equal_3", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "Cx", "_HC": "Cxx"}, - ) - value_0.write_inp() - value_0.write_pdb() - value_0.write_psf() - - def test_gomc_fix_bonds_angles_string(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: Please ensure the residue names in the \({}\) variable " - r"are in a list.".format("gomc_fix_bonds_angles"), - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - gomc_fix_bonds_angles="two_propanol_ua.name", - ) - - def test_gomc_fix_bonds_angles_residue_not_in_system(self, two_propanol_ua): - with pytest.raises( - ValueError, - match=r"ERROR: Please ensure that all the residue names in the " - r"{} list are also in the residues list.".format( - "gomc_fix_bonds_angles" - ), - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - gomc_fix_bonds_angles=["WNG"], - ) - - def test_gomc_fix_bonds_string(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: Please ensure the residue names in the \({}\) variable " - r"are in a list.".format("gomc_fix_bonds"), - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - gomc_fix_bonds="two_propanol_ua.name", - ) - - def test_gomc_fix_bonds_residue_not_in_system(self, two_propanol_ua): - with pytest.raises( - ValueError, - match=r"ERROR: Please ensure that all the residue names in the " - r"{} list are also in the residues list.".format("gomc_fix_bonds"), - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - gomc_fix_bonds=["WNG"], - ) - - def test_gomc_fix_angles_string(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: Please ensure the residue names in the \({}\) variable " - r"are in a list.".format("gomc_fix_angles"), - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - gomc_fix_angles="two_propanol_ua.name", - ) - - def test_gomc_fix_angles_residue_not_in_system(self, two_propanol_ua): - with pytest.raises( - ValueError, - match=r"ERROR: Please ensure that all the residue names in the " - r"{} list are also in the residues list.".format("gomc_fix_angles"), - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - gomc_fix_angles=["WNG"], - ) - - def test_fix_residue_string(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the fix_residue in a list format", - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - fix_residue="two_propanol_ua.name", - ) - - def test_fix_residue_string_residue_not_in_system(self, two_propanol_ua): - with pytest.raises( - ValueError, - match=r"Error: Please ensure that all the residue names in the fix_residue " - r"list are also in the residues list.", - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - fix_residue=["WNG"], - ) - - def test_fix_residue_in_box_string(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the fix_residue_in_box in a list format.", - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - fix_residue_in_box="two_propanol_ua.name", - ) - - def test_fix_residue_in_box_string_residue_not_in_system( - self, two_propanol_ua - ): - with pytest.raises( - ValueError, - match=r"Error: Please ensure that all the residue names in the " - r"fix_residue_in_box list are also in the residues list.", - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - fix_residue_in_box=["WNG"], - ) - - def test_bead_to_atom_name_dict_list(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the a bead type to atom in the dictionary " - r"\(bead_to_atom_name_dict\) so GOMC can properly evaluate the " - r"unique atom names", - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict=["_CH3", "C"], - ) - - def test_bead_to_atom_name_dict_not_string_0(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the bead_to_atom_name_dict with only " - r"string inputs.", - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": 0}, - ) - - def test_bead_to_atom_name_dict_not_string_1(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the bead_to_atom_name_dict with only " - r"string inputs.", - ): - Charmm( - two_propanol_ua, - "charmm_data_UA", - ff_filename="charmm_data_UA", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={0: "C"}, - ) - - def test_1_box_residues_not_all_listed_box_0( - self, ethane_gomc, ethanol_gomc - ): - with pytest.raises( - ValueError, - match=r"ERROR: All the residues are not specified, or the residues " - r"entered does not match the residues that were found and " - r"built for structure.", - ): - Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="charmm_data", - residues=[ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - def test_2_box_residues_not_all_listed_box_0( - self, ethane_gomc, ethanol_gomc - ): - with pytest.raises( - ValueError, - match=r"ERROR: All the residues are not specified, or the residues " - r"entered does not match the residues that were found and " - r"built for structure.", - ): - Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=ethanol_gomc, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=["XXX", ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - def test_2_box_residues_not_all_listed_box_1( - self, ethane_gomc, ethanol_gomc - ): - with pytest.raises( - ValueError, - match=r"ERROR: All the residues are not specified, or the residues " - r"entered does not match the residues that were found and " - r"built for structure.", - ): - Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=ethanol_gomc, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=["XXX", ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - def test_2_box_residues_listed_2x(self, ethane_gomc, ethanol_gomc): - with pytest.raises( - ValueError, - match=r"ERROR: Please enter the residues list \(residues\) that has " - r"only unique residue names.", - ): - Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=ethanol_gomc, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[ethanol_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - def test_all_residues_are_listed(self, ethane_gomc, ethanol_gomc): - with pytest.raises( - ValueError, - match=r"ERROR: All the residues are not specified, or the residues " - r"entered does not match the residues that were found and " - r"built for structure.", - ): - Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=ethanol_gomc, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - # Test that an empty box (psf and pdb files) can be created to start a simulation - def test_box_1_empty_test_1(self, two_propanol_ua): - empty_compound = Box(lengths=[2, 2, 2]) - - charmm = Charmm( - two_propanol_ua, - "charmm_filled_box", - structure_box_1=empty_compound, - filename_box_1="charmm_empty_box", - ff_filename="charmm_empty_box.inp", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - ) - charmm.write_pdb() - charmm.write_psf() - - with open("charmm_empty_box.pdb", "r") as fp: - pdb_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_read = True - assert out_gomc[i].split()[0:7] == [ - "CRYST1", - "20.000", - "20.000", - "20.000", - "90.00", - "90.00", - "90.00", - ] - assert out_gomc[i + 1].split() == ["END"] - - else: - pass - - assert pdb_read - - with open("charmm_filled_box.pdb", "r") as fp: - pdb_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_read = True - atom_type_res_part_1_list = [ - ["ATOM", "1", "C1", "POL", "A", "1"], - ["ATOM", "2", "BD1", "POL", "A", "1"], - ["ATOM", "3", "O1", "POL", "A", "1"], - ["ATOM", "4", "H1", "POL", "A", "1"], - ["ATOM", "5", "C2", "POL", "A", "1"], - ] - atom_type_res_part_2_list = [ - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "O"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "EP"], - ] - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert pdb_read - - def test_box_1_empty_test_2(self, two_propanol_ua): - empty_compound = Box(lengths=[3, 3, 3], angles=[90, 90, 90]) - - charmm = Charmm( - two_propanol_ua, - "charmm_filled_box", - structure_box_1=empty_compound, - filename_box_1="charmm_empty_box", - ff_filename="charmm_empty_box.inp", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - ) - charmm.write_pdb() - charmm.write_psf() - - with open("charmm_empty_box.pdb", "r") as fp: - pdb_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_read = True - assert out_gomc[i].split()[0:7] == [ - "CRYST1", - "30.000", - "30.000", - "30.000", - "90.00", - "90.00", - "90.00", - ] - assert out_gomc[i + 1].split() == ["END"] - - else: - pass - - assert pdb_read - - with open("charmm_filled_box.pdb", "r") as fp: - pdb_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_read = True - atom_type_res_part_1_list = [ - ["ATOM", "1", "C1", "POL", "A", "1"], - ["ATOM", "2", "BD1", "POL", "A", "1"], - ["ATOM", "3", "O1", "POL", "A", "1"], - ["ATOM", "4", "H1", "POL", "A", "1"], - ["ATOM", "5", "C2", "POL", "A", "1"], - ] - atom_type_res_part_2_list = [ - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "O"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "EP"], - ] - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert pdb_read - - def test_box_1_empty_test_3(self, two_propanol_ua): - empty_compound = Box(lengths=[4, 5, 6]) - - test_box_two_propanol_ua_gomc = mb.fill_box( - compound=[two_propanol_ua], n_compounds=[1], box=[3, 4, 5] - ) - - charmm = Charmm( - empty_compound, - "charmm_empty_box", - structure_box_1=test_box_two_propanol_ua_gomc, - filename_box_1="charmm_filled_box", - ff_filename="charmm_empty_box", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - ) - charmm.write_pdb() - charmm.write_psf() - - with open("charmm_empty_box.pdb", "r") as fp: - pdb_part_1_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_part_1_read = True - assert out_gomc[i].split()[0:7] == [ - "CRYST1", - "40.000", - "50.000", - "60.000", - "90.00", - "90.00", - "90.00", - ] - assert out_gomc[i + 1].split() == ["END"] - - else: - pass - - assert pdb_part_1_read - - with open("charmm_filled_box.pdb", "r") as fp: - pdb_part_2_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_part_2_read = True - atom_type_res_part_1_list = [ - ["ATOM", "1", "C1", "POL", "A", "1"], - ["ATOM", "2", "BD1", "POL", "A", "1"], - ["ATOM", "3", "O1", "POL", "A", "1"], - ["ATOM", "4", "H1", "POL", "A", "1"], - ["ATOM", "5", "C2", "POL", "A", "1"], - ] - atom_type_res_part_2_list = [ - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "EP"], - ["0.00", "0.00", "O"], - ["0.00", "0.00", "H"], - ["0.00", "0.00", "EP"], - ] - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert pdb_part_2_read - - def test_box_1_empty_test_4(self): - empty_compound_box_0 = Box(lengths=[2, 2, 2]) - empty_compound_box_1 = Box(lengths=[3, 3, 3]) - with pytest.raises( - TypeError, - match=r"ERROR: Both structure_box_0 and structure_box_0 are empty Boxes {}. " - "At least 1 structure must be an mbuild compound {} with 1 " - "or more atoms in it".format( - type(Box(lengths=[1, 1, 1])), type(Compound()) - ), - ): - Charmm( - empty_compound_box_0, - "charmm_data_box_0", - structure_box_1=empty_compound_box_1, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[], - forcefield_selection="oplsaa", - ) - - def test_box_1_empty_test_5(self): - empty_compound_box_0 = Box(lengths=[2, 2, 2]) - with pytest.raises( - TypeError, - match=r"ERROR: Only 1 structure is provided and it can not be an empty " - r"mbuild Box {}. " - "it must be an mbuild compound {} with at least 1 " - "or more atoms in it.".format( - type(Box(lengths=[1, 1, 1])), type(Compound()) - ), - ): - Charmm( - empty_compound_box_0, - "charmm_data_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="charmm_data", - residues=[], - forcefield_selection="oplsaa", - ) - - def test_box_1_empty_test_6(self, two_propanol_ua): - with pytest.raises( - TypeError, - match=r"ERROR: If you are not providing an empty box, " - r"you need to specify the atoms/beads as children in the mb.Compound. " - r"If you are providing and empty box, please do so by specifying and " - r"mbuild Box \({}\)".format(type(Box(lengths=[1, 1, 1]))), - ): - test_box_two_propanol_ua_gomc = mb.fill_box( - compound=[two_propanol_ua], n_compounds=[1], box=[3, 4, 5] - ) - - empty_compound = mb.Compound() - Charmm( - empty_compound, - "charmm_empty_box", - structure_box_1=test_box_two_propanol_ua_gomc, - filename_box_1="charmm_filled_box", - ff_filename="charmm_empty_box", - residues=[two_propanol_ua.name], - forcefield_selection="trappe-ua", - bead_to_atom_name_dict={"_CH3": "C"}, - ) - - def test_structure_box_0_not_mb_compound(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: The structure_box_0 expected to be of type: " - r"{} or {}, received: {}".format( - type(Compound()), - type(Box(lengths=[1, 1, 1])), - type("ethane_gomc"), - ), - ): - Charmm( - "ethane_gomc", - "charmm_data_box_0", - structure_box_1=ethane_gomc, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - def test_structure_box_1_not_mb_compound(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: The structure_box_1 expected to be of type: " - "{} or {}, received: {}".format( - type(Compound()), type(Box(lengths=[1, 1, 1])), type(0) - ), - ): - Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=0, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - def test_ff_dict_not_entered(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter the forcefield_selection as it was not provided.", - ): - Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=ethane_gomc, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[ethane_gomc.name], - forcefield_selection=None, - ) - - def test_mie_non_bonded_type(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"ERROR: Currently the Mie potential \(non_bonded_type\) is not " - r"supported in this MoSDeF GOMC parameter writer.", - ): - charmm = Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=ethane_gomc, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - non_bonded_type="Mie", - ) - charmm.write_inp() - - def test_other_non_bonded_type(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"ERROR: Currently this potential \(non_bonded_type\) is not " - r"supported in this MoSDeF GOMC parameter writer.", - ): - charmm = Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=ethane_gomc, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - non_bonded_type="XXX", - ) - charmm.write_inp() - - def test_diff_1_4_coul_scalars(self, ethane_gomc, two_propanol_ua): - with pytest.raises( - ValueError, - match=r"ERROR: There are multiple 1,4-coulombic scaling factors " - "GOMC will only accept a singular input for the 1,4-coulombic " - "scaling factors.", - ): - Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=two_propanol_ua, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[ethane_gomc.name, two_propanol_ua.name], - forcefield_selection={ - ethane_gomc.name: "oplsaa", - two_propanol_ua.name: "trappe-ua", - }, - ) - - def test_write_inp_wo_ff_filename(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: The force field file name was not specified and in the " - r"Charmm object. " - r"Therefore, the force field file \(.inp\) can not be written. " - r"Please use the force field file name when building the Charmm object, " - r"then use the write_inp function.", - ): - charmm = Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=ethane_gomc, - filename_box_1="charmm_data_box_1", - ff_filename=None, - forcefield_selection="oplsaa", - residues=[ethane_gomc.name], - ) - charmm.write_inp() - - def test_write_inp_with_2_boxes(self, ethane_gomc): - charmm = Charmm( - ethane_gomc, - "charmm_data_box_0", - structure_box_1=ethane_gomc, - filename_box_1="charmm_data_box_1", - ff_filename="charmm_data", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - charmm.write_inp() - - with open("charmm_data.inp", "r") as fp: - masses_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if ( - "!atom_types" in line - and "mass" in line - and "atomTypeForceFieldName_ResidueName" in line - and "(i.e., atoms_type_per_utilized_FF)" in line - ): - masses_read = True - mass_type_1 = [ - ["*", "A", "12.010780"], - ["*", "B", "1.007947"], - ] - mass_type_2 = [["opls_135_ETH"], ["opls_140_ETH"]] - for j in range(0, len(mass_type_1)): - assert ( - len(out_gomc[i + 1 + j].split("!")[0].split()) == 3 - ) - assert ( - out_gomc[i + 1 + j].split("!")[0].split()[0:3] - == mass_type_1[j] - ) - assert ( - out_gomc[i + 1 + j].split()[4:5] == mass_type_2[j] - ) - - assert masses_read - - # test cif reader ETA psf writer outputs correct atom and residue numbering using non-orthoganol box - def test_save_non_othoganol_box_psf(self): - lattice_cif_ETV_triclinic = load_cif( - file_or_path=get_fn("ETV_triclinic.cif") - ) - ETV_triclinic = lattice_cif_ETV_triclinic.populate(x=1, y=1, z=1) - ETV_triclinic.name = "ETV" - - charmm = Charmm( - ETV_triclinic, - "ETV_triclinic", - ff_filename="ETV_triclinic_FF", - forcefield_selection={ - ETV_triclinic.name: get_fn( - "Charmm_writer_testing_only_zeolite.xml" - ) - }, - residues=[ETV_triclinic.name], - bead_to_atom_name_dict=None, - fix_residue=[ETV_triclinic.name], - ) - - charmm.write_psf() - - with open("ETV_triclinic.psf", "r") as fp: - psf_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "42 !NATOM" in line: - psf_read = True - no_O_atoms = 28 - no_Si_atoms = 14 - atom_type_charge_etc_list = [] - for f_i in range(0, no_O_atoms): - atom_type_charge_etc_list.append( - [ - str(f_i + 1), - "SYS", - str(f_i + 1), - "ETV", - "O1", - "A", - "-0.400000", - "15.9994", - ], - ) - for f_i in range(no_O_atoms, no_O_atoms + no_Si_atoms): - atom_type_charge_etc_list.append( - [ - str(f_i + 1), - "SYS", - str(f_i + 1), - "ETV", - "Si1", - "B", - "0.800000", - "28.0855", - ], - ) - - for j in range(0, len(atom_type_charge_etc_list)): - assert ( - out_gomc[i + 1 + j].split()[0:8] - == atom_type_charge_etc_list[j] - ) - - else: - pass - - assert psf_read - - # test cif reader ETA pdb writer outputs correct atom and residue numbering using non-orthoganol box - def test_save_non_othoganol_box_pdb(self): - lattice_cif_ETV_triclinic = load_cif( - file_or_path=get_fn("ETV_triclinic.cif") - ) - ETV_triclinic = lattice_cif_ETV_triclinic.populate(x=1, y=1, z=1) - ETV_triclinic.name = "ETV" - - charmm = Charmm( - ETV_triclinic, - "ETV_triclinic", - ff_filename="ETV_triclinic_FF", - forcefield_selection={ - ETV_triclinic.name: get_fn( - "Charmm_writer_testing_only_zeolite.xml" - ) - }, - residues=[ETV_triclinic.name], - bead_to_atom_name_dict=None, - fix_residue=[ETV_triclinic.name], - ) - - charmm.write_pdb() - - with open("ETV_triclinic.pdb", "r") as fp: - pdb_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_read = True - crystal_box_length_angles = [ - "CRYST1", - "8.750", - "9.648", - "10.272", - "105.72", - "100.19", - "97.02", - ] - - no_O_atoms = 28 - no_Si_atoms = 14 - atom_type_res_part_1_list = [] - for f_i in range(0, no_O_atoms): - atom_type_res_part_1_list.append( - [ - "ATOM", - str(f_i + 1), - "O1", - "ETV", - "A", - str(f_i + 1), - ] - ) - for f_i in range(no_O_atoms, no_O_atoms + no_Si_atoms): - atom_type_res_part_1_list.append( - [ - "ATOM", - str(f_i + 1), - "Si1", - "ETV", - "A", - str(f_i + 1), - ] - ) - - atom_type_res_part_2_list = [] - for f_i in range(0, no_O_atoms): - atom_type_res_part_2_list.append(["0.00", "1.00", "O"]) - for f_i in range(no_O_atoms, no_O_atoms + no_Si_atoms): - atom_type_res_part_2_list.append(["0.00", "1.00", "SI"]) - - assert out_gomc[i].split()[0:7] == crystal_box_length_angles - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert pdb_read - - # test methane UA psf writer outputs correct atom and residue numbering using orthoganol box - def test_save_othoganol_methane_ua_psf(self): - methane = mb.Compound(name="MET") - methane_child_bead = mb.Compound(name="_CH4") - methane.add(methane_child_bead, inherit_periodicity=False) - - methane_box = mb.fill_box( - compound=methane, n_compounds=4, box=[1, 1, 1] - ) - - charmm = Charmm( - methane_box, - "methane_box", - ff_filename="methane_box_FF", - forcefield_selection={methane.name: "trappe-ua"}, - residues=[methane.name], - bead_to_atom_name_dict={"_CH4": "C"}, - ) - - charmm.write_psf() - - with open("methane_box.psf", "r") as fp: - psf_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "4 !NATOM" in line: - psf_read = True - no_methane_atoms = 4 - atom_type_charge_etc_list = [] - for f_i in range(0, no_methane_atoms): - atom_type_charge_etc_list.append( - [ - str(f_i + 1), - "SYS", - str(f_i + 1), - "MET", - "C1", - "A", - "0.000000", - "16.0430", - ], - ) - - for j in range(0, len(atom_type_charge_etc_list)): - assert ( - out_gomc[i + 1 + j].split()[0:8] - == atom_type_charge_etc_list[j] - ) - - else: - pass - - assert psf_read - - # test methane UA pdb writer outputs correct atom and residue numbering using orthoganol box - def test_save_othoganol_methane_ua_pdb(self): - methane = mb.Compound(name="MET") - methane_child_bead = mb.Compound(name="_CH4") - methane.add(methane_child_bead, inherit_periodicity=False) - - methane_box = mb.fill_box( - compound=methane, n_compounds=10, box=[1, 2, 3] - ) - - charmm = Charmm( - methane_box, - "methane_box", - ff_filename="methane_box_FF", - forcefield_selection={methane.name: "trappe-ua"}, - residues=[methane.name], - bead_to_atom_name_dict={"_CH4": "C"}, - ) - - charmm.write_pdb() - - with open("methane_box.pdb", "r") as fp: - pdb_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if "CRYST1" in line: - pdb_read = True - crystal_box_length_angles = [ - "CRYST1", - "10.000", - "20.000", - "30.000", - "90.00", - "90.00", - "90.00", - ] - - no_methane_atoms = 4 - atom_type_res_part_1_list = [] - for f_i in range(0, no_methane_atoms): - atom_type_res_part_1_list.append( - [ - "ATOM", - str(f_i + 1), - "C1", - "MET", - "A", - str(f_i + 1), - ] - ) - - atom_type_res_part_2_list = [] - for f_i in range(0, no_methane_atoms): - atom_type_res_part_2_list.append(["0.00", "0.00", "EP"]) - - assert out_gomc[i].split()[0:7] == crystal_box_length_angles - - for j in range(0, len(atom_type_res_part_1_list)): - assert ( - out_gomc[i + 1 + j].split()[0:6] - == atom_type_res_part_1_list[j] - ) - assert ( - out_gomc[i + 1 + j].split()[9:12] - == atom_type_res_part_2_list[j] - ) - - else: - pass - - assert pdb_read diff --git a/mosdef_gomc/tests/test_gomc_conf_writer.py b/mosdef_gomc/tests/test_gomc_conf_writer.py deleted file mode 100644 index fbb5f3b6..00000000 --- a/mosdef_gomc/tests/test_gomc_conf_writer.py +++ /dev/null @@ -1,14048 +0,0 @@ -import os - -import mbuild as mb -import pytest -from mbuild.lattice import load_cif -from mbuild.utils.io import get_fn, has_foyer - -import mosdef_gomc.formats.gomc_conf_writer as gomc_control -from mosdef_gomc.formats.charmm_writer import Charmm -from mosdef_gomc.tests.base_test import BaseTest - - -@pytest.mark.skipif(not has_foyer, reason="Foyer package not installed") -class TestGOMCControlFileWriter(BaseTest): - def test_dict_keys_to_list( - self, - ): - dict = {"a": "1", "b": "2", "c": "3"} - keys = gomc_control.dict_keys_to_list(dict) - - assert keys == ["a", "b", "c"] - - def test_get_required_data(self): - value = gomc_control._get_required_data(description=False) - assert ( - value.sort() - == [ - "charmm_object", - "ensemble_type", - "RunSteps", - "Temperature", - "ff_psf_pdb_file_directory", - "check_input_files_exist", - "Restart", - "RestartCheckpoint", - "Parameters", - "Coordinates_box_0", - "override_psf_box_0", - "Coordinates_box_1", - "Structure_box_1", - "binCoordinates_box_0", - "extendedSystem_box_0", - "binVelocities_box_0", - "binCoordinates_box_1", - "extendedSystem_box_1", - "binVelocities_box_1", - ].sort() - ) - - value = gomc_control._get_required_data(description=True) - assert ( - gomc_control.dict_keys_to_list(value).sort() - == [ - "charmm_object", - "ensemble_type", - "RunSteps", - "Temperature", - "ff_psf_pdb_file_directory", - "Restart", - "RestartCheckpoint", - "ExpertMode", - "check_input_files_exist", - "Parameters", - "Coordinate_box_0", - "Structure_box_0", - "Coordinate_box_1", - "Structure_box_1", - "binCoordinates_box_0", - "extendedSystem_box_0", - "binVelocities_box_0", - "binCoordinates_box_1", - "extendedSystem_box_1", - "binVelocities_box_1", - ].sort() - ) - - def test_get_all_possible_input_variable(self): - value = gomc_control._get_all_possible_input_variables( - description=False - ) - assert ( - value.sort() - == [ - "PRNG", - "ParaTypeCHARMM", - "ParaTypeMie", - "ParaTypeMARTINI", - "RcutCoulomb_box_0", - "RcutCoulomb_box_1", - "Pressure", - "Rcut", - "RcutLow", - "LRC", - "IPC", - "Exclude", - "Potential", - "Rswitch", - "ElectroStatic", - "Ewald", - "CachedFourier", - "Tolerance", - "Dielectric", - "PressureCalc", - "EqSteps", - "AdjSteps", - "VDWGeometricSigma", - "useConstantArea", - "FixVolBox0", - "ChemPot", - "Fugacity", - "CBMC_First", - "CBMC_Nth", - "CBMC_Ang", - "CBMC_Dih", - "OutputName", - "CoordinatesFreq", - "DCDFreq", - "RestartFreq", - "CheckpointFreq", - "ConsoleFreq", - "BlockAverageFreq", - "HistogramFreq", - "DistName", - "HistName", - "RunNumber", - "RunLetter", - "SampleFreq", - "OutEnergy", - "OutPressure", - "OutMolNum", - "OutDensity", - "OutVolume", - "OutSurfaceTension", - "FreeEnergyCalc", - "MoleculeType", - "InitialState", - "LambdaVDW", - "LambdaCoulomb", - "ScaleCoulomb", - "ScalePower", - "ScaleAlpha", - "MinSigma", - "DisFreq", - "RotFreq", - "IntraSwapFreq", - "SwapFreq", - "RegrowthFreq", - "CrankShaftFreq", - "VolFreq", - "MultiParticleFreq", - "IntraMEMC-1Freq", - "MEMC-1Freq", - "IntraMEMC-2Freq", - "MEMC-2Freq", - "IntraMEMC-3Freq", - "MEMC-3Freq", - "ExchangeVolumeDim", - "MEMC_DataInput", - "TargetedSwap", - ].sort() - ) - - value = gomc_control._get_all_possible_input_variables(description=True) - assert ( - gomc_control.dict_keys_to_list(value).sort() - == [ - "PRNG", - "ParaTypeCHARMM", - "ParaTypeMie", - "ParaTypeMARTINI", - "RcutCoulomb_box_0", - "RcutCoulomb_box_1", - "Pressure", - "Rcut", - "RcutLow", - "LRC", - "IPC", - "Exclude", - "Potential", - "Rswitch", - "ElectroStatic", - "Ewald", - "CachedFourier", - "Tolerance", - "Dielectric", - "PressureCalc", - "EqSteps", - "AdjSteps", - "VDWGeometricSigma", - "useConstantArea", - "FixVolBox0", - "ChemPot", - "Fugacity", - "CBMC_First", - "CBMC_Nth", - "CBMC_Ang", - "CBMC_Dih", - "OutputName", - "CoordinatesFreq", - "DCDFreq", - "RestartFreq", - "CheckpointFreq", - "ConsoleFreq", - "BlockAverageFreq", - "HistogramFreq", - "DistName", - "HistName", - "RunNumber", - "RunLetter", - "SampleFreq", - "OutEnergy", - "OutPressure", - "OutMolNum", - "OutDensity", - "OutVolume", - "OutSurfaceTension", - "FreeEnergyCalc", - "MoleculeType", - "InitialState", - "LambdaVDW", - "LambdaCoulomb", - "ScaleCoulomb", - "ScalePower", - "ScaleAlpha", - "MinSigma", - "DisFreq", - "RotFreq", - "IntraSwapFreq", - "SwapFreq", - "RegrowthFreq", - "CrankShaftFreq", - "VolFreq", - "MultiParticleFreq", - "IntraMEMC-1Freq", - "MEMC-1Freq", - "IntraMEMC-2Freq", - "MEMC-2Freq", - "IntraMEMC-3Freq", - "MEMC-3Freq", - "ExchangeVolumeDim", - "MEMC_DataInput", - "TargetedSwap", - ].sort() - ) - - def test_get_default_variables_dict(self): - value = gomc_control._get_default_variables_dict() - assert ( - gomc_control.dict_keys_to_list(value).sort() - == [ - "PRNG", - "ParaTypeCHARMM", - "ParaTypeMie", - "ParaTypeMARTINI", - "RcutCoulomb_box_0", - "RcutCoulomb_box_1", - "Pressure", - "Rcut", - "RcutLow", - "LRC", - "IPC", - "Exclude", - "coul_1_4_scaling", - "Potential", - "Rswitch", - "ElectroStatic", - "Ewald", - "CachedFourier", - "Tolerance", - "Dielectric", - "PressureCalc", - "EqSteps", - "AdjSteps", - "VDWGeometricSigma", - "useConstantArea", - "FixVolBox0", - "ChemPot", - "Fugacity", - "CBMC_First", - "CBMC_Nth", - "CBMC_Ang", - "CBMC_Dih", - "OutputName", - "CoordinatesFreq", - "DCDFreq", - "RestartFreq", - "CheckpointFreq", - "ConsoleFreq", - "BlockAverageFreq", - "HistogramFreq", - "DistName", - "HistName", - "RunNumber", - "RunLetter", - "SampleFreq", - "OutEnergy", - "OutPressure", - "OutMolNum", - "OutDensity", - "OutVolume", - "OutSurfaceTension", - "FreeEnergyCalc", - "MoleculeType", - "InitialState", - "LambdaVDW", - "LambdaCoulomb", - "ScaleCoulomb", - "ScalePower", - "ScaleAlpha", - "MinSigma", - "ExchangeVolumeDim", - "MEMC_DataInput", - "DisFreq", - "RotFreq", - "IntraSwapFreq", - "SwapFreq", - "RegrowthFreq", - "CrankShaftFreq", - "VolFreq", - "MultiParticleFreq", - "IntraMEMC-1Freq", - "MEMC-1Freq", - "IntraMEMC-2Freq", - "MEMC-2Freq", - "IntraMEMC-3Freq", - "MEMC-3Freq", - "TargetedSwap", - ].sort() - ) - - def test_print_ensemble_info(self): - try: - gomc_control.print_required_input(description=True) - gomc_control.print_required_input(description=False) - test_status = "PASSED" - except: - test_status = "FAILED" - assert test_status == "PASSED" - - try: - gomc_control.print_valid_ensemble_input_variables( - "NVT", description=True - ) - gomc_control.print_valid_ensemble_input_variables( - "NVT", description=False - ) - test_status = "PASSED" - except: - test_status = "FAILED" - assert test_status == "PASSED" - - try: - gomc_control.print_valid_ensemble_input_variables( - "NPT", description=True - ) - gomc_control.print_valid_ensemble_input_variables( - "NPT", description=False - ) - test_status = "PASSED" - except: - test_status = "FAILED" - assert test_status == "PASSED" - - try: - gomc_control.print_valid_ensemble_input_variables( - "GEMC_NVT", description=True - ) - gomc_control.print_valid_ensemble_input_variables( - "GEMC_NVT", description=False - ) - test_status = "PASSED" - except: - test_status = "FAILED" - assert test_status == "PASSED" - - try: - gomc_control.print_valid_ensemble_input_variables( - "GEMC_NPT", description=True - ) - gomc_control.print_valid_ensemble_input_variables( - "GEMC_NPT", description=False - ) - test_status = "PASSED" - except: - test_status = "FAILED" - assert test_status == "PASSED" - - try: - gomc_control.print_valid_ensemble_input_variables( - "GCMC", description=True - ) - gomc_control.print_valid_ensemble_input_variables( - "GCMC", description=False - ) - test_status = "PASSED" - except: - test_status = "FAILED" - assert test_status == "PASSED" - - try: - gomc_control.print_valid_ensemble_input_variables( - "XXXXX", description=True - ) - gomc_control.print_valid_ensemble_input_variables( - "XXXXX", description=False - ) - test_status = "PASSED" - except: - test_status = "FAILED" - assert test_status == "FAILED" - - def test_get_possible_ensemble_input_variables(self): - with pytest.warns( - UserWarning, - match="WARNING: The ensemble_type selected for " - "the _get_possible_ensemble_input_variables " - "function is not valid.", - ): - gomc_control._get_possible_ensemble_input_variables("XXX") - - def test_wrong_ensemble_gomccontrol(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - ensemble_input = "XXXXX" - with pytest.raises( - ValueError, - match=r"ERROR: The ensemble type selection of '{}' is not a valid ensemble option. " - r"Please choose the 'NPT', 'NVT', 'GEMC_NVT', 'GEMC_NPT', or 'GCMC' " - "ensembles".format(ensemble_input), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_wrong_ensemble_gomccontrol", - ensemble_input, - 100, - 300, - check_input_files_exist=False, - ) - - def test_charmm_ff_name_is_none(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename=None, - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"The force field file name was not specified and in the Charmm object \({}\)." - r"Therefore, the force field file \(.inp\) can not be written, and thus, the " - r"GOMC control file \(.conf\) can not be created. Please use the force field file " - r"name when building the Charmm object".format(type(Charmm)), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_charmm_ff_name_is_none", - "NVT", - 100, - 300, - check_input_files_exist=False, - ) - - def test_input_variables_dict_wrong_value(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The input_variables_dict variable is not None or a dictionary.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_input_variables_dict_wrong_value", - "NVT", - 100, - 300, - check_input_files_exist=False, - input_variables_dict="XXXXX", - ) - - def test_not_entered_charmm_object(self): - not_charmm_object = "XXXXX" - with pytest.raises( - TypeError, - match=r"ERROR: The variable supplied is a \({}\), not a charmm_object \({}\)" - r"".format(type(not_charmm_object), type(Charmm)), - ): - gomc_control.write_gomc_control_file( - not_charmm_object, - "test_not_charmm_object", - "NVT", - 100, - 300, - check_input_files_exist=False, - ) - - def test_save_basic_NVT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane", - ff_filename="ethane", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - charmm.write_inp() - charmm.write_psf() - charmm.write_pdb() - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_NVT.conf", - "NVT", - 10, - 300, - check_input_files_exist=True, - Restart=False, - ) - - with open("test_save_basic_NVT.conf", "r") as fp: - variables_read_dict = { - "Restart": False, - "ExpertMode": False, - "PRNG": False, - "ParaTypeCHARMM": False, - "Parameters": False, - "Coordinates": False, - "Structure": False, - "Temperature": False, - "Potential": False, - "LRC": False, - "IPC": False, - "Rcut": False, - "RcutLow": False, - "VDWGeometricSigma": False, - "Exclude": False, - "Ewald": False, - "ElectroStatic": False, - "CachedFourier": False, - "Tolerance": False, - "1-4scaling": False, - "PressureCalc": False, - "RunSteps": False, - "EqSteps": False, - "AdjSteps": False, - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "RegrowthFreq": False, - "CrankShaftFreq": False, - "CellBasisVector1": False, - "CellBasisVector2": False, - "CellBasisVector3": False, - "CBMC_First": False, - "CBMC_Nth": False, - "CBMC_Ang": False, - "CBMC_Dih": False, - "OutputName": False, - "RestartFreq": False, - "CheckpointFreq": False, - "CoordinatesFreq": False, - "ConsoleFreq": False, - "BlockAverageFreq": False, - "HistogramFreq": False, - "DistName": False, - "HistName": False, - "RunNumber": False, - "RunLetter": False, - "SampleFreq": False, - "OutEnergy": False, - "OutPressure": False, - "OutMolNum": False, - "OutDensity": False, - "OutVolume": False, - "OutSurfaceTension": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Restart "): - variables_read_dict["Restart"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("ExpertMode"): - variables_read_dict["ExpertMode"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("PRNG "): - variables_read_dict["PRNG"] = True - split_line = line.split() - assert split_line[1] == "RANDOM" - - elif line.startswith("ParaTypeCHARMM "): - variables_read_dict["ParaTypeCHARMM"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("Parameters "): - variables_read_dict["Parameters"] = True - split_line = line.split() - assert split_line[1] == "ethane.inp" - - elif line.startswith("Coordinates "): - variables_read_dict["Coordinates"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "ethane.pdb" - - elif line.startswith("Structure "): - variables_read_dict["Structure"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "ethane.psf" - - elif line.startswith("Temperature "): - variables_read_dict["Temperature"] = True - split_line = line.split() - assert split_line[1] == "300" - - elif line.startswith("Potential "): - variables_read_dict["Potential"] = True - split_line = line.split() - assert split_line[1] == "VDW" - - elif line.startswith("LRC "): - variables_read_dict["LRC"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("IPC "): - variables_read_dict["IPC"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("Rcut "): - variables_read_dict["Rcut"] = True - split_line = line.split() - assert split_line[1] == "10" - - elif line.startswith("RcutLow "): - variables_read_dict["RcutLow"] = True - split_line = line.split() - assert split_line[1] == "0" - - elif line.startswith("VDWGeometricSigma "): - variables_read_dict["VDWGeometricSigma"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("Exclude "): - variables_read_dict["Exclude"] = True - split_line = line.split() - assert split_line[1] == "1-3" - - elif line.startswith("Ewald "): - variables_read_dict["Ewald"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("ElectroStatic "): - variables_read_dict["ElectroStatic"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("CachedFourier "): - variables_read_dict["CachedFourier"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("Tolerance "): - variables_read_dict["Tolerance"] = True - split_line = line.split() - assert split_line[1] == "1e-05" - - elif line.startswith("1-4scaling "): - variables_read_dict["1-4scaling"] = True - split_line = line.split() - assert split_line[1] == "0.5" - - elif line.startswith("PressureCalc "): - variables_read_dict["PressureCalc"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1" - - elif line.startswith("RunSteps "): - variables_read_dict["RunSteps"] = True - split_line = line.split() - assert split_line[1] == "10" - - elif line.startswith("EqSteps "): - variables_read_dict["EqSteps"] = True - split_line = line.split() - assert split_line[1] == "1" - - elif line.startswith("AdjSteps "): - variables_read_dict["AdjSteps"] = True - split_line = line.split() - assert split_line[1] == "1" - - elif line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.15" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.15" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.3" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.3" - - elif line.startswith("CrankShaftFreq "): - variables_read_dict["CrankShaftFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("CellBasisVector1 "): - variables_read_dict["CellBasisVector1"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "10.0" - assert split_line[3] == "0.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector2 "): - variables_read_dict["CellBasisVector2"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "0.0" - assert split_line[3] == "10.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector3 "): - variables_read_dict["CellBasisVector3"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "0.0" - assert split_line[3] == "0.0" - assert split_line[4] == "10.0" - - elif line.startswith("CBMC_First "): - variables_read_dict["CBMC_First"] = True - split_line = line.split() - assert split_line[1] == "12" - - elif line.startswith("CBMC_Nth"): - variables_read_dict["CBMC_Nth"] = True - split_line = line.split() - assert split_line[1] == "10" - - elif line.startswith("CBMC_Ang "): - variables_read_dict["CBMC_Ang"] = True - split_line = line.split() - assert split_line[1] == "50" - - elif line.startswith("CBMC_Dih "): - variables_read_dict["CBMC_Dih"] = True - split_line = line.split() - assert split_line[1] == "50" - - elif line.startswith("OutputName "): - variables_read_dict["OutputName"] = True - split_line = line.split() - assert split_line[1] == "Output_data" - - elif line.startswith("RestartFreq "): - variables_read_dict["RestartFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1" - - elif line.startswith("CheckpointFreq "): - variables_read_dict["CheckpointFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1" - - elif line.startswith("CoordinatesFreq "): - variables_read_dict["CoordinatesFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1" - - elif line.startswith("ConsoleFreq "): - variables_read_dict["ConsoleFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1" - - elif line.startswith("BlockAverageFreq "): - variables_read_dict["BlockAverageFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1" - - elif line.startswith("HistogramFreq "): - variables_read_dict["HistogramFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1" - - elif line.startswith("DistName "): - variables_read_dict["DistName"] = True - split_line = line.split() - assert split_line[1] == "dis" - - elif line.startswith("HistName "): - variables_read_dict["HistName"] = True - split_line = line.split() - assert split_line[1] == "his" - - elif line.startswith("RunNumber "): - variables_read_dict["RunNumber"] = True - split_line = line.split() - assert split_line[1] == "1" - - elif line.startswith("RunLetter "): - variables_read_dict["RunLetter"] = True - split_line = line.split() - assert split_line[1] == "a" - - elif line.startswith("SampleFreq "): - variables_read_dict["SampleFreq"] = True - split_line = line.split() - assert split_line[1] == "1" - - elif line.startswith("OutEnergy "): - variables_read_dict["OutEnergy"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "True" - - elif line.startswith("OutPressure "): - variables_read_dict["OutPressure"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "True" - - elif line.startswith("OutMolNum "): - variables_read_dict["OutMolNum"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "True" - - elif line.startswith("OutDensity "): - variables_read_dict["OutDensity"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "True" - - elif line.startswith("OutVolume "): - variables_read_dict["OutVolume"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "True" - - elif line.startswith("OutSurfaceTension "): - variables_read_dict["OutSurfaceTension"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "False" - - else: - pass - - assert variables_read_dict == { - "Restart": True, - "ExpertMode": True, - "PRNG": True, - "ParaTypeCHARMM": True, - "Parameters": True, - "Coordinates": True, - "Structure": True, - "Temperature": True, - "Potential": True, - "LRC": True, - "IPC": True, - "Rcut": True, - "RcutLow": True, - "VDWGeometricSigma": True, - "Exclude": True, - "Ewald": True, - "ElectroStatic": True, - "CachedFourier": True, - "Tolerance": True, - "1-4scaling": True, - "PressureCalc": True, - "RunSteps": True, - "EqSteps": True, - "AdjSteps": True, - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "RegrowthFreq": True, - "CrankShaftFreq": True, - "CellBasisVector1": True, - "CellBasisVector2": True, - "CellBasisVector3": True, - "CBMC_First": True, - "CBMC_Nth": True, - "CBMC_Ang": True, - "CBMC_Dih": True, - "OutputName": True, - "RestartFreq": True, - "CheckpointFreq": True, - "CoordinatesFreq": True, - "ConsoleFreq": True, - "BlockAverageFreq": True, - "HistogramFreq": True, - "DistName": True, - "HistName": True, - "RunNumber": True, - "RunLetter": True, - "SampleFreq": True, - "OutEnergy": True, - "OutPressure": True, - "OutMolNum": True, - "OutDensity": True, - "OutVolume": True, - "OutSurfaceTension": True, - } - - def test_save_basic_NPT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane", - ff_filename="ethane", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - charmm.write_inp() - charmm.write_psf() - charmm.write_pdb() - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_NPT.conf", - "NPT", - 1000, - 500, - check_input_files_exist=True, - input_variables_dict={"Potential": "SWITCH"}, - ) - - with open("test_save_basic_NPT.conf", "r") as fp: - variables_read_dict = { - "Potential": False, - "Rswitch": False, - "Rcut": False, - "Pressure": False, - "Temperature": False, - "PressureCalc": False, - "RunSteps": False, - "EqSteps": False, - "AdjSteps": False, - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "RegrowthFreq": False, - "CrankShaftFreq": False, - "CellBasisVector1": False, - "CellBasisVector2": False, - "CellBasisVector3": False, - "RestartFreq": False, - "CheckpointFreq": False, - "CoordinatesFreq": False, - "ConsoleFreq": False, - "BlockAverageFreq": False, - "HistogramFreq": False, - "SampleFreq": False, - "VDWGeometricSigma": False, - "useConstantArea": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Potential "): - variables_read_dict["Potential"] = True - split_line = line.split() - assert split_line[1] == "SWITCH" - - elif line.startswith("Rswitch "): - variables_read_dict["Rswitch"] = True - split_line = line.split() - assert split_line[1] == "9" - - elif line.startswith("Rcut "): - variables_read_dict["Rcut"] = True - split_line = line.split() - assert split_line[1] == "10" - - elif line.startswith("Pressure "): - variables_read_dict["Pressure"] = True - split_line = line.split() - assert split_line[1] == "1.01325" - - elif line.startswith("Temperature "): - variables_read_dict["Temperature"] = True - split_line = line.split() - assert split_line[1] == "500" - - elif line.startswith("PressureCalc "): - variables_read_dict["PressureCalc"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "100" - - elif line.startswith("RunSteps "): - variables_read_dict["RunSteps"] = True - split_line = line.split() - assert split_line[1] == "1000" - - elif line.startswith("EqSteps "): - variables_read_dict["EqSteps"] = True - split_line = line.split() - assert split_line[1] == "100" - - elif line.startswith("AdjSteps "): - variables_read_dict["AdjSteps"] = True - split_line = line.split() - assert split_line[1] == "100" - - elif line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.15" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.15" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.29" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.3" - - elif line.startswith("CrankShaftFreq "): - variables_read_dict["CrankShaftFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("CellBasisVector1 "): - variables_read_dict["CellBasisVector1"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "20.0" - assert split_line[3] == "0.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector2 "): - variables_read_dict["CellBasisVector2"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "0.0" - assert split_line[3] == "20.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector3 "): - variables_read_dict["CellBasisVector3"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "0.0" - assert split_line[3] == "0.0" - assert split_line[4] == "20.0" - - elif line.startswith("RestartFreq "): - variables_read_dict["RestartFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "100" - - elif line.startswith("CheckpointFreq "): - variables_read_dict["CheckpointFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "100" - - elif line.startswith("CoordinatesFreq "): - variables_read_dict["CoordinatesFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "100" - - elif line.startswith("ConsoleFreq "): - variables_read_dict["ConsoleFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "100" - - elif line.startswith("BlockAverageFreq "): - variables_read_dict["BlockAverageFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "100" - - elif line.startswith("HistogramFreq "): - variables_read_dict["HistogramFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "100" - - elif line.startswith("SampleFreq "): - variables_read_dict["SampleFreq"] = True - split_line = line.split() - assert split_line[1] == "100" - - elif line.startswith("VDWGeometricSigma "): - variables_read_dict["VDWGeometricSigma"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("useConstantArea "): - variables_read_dict["useConstantArea"] = True - split_line = line.split() - assert split_line[1] == "False" - - else: - pass - - assert variables_read_dict == { - "Potential": True, - "Rswitch": True, - "Rcut": True, - "Pressure": True, - "Temperature": True, - "PressureCalc": True, - "RunSteps": True, - "EqSteps": True, - "AdjSteps": True, - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "RegrowthFreq": True, - "CrankShaftFreq": True, - "CellBasisVector1": True, - "CellBasisVector2": True, - "CellBasisVector3": True, - "RestartFreq": True, - "CheckpointFreq": True, - "CoordinatesFreq": True, - "ConsoleFreq": True, - "BlockAverageFreq": True, - "HistogramFreq": True, - "SampleFreq": True, - "VDWGeometricSigma": True, - "useConstantArea": True, - } - - def test_save_basic_GCMC(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - charmm.write_inp() - charmm.write_psf() - charmm.write_pdb() - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_GCMC.conf", - "GCMC", - 100000, - 500, - check_input_files_exist=True, - input_variables_dict={ - "ChemPot": {"ETH": -4000}, - "VDWGeometricSigma": True, - }, - ) - - with open("test_save_basic_GCMC.conf", "r") as fp: - variables_read_dict = { - "Parameters": False, - "Coordinates 0": False, - "Coordinates 1": False, - "Structure 0": False, - "Structure 1": False, - "Temperature": False, - "ChemPot": False, - "PressureCalc": False, - "RunSteps": False, - "EqSteps": False, - "AdjSteps": False, - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "SwapFreq": False, - "RegrowthFreq": False, - "CrankShaftFreq": False, - "CellBasisVector1 0": False, - "CellBasisVector2 0": False, - "CellBasisVector3 0": False, - "CellBasisVector1 1": False, - "CellBasisVector2 1": False, - "CellBasisVector3 1": False, - "RestartFreq": False, - "CheckpointFreq": False, - "CoordinatesFreq": False, - "ConsoleFreq": False, - "BlockAverageFreq": False, - "HistogramFreq": False, - "SampleFreq": False, - "VDWGeometricSigma": False, - "ExpertMode": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Parameters "): - variables_read_dict["Parameters"] = True - split_line = line.split() - assert split_line[1] == "ethane_FF.inp" - - elif line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates 0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "ethane_box_0.pdb" - - elif line.startswith("Coordinates 1"): - variables_read_dict["Coordinates 1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "ethane_box_1.pdb" - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure 0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "ethane_box_0.psf" - - elif line.startswith("Structure 1 "): - variables_read_dict["Structure 1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "ethane_box_1.psf" - - elif line.startswith("Temperature "): - variables_read_dict["Temperature"] = True - split_line = line.split() - assert split_line[1] == "500" - - elif line.startswith("ChemPot "): - variables_read_dict["ChemPot"] = True - split_line = line.split() - assert split_line[1] == "ETH" - assert split_line[2] == "-4000" - - elif line.startswith("PressureCalc "): - variables_read_dict["PressureCalc"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "10000" - - elif line.startswith("RunSteps "): - variables_read_dict["RunSteps"] = True - split_line = line.split() - assert split_line[1] == "100000" - - elif line.startswith("EqSteps "): - variables_read_dict["EqSteps"] = True - split_line = line.split() - assert split_line[1] == "10000" - - elif line.startswith("AdjSteps "): - variables_read_dict["AdjSteps"] = True - split_line = line.split() - assert split_line[1] == "1000" - - elif line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.15" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.15" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("SwapFreq "): - variables_read_dict["SwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.35" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.15" - - elif line.startswith("CrankShaftFreq "): - variables_read_dict["CrankShaftFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("CellBasisVector1 0"): - variables_read_dict["CellBasisVector1 0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "20.0" - assert split_line[3] == "0.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector2 0"): - variables_read_dict["CellBasisVector2 0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "0.0" - assert split_line[3] == "20.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector3 0"): - variables_read_dict["CellBasisVector3 0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "0.0" - assert split_line[3] == "0.0" - assert split_line[4] == "20.0" - - elif line.startswith("CellBasisVector1 1"): - variables_read_dict["CellBasisVector1 1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "20.0" - assert split_line[3] == "0.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector2 1"): - variables_read_dict["CellBasisVector2 1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "0.0" - assert split_line[3] == "20.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector3 1"): - variables_read_dict["CellBasisVector3 1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "0.0" - assert split_line[3] == "0.0" - assert split_line[4] == "20.0" - - elif line.startswith("RestartFreq "): - variables_read_dict["RestartFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "10000" - - elif line.startswith("CheckpointFreq "): - variables_read_dict["CheckpointFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "10000" - - elif line.startswith("CoordinatesFreq "): - variables_read_dict["CoordinatesFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "10000" - - elif line.startswith("ConsoleFreq "): - variables_read_dict["ConsoleFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "10000" - - elif line.startswith("BlockAverageFreq "): - variables_read_dict["BlockAverageFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "10000" - - elif line.startswith("HistogramFreq "): - variables_read_dict["HistogramFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "10000" - - elif line.startswith("SampleFreq "): - variables_read_dict["SampleFreq"] = True - split_line = line.split() - assert split_line[1] == "500" - - elif line.startswith("VDWGeometricSigma "): - variables_read_dict["VDWGeometricSigma"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("ExpertMode"): - variables_read_dict["ExpertMode"] = True - split_line = line.split() - assert split_line[1] == "False" - - else: - pass - - assert variables_read_dict == { - "Parameters": True, - "Coordinates 0": True, - "Coordinates 1": True, - "Structure 0": True, - "Structure 1": True, - "Temperature": True, - "ChemPot": True, - "PressureCalc": True, - "RunSteps": True, - "EqSteps": True, - "AdjSteps": True, - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "SwapFreq": True, - "RegrowthFreq": True, - "CrankShaftFreq": True, - "CellBasisVector1 0": True, - "CellBasisVector2 0": True, - "CellBasisVector3 0": True, - "CellBasisVector1 1": True, - "CellBasisVector2 1": True, - "CellBasisVector3 1": True, - "RestartFreq": True, - "CheckpointFreq": True, - "CoordinatesFreq": True, - "ConsoleFreq": True, - "BlockAverageFreq": True, - "HistogramFreq": True, - "SampleFreq": True, - "VDWGeometricSigma": True, - "ExpertMode": True, - } - - def test_save_basic_GEMC_NVT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - charmm.write_inp() - charmm.write_psf() - charmm.write_pdb() - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_GEMC_NVT.conf", - "GEMC_NVT", - 1000000, - 500, - check_input_files_exist=True, - ) - - with open("test_save_basic_GEMC_NVT.conf", "r") as fp: - variables_read_dict = { - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "SwapFreq": False, - "RegrowthFreq": False, - "CrankShaftFreq": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("SwapFreq "): - variables_read_dict["SwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("CrankShaftFreq "): - variables_read_dict["CrankShaftFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - else: - pass - - assert variables_read_dict == { - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "SwapFreq": True, - "RegrowthFreq": True, - "CrankShaftFreq": True, - } - - def test_save_basic_GEMC_NPT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_GEMC_NPT.conf", - "GEMC-NPT", - 1000000, - 500, - check_input_files_exist=False, - input_variables_dict={ - "Pressure": 10, - "useConstantArea": True, - "FixVolBox0": True, - "RcutCoulomb_box_0": 14, - "RcutCoulomb_box_1": 14, - }, - ) - - with open("test_save_basic_GEMC_NPT.conf", "r") as fp: - variables_read_dict = { - "Pressure": False, - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "SwapFreq": False, - "RegrowthFreq": False, - "CrankShaftFreq": False, - "VolFreq": False, - "useConstantArea": False, - "FixVolBox0": False, - "RcutCoulomb_box_0": False, - "RcutCoulomb_box_1": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Pressure "): - variables_read_dict["Pressure"] = True - split_line = line.split() - assert split_line[1] == "10" - - elif line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.19" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("SwapFreq "): - variables_read_dict["SwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("CrankShaftFreq "): - variables_read_dict["CrankShaftFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("VolFreq "): - variables_read_dict["VolFreq"] = True - split_line = line.split() - assert split_line[1] == "0.01" - - elif line.startswith("useConstantArea "): - variables_read_dict["useConstantArea"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("FixVolBox0 "): - variables_read_dict["FixVolBox0"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("RcutCoulomb 0 "): - variables_read_dict["RcutCoulomb_box_0"] = True - split_line = line.split() - assert split_line[2] == "14" - - elif line.startswith("RcutCoulomb 1 "): - variables_read_dict["RcutCoulomb_box_1"] = True - split_line = line.split() - assert split_line[2] == "14" - - else: - pass - - assert variables_read_dict == { - "Pressure": True, - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "SwapFreq": True, - "RegrowthFreq": True, - "CrankShaftFreq": True, - "VolFreq": True, - "useConstantArea": True, - "FixVolBox0": True, - "RcutCoulomb_box_0": True, - "RcutCoulomb_box_1": True, - } - - def test_save_change_most_variable_NVT(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[4.0, 4.0, 4.0], - ) - charmm = Charmm( - test_box_ethane_ethanol, - "ethane_ethanol", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_change_most_variable_NVT.conf", - "NVT", - 100000, - 300, - check_input_files_exist=False, - Restart=False, - input_variables_dict={ - "PRNG": 123, - "ParaTypeCHARMM": True, - "ParaTypeMARTINI": False, - "ParaTypeMie": False, - "LRC": False, - "IPC": True, - "Rcut": 12, - "RcutLow": 1, - "Exclude": "1-4", - "Ewald": False, - "ElectroStatic": False, - "CachedFourier": True, - "RcutCoulomb_box_0": 14, - "PressureCalc": [False, 4], - "Tolerance": 0.01, - "DisFreq": 0.2, - "RotFreq": 0.2, - "IntraSwapFreq": 0.1, - "RegrowthFreq": 0.1, - "CrankShaftFreq": 0.2, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.05, - "IntraMEMC-2Freq": 0.05, - "IntraMEMC-3Freq": 0.05, - "TargetedSwapFreq": 0.00, - "CBMC_First": 55, - "CBMC_Nth": 66, - "CBMC_Ang": 33, - "CBMC_Dih": 22, - "OutputName": "test_out", - "RestartFreq": [False, 50], - "CheckpointFreq": [False, 50], - "CoordinatesFreq": [False, 50], - "ConsoleFreq": [False, 500], - "BlockAverageFreq": [False, 50], - "HistogramFreq": [False, 50], - "DistName": "dist", - "HistName": "hist", - "RunNumber": 4, - "RunLetter": "c", - "SampleFreq": 25, - "FreeEnergyCalc": [True, 50], - "MoleculeType": ["ETH", 1], - "InitialState": 3, - "LambdaVDW": [0.0, 0.1, 0.1, 0.2, 1.0], - "LambdaCoulomb": [0.0, 0.0, 0.3, 0.8, 1.0], - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "OutEnergy": [False, False], - "OutPressure": [False, False], - "OutMolNum": [False, False], - "OutDensity": [False, False], - "OutVolume": [False, False], - "OutSurfaceTension": [True, True], - }, - ) - - with open("test_save_change_most_variable_NVT.conf", "r") as fp: - variables_read_dict = { - "Restart": False, - "ExpertMode": False, - "PRNG": False, - "Random_Seed": False, - "ParaTypeCHARMM": False, - "Parameters": False, - "Coordinates": False, - "Structure": False, - "Temperature": False, - "Potential": False, - "LRC": False, - "IPC": False, - "Rcut": False, - "RcutLow": False, - "Exclude": False, - "Ewald": False, - "ElectroStatic": False, - "CachedFourier": False, - "Tolerance": False, - "1-4scaling": False, - "RcutCoulomb 0": False, - "PressureCalc": False, - "RunSteps": False, - "EqSteps": False, - "AdjSteps": False, - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "RegrowthFreq": False, - "CrankShaftFreq": False, - "MultiParticleFreq": False, - "IntraMEMC-1Freq": False, - "IntraMEMC-2Freq": False, - "IntraMEMC-3Freq": False, - "CellBasisVector1": False, - "CellBasisVector2": False, - "CellBasisVector3": False, - "FreeEnergyCalc": False, - "MoleculeType": False, - "InitialState": False, - "ScalePower": False, - "ScaleAlpha": False, - "MinSigma": False, - "ScaleCoulomb": False, - "# States": False, - "LambdaVDW": False, - "LambdaCoulomb": False, - "CBMC_First": False, - "CBMC_Nth": False, - "CBMC_Ang": False, - "CBMC_Dih": False, - "OutputName": False, - "RestartFreq": False, - "CheckpointFreq": False, - "CoordinatesFreq": False, - "ConsoleFreq": False, - "BlockAverageFreq": False, - "HistogramFreq": False, - "DistName": False, - "HistName": False, - "RunNumber": False, - "RunLetter": False, - "SampleFreq": False, - "OutEnergy": False, - "OutPressure": False, - "OutMolNum": False, - "OutDensity": False, - "OutVolume": False, - "OutSurfaceTension": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Restart "): - variables_read_dict["Restart"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("ExpertMode"): - variables_read_dict["ExpertMode"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("PRNG "): - variables_read_dict["PRNG"] = True - split_line = line.split() - assert split_line[1] == "INTSEED" - - elif line.startswith("Random_Seed "): - variables_read_dict["Random_Seed"] = True - split_line = line.split() - assert split_line[1] == "123" - - elif line.startswith("ParaTypeCHARMM "): - variables_read_dict["ParaTypeCHARMM"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("Parameters "): - variables_read_dict["Parameters"] = True - split_line = line.split() - assert split_line[1] == "ethane_ethanol.inp" - - elif line.startswith("Coordinates "): - variables_read_dict["Coordinates"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "ethane_ethanol.pdb" - - elif line.startswith("Structure "): - variables_read_dict["Structure"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "ethane_ethanol.psf" - - elif line.startswith("Temperature "): - variables_read_dict["Temperature"] = True - split_line = line.split() - assert split_line[1] == "300" - - elif line.startswith("Potential "): - variables_read_dict["Potential"] = True - split_line = line.split() - assert split_line[1] == "VDW" - - elif line.startswith("LRC "): - variables_read_dict["LRC"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("IPC "): - variables_read_dict["IPC"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("Rcut "): - variables_read_dict["Rcut"] = True - split_line = line.split() - assert split_line[1] == "12" - - elif line.startswith("RcutLow "): - variables_read_dict["RcutLow"] = True - split_line = line.split() - assert split_line[1] == "1" - - elif line.startswith("Exclude "): - variables_read_dict["Exclude"] = True - split_line = line.split() - assert split_line[1] == "1-4" - - elif line.startswith("Ewald "): - variables_read_dict["Ewald"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("ElectroStatic "): - variables_read_dict["ElectroStatic"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("CachedFourier "): - variables_read_dict["CachedFourier"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("Tolerance "): - variables_read_dict["Tolerance"] = True - split_line = line.split() - assert split_line[1] == "0.01" - - elif line.startswith("1-4scaling "): - variables_read_dict["1-4scaling"] = True - split_line = line.split() - assert split_line[1] == "0.5" - - elif line.startswith("RcutCoulomb 0 "): - variables_read_dict["RcutCoulomb 0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "14" - - elif line.startswith("PressureCalc "): - variables_read_dict["PressureCalc"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "4" - - elif line.startswith("RunSteps "): - variables_read_dict["RunSteps"] = True - split_line = line.split() - assert split_line[1] == "100000" - - elif line.startswith("EqSteps "): - variables_read_dict["EqSteps"] = True - split_line = line.split() - assert split_line[1] == "10000" - - elif line.startswith("AdjSteps "): - variables_read_dict["AdjSteps"] = True - split_line = line.split() - assert split_line[1] == "1000" - - elif line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("CrankShaftFreq "): - variables_read_dict["CrankShaftFreq"] = True - split_line = line.split() - assert split_line[1] == "0.2" - - elif line.startswith("MultiParticleFreq "): - variables_read_dict["MultiParticleFreq"] = True - split_line = line.split() - assert split_line[1] == "0.05" - - elif line.startswith("IntraMEMC-1Freq "): - variables_read_dict["IntraMEMC-1Freq"] = True - split_line = line.split() - assert split_line[1] == "0.05" - - elif line.startswith("IntraMEMC-2Freq "): - variables_read_dict["IntraMEMC-2Freq"] = True - split_line = line.split() - assert split_line[1] == "0.05" - - elif line.startswith("IntraMEMC-3Freq "): - variables_read_dict["IntraMEMC-3Freq"] = True - split_line = line.split() - assert split_line[1] == "0.05" - - elif line.startswith("CellBasisVector1 "): - variables_read_dict["CellBasisVector1"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "40.0" - assert split_line[3] == "0.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector2 "): - variables_read_dict["CellBasisVector2"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "0.0" - assert split_line[3] == "40.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector3 "): - variables_read_dict["CellBasisVector3"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "0.0" - assert split_line[3] == "0.0" - assert split_line[4] == "40.0" - - elif line.startswith("FreeEnergyCalc "): - variables_read_dict["FreeEnergyCalc"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "50" - - elif line.startswith("MoleculeType "): - variables_read_dict["MoleculeType"] = True - split_line = line.split() - assert split_line[1] == "ETH" - assert split_line[2] == "1" - - elif line.startswith("InitialState "): - variables_read_dict["InitialState"] = True - split_line = line.split() - assert split_line[1] == "3" - - elif line.startswith("ScalePower "): - variables_read_dict["ScalePower"] = True - split_line = line.split() - assert split_line[1] == "2" - - elif line.startswith("ScaleAlpha "): - variables_read_dict["ScaleAlpha"] = True - split_line = line.split() - assert split_line[1] == "0.5" - - elif line.startswith("MinSigma "): - variables_read_dict["MinSigma"] = True - split_line = line.split() - assert split_line[1] == "3" - - elif line.startswith("ScaleCoulomb "): - variables_read_dict["ScaleCoulomb"] = True - split_line = line.split() - assert split_line[1] == "False" - - elif line.startswith("# States "): - variables_read_dict["# States"] = True - split_line = line.split() - assert split_line[2] == "0" - assert split_line[3] == "1" - assert split_line[4] == "2" - assert split_line[5] == "3" - - elif line.startswith("LambdaVDW "): - variables_read_dict["LambdaVDW"] = True - split_line = line.split() - assert split_line[1] == "0.0" - assert split_line[2] == "0.1" - assert split_line[3] == "0.1" - assert split_line[4] == "0.2" - assert split_line[5] == "1.0" - - elif line.startswith("LambdaCoulomb "): - variables_read_dict["LambdaCoulomb"] = True - split_line = line.split() - assert split_line[1] == "0.0" - assert split_line[2] == "0.0" - assert split_line[3] == "0.3" - assert split_line[4] == "0.8" - assert split_line[5] == "1.0" - - elif line.startswith("CBMC_First "): - variables_read_dict["CBMC_First"] = True - split_line = line.split() - assert split_line[1] == "55" - - elif line.startswith("CBMC_Nth "): - variables_read_dict["CBMC_Nth"] = True - split_line = line.split() - assert split_line[1] == "66" - - elif line.startswith("CBMC_Ang "): - variables_read_dict["CBMC_Ang"] = True - split_line = line.split() - assert split_line[1] == "33" - - elif line.startswith("CBMC_Dih "): - variables_read_dict["CBMC_Dih"] = True - split_line = line.split() - assert split_line[1] == "22" - - elif line.startswith("OutputName "): - variables_read_dict["OutputName"] = True - split_line = line.split() - assert split_line[1] == "test_out" - - elif line.startswith("RestartFreq "): - variables_read_dict["RestartFreq"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "50" - - elif line.startswith("CheckpointFreq "): - variables_read_dict["CheckpointFreq"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "50" - - elif line.startswith("CoordinatesFreq "): - variables_read_dict["CoordinatesFreq"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "50" - - elif line.startswith("ConsoleFreq "): - variables_read_dict["ConsoleFreq"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "500" - - elif line.startswith("BlockAverageFreq "): - variables_read_dict["BlockAverageFreq"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "50" - - elif line.startswith("HistogramFreq "): - variables_read_dict["HistogramFreq"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "50" - - elif line.startswith("DistName "): - variables_read_dict["DistName"] = True - split_line = line.split() - assert split_line[1] == "dist" - - elif line.startswith("HistName "): - variables_read_dict["HistName"] = True - split_line = line.split() - assert split_line[1] == "hist" - - elif line.startswith("RunNumber "): - variables_read_dict["RunNumber"] = True - split_line = line.split() - assert split_line[1] == "4" - - elif line.startswith("RunLetter "): - variables_read_dict["RunLetter"] = True - split_line = line.split() - assert split_line[1] == "c" - - elif line.startswith("SampleFreq "): - variables_read_dict["SampleFreq"] = True - split_line = line.split() - assert split_line[1] == "25" - - elif line.startswith("OutEnergy "): - variables_read_dict["OutEnergy"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "False" - - elif line.startswith("OutPressure "): - variables_read_dict["OutPressure"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "False" - - elif line.startswith("OutMolNum "): - variables_read_dict["OutMolNum"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "False" - - elif line.startswith("OutDensity "): - variables_read_dict["OutDensity"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "False" - - elif line.startswith("OutVolume "): - variables_read_dict["OutVolume"] = True - split_line = line.split() - assert split_line[1] == "False" - assert split_line[2] == "False" - - elif line.startswith("OutSurfaceTension "): - variables_read_dict["OutSurfaceTension"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "True" - - else: - pass - - assert variables_read_dict == { - "Restart": True, - "ExpertMode": True, - "PRNG": True, - "Random_Seed": True, - "ParaTypeCHARMM": True, - "Parameters": True, - "Coordinates": True, - "Structure": True, - "Temperature": True, - "Potential": True, - "LRC": True, - "IPC": True, - "Rcut": True, - "RcutLow": True, - "Exclude": True, - "Ewald": True, - "ElectroStatic": True, - "CachedFourier": True, - "Tolerance": True, - "1-4scaling": True, - "RcutCoulomb 0": True, - "PressureCalc": True, - "RunSteps": True, - "EqSteps": True, - "AdjSteps": True, - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "RegrowthFreq": True, - "CrankShaftFreq": True, - "MultiParticleFreq": True, - "IntraMEMC-1Freq": True, - "IntraMEMC-2Freq": True, - "IntraMEMC-3Freq": True, - "CellBasisVector1": True, - "CellBasisVector2": True, - "CellBasisVector3": True, - "FreeEnergyCalc": True, - "MoleculeType": True, - "InitialState": True, - "ScalePower": True, - "ScaleAlpha": True, - "MinSigma": True, - "ScaleCoulomb": True, - "# States": True, - "LambdaVDW": True, - "LambdaCoulomb": True, - "CBMC_First": True, - "CBMC_Nth": True, - "CBMC_Ang": True, - "CBMC_Dih": True, - "OutputName": True, - "RestartFreq": True, - "CheckpointFreq": True, - "CoordinatesFreq": True, - "ConsoleFreq": True, - "BlockAverageFreq": True, - "HistogramFreq": True, - "DistName": True, - "HistName": True, - "RunNumber": True, - "RunLetter": True, - "SampleFreq": True, - "OutEnergy": True, - "OutPressure": True, - "OutMolNum": True, - "OutDensity": True, - "OutVolume": True, - "OutSurfaceTension": True, - } - - def test_save_NVT_bad_lamda_value(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[1, 1, 1], - ) - - charmm = Charmm( - test_box_ethane_ethanol, - "ethane_ethanol", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The last value in the LambdaCoulomb variable list must be a 1.0", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 100, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10], - "MoleculeType": ["ETH", 1], - "InitialState": 3, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 0.9], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The first value in the LambdaCoulomb variable list must be a 0.0", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 100, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10], - "MoleculeType": ["ETH", 1], - "InitialState": 3, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.1, 0.3, 0.8, 0.9, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The last value in the LambdaVDW variable list must be a 1.0", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 100, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10], - "MoleculeType": ["ETH", 1], - "InitialState": 3, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 0.9], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The first value in the LambdaVDW variable list must be a 0.0", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 100, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10], - "MoleculeType": ["ETH", 1], - "InitialState": 3, - "LambdaVDW": [0.1, 0.2, 0.4, 0.9, 1.0], - }, - ) - - def test_save_NVT_bad_variables_part_1(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[1, 1, 1], - ) - - charmm = Charmm( - test_box_ethane_ethanol, - "ethane_ethanol", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PRNG'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PRNG": [1]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ParaTypeCHARMM'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ParaTypeCHARMM": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ParaTypeMie'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ParaTypeMie": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ParaTypeMARTINI'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ParaTypeMARTINI": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RcutCoulomb_box_0'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RcutCoulomb_box_0": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the correct input variables where not provided for " - r"the NVT ensemble. Please be sure to check that the keys in the " - r"input variables dictionary \(input_variables_dict\) is correct, and " - r"be aware that added spaces before or after the variable in any keys " - r"will also give this warning. The bad variable inputs ensemble " - r"inputs = \['RcutCoulomb_box_1'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RcutCoulomb_box_1": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Pressure'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Pressure": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Rcut'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Rcut": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RcutLow'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RcutLow": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LRC'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"LRC": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Exclude'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Exclude": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Potential'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Potential": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Rswitch'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Rswitch": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ElectroStatic'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ElectroStatic": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Ewald'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Ewald": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CachedFourier'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CachedFourier": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Tolerance'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Tolerance": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Dielectric'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Dielectric": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['EqSteps'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"EqSteps": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['EqSteps'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"EqSteps": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['useConstantArea'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"useConstantArea": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the correct input variables where not provided for " - r"the NVT ensemble. Please be sure to check that the keys in the " - r"input variables dictionary \(input_variables_dict\) is correct, and " - r"be aware that added spaces before or after the variable in any keys " - r"will also give this warning. The bad variable inputs ensemble " - r"inputs = \['ChemPot'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ChemPot": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the correct input variables where not provided for " - r"the NVT ensemble. Please be sure to check that the keys in the " - r"input variables dictionary \(input_variables_dict\) is correct, and " - r"be aware that added spaces before or after the variable in any keys " - r"will also give this warning. The bad variable inputs ensemble " - r"inputs = \['Fugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Fugacity": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CBMC_First'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CBMC_First": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CBMC_Nth'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CBMC_Nth": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CBMC_Ang'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CBMC_Ang": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CBMC_Dih'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CBMC_Dih": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutputName'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutputName": 1}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CoordinatesFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CoordinatesFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RestartFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RestartFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CheckpointFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CheckpointFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ConsoleFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ConsoleFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['BlockAverageFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"BlockAverageFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['HistogramFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"HistogramFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['DistName'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"DistName": 1}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['HistName'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"HistName": 1}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RunNumber'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RunNumber": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RunLetter'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RunLetter": 1}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['SampleFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"SampleFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutPressure'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutPressure": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutMolNum'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutMolNum": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutDensity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutDensity": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutVolume'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutVolume": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutSurfaceTension'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutSurfaceTension": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": "s", - "MoleculeType": ["ETH", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", "s"], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": [["ETH"], 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": [{"ETH": "1"}, 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['InitialState'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", 1], - "InitialState": "s", - "LambdaVDW": [0.0, 0.1, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaVDW'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", 1], - "InitialState": 1, - "LambdaVDW": "s", - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaCoulomb'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": "s", - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: To utilize the free energy calculations all the " - r"following variables need to be set, and not equal to " - r"None: FreeEnergyCalc, MoleculeType, InitialState, LambdaVDW.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"FreeEnergyCalc": [True, 10000]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ScaleCoulomb'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ScaleCoulomb": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ScalePower'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ScalePower": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ScaleAlpha'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ScaleAlpha": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MinSigma'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MinSigma": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ExchangeVolumeDim'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ExchangeVolumeDim": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MEMC_DataInput": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['DisFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"DisFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RotFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RotFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['IntraSwapFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"IntraSwapFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['SwapFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"SwapFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RegrowthFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RegrowthFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CrankShaftFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CrankShaftFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['VolFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"VolFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MultiParticleFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MultiParticleFreq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['IntraMEMC-1Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"IntraMEMC-1Freq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC-1Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MEMC-1Freq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['IntraMEMC-2Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"IntraMEMC-2Freq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC-2Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MEMC-2Freq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['IntraMEMC-3Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"IntraMEMC-3Freq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC-3Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MEMC-3Freq": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the correct input variables where not provided for " - r"the NVT ensemble. Please be sure to check that the keys in the " - r"input variables dictionary \(input_variables_dict\) is correct, and " - r"be aware that added spaces before or after the variable in any keys " - r"will also give this warning. The bad variable inputs ensemble " - r"inputs = \['XXXXXX'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"XXXXXX": "s"}, - ) - - def test_save_NVT_bad_variables_part_2(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[1, 1, 1], - ) - - charmm = Charmm( - test_box_ethane_ethanol, - "ethane_ethanol", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PRNG'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PRNG": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ParaTypeCHARMM'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ParaTypeCHARMM": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ParaTypeMie'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ParaTypeMie": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ParaTypeMARTINI'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ParaTypeMARTINI": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RcutCoulomb_box_0'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RcutCoulomb_box_0": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the correct input variables where not provided for " - r"the NVT ensemble. Please be sure to check that the keys in the " - r"input variables dictionary \(input_variables_dict\) is correct, and " - r"be aware that added spaces before or after the variable in any keys " - r"will also give this warning. The bad variable inputs ensemble " - r"inputs = \['RcutCoulomb_box_1'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RcutCoulomb_box_1": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Pressure'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Pressure": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Rcut'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Rcut": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RcutLow'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RcutLow": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LRC'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"LRC": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Exclude'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Exclude": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Potential'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Potential": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Rswitch'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Rswitch": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ElectroStatic'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ElectroStatic": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Ewald'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Ewald": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CachedFourier'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CachedFourier": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Tolerance'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Tolerance": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Dielectric'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Dielectric": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['EqSteps'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"EqSteps": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['AdjSteps'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"AdjSteps": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['useConstantArea'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"useConstantArea": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the correct input variables where not provided for " - r"the NVT ensemble. Please be sure to check that the keys in the " - r"input variables dictionary \(input_variables_dict\) is correct, and " - r"be aware that added spaces before or after the variable in any keys " - r"will also give this warning. The bad variable inputs ensemble " - r"inputs = \['FixVolBox0'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"FixVolBox0": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the correct input variables where not provided for " - r"the NVT ensemble. Please be sure to check that the keys in the " - r"input variables dictionary \(input_variables_dict\) is correct, and " - r"be aware that added spaces before or after the variable in any keys " - r"will also give this warning. The bad variable inputs ensemble " - r"inputs = \['ChemPot'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ChemPot": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the correct input variables where not provided for " - r"the NVT ensemble. Please be sure to check that the keys in the " - r"input variables dictionary \(input_variables_dict\) is correct, and " - r"be aware that added spaces before or after the variable in any keys " - r"will also give this warning. The bad variable inputs ensemble " - r"inputs = \['Fugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Fugacity": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CBMC_First'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CBMC_First": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CBMC_Nth'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CBMC_Nth": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CBMC_Ang'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CBMC_Ang": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CBMC_Dih'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CBMC_Dih": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutputName'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutputName": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CoordinatesFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CoordinatesFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RestartFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RestartFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CheckpointFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CheckpointFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ConsoleFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ConsoleFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['BlockAverageFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"BlockAverageFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['HistogramFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"HistogramFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['DistName'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"DistName": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['HistName'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"HistName": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RunNumber'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RunNumber": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RunLetter'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RunLetter": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['SampleFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"SampleFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutPressure'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutPressure": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutMolNum'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutMolNum": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutDensity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutDensity": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutVolume'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutVolume": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutSurfaceTension'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutSurfaceTension": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [], - "MoleculeType": ["ETH", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", []], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": [["ETH"], 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": [{"ETH": "1"}, 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['InitialState'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", 1], - "InitialState": [], - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaVDW'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", 1], - "InitialState": 1, - "LambdaVDW": [], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaCoulomb'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: To utilize the free energy calculations all the " - r"following variables need to be set, and not equal to " - r"None: FreeEnergyCalc, MoleculeType, InitialState, LambdaVDW.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"FreeEnergyCalc": [True, 10000]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ScaleCoulomb'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ScaleCoulomb": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ScalePower'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ScalePower": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ScaleAlpha'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ScaleAlpha": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MinSigma'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MinSigma": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ExchangeVolumeDim'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ExchangeVolumeDim": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MEMC_DataInput": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['DisFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"DisFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['DisFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"DisFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['IntraSwapFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"IntraSwapFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['IntraSwapFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"IntraSwapFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RegrowthFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RegrowthFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['CrankShaftFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"CrankShaftFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['VolFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"VolFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MultiParticleFreq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MultiParticleFreq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['IntraMEMC-1Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"IntraMEMC-1Freq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC-1Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MEMC-1Freq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['IntraMEMC-2Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"IntraMEMC-2Freq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC-2Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MEMC-2Freq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['IntraMEMC-3Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"IntraMEMC-3Freq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC-3Freq'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MEMC-3Freq": []}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the correct input variables where not provided for " - r"the NVT ensemble. Please be sure to check that the keys in the " - r"input variables dictionary \(input_variables_dict\) is correct, and " - r"be aware that added spaces before or after the variable in any keys " - r"will also give this warning. The bad variable inputs ensemble " - r"inputs = \['XXXXXX'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_2.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"XXXXXX": []}, - ) - - def test_save_NVT_bad_variables_part_5(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[1, 1, 1], - ) - - charmm = Charmm( - test_box_ethane_ethanol, - "ethane_ethanol", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [True, 10000]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [False, 10000]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [1, 10000]}, - ) - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [True, 10000]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [False, 10000]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [1, 10000]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": ["", 10000]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [["x"], 10000]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [{"s": 1}, 10000]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [True, 1.0]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [True, "x"]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [True, ["x"]]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [True, {"s": 1}]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['PressureCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_5.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"PressureCalc": [1, True]}, - ) - - def test_save_NVT_bad_variables_part_6(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[1, 1, 1], - ) - - charmm = Charmm( - test_box_ethane_ethanol, - "ethane_ethanol", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [True, True]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [False, True]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [False, False]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [True, True]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [False, True]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [False, False]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [1, True]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": ["", True]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [["x"], True]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [{"s": 1}, True]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [True, 1.0]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [True, "x"]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [True, ["x"]]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['OutEnergy'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_6.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"OutEnergy": [True, {"s": 1}]}, - ) - - def test_save_NVT_bad_variables_part_7(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[1, 1, 1], - ) - - charmm = Charmm( - test_box_ethane_ethanol, - "ethane_ethanol", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [False, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 0.9, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 0.8, 1.0], - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETH", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [False, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: To utilize the free energy calculations all the following " - r"variables need to be set, and not equal to None: FreeEnergyCalc, " - r"MoleculeType, InitialState, LambdaVDW.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: To utilize the free energy calculations all the following " - r"variables need to be set, and not equal to None: FreeEnergyCalc, " - r"MoleculeType, InitialState, LambdaVDW.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [False, 10000], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: To utilize the free energy calculations all the following " - r"variables need to be set, and not equal to None: FreeEnergyCalc, " - r"MoleculeType, InitialState, LambdaVDW.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [False, 10000], - "MoleculeType": ["ETO", 1], - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: To utilize the free energy calculations all the following " - r"variables need to be set, and not equal to None: FreeEnergyCalc, " - r"MoleculeType, InitialState, LambdaVDW.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [False, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaCoulomb": [0.1, 0.3, 0.8, 1.0], - }, - ) - - try: - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [False, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - # starting bad inputs for the Free engergy calcs side from not using all required variables - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [1, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": ["1", 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [["1"], 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [{"a": "1"}, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [False, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - # starting bad inputs for the Free engergy calcs side from not using all required variables - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 1.0], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, "1"], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, ["1"]], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, {"a": "1"}], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FreeEnergyCalc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000, "s"], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - # start checking the MoleculeType variable for errors - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": [1, 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": [[1], 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": [{"a": "1"}, 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", "1"], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", ["1"]], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", {"a": "1"}], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MoleculeType'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETOa", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - # start checking the initial state variable - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['InitialState'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": "s", - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['InitialState'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": ["s"], - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['InitialState'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": {"a": "1"}, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['InitialState'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1.0, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - # start checking the LamdaVDW variable - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaVDW'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": ["x", 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaVDW'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [[0.0], 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaVDW'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [{"a": "1"}, 0.2, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 1.0], - }, - ) - - # start testing the LambdaCoulomb - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaCoulomb'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": ["x", 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaCoulomb'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [[0.0], 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['LambdaCoulomb'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 1.0], - "LambdaCoulomb": [{"a": "1"}, 0.3, 1.0], - }, - ) - with pytest.raises( - ValueError, - match=r"ERROR: The LambdaVDW and LambdaCoulomb list must be of equal length.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.1, 0.3, 0.8, 1.0], - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The LambdaVDW and LambdaCoulomb list must be of equal length.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_7.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - "LambdaCoulomb": [0.0, 0.3, 0.8, 1.0], - }, - ) - - with pytest.warns( - UserWarning, - match="WARNING: The free energy calculations are being used when RcutLow is not zero \(0\), " - "which can produce free energy results that are slightly off or wrong. " - "Please set RcutLow to zero \(RcutLow=0\) when using the free energy calculations.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_RcutLow_not_0_for_free_energy", - "NVT", - 1000, - 300, - check_input_files_exist=False, - input_variables_dict={ - "RcutLow": 1, - "FreeEnergyCalc": [True, 10000], - "MoleculeType": ["ETO", 1], - "InitialState": 1, - "LambdaVDW": [0.0, 0.1, 0.2, 0.4, 1.0], - }, - ) - - def test_save_NVT_bad_variables_part_8(self, ethane_gomc, ethanol_gomc): - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[4.0, 4.0, 4.0], - ) - - charmm = Charmm( - test_box_ethane_ethanol, - "ethane_ethanol_box_0", - structure_box_1=test_box_ethane_ethanol, - filename_box_1="ethane_ethanol_box_1", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - test_box_ethane_ethanol = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[4.0, 4.0, 4.0], - ) - - charmm_NPT_NVT = Charmm( - test_box_ethane_ethanol, - "ethane_ethanol_box_0", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['RcutCoulomb_box_1'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "GEMC_NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"RcutCoulomb_box_1": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['FixVolBox0'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"FixVolBox0": "s"}, - ) - - # test ExchangeVolumeDim for errors - with pytest.raises( - ValueError, - match=r"The MEMC_DataInput variable is equal to None, but at least one " - r"of the MEMC move ratios are all non-zero \(IntraMEMC-1Freq, " - r"MEMC-1Freq, IntraMEMC-2Freq, MEMC-2Freq, IntraMEMC-3Freq, " - r"and MEMC-3Freq\).", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"MEMC-1Freq": 1}, - ) - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ExchangeVolumeDim": [1.0, 1.0, 1.0]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ExchangeVolumeDim": [1, 1, 1]}, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ExchangeVolumeDim'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ExchangeVolumeDim": ["s", 1.0, 1.0]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ExchangeVolumeDim'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ExchangeVolumeDim": [1.0, [1.0], 1.0]}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ExchangeVolumeDim'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "ExchangeVolumeDim": [1.0, 1.0, {"a": 1.0}] - }, - ) - - # testing failures and passes for MEMC_DataInput - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "O1"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C2", "C1"], "ETO", ["O1", "C1"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "O1"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["O1", "C1"], "ETO", ["C2", "C1"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1.0, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - ["s", "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [[1], "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [{"a": "1"}, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETHa", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, 1, ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, [1], ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", [1, "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", [[1], "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", 1], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", [1]], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], 1, ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], [1], ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", [1, "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", [[1], "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", 1]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['MEMC_DataInput'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", [1]]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - # test the MEMC move ratios cant be set without specifying the MEMC move paramters ("MEMC_DataInput") - with pytest.raises( - ValueError, - match=r"ERROR: The MEMC_DataInput variable is equal to None, but at least " - r"one of the MEMC move ratios are all non-zero " - r"\(IntraMEMC-1Freq, MEMC-1Freq, IntraMEMC-2Freq, MEMC-2Freq, " - r"IntraMEMC-3Freq, and MEMC-3Freq\).", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "IntraMEMC-1Freq": 0.20, - "MEMC-1Freq": 0.20, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.20, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - - # test some GCMC variable errors with Chempot and fugacity - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ChemPot'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"ChemPot": "s"}, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Fugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_1.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={"Fugacity": "s"}, - ) - - # testing the move frequency sum to 1 for all ensembles - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The sum of the Monte Carlo move ratios does not equal 1. " - r"Note: The sum that was manually entered may equal 1, but some " - r"moves may not be valid for the provided ensemble. The moves that " - r"are invalid for a given ensemble are set to zero. If the default " - r"moves are not being used, all the move frequencies which do not have " - r"default values of zero will need to be set manually so the sum equals " - r"\(DisFreq, RotFreq, IntraSwapFreq, SwapFreq, RegrowthFreq, " - r"CrankShaftFreq, and VolFreq\).", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.20, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.20, - }, - ) - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.1, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The sum of the Monte Carlo move ratios does not equal 1. " - r"Note: The sum that was manually entered may equal 1, but some " - r"moves may not be valid for the provided ensemble. The moves that " - r"are invalid for a given ensemble are set to zero. If the default " - r"moves are not being used, all the move frequencies which do not have " - r"default values of zero will need to be set manually so the sum equals " - r"\(DisFreq, RotFreq, IntraSwapFreq, SwapFreq, RegrowthFreq, " - r"CrankShaftFreq, and VolFreq\).", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GEMC_NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.1, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.20, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.20, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.20, - }, - ) - - try: - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.1, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - "ChemPot": {"ETH": -4000, "ETO": 8000}, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The sum of the Monte Carlo move ratios does not equal 1. " - r"Note: The sum that was manually entered may equal 1, but some " - r"moves may not be valid for the provided ensemble. The moves that " - r"are invalid for a given ensemble are set to zero. If the default " - r"moves are not being used, all the move frequencies which do not have " - r"default values of zero will need to be set manually so the sum equals " - r"\(DisFreq, RotFreq, IntraSwapFreq, SwapFreq, RegrowthFreq, " - r"CrankShaftFreq, and VolFreq\).", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.05, - "RegrowthFreq": 0.05, - "CrankShaftFreq": 0.1, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.20, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.20, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.20, - "Fugacity": {"ETH": 0, "ETO": 1.0}, - }, - ) - - try: - value = gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.20, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The sum of the Monte Carlo move ratios does not equal 1. " - r"Note: The sum that was manually entered may equal 1, but some " - r"moves may not be valid for the provided ensemble. The moves that " - r"are invalid for a given ensemble are set to zero. If the default " - r"moves are not being used, all the move frequencies which do not have " - r"default values of zero will need to be set manually so the sum equals " - r"\(DisFreq, RotFreq, IntraSwapFreq, SwapFreq, RegrowthFreq, " - r"CrankShaftFreq, and VolFreq\).", - ): - gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.05, - "MultiParticleFreq": 0.05, - "IntraMEMC-1Freq": 0.20, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.19, - "MEMC-3Freq": 0.00, - }, - ) - - try: - value = gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.20, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - with pytest.raises( - ValueError, - match=r"ERROR: The sum of the Monte Carlo move ratios does not equal 1. " - r"Note: The sum that was manually entered may equal 1, but some " - r"moves may not be valid for the provided ensemble. The moves that " - r"are invalid for a given ensemble are set to zero. If the default " - r"moves are not being used, all the move frequencies which do not have " - r"default values of zero will need to be set manually so the sum equals " - r"\(DisFreq, RotFreq, IntraSwapFreq, SwapFreq, RegrowthFreq, " - r"CrankShaftFreq, and VolFreq\).", - ): - gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.20, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.21, - "MEMC-3Freq": 0.00, - }, - ) - - # test good values of Volume for NVT, and GCMC if set to zero - try: - value = gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.20, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.20, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "ChemPot": {"ETH": -4000, "ETO": -8000}, - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.10, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.10, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.10, - "MEMC-3Freq": 0.10, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - # test come MEMC with GCMC - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Fugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 1, - "Fugacity": {1: 0, "ETO": 1.0}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Fugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 1, - "Fugacity": {"ETH": -1, "ETO": 1.0}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Fugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 1, - "Fugacity": {"ETH": "1", "ETO": 1.0}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The MEMC_DataInput variable is not equal to None, " - r"but all the MEMC move ratios are zero \(IntraMEMC-1Freq, MEMC-1Freq, " - r"IntraMEMC-2Freq, MEMC-2Freq, IntraMEMC-3Freq, and MEMC-3Freq\).", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 1, - "Fugacity": {"ETH": 2, "ETO": 1.0}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Fugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 1, - "Fugacity": {"ETH": 0, "XXX": 1.0}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['Fugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 1, - "Fugacity": {"XXX": 0, "ETO": 1.0}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ChemPot'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 1, - "ChemPot": {1: -4000, "ETO": -8000}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ChemPot'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 1, - "ChemPot": {"XXX": -4000, "ETO": -8000}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ChemPot'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 1, - "ChemPot": {"ETH": -4000, "XXX": -8000}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ChemPot'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 1, - "ChemPot": {"ETH": "40", "ETO": -8000}, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['ChemPot'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 1, - "ChemPot": {"ETH": ["40"], "ETO": -8000}, - }, - ) - - # test bad values of Volume for NVT, and GCMC - with pytest.raises( - ValueError, - match=r"ERROR: The input variable VolFreq is non-zero \(0\). " - r'VolFreq must be zero \(0\) for the "NVT", "GEMC_NVT", ' - r'and "GCMC" ensembles.', - ): - gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.1, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The input variable VolFreq is non-zero \(0\). " - r'VolFreq must be zero \(0\) for the "NVT", "GEMC_NVT", ' - r'and "GCMC" ensembles.', - ): - gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "ChemPot": {"ETH": -4000, "ETO": -8000}, - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.1, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - - # test bad values of MEMC for NVT, NPT - with pytest.raises( - ValueError, - match=r"ERROR: All the MC move input variables must be non-zero \(0\) " - r"for the SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq. " - r"The SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq need to be zero " - r'\(0\) for the "NVT" and "NPT" ensembles.', - ): - gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the MC move input variables must be non-zero \(0\) " - r"for the SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq. " - r"The SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq need to be zero " - r'\(0\) for the "NVT" and "NPT" ensembles.', - ): - gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the MC move input variables must be non-zero \(0\) " - r"for the SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq. " - r"The SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq need to be zero " - r'\(0\) for the "NVT" and "NPT" ensembles.', - ): - gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NVT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the MC move input variables must be non-zero \(0\) " - r"for the SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq. " - r"The SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq need to be zero " - r'\(0\) for the "NVT" and "NPT" ensembles.', - ): - gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the MC move input variables must be non-zero \(0\) " - r"for the SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq. " - r"The SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq need to be zero " - r'\(0\) for the "NVT" and "NPT" ensembles.', - ): - gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: All the MC move input variables must be non-zero \(0\) " - r"for the SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq. " - r"The SwapFreq, MEMC-1Freq, MEMC-2Freq, and MEMC-3Freq need to be zero " - r'\(0\) for the "NVT" and "NPT" ensembles.', - ): - gomc_control.write_gomc_control_file( - charmm_NPT_NVT, - "test_save_NVT_bad_variables_part_8.conf", - "NPT", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.10, - }, - ) - - # test good values of MEMC with GCMC - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "ChemPot": {"ETH": -4000, "ETO": -8000}, - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.10, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.10, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "ChemPot": {"ETH": -4000, "ETO": -8000}, - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.10, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.00, - "TargetedSwapFreq": 0.00, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]] - ], - "ChemPot": {"ETH": -4000, "ETO": -8000}, - "DisFreq": 0.05, - "RotFreq": 0.05, - "IntraSwapFreq": 0.05, - "SwapFreq": 0.00, - "RegrowthFreq": 0.10, - "CrankShaftFreq": 0.05, - "VolFreq": 0.0, - "MultiParticleFreq": 0.1, - "IntraMEMC-1Freq": 0.10, - "MEMC-1Freq": 0.00, - "IntraMEMC-2Freq": 0.20, - "MEMC-2Freq": 0.00, - "IntraMEMC-3Freq": 0.20, - "MEMC-3Freq": 0.10, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - # try all case unspecific values - try: - value = gomc_control.write_gomc_control_file( - charmm, - "test_save_NVT_bad_variables_part_8.conf", - "GCMC", - 10, - 300, - check_input_files_exist=False, - input_variables_dict={ - "MEMC_DataInput": [ - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "C2"]], - [1, "ETH", ["C1", "C2"], "ETO", ["C1", "O1"]], - ], - "ChEmPot": {"ETH": -4000, "ETO": -8000}, - "DisFreQ": 0.05, - "RotFreq": 0.05, - "InTraSwapFreq": 0.05, - "SwaPFreq": 0.00, - "ReGrowthFreq": 0.10, - "crankshaftfreq": 0.05, - "VolFrEQ": 0.0, - "MULtiParticleFreq": 0.1, - "IntRAMEMC-1Freq": 0.10, - "MEMC-1FREQ": 0.00, - "IntrAMEMC-2Freq": 0.20, - "MEMC-2FReq": 0.00, - "intramemc-3Freq": 0.20, - "memc-3Freq": 0.10, - }, - ) - except: - value = "TEST_FAILED" - - assert value == "GOMC_CONTROL_FILE_WRITTEN" - - def test_charmm_object_has_proper_no_boxes_for_ensemble_part_9( - self, ethane_gomc, ethanol_gomc - ): - test_box_ethane_ethanol_liq = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[4, 4], - box=[4.0, 4.0, 4.0], - ) - - test_box_ethane_ethanol_vap = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[1, 1], - box=[8.0, 8.0, 8.0], - ) - - charmm_one_box = Charmm( - test_box_ethane_ethanol_liq, - "ethane_ethanol_1_box_liq", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - charmm_two_boxes = Charmm( - test_box_ethane_ethanol_liq, - "ethane_ethanol_2_boxes_liq", - structure_box_1=test_box_ethane_ethanol_vap, - filename_box_1="ethane_box_2_boxes_vap", - ff_filename="ethane_ethanol", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - # test that it fails with the GEMC_NVT with only 1 box in the Charmm object - with pytest.raises( - ValueError, - match=r"ERROR: The ensemble type selection of {} is using a Charmm " - r"object with one simulation boxes, and the {} ensemble only accepts " - r"two boxes \(box 0 and box 1\).".format("GEMC_NVT", "GEMC_NVT"), - ): - gomc_control.write_gomc_control_file( - charmm_one_box, - "test_charmm_object_has_proper_no_boxes_for_ensemble_part_9_1_box", - "GEMC_NVT", - 100, - 300, - check_input_files_exist=False, - ) - - # test that it fails with the GEMC_NPT with only 1 box in the Charmm object - with pytest.raises( - ValueError, - match=r"ERROR: The ensemble type selection of {} is using a Charmm " - r"object with one simulation boxes, and the {} ensemble only accepts " - r"two boxes \(box 0 and box 1\).".format("GEMC_NPT", "GEMC_NPT"), - ): - gomc_control.write_gomc_control_file( - charmm_one_box, - "test_charmm_object_has_proper_no_boxes_for_ensemble_part_9_1_box", - "GEMC_NPT", - 100, - 300, - check_input_files_exist=False, - ) - - # test that it fails with the GCMC with only 1 box in the Charmm object - with pytest.raises( - ValueError, - match=r"ERROR: The ensemble type selection of {} is using a Charmm " - r"object with one simulation boxes, and the {} ensemble only accepts " - r"two boxes \(box 0 and box 1\).".format("GCMC", "GCMC"), - ): - gomc_control.write_gomc_control_file( - charmm_one_box, - "test_charmm_object_has_proper_no_boxes_for_ensemble_part_9_1_box", - "GCMC", - 100, - 300, - check_input_files_exist=False, - ) - - # test that it fails with the NVT with 2 boxes in the Charmm object - with pytest.raises( - ValueError, - match=r"ERROR: The ensemble type selection of {} is using a Charmm " - r"object with two simulation boxes, and the {} ensemble only accepts " - r"one box \(box 0\).".format("NVT", "NVT"), - ): - gomc_control.write_gomc_control_file( - charmm_two_boxes, - "test_charmm_object_has_proper_no_boxes_for_ensemble_part_9_1_box", - "NVT", - 100, - 300, - check_input_files_exist=False, - ) - - # test that it fails with the NPT with 2 boxes in the Charmm object - with pytest.raises( - ValueError, - match=r"ERROR: The ensemble type selection of {} is using a Charmm " - r"object with two simulation boxes, and the {} ensemble only accepts " - r"one box \(box 0\).".format("NPT", "NPT"), - ): - gomc_control.write_gomc_control_file( - charmm_two_boxes, - "test_charmm_object_has_proper_no_boxes_for_ensemble_part_9_1_box", - "NPT", - 100, - 300, - check_input_files_exist=False, - ) - - def test_save_non_othoganol_writer(self): - lattice_cif_ETV_triclinic = load_cif( - file_or_path=get_fn("ETV_triclinic.cif") - ) - ETV_triclinic_1_cell = lattice_cif_ETV_triclinic.populate(x=1, y=1, z=1) - ETV_triclinic_1_cell.name = "ETV_1" - ETV_triclinic_3_cell = lattice_cif_ETV_triclinic.populate(x=3, y=3, z=3) - ETV_triclinic_3_cell.name = "ETV_3" - - charmm = Charmm( - ETV_triclinic_1_cell, - "ETV_triclinic_1_cell_box_0", - structure_box_1=ETV_triclinic_3_cell, - filename_box_1="ETV_triclinic_3_cell_box_1", - ff_filename="ETV_triclinic_FF", - forcefield_selection={ - ETV_triclinic_1_cell.name: get_fn( - "Charmm_writer_testing_only_zeolite.xml" - ), - ETV_triclinic_3_cell.name: get_fn( - "Charmm_writer_testing_only_zeolite.xml" - ), - }, - residues=[ETV_triclinic_1_cell.name, ETV_triclinic_3_cell.name], - bead_to_atom_name_dict=None, - fix_residue=[ETV_triclinic_1_cell.name, ETV_triclinic_3_cell.name], - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_non_othoganol_writer.conf", - "GEMC_NVT", - 100000, - 300, - check_input_files_exist=False, - ) - - with open("test_save_non_othoganol_writer.conf", "r") as fp: - cell_vector_box_0_1_read = False - cell_vector_box_0_2_read = False - cell_vector_box_0_3_read = False - cell_vector_box_1_1_read = False - cell_vector_box_1_2_read = False - cell_vector_box_1_3_read = False - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("CellBasisVector1 0"): - cell_vector_box_0_1_read = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "8.7503" - assert split_line[3] == "0.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector2 0"): - cell_vector_box_0_2_read = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "-1.179131" - assert split_line[3] == "9.575585" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector3 0"): - cell_vector_box_0_3_read = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "-1.817231" - assert split_line[3] == "-3.027821" - assert split_line[4] == "9.645823" - - if line.startswith("CellBasisVector1 1"): - cell_vector_box_1_1_read = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "26.2509" - assert split_line[3] == "0.0" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector2 1"): - cell_vector_box_1_2_read = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "-3.537381" - assert split_line[3] == "28.726735" - assert split_line[4] == "0.0" - - elif line.startswith("CellBasisVector3 1"): - cell_vector_box_1_3_read = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "-5.451699" - assert split_line[3] == "-9.083469" - assert split_line[4] == "28.937455" - - else: - pass - - assert cell_vector_box_0_1_read == True - assert cell_vector_box_0_2_read == True - assert cell_vector_box_0_3_read == True - assert cell_vector_box_1_1_read == True - assert cell_vector_box_1_2_read == True - assert cell_vector_box_1_3_read == True - - def test_box_vector_too_many_char(self): - methane = mb.Compound(name="MET") - methane_child_bead = mb.Compound(name="_CH4") - methane.add(methane_child_bead, inherit_periodicity=False) - - methane_box_orth = mb.fill_box( - compound=methane, n_compounds=10, box=[1, 2, 3] - ) - - charmm_bad_box_0 = Charmm( - methane_box_orth, - "methane_box_0_orth", - ff_filename="methane_box_orth_bad_box_0_non_orth", - residues=[methane.name], - forcefield_selection="trappe-ua", - ) - - # set the vectors all too long - charmm_bad_box_0.box_0_vectors[0][0] = -0.45678901234561 - charmm_bad_box_0.box_0_vectors[0][1] = -0.45678901234562 - charmm_bad_box_0.box_0_vectors[0][2] = -0.45678901234563 - charmm_bad_box_0.box_0_vectors[1][0] = -0.45678901234564 - charmm_bad_box_0.box_0_vectors[1][1] = -0.45678901234565 - charmm_bad_box_0.box_0_vectors[1][2] = -0.45678901234566 - charmm_bad_box_0.box_0_vectors[2][0] = -0.45678901234567 - charmm_bad_box_0.box_0_vectors[2][1] = -0.45678901234568 - charmm_bad_box_0.box_0_vectors[2][2] = -0.45678901234569 - - charmm_bad_box_1 = Charmm( - methane_box_orth, - "methane_box_0_orth", - structure_box_1=methane_box_orth, - filename_box_1="methane_box_1_orth", - ff_filename="methane_box_orth_bad_box_1_non_orth", - residues=[methane.name], - forcefield_selection="trappe-ua", - ) - - # set the vectors all too long - charmm_bad_box_1.box_1_vectors[0][0] = -0.45678901234561 - charmm_bad_box_1.box_1_vectors[0][1] = -0.45678901234562 - charmm_bad_box_1.box_1_vectors[0][2] = -0.45678901234563 - charmm_bad_box_1.box_1_vectors[1][0] = -0.45678901234564 - charmm_bad_box_1.box_1_vectors[1][1] = -0.45678901234565 - charmm_bad_box_1.box_1_vectors[1][2] = -0.45678901234566 - charmm_bad_box_1.box_1_vectors[2][0] = -0.45678901234567 - charmm_bad_box_1.box_1_vectors[2][1] = -0.45678901234568 - charmm_bad_box_1.box_1_vectors[2][2] = -0.45678901234569 - - # test that it fails with the GEMC_NVT with only 1 box in the Charmm object - with pytest.raises( - ValueError, - match=r"ERROR: At lease one of the individual box {} vectors are too large " - "or greater than {} characters." - "".format(0, 16), - ): - gomc_control.write_gomc_control_file( - charmm_bad_box_0, - "test_box_vector_too_many_char_box_0", - "NVT", - 100, - 300, - check_input_files_exist=False, - ) - - # test that it fails with the GEMC_NPT with only 1 box in the Charmm object - with pytest.raises( - ValueError, - match=r"ERROR: At lease one of the individual box {} vectors are too large " - "or greater than {} characters." - "".format(1, 16), - ): - gomc_control.write_gomc_control_file( - charmm_bad_box_1, - "test_box_vector_too_many_char_box_1", - "GCMC", - 100, - 300, - check_input_files_exist=False, - ) - - def test_adjustment_steps_and_ff_psf_pdb_file_directory(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - changed_file_path = "../files" - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - # test the failure of the ff_psf_pdb_file_directory variable is not None or a string - with pytest.raises( - TypeError, - match=f"ERROR: The {'ff_psf_pdb_file_directory'} variable for directly entering the " - f"{'force field, pdb, and psf'} file directory and name is a {type(['x'])} and not a string.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_charmm_object_ff_psf_pdb_file_directory_not_a_sting", - "GEMC_NPT", - 100, - 300, - check_input_files_exist=False, - ff_psf_pdb_file_directory=["x"], - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_adjustment_steps.conf", - "GEMC_NVT", - 100000, - 500, - check_input_files_exist=False, - ff_psf_pdb_file_directory=changed_file_path, - input_variables_dict={ - "PressureCalc": [True, 1], - "AdjSteps": 2, - "EqSteps": 3, - "CoordinatesFreq": [True, 4], - "RestartFreq": [True, 5], - "CheckpointFreq": [True, 6], - "ConsoleFreq": [True, 7], - "BlockAverageFreq": [True, 8], - "HistogramFreq": [True, 9], - "SampleFreq": 11, - "VDWGeometricSigma": True, - }, - ) - - with open("test_adjustment_steps.conf", "r") as fp: - variables_read_dict = { - "PressureCalc": False, - "AdjSteps": False, - "EqSteps": False, - "CoordinatesFreq": False, - "RestartFreq": False, - "CheckpointFreq": False, - "ConsoleFreq": False, - "BlockAverageFreq": False, - "HistogramFreq": False, - "SampleFreq": False, - "VDWGeometricSigma": False, - "Parameters": False, - "Coordinates_box_0": False, - "Structure_box_0": False, - "Coordinates_box_1": False, - "Structure_box_1": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("PressureCalc "): - variables_read_dict["PressureCalc"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1" - - elif line.startswith("AdjSteps "): - variables_read_dict["AdjSteps"] = True - split_line = line.split() - assert split_line[1] == "2" - - elif line.startswith("EqSteps "): - variables_read_dict["EqSteps"] = True - split_line = line.split() - assert split_line[1] == "3" - - elif line.startswith("CoordinatesFreq "): - variables_read_dict["CoordinatesFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "4" - - elif line.startswith("RestartFreq "): - variables_read_dict["RestartFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "5" - - elif line.startswith("CheckpointFreq "): - variables_read_dict["CheckpointFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "6" - - elif line.startswith("ConsoleFreq "): - variables_read_dict["ConsoleFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "7" - - elif line.startswith("BlockAverageFreq "): - variables_read_dict["BlockAverageFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "8" - - elif line.startswith("HistogramFreq "): - variables_read_dict["HistogramFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "9" - - elif line.startswith("SampleFreq "): - variables_read_dict["SampleFreq"] = True - split_line = line.split() - assert split_line[1] == "11" - - elif line.startswith("VDWGeometricSigma "): - variables_read_dict["VDWGeometricSigma"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("Parameters "): - variables_read_dict["Parameters"] = True - split_line = line.split() - assert split_line[1] == "{}/ethane_FF.inp".format( - changed_file_path - ) - - elif line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates_box_0"] = True - split_line = line.split() - assert split_line[2] == "{}/ethane_box_0.pdb".format( - changed_file_path - ) - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure_box_0"] = True - split_line = line.split() - assert split_line[2] == "{}/ethane_box_0.psf".format( - changed_file_path - ) - - elif line.startswith("Coordinates 1 "): - variables_read_dict["Coordinates_box_1"] = True - split_line = line.split() - assert split_line[2] == "{}/ethane_box_1.pdb".format( - changed_file_path - ) - - elif line.startswith("Structure 1 "): - variables_read_dict["Structure_box_1"] = True - split_line = line.split() - assert split_line[2] == "{}/ethane_box_1.psf".format( - changed_file_path - ) - - assert variables_read_dict == { - "PressureCalc": True, - "AdjSteps": True, - "EqSteps": True, - "CoordinatesFreq": True, - "RestartFreq": True, - "CheckpointFreq": True, - "ConsoleFreq": True, - "BlockAverageFreq": True, - "HistogramFreq": True, - "SampleFreq": True, - "VDWGeometricSigma": True, - "Parameters": True, - "Coordinates_box_0": True, - "Structure_box_0": True, - "Coordinates_box_1": True, - "Structure_box_1": True, - } - - def test_check_required_gomc_files_inp_exist_GEMC_NPT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"The {} with the file directory and name {}, " - "does not exist.".format( - "force field file or parameter file", - "{}".format("ethane_FF.inp"), - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_gomc_ff_exists_GEMC_NPT", - "GEMC_NPT", - 100, - 300, - check_input_files_exist=True, - ) - - def test_check_required_gomc_files_pdb_exist_GEMC_NPT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - charmm.write_inp() - - with pytest.raises( - ValueError, - match=r"The {} with the file directory and name {}, " - "does not exist.".format( - "box 0 pdb file", "{}".format("ethane_box_0.pdb") - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_gomc_pdb_exists_GEMC_NPT", - "GEMC_NPT", - 100, - 300, - check_input_files_exist=True, - ) - - def test_check_required_gomc_files_psf_exist_GEMC_NPT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - charmm.write_inp() - charmm.write_pdb() - - with pytest.raises( - ValueError, - match=r"The {} with the file directory and name {}, " - "does not exist.".format( - "box 0 psf file", "{}".format("ethane_box_0.psf") - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_gomc_psf_exists_GEMC_NPT", - "GEMC_NPT", - 100, - 300, - check_input_files_exist=True, - ) - - def test_check_required_gomc_files_pdb_exist_NVT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - charmm.write_inp() - - with pytest.raises( - ValueError, - match=r"The {} with the file directory and name {}, " - "does not exist.".format( - "box 0 pdb file", "{}".format("ethane_box_0.pdb") - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_gomc_pdb_exists_NVT", - "NVT", - 100, - 300, - check_input_files_exist=True, - ) - - def test_check_required_gomc_files_psf_exist_NVT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - charmm.write_inp() - charmm.write_pdb() - - with pytest.raises( - ValueError, - match=r"The {} with the file directory and name {}, " - "does not exist.".format( - "box 0 psf file", "{}".format("ethane_box_0.psf") - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_gomc_psf_exists_NVT", - "NVT", - 100, - 300, - check_input_files_exist=True, - ) - - def test_check_restart_bool(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - restart_input = "XXXXX" - with pytest.raises( - TypeError, - match=r"ERROR: The {} input is {} and needs to be a boolean \(i.e., True or False\)." - "".format("Restart", type(restart_input)), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_checkpoint_error", - "NVT", - 100, - 300, - check_input_files_exist=False, - Restart=restart_input, - ) - - restart_checkpoint_input = "XXXXX" - with pytest.raises( - TypeError, - match=r"ERROR: The {} input is {} and needs to be a boolean \(i.e., True or False\)." - "".format("RestartCheckpoint", type(restart_checkpoint_input)), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_checkpoint_error", - "NVT", - 100, - 300, - check_input_files_exist=False, - RestartCheckpoint="XXXXX", - ) - - check_input_files_exist_input = "XXXXX" - with pytest.raises( - TypeError, - match=r"ERROR: The {} input is {} and needs to be a boolean \(i.e., True or False\)." - "".format( - "check_input_files_exist", type(check_input_files_exist_input) - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "check_input_files_exist_error", - "NVT", - 100, - 300, - check_input_files_exist="XXXXX", - ) - - def test_restarting_dcd_and_binary_files_NVT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_restarting_dcd_and_binary_files_NVT", - "NVT", - 1000, - 300, - Restart=True, - check_input_files_exist=False, - Coordinates_box_0="../test_files/NVT_toluene_box_0.pdb", - Structure_box_0="../test_files/NVT_toluene_box_0.psf", - binCoordinates_box_0="../test_files/NVT_toluene_box_0.coor", - extendedSystem_box_0="../test_files/NVT_toluene_box_0.xsc", - binVelocities_box_0="../test_files/NVT_toluene_box_0.vel", - input_variables_dict={ - "VDWGeometricSigma": True, - "DCDFreq": [True, 1000], - }, - ) - - with open("test_restarting_dcd_and_binary_files_NVT.conf", "r") as fp: - variables_read_dict = { - "VDWGeometricSigma": False, - "DCDFreq": False, - "Coordinates_box_0": False, - "Structure_box_0": False, - "binCoordinates_box_0": False, - "extendedSystem_box_0": False, - "binVelocities_box_0": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Restart "): - variables_read_dict["Restart"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("VDWGeometricSigma "): - variables_read_dict["VDWGeometricSigma"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("DCDFreq "): - variables_read_dict["DCDFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1000" - - elif line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files/NVT_toluene_box_0.pdb" - ) - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files/NVT_toluene_box_0.psf" - ) - - elif line.startswith("binCoordinates 0 "): - variables_read_dict["binCoordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files/NVT_toluene_box_0.coor" - ) - - elif line.startswith("extendedSystem 0 "): - variables_read_dict["extendedSystem_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files/NVT_toluene_box_0.xsc" - ) - - elif line.startswith("binVelocities 0"): - variables_read_dict["binVelocities_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files/NVT_toluene_box_0.vel" - ) - - assert variables_read_dict == { - "Restart": True, - "VDWGeometricSigma": True, - "DCDFreq": True, - "Coordinates_box_0": True, - "Structure_box_0": True, - "binCoordinates_box_0": True, - "extendedSystem_box_0": True, - "binVelocities_box_0": True, - } - - def test_restarting_dcd_and_binary_files_GEMC_NVT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_restarting_dcd_and_binary_files_GEMC_NVT", - "GEMC_NVT", - 1000, - 300, - Restart=True, - check_input_files_exist=False, - Coordinates_box_0="../test_files/NVT_ethane_box_0.pdb", - Structure_box_0="../test_files/NVT_ethane_box_0.psf", - binCoordinates_box_0="../test_files/NVT_ethane_box_0.coor", - extendedSystem_box_0="../test_files/NVT_ethane_box_0.xsc", - binVelocities_box_0="../test_files/NVT_ethane_box_0.vel", - Coordinates_box_1="../test_files/NVT_ethane_box_1.pdb", - Structure_box_1="../test_files/NVT_ethane_box_1.psf", - binCoordinates_box_1="../test_files/NVT_ethane_box_1.coor", - extendedSystem_box_1="../test_files/NVT_ethane_box_1.xsc", - binVelocities_box_1="../test_files/NVT_ethane_box_1.vel", - input_variables_dict={ - "VDWGeometricSigma": True, - "DCDFreq": [True, 1000], - }, - ) - - with open( - "test_restarting_dcd_and_binary_files_GEMC_NVT.conf", "r" - ) as fp: - variables_read_dict = { - "VDWGeometricSigma": False, - "DCDFreq": False, - "Coordinates_box_0": False, - "Structure_box_0": False, - "binCoordinates_box_0": False, - "extendedSystem_box_0": False, - "binVelocities_box_0": False, - "Coordinates_box_1": False, - "Structure_box_1": False, - "binCoordinates_box_1": False, - "extendedSystem_box_1": False, - "binVelocities_box_1": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Restart "): - variables_read_dict["Restart"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("VDWGeometricSigma "): - variables_read_dict["VDWGeometricSigma"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("DCDFreq "): - variables_read_dict["DCDFreq"] = True - split_line = line.split() - assert split_line[1] == "True" - assert split_line[2] == "1000" - - elif line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../test_files/NVT_ethane_box_0.pdb" - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../test_files/NVT_ethane_box_0.psf" - - elif line.startswith("binCoordinates 0 "): - variables_read_dict["binCoordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files/NVT_ethane_box_0.coor" - ) - - elif line.startswith("extendedSystem 0 "): - variables_read_dict["extendedSystem_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../test_files/NVT_ethane_box_0.xsc" - - elif line.startswith("binVelocities 0"): - variables_read_dict["binVelocities_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../test_files/NVT_ethane_box_0.vel" - - elif line.startswith("Coordinates 1 "): - variables_read_dict["Coordinates_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "../test_files/NVT_ethane_box_1.pdb" - - elif line.startswith("Structure 1 "): - variables_read_dict["Structure_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "../test_files/NVT_ethane_box_1.psf" - - elif line.startswith("binCoordinates 1 "): - variables_read_dict["binCoordinates_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert ( - split_line[2] == "../test_files/NVT_ethane_box_1.coor" - ) - - elif line.startswith("extendedSystem 1 "): - variables_read_dict["extendedSystem_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "../test_files/NVT_ethane_box_1.xsc" - - elif line.startswith("binVelocities 1"): - variables_read_dict["binVelocities_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "../test_files/NVT_ethane_box_1.vel" - - assert variables_read_dict == { - "Restart": True, - "VDWGeometricSigma": True, - "DCDFreq": True, - "Coordinates_box_0": True, - "Structure_box_0": True, - "binCoordinates_box_0": True, - "extendedSystem_box_0": True, - "binVelocities_box_0": True, - "Coordinates_box_1": True, - "Structure_box_1": True, - "binCoordinates_box_1": True, - "extendedSystem_box_1": True, - "binVelocities_box_1": True, - } - - def test_restarting_pdb_psf_NVT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_restarting_pdb_psf_NVT", - "NVT", - 1000, - 300, - ff_psf_pdb_file_directory="../Test", - Parameters="../test_folder/new.par", - Restart=True, - RestartCheckpoint=True, - check_input_files_exist=False, - input_variables_dict={}, - ) - - with open("test_restarting_pdb_psf_NVT.conf", "r") as fp: - variables_read_dict = { - "Parameters": False, - "Coordinates_box_0": False, - "Structure_box_0": False, - "Restart": False, - "RestartCheckpoint": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Parameters "): - variables_read_dict["Parameters"] = True - split_line = line.split() - assert split_line[1] == "../test_folder/new.par" - - elif line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../Test/ethane_box_0.pdb" - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../Test/ethane_box_0.psf" - - elif line.startswith("Restart "): - variables_read_dict["Restart"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("RestartCheckpoint "): - variables_read_dict["RestartCheckpoint"] = True - split_line = line.split() - assert split_line[1] == "True" - - assert variables_read_dict == { - "Parameters": True, - "Coordinates_box_0": True, - "Structure_box_0": True, - "Restart": True, - "RestartCheckpoint": True, - } - - def test_restarting_pdb_psf_NVT_only_rename_coordinates(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_restarting_pdb_psf_NVT_only_rename_coordinates", - "NVT", - 1000, - 300, - ff_psf_pdb_file_directory="../Test", - Restart=True, - RestartCheckpoint=True, - Coordinates_box_0="../test_files_1/NVT_toluene_box_0.pdb", - Structure_box_0=None, - check_input_files_exist=False, - input_variables_dict={}, - ) - - with open( - "test_restarting_pdb_psf_NVT_only_rename_coordinates.conf", "r" - ) as fp: - variables_read_dict = { - "Coordinates_box_0": False, - "Structure_box_0": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files_1/NVT_toluene_box_0.pdb" - ) - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../Test/ethane_box_0.psf" - - assert variables_read_dict == { - "Coordinates_box_0": True, - "Structure_box_0": True, - } - - def test_restarting_pdb_psf_NVT_only_rename_structure(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_restarting_pdb_psf_NVT_only_rename_structure", - "NVT", - 1000, - 300, - ff_psf_pdb_file_directory=None, - Restart=True, - RestartCheckpoint=True, - Coordinates_box_0=None, - Structure_box_0="../test_files_2/NVT_toluene_box_0.psf", - check_input_files_exist=False, - input_variables_dict={}, - ) - - with open( - "test_restarting_pdb_psf_NVT_only_rename_structure.conf", "r" - ) as fp: - variables_read_dict = { - "Coordinates_box_0": False, - "Structure_box_0": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "ethane_box_0.pdb" - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files_2/NVT_toluene_box_0.psf" - ) - - assert variables_read_dict == { - "Coordinates_box_0": True, - "Structure_box_0": True, - } - - def test_restarting_pdb_psf_GEMC_NVT_only_rename_coordinates( - self, ethane_gomc - ): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_restarting_pdb_psf_GEMC_NVT_only_rename_coordinates", - "GEMC_NVT", - 1000, - 300, - ff_psf_pdb_file_directory=None, - Restart=True, - RestartCheckpoint=True, - Coordinates_box_0="../test_files_1/NVT_toluene_box_0.pdb", - Structure_box_0=None, - Coordinates_box_1="../test_files_2/NVT_toluene_box_1.pdb", - Structure_box_1=None, - check_input_files_exist=False, - input_variables_dict={}, - ) - - with open( - "test_restarting_pdb_psf_GEMC_NVT_only_rename_coordinates.conf", "r" - ) as fp: - variables_read_dict = { - "Coordinates_box_0": False, - "Structure_box_0": False, - "Coordinates_box_1": False, - "Structure_box_1": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files_1/NVT_toluene_box_0.pdb" - ) - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "ethane_box_0.psf" - - elif line.startswith("Coordinates 1 "): - variables_read_dict["Coordinates_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert ( - split_line[2] == "../test_files_2/NVT_toluene_box_1.pdb" - ) - - elif line.startswith("Structure 1 "): - variables_read_dict["Structure_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "ethane_box_1.psf" - - assert variables_read_dict == { - "Coordinates_box_0": True, - "Structure_box_0": True, - "Coordinates_box_1": True, - "Structure_box_1": True, - } - - def test_restarting_pdb_psf_GEMC_NVT_only_rename_structure( - self, ethane_gomc - ): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_restarting_pdb_psf_GEMC_NVT_only_rename_structure", - "GEMC_NVT", - 1000, - 300, - ff_psf_pdb_file_directory="../Test", - Restart=True, - RestartCheckpoint=True, - Coordinates_box_0=None, - Structure_box_0="../test_files_1/NVT_toluene_box_0.psf", - Coordinates_box_1=None, - Structure_box_1="../test_files_2/NVT_toluene_box_1.psf", - check_input_files_exist=False, - input_variables_dict={}, - ) - - with open( - "test_restarting_pdb_psf_GEMC_NVT_only_rename_structure.conf", "r" - ) as fp: - variables_read_dict = { - "Coordinates_box_0": False, - "Structure_box_0": False, - "Coordinates_box_1": False, - "Structure_box_1": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../Test/ethane_box_0.pdb" - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert ( - split_line[2] == "../test_files_1/NVT_toluene_box_0.psf" - ) - - if line.startswith("Coordinates 1 "): - variables_read_dict["Coordinates_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "../Test/ethane_box_1.pdb" - - elif line.startswith("Structure 1 "): - variables_read_dict["Structure_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert ( - split_line[2] == "../test_files_2/NVT_toluene_box_1.psf" - ) - - assert variables_read_dict == { - "Coordinates_box_0": True, - "Structure_box_0": True, - "Coordinates_box_1": True, - "Structure_box_1": True, - } - - def test_restarting_pdb_psf_GEMC_NVT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_restarting_pdb_psf_GEMC_NVT", - "GEMC-NVT", - 1000, - 300, - ff_psf_pdb_file_directory="../Test", - Parameters="../test_folder/new.inp", - Restart=True, - RestartCheckpoint=True, - check_input_files_exist=False, - input_variables_dict={}, - ) - - with open("test_restarting_pdb_psf_GEMC_NVT.conf", "r") as fp: - variables_read_dict = { - "Parameters": False, - "Coordinates_box_0": False, - "Structure_box_0": False, - "Coordinates_box_1": False, - "Structure_box_1": False, - "Restart": False, - "RestartCheckpoint": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("Parameters "): - variables_read_dict["Parameters"] = True - split_line = line.split() - assert split_line[1] == "../test_folder/new.inp" - - elif line.startswith("Coordinates 0 "): - variables_read_dict["Coordinates_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../Test/ethane_box_0.pdb" - - elif line.startswith("Structure 0 "): - variables_read_dict["Structure_box_0"] = True - split_line = line.split() - assert split_line[1] == "0" - assert split_line[2] == "../Test/ethane_box_0.psf" - - elif line.startswith("Coordinates 1 "): - variables_read_dict["Coordinates_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "../Test/ethane_box_1.pdb" - - elif line.startswith("Structure 1 "): - variables_read_dict["Structure_box_1"] = True - split_line = line.split() - assert split_line[1] == "1" - assert split_line[2] == "../Test/ethane_box_1.psf" - - elif line.startswith("Restart "): - variables_read_dict["Restart"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("RestartCheckpoint "): - variables_read_dict["RestartCheckpoint"] = True - split_line = line.split() - assert split_line[1] == "True" - - assert variables_read_dict == { - "Parameters": True, - "Coordinates_box_0": True, - "Structure_box_0": True, - "Coordinates_box_1": True, - "Structure_box_1": True, - "Restart": True, - "RestartCheckpoint": True, - } - - def test_failures_restarting_dcd_and_binary_files_NVT(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - with pytest.raises( - ValueError, - match="ERROR: To restart a simulation with the binary files both the coor " - "and xsc files for box 0 must be provided.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "NVT", - 1000, - 300, - Restart=True, - check_input_files_exist=False, - binCoordinates_box_0="../test_files/NVT_ethane_box_0.coor", - extendedSystem_box_0=None, - binVelocities_box_0=None, - input_variables_dict={ - "VDWGeometricSigma": True, - "DCDFreq": [True, 1000], - }, - ) - - with pytest.raises( - ValueError, - match="ERROR: To restart a simulation with the binary files both the coor and " - "xsc files for box 0 must be provided.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "NVT", - 1000, - 300, - Restart=True, - check_input_files_exist=False, - binCoordinates_box_0=None, - extendedSystem_box_0="../test_files/NVT_ethane_box_0.xsc", - binVelocities_box_0=None, - input_variables_dict={ - "VDWGeometricSigma": True, - "DCDFreq": [True, 1000], - }, - ) - - with pytest.raises( - ValueError, - match='ERROR: To restart a "NVT", "NPT" simulation with the ' - "velocity binary files, the velocity files for box 0 " - "must be provided.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "NVT", - 1000, - 300, - Restart=True, - check_input_files_exist=False, - binCoordinates_box_0=None, - extendedSystem_box_0=None, - binVelocities_box_0="../test_files/NVT_ethane_box_0.vel", - input_variables_dict={ - "VDWGeometricSigma": True, - "DCDFreq": [True, 1000], - }, - ) - - def test_failures_restarting_dcd_and_binary_files_GEMC_NVT( - self, ethane_gomc - ): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - charmm.write_inp() - charmm.write_pdb() - charmm.write_psf() - - with pytest.raises( - ValueError, - match="ERROR: To restart a simulation with the binary files both the coor and " - "xsc files for box 0 and box 1 must be provided.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "GEMC_NVT", - 1000, - 300, - Restart=True, - check_input_files_exist=False, - binCoordinates_box_0="../test_files/NVT_ethane_box_0.coor", - extendedSystem_box_0="../test_files/NVT_ethane_box_0.xsc", - binVelocities_box_0=None, - binCoordinates_box_1="../test_files/NVT_ethane_box_1.coor", - extendedSystem_box_1=None, - binVelocities_box_1=None, - input_variables_dict={ - "VDWGeometricSigma": True, - "DCDFreq": [True, 1000], - }, - ) - - with pytest.raises( - ValueError, - match="ERROR: To restart a simulation with the binary files both the coor and " - "xsc files for box 0 and box 1 must be provided.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "GEMC_NVT", - 1000, - 300, - Restart=True, - check_input_files_exist=False, - binCoordinates_box_0="../test_files/NVT_ethane_box_0.coor", - extendedSystem_box_0="../test_files/NVT_ethane_box_0.xsc", - binVelocities_box_0=None, - binCoordinates_box_1=None, - extendedSystem_box_1="../test_files/NVT_ethane_box_0.xsc", - binVelocities_box_1=None, - input_variables_dict={ - "VDWGeometricSigma": True, - "DCDFreq": [True, 1000], - }, - ) - - with pytest.raises( - ValueError, - match='ERROR: To restart a "GEMC_NPT", "GEMC_NVT", "GCMC" simulation with the ' - "velocity binary files, both the velocity files for box 0 and box 1 " - "must be provided.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "GEMC_NVT", - 1000, - 300, - Restart=True, - check_input_files_exist=False, - binCoordinates_box_0="../test_files/NVT_ethane_box_0.coor", - extendedSystem_box_0="../test_files/NVT_ethane_box_0.xsc", - binVelocities_box_0="../test_files/NVT_ethane_box_0.vel", - binCoordinates_box_1="../test_files/NVT_ethane_box_1.coor", - extendedSystem_box_1="../test_files/NVT_ethane_box_1.xsc", - binVelocities_box_1=None, - input_variables_dict={ - "VDWGeometricSigma": True, - "DCDFreq": [True, 1000], - }, - ) - - test_box_0_pdb = "XXXX" - with pytest.raises( - TypeError, - match=r'ERROR: The {} variable expects a file extension of {}, but the actual file extension is "{}". ' - r"".format( - "Coordinates_box_0", - r"\['.pdb'\]", - os.path.splitext(test_box_0_pdb)[-1], - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "GEMC_NVT", - 1000, - 300, - check_input_files_exist=True, - Coordinates_box_0=test_box_0_pdb, - Structure_box_0="ethane_box_0.psf", - Coordinates_box_1="ethane_box_0.pdb", - Structure_box_1="ethane_box_1.psf", - ) - - test_box_1_pdb = "XXXX" - with pytest.raises( - TypeError, - match=r'ERROR: The {} variable expects a file extension of {}, but the actual file extension is "{}". ' - r"".format( - "Coordinates_box_1", - r"\['.pdb'\]", - os.path.splitext(test_box_1_pdb)[-1], - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "GEMC_NVT", - 1000, - 300, - check_input_files_exist=True, - Coordinates_box_0="ethane_box_0.pdb", - Structure_box_0="ethane_box_0.psf", - Coordinates_box_1=test_box_1_pdb, - Structure_box_1="ethane_box_1.psf", - ) - - test_box_0_psf = "XXXX" - with pytest.raises( - TypeError, - match=r'ERROR: The {} variable expects a file extension of {}, but the actual file extension is "{}". ' - r"".format( - "Structure_box_0", - r"\['.psf'\]", - os.path.splitext(test_box_0_psf)[-1], - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "GEMC_NVT", - 1000, - 300, - check_input_files_exist=True, - Coordinates_box_0="ethane_box_0.pdb", - Structure_box_0=test_box_0_psf, - Coordinates_box_1="ethane_box_1.pdb", - Structure_box_1="ethane_box_1.psf", - ) - - test_box_1_psf = "XXXX" - with pytest.raises( - TypeError, - match=r'ERROR: The {} variable expects a file extension of {}, but the actual file extension is "{}". ' - r"".format( - "Structure_box_1", - r"\['.psf'\]", - os.path.splitext(test_box_1_psf)[-1], - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "GEMC_NVT", - 1000, - 300, - check_input_files_exist=True, - Coordinates_box_0="ethane_box_0.pdb", - Structure_box_0="ethane_box_0.psf", - Coordinates_box_1="ethane_box_1.pdb", - Structure_box_1=test_box_1_psf, - ) - - test_parameters = ["XXXX"] - with pytest.raises( - TypeError, - match=r"ERROR: The {} variable for directly entering the " - r"{} file directory and name is a {} and not a string.".format( - "Parameters", "force field", type(test_parameters) - ), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_restart_inputs", - "GEMC_NVT", - 1000, - 300, - check_input_files_exist=True, - Parameters=test_parameters, - Coordinates_box_0="ethane_box_0.pdb", - Structure_box_0="ethane_box_0.psf", - Coordinates_box_1="ethane_box_1.pdb", - Structure_box_1=test_box_1_psf, - ) - - def test_save_basic_NPT_use_ExpertMode(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane", - ff_filename="ethane", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_NPT_ExpertMode.conf", - "NPT", - 1000, - 500, - ExpertMode=True, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.25, - "RotFreq": 0.25, - "IntraSwapFreq": 0.25, - "SwapFreq": 0.0, - "RegrowthFreq": 0.25, - "VolFreq": 0.0, - }, - ) - - with open("test_save_basic_NPT_ExpertMode.conf", "r") as fp: - variables_read_dict = { - "ExpertMode": False, - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "RegrowthFreq": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("ExpertMode"): - variables_read_dict["ExpertMode"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - else: - pass - - assert variables_read_dict == { - "ExpertMode": True, - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "RegrowthFreq": True, - } - - def test_save_basic_GCMC_use_ExpertMode(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_GCMC_ExpertMode.conf", - "GCMC", - 1000, - 500, - ExpertMode=True, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.25, - "RotFreq": 0.25, - "IntraSwapFreq": 0.25, - "SwapFreq": 0.0, - "RegrowthFreq": 0.25, - "VolFreq": 0.0, - "Fugacity": {"ETH": 1.0}, - }, - ) - - with open("test_save_basic_GCMC_ExpertMode.conf", "r") as fp: - variables_read_dict = { - "ExpertMode": False, - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "RegrowthFreq": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("ExpertMode"): - variables_read_dict["ExpertMode"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - else: - pass - - assert variables_read_dict == { - "ExpertMode": True, - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "RegrowthFreq": True, - } - - def test_save_basic_GEMC_NVT_use_ExpertMode(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_GEMC_NVT_ExpertMode.conf", - "GEMC-NVT", - 1000, - 500, - ExpertMode=True, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.25, - "RotFreq": 0.25, - "IntraSwapFreq": 0.25, - "SwapFreq": 0.0, - "RegrowthFreq": 0.25, - "VolFreq": 0.0, - }, - ) - - with open("test_save_basic_GEMC_NVT_ExpertMode.conf", "r") as fp: - variables_read_dict = { - "ExpertMode": False, - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "RegrowthFreq": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("ExpertMode"): - variables_read_dict["ExpertMode"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - else: - pass - - assert variables_read_dict == { - "ExpertMode": True, - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "RegrowthFreq": True, - } - - def test_save_basic_GEMC_NPT_use_ExpertMode(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=test_box_ethane_gomc, - filename_box_1="ethane_box_1", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_GEMC_NPT_ExpertMode.conf", - "GEMC-NPT", - 1000, - 500, - ExpertMode=True, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.25, - "RotFreq": 0.25, - "IntraSwapFreq": 0.15, - "SwapFreq": 0.10, - "RegrowthFreq": 0.25, - "VolFreq": 0.0, - }, - ) - - with open("test_save_basic_GEMC_NPT_ExpertMode.conf", "r") as fp: - variables_read_dict = { - "ExpertMode": False, - "DisFreq": False, - "RotFreq": False, - "IntraSwapFreq": False, - "SwapFreq": False, - "RegrowthFreq": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("ExpertMode"): - variables_read_dict["ExpertMode"] = True - split_line = line.split() - assert split_line[1] == "True" - - elif line.startswith("DisFreq "): - variables_read_dict["DisFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("RotFreq "): - variables_read_dict["RotFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - elif line.startswith("IntraSwapFreq "): - variables_read_dict["IntraSwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.15" - - elif line.startswith("SwapFreq "): - variables_read_dict["SwapFreq"] = True - split_line = line.split() - assert split_line[1] == "0.1" - - elif line.startswith("RegrowthFreq "): - variables_read_dict["RegrowthFreq"] = True - split_line = line.split() - assert split_line[1] == "0.25" - - else: - pass - - assert variables_read_dict == { - "ExpertMode": True, - "DisFreq": True, - "RotFreq": True, - "IntraSwapFreq": True, - "SwapFreq": True, - "RegrowthFreq": True, - } - - def test_save_basic_GCMC_use_targetedswap_chempot( - self, ethane_gomc, ethanol_gomc - ): - test_box_ethane_gomc_ethanol_gomc = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[10, 10], - box=[2, 2, 2], - ) - charmm = Charmm( - test_box_ethane_gomc_ethanol_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=test_box_ethane_gomc_ethanol_gomc, - filename_box_1="ethane_box_1", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_GCMC_use_targetedswap_chempot.conf", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.10, - "SwapFreq": 0.10, - "RegrowthFreq": 0.20, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.10, - "IntraTargetedSwapFreq": 0.10, - "ChemPot": {"ETH": -444, "ETO": -555}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-2", 3, 4], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["all"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": -222, "ETO": -22}, - }, - 1: { - "SubVolumeType": "static", - "SubVolumeBox": 0, - "SubVolumeCenter": [2, 3, 4], - "SubVolumeDim": [4, 3, 2], - "SubVolumeResidueKind": "All", - "SubVolumeRigidSwap": False, - "SubVolumePBC": "XYZ", - "SubVolumeChemPot": {"ETH": -333, "ETO": -33}, - }, - }, - }, - ) - - with open( - "test_save_basic_GCMC_use_targetedswap_chempot.conf", "r" - ) as fp: - variables_read_dict = { - "TargetedSwapFreq": False, - "IntraTargetedSwapFreq": False, - "SubVolumeBox_number_0": False, - "SubVolumeCenterList_number_0": False, - "SubVolumeDim_number_0": False, - "SubVolumeResidueKind_number_0": False, - "SubVolumeRigidSwap_number_0": False, - "SubVolumePBC_number_0": False, - "SubVolumeChemPot_number_0_value_0": False, - "SubVolumeChemPot_number_0_value_1": False, - "SubVolumeBox_number_1": False, - "SubVolumeCenter_number_1": False, - "SubVolumeDim_number_1": False, - "SubVolumeResidueKind_number_1": False, - "SubVolumeRigidSwap_number_1": False, - "SubVolumePBC_number_1": False, - "SubVolumeChemPot_number_1_value_0": False, - "SubVolumeChemPot_number_1_value_1": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("TargetedSwapFreq "): - split_line = line.split() - assert split_line[1] == "0.1" - variables_read_dict["TargetedSwapFreq"] = True - - elif line.startswith("IntraTargetedSwapFreq "): - split_line = line.split() - assert split_line[1] == "0.1" - variables_read_dict["IntraTargetedSwapFreq"] = True - - elif line.startswith("SubVolumeBox "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "0" - variables_read_dict["SubVolumeBox_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "0" - variables_read_dict["SubVolumeBox_number_1"] = True - - elif line.startswith("SubVolumeCenterList "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "1-2" - assert split_line[3] == "3" - assert split_line[4] == "4" - variables_read_dict[ - "SubVolumeCenterList_number_0" - ] = True - - elif line.startswith("SubVolumeCenter "): - split_line = line.split() - if split_line[1] == "1": - assert split_line[2] == "2" - assert split_line[3] == "3" - assert split_line[4] == "4" - variables_read_dict["SubVolumeCenter_number_1"] = True - - elif line.startswith("SubVolumeDim "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "3" - assert split_line[3] == "2" - assert split_line[4] == "1" - variables_read_dict["SubVolumeDim_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "4" - assert split_line[3] == "3" - assert split_line[4] == "2" - variables_read_dict["SubVolumeDim_number_1"] = True - - elif line.startswith("SubVolumeResidueKind "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "ALL" - variables_read_dict[ - "SubVolumeResidueKind_number_0" - ] = True - if split_line[1] == "1": - assert split_line[2] == "ALL" - variables_read_dict[ - "SubVolumeResidueKind_number_1" - ] = True - - elif line.startswith("SubVolumeRigidSwap "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "True" - variables_read_dict[ - "SubVolumeRigidSwap_number_0" - ] = True - if split_line[1] == "1": - assert split_line[2] == "False" - variables_read_dict[ - "SubVolumeRigidSwap_number_1" - ] = True - - elif line.startswith("SubVolumePBC "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "XY" - variables_read_dict["SubVolumePBC_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "XYZ" - variables_read_dict["SubVolumePBC_number_1"] = True - - elif line.startswith("SubVolumeChemPot "): - split_line = line.split() - if split_line[1] == "0" and split_line[2] == "ETH": - assert split_line[3] == "-222" - variables_read_dict[ - "SubVolumeChemPot_number_0_value_0" - ] = True - if split_line[1] == "0" and split_line[2] == "ETO": - assert split_line[3] == "-22" - variables_read_dict[ - "SubVolumeChemPot_number_0_value_1" - ] = True - if split_line[1] == "1" and split_line[2] == "ETH": - assert split_line[3] == "-333" - variables_read_dict[ - "SubVolumeChemPot_number_1_value_0" - ] = True - if split_line[1] == "1" and split_line[2] == "ETO": - assert split_line[3] == "-33" - variables_read_dict[ - "SubVolumeChemPot_number_1_value_1" - ] = True - - else: - pass - - assert variables_read_dict == { - "TargetedSwapFreq": True, - "IntraTargetedSwapFreq": True, - "SubVolumeBox_number_0": True, - "SubVolumeCenterList_number_0": True, - "SubVolumeDim_number_0": True, - "SubVolumeResidueKind_number_0": True, - "SubVolumeRigidSwap_number_0": True, - "SubVolumePBC_number_0": True, - "SubVolumeChemPot_number_0_value_0": True, - "SubVolumeChemPot_number_0_value_1": True, - "SubVolumeBox_number_1": True, - "SubVolumeCenter_number_1": True, - "SubVolumeDim_number_1": True, - "SubVolumeResidueKind_number_1": True, - "SubVolumeRigidSwap_number_1": True, - "SubVolumePBC_number_1": True, - "SubVolumeChemPot_number_1_value_0": True, - "SubVolumeChemPot_number_1_value_1": True, - } - - def test_save_basic_GCMC_use_targetedswap_fugacity( - self, ethane_gomc, ethanol_gomc - ): - test_box_ethane_gomc_ethanol_gomc = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[10, 10], - box=[2, 2, 2], - ) - charmm = Charmm( - test_box_ethane_gomc_ethanol_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=test_box_ethane_gomc_ethanol_gomc, - filename_box_1="ethane_box_1", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_GCMC_use_targetedswap_fugacity.conf", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.10, - "SwapFreq": 0.10, - "RegrowthFreq": 0.20, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.10, - "IntraTargetedSwapFreq": 0.10, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": False, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - 1: { - "SubVolumeType": "static", - "SubVolumeBox": 0, - "SubVolumeCenter": [2, 3, 4], - "SubVolumeDim": [4, 3, 2], - "SubVolumeResidueKind": "ETH", - "SubVolumeFugacity": {"ETH": 3.33}, - }, - }, - }, - ) - - with open( - "test_save_basic_GCMC_use_targetedswap_fugacity.conf", "r" - ) as fp: - variables_read_dict = { - "TargetedSwapFreq": False, - "IntraTargetedSwapFreq": False, - "SubVolumeBox_number_0": False, - "SubVolumeCenterList_number_0": False, - "SubVolumeDim_number_0": False, - "SubVolumeResidueKind_number_0": False, - "SubVolumeRigidSwap_number_0": False, - "SubVolumePBC_number_0": False, - "SubVolumeFugacity_number_0_value_0": False, - "SubVolumeFugacity_number_0_value_1": False, - "SubVolumeBox_number_1": False, - "SubVolumeCenter_number_1": False, - "SubVolumeDim_number_1": False, - "SubVolumeResidueKind_number_1": False, - "SubVolumeRigidSwap_number_1": False, - "SubVolumePBC_number_1": False, - "SubVolumeFugacity_number_1_value_0": False, - } - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("TargetedSwapFreq "): - split_line = line.split() - assert split_line[1] == "0.1" - variables_read_dict["TargetedSwapFreq"] = True - - elif line.startswith("IntraTargetedSwapFreq "): - split_line = line.split() - assert split_line[1] == "0.1" - variables_read_dict["IntraTargetedSwapFreq"] = True - - elif line.startswith("SubVolumeBox "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "0" - variables_read_dict["SubVolumeBox_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "0" - variables_read_dict["SubVolumeBox_number_1"] = True - - elif line.startswith("SubVolumeCenterList "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "1-6" - assert split_line[3] == "7" - assert split_line[4] == "8" - variables_read_dict[ - "SubVolumeCenterList_number_0" - ] = True - - elif line.startswith("SubVolumeCenter "): - split_line = line.split() - if split_line[1] == "1": - assert split_line[2] == "2" - assert split_line[3] == "3" - assert split_line[4] == "4" - variables_read_dict["SubVolumeCenter_number_1"] = True - - elif line.startswith("SubVolumeDim "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "3" - assert split_line[3] == "2" - assert split_line[4] == "1" - variables_read_dict["SubVolumeDim_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "4" - assert split_line[3] == "3" - assert split_line[4] == "2" - variables_read_dict["SubVolumeDim_number_1"] = True - - elif line.startswith("SubVolumeResidueKind "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "ETH" - assert split_line[3] == "ETO" - variables_read_dict[ - "SubVolumeResidueKind_number_0" - ] = True - if split_line[1] == "1": - assert split_line[2] == "ETH" - variables_read_dict[ - "SubVolumeResidueKind_number_1" - ] = True - - elif line.startswith("SubVolumeRigidSwap "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "False" - variables_read_dict[ - "SubVolumeRigidSwap_number_0" - ] = True - if split_line[1] == "1": - assert split_line[2] == "True" - variables_read_dict[ - "SubVolumeRigidSwap_number_1" - ] = True - - elif line.startswith("SubVolumePBC "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "XY" - variables_read_dict["SubVolumePBC_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "XYZ" - variables_read_dict["SubVolumePBC_number_1"] = True - - elif line.startswith("SubVolumeFugacity "): - split_line = line.split() - if split_line[1] == "0" and split_line[2] == "ETH": - assert split_line[3] == "2.22" - variables_read_dict[ - "SubVolumeFugacity_number_0_value_0" - ] = True - if split_line[1] == "0" and split_line[2] == "ETO": - assert split_line[3] == "0.22" - variables_read_dict[ - "SubVolumeFugacity_number_0_value_1" - ] = True - if split_line[1] == "1" and split_line[2] == "ETH": - assert split_line[3] == "3.33" - variables_read_dict[ - "SubVolumeFugacity_number_1_value_0" - ] = True - - else: - pass - - assert variables_read_dict == { - "TargetedSwapFreq": True, - "IntraTargetedSwapFreq": True, - "SubVolumeBox_number_0": True, - "SubVolumeCenterList_number_0": True, - "SubVolumeDim_number_0": True, - "SubVolumeResidueKind_number_0": True, - "SubVolumeRigidSwap_number_0": True, - "SubVolumePBC_number_0": True, - "SubVolumeFugacity_number_0_value_0": True, - "SubVolumeFugacity_number_0_value_1": True, - "SubVolumeBox_number_1": True, - "SubVolumeCenter_number_1": True, - "SubVolumeDim_number_1": True, - "SubVolumeResidueKind_number_1": True, - "SubVolumeRigidSwap_number_1": True, - "SubVolumePBC_number_1": True, - "SubVolumeFugacity_number_1_value_0": True, - } - - def test_save_basic_GEMC_NVT_use_targetedswap( - self, ethane_gomc, ethanol_gomc - ): - test_box_ethane_gomc_ethanol_gomc = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[10, 10], - box=[2, 2, 2], - ) - charmm = Charmm( - test_box_ethane_gomc_ethanol_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=test_box_ethane_gomc_ethanol_gomc, - filename_box_1="ethane_box_1", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_GEMC_NVT_use_targetedswap.conf", - "GEMC_NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "IPC": True, - "LRC": False, - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.10, - "SwapFreq": 0.10, - "RegrowthFreq": 0.20, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.10, - "IntraTargetedSwapFreq": 0.10, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - 1: { - "SubVolumeType": "static", - "SubVolumeBox": 1, - "SubVolumeCenter": [2, 3, 4], - "SubVolumeDim": [4, 3, 2], - "SubVolumeResidueKind": "ETH", - "SubVolumeRigidSwap": False, - "SubVolumePBC": "XYZ", - }, - }, - }, - ) - - with open("test_save_basic_GEMC_NVT_use_targetedswap.conf", "r") as fp: - variables_read_dict = { - "IPC": False, - "LRC": False, - "TargetedSwapFreq": False, - "IntraTargetedSwapFreq": False, - "SubVolumeBox_number_0": False, - "SubVolumeCenterList_number_0": False, - "SubVolumeDim_number_0": False, - "SubVolumeResidueKind_number_0": False, - "SubVolumeRigidSwap_number_0": False, - "SubVolumePBC_number_0": False, - "SubVolumeBox_number_1": False, - "SubVolumeCenter_number_1": False, - "SubVolumeDim_number_1": False, - "SubVolumeResidueKind_number_1": False, - "SubVolumeRigidSwap_number_1": False, - "SubVolumePBC_number_1": False, - } - - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("IPC "): - split_line = line.split() - assert split_line[1] == "True" - variables_read_dict["IPC"] = True - - elif line.startswith("LRC "): - split_line = line.split() - assert split_line[1] == "False" - variables_read_dict["LRC"] = True - - elif line.startswith("TargetedSwapFreq "): - split_line = line.split() - assert split_line[1] == "0.1" - variables_read_dict["TargetedSwapFreq"] = True - - elif line.startswith("IntraTargetedSwapFreq "): - split_line = line.split() - assert split_line[1] == "0.1" - variables_read_dict["IntraTargetedSwapFreq"] = True - - elif line.startswith("SubVolumeBox "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "0" - variables_read_dict["SubVolumeBox_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "1" - variables_read_dict["SubVolumeBox_number_1"] = True - - elif line.startswith("SubVolumeCenterList "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "1-6" - assert split_line[3] == "7" - assert split_line[4] == "8" - variables_read_dict[ - "SubVolumeCenterList_number_0" - ] = True - - elif line.startswith("SubVolumeCenter "): - split_line = line.split() - if split_line[1] == "1": - assert split_line[2] == "2" - assert split_line[3] == "3" - assert split_line[4] == "4" - variables_read_dict["SubVolumeCenter_number_1"] = True - - elif line.startswith("SubVolumeDim "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "3" - assert split_line[3] == "2" - assert split_line[4] == "1" - variables_read_dict["SubVolumeDim_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "4" - assert split_line[3] == "3" - assert split_line[4] == "2" - variables_read_dict["SubVolumeDim_number_1"] = True - - elif line.startswith("SubVolumeResidueKind "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "ETH" - assert split_line[3] == "ETO" - variables_read_dict[ - "SubVolumeResidueKind_number_0" - ] = True - if split_line[1] == "1": - assert split_line[2] == "ETH" - variables_read_dict[ - "SubVolumeResidueKind_number_1" - ] = True - - elif line.startswith("SubVolumeRigidSwap "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "True" - variables_read_dict[ - "SubVolumeRigidSwap_number_0" - ] = True - if split_line[1] == "1": - assert split_line[2] == "False" - variables_read_dict[ - "SubVolumeRigidSwap_number_1" - ] = True - - elif line.startswith("SubVolumePBC "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "XY" - variables_read_dict["SubVolumePBC_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "XYZ" - variables_read_dict["SubVolumePBC_number_1"] = True - - else: - pass - - assert variables_read_dict == { - "IPC": True, - "LRC": True, - "TargetedSwapFreq": True, - "IntraTargetedSwapFreq": True, - "SubVolumeBox_number_0": True, - "SubVolumeCenterList_number_0": True, - "SubVolumeDim_number_0": True, - "SubVolumeResidueKind_number_0": True, - "SubVolumeRigidSwap_number_0": True, - "SubVolumePBC_number_0": True, - "SubVolumeBox_number_1": True, - "SubVolumeCenter_number_1": True, - "SubVolumeDim_number_1": True, - "SubVolumeResidueKind_number_1": True, - "SubVolumeRigidSwap_number_1": True, - "SubVolumePBC_number_1": True, - } - - def test_save_basic_NVT_use_targetedswap(self, ethane_gomc, ethanol_gomc): - test_box_ethane_gomc_ethanol_gomc = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[10, 10], - box=[2, 2, 2], - ) - charmm = Charmm( - test_box_ethane_gomc_ethanol_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=None, - filename_box_1=None, - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - gomc_control.write_gomc_control_file( - charmm, - "test_save_basic_NVT_use_targetedswap.conf", - "NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.10, - "SwapFreq": 0.00, - "RegrowthFreq": 0.20, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.00, - "IntraTargetedSwapFreq": 0.30, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - 1: { - "SubVolumeType": "static", - "SubVolumeBox": 0, - "SubVolumeCenter": [2, 3, 4], - "SubVolumeDim": [4, 3, 2], - "SubVolumeResidueKind": "ETH", - "SubVolumeRigidSwap": False, - "SubVolumePBC": "XYZ", - }, - }, - }, - ) - - with open("test_save_basic_NVT_use_targetedswap.conf", "r") as fp: - variables_read_dict = { - "IntraTargetedSwapFreq": False, - "SubVolumeBox_number_0": False, - "SubVolumeCenterList_number_0": False, - "SubVolumeDim_number_0": False, - "SubVolumeResidueKind_number_0": False, - "SubVolumeRigidSwap_number_0": False, - "SubVolumePBC_number_0": False, - "SubVolumeBox_number_1": False, - "SubVolumeCenter_number_1": False, - "SubVolumeDim_number_1": False, - "SubVolumeResidueKind_number_1": False, - "SubVolumeRigidSwap_number_1": False, - "SubVolumePBC_number_1": False, - } - - out_gomc = fp.readlines() - for i, line in enumerate(out_gomc): - if line.startswith("IntraTargetedSwapFreq "): - split_line = line.split() - assert split_line[1] == "0.3" - variables_read_dict["IntraTargetedSwapFreq"] = True - - elif line.startswith("SubVolumeBox "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "0" - variables_read_dict["SubVolumeBox_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "0" - variables_read_dict["SubVolumeBox_number_1"] = True - - elif line.startswith("SubVolumeCenterList "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "1-6" - assert split_line[3] == "7" - assert split_line[4] == "8" - variables_read_dict[ - "SubVolumeCenterList_number_0" - ] = True - - elif line.startswith("SubVolumeCenter "): - split_line = line.split() - if split_line[1] == "1": - assert split_line[2] == "2" - assert split_line[3] == "3" - assert split_line[4] == "4" - variables_read_dict["SubVolumeCenter_number_1"] = True - - elif line.startswith("SubVolumeDim "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "3" - assert split_line[3] == "2" - assert split_line[4] == "1" - variables_read_dict["SubVolumeDim_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "4" - assert split_line[3] == "3" - assert split_line[4] == "2" - variables_read_dict["SubVolumeDim_number_1"] = True - - elif line.startswith("SubVolumeResidueKind "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "ETH" - assert split_line[3] == "ETO" - variables_read_dict[ - "SubVolumeResidueKind_number_0" - ] = True - if split_line[1] == "1": - assert split_line[2] == "ETH" - variables_read_dict[ - "SubVolumeResidueKind_number_1" - ] = True - - elif line.startswith("SubVolumeRigidSwap "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "True" - variables_read_dict[ - "SubVolumeRigidSwap_number_0" - ] = True - if split_line[1] == "1": - assert split_line[2] == "False" - variables_read_dict[ - "SubVolumeRigidSwap_number_1" - ] = True - - elif line.startswith("SubVolumePBC "): - split_line = line.split() - if split_line[1] == "0": - assert split_line[2] == "XY" - variables_read_dict["SubVolumePBC_number_0"] = True - if split_line[1] == "1": - assert split_line[2] == "XYZ" - variables_read_dict["SubVolumePBC_number_1"] = True - - else: - pass - - assert variables_read_dict == { - "IntraTargetedSwapFreq": True, - "SubVolumeBox_number_0": True, - "SubVolumeCenterList_number_0": True, - "SubVolumeDim_number_0": True, - "SubVolumeResidueKind_number_0": True, - "SubVolumeRigidSwap_number_0": True, - "SubVolumePBC_number_0": True, - "SubVolumeBox_number_1": True, - "SubVolumeCenter_number_1": True, - "SubVolumeDim_number_1": True, - "SubVolumeResidueKind_number_1": True, - "SubVolumeRigidSwap_number_1": True, - "SubVolumePBC_number_1": True, - } - - def test_failures_targetedswap_GCMC(self, ethane_gomc, ethanol_gomc): - test_box_ethane_gomc_ethanol_gomc = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[10, 10], - box=[2, 2, 2], - ) - - charmm = Charmm( - test_box_ethane_gomc_ethanol_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=test_box_ethane_gomc_ethanol_gomc, - filename_box_1="ethane_box_1", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The TargetedSwap_DataInput variable is equal to None, " - r"but the TargetedSwapFreq or IntraTargetedSwapFreq move ratio is non-zero.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.00, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.20, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - }, - ) - - with pytest.raises( - ValueError, - match=r"The TargetedSwap_DataInput is not formatted correctly as a dictionary" - r" or has the wrong input keys, values, or types.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - "x": { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumefugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumetype'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "s", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumetype'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": 0, - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumebox'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": "x", - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumebox'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 2, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumebox'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": ["s"], - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenterlist'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6.0", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenterlist'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenterlist'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": 3, - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenterlist'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": "x", - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenterlist'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": "x", - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": -2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumedim'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [-3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumedim'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": ["s", 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumedim'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": "s", - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumedim'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [1, 2, 3, 4], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumeresiduekind'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": [0, "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumeresiduekind'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": "x", - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumeresiduekind'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": 0, - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumeresiduekind'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["x"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumerigidswap'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": 0, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumerigidswap'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": "s", - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumerigidswap'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": [True], - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumepbc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "s", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumepbc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": 0, - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumepbc'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": [0], - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumefugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"X": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumefugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ET": -2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumefugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ET": 2.22, "ETO": "x"}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumefugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": ["s"], - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumefugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": "s", - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumefugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": 1, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match="Both ChemPot and Fugacity were used in the " - "TargetedSwap_DataInput dictionaries " - "and in the standard GOMC swap inputs. " - "However, only ChemPot or Fugacity may be used, not both.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match="Both ChemPot and Fugacity were used in the " - "TargetedSwap_DataInput dictionaries " - "and in the standard GOMC swap inputs. " - "However, only ChemPot or Fugacity may be used, not both.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match="Both ChemPot and Fugacity were used in the " - "TargetedSwap_DataInput dictionaries. " - "However, only ChemPot or Fugacity may be used, not both.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 2.22, "ETO": 0.22}, - "SubVolumeChemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenter'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "static", - "SubVolumeBox": 0, - "SubVolumeCenter": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenter'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "subVolumetype": "static", - "subVolumeBox": 0, - "SubVolumecenter": 0, - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumechemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenter'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "static", - "SubVolumeBox": 0, - "SubVolumeCenter": "0", - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - # missing the subvolumecenter variable - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenter'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "static", - "SubVolumeBox": 0, - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - # missing the subvolumecenterlist variable - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenterlist'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "Swapfreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH"], - "SubVolumeRigidSwap": True, - "SubVolumepbc": "XY", - "SubVolumechemPot": {"ETH": 4.44}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenter'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "static", - "SubVolumeBox": 0, - "SubVolumeCenter": [1, 1, 1, 1], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": "All", - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"The TargetedSwap_DataInput is not formatted correctly as a dictionary" - r" or has the wrong input keys, values, or types.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - 0: "static", - "SubVolumeBox": 0, - "SubVolumeCenter": [1, 1, 1], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": "all", - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"The TargetedSwap_DataInput is not formatted correctly as a dictionary" - r" or has the wrong input keys, values, or types.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "static", - "SubVolumeBox": 0, - "SubVolumeCenter": [1, 1, 1], - "x": [3, 2, 1], - "SubVolumeResidueKind": "ETH", - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": 4.44}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"The TargetedSwap_DataInput is not formatted correctly as a dictionary" - r" or has the wrong input keys, values, or types.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "Subvolumebox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [1, 1, 1], - "SubVolumeresidueKind": ["ETH", "ETO"], - "SubVolumeRigidswap": True, - "Subvolume": "XY", - "SubVolumeChemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumeresiduekind'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "Subvolumebox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [1, 1, 1], - "SubVolumeresidueKind": ["ETO"], - "SubVolumeRigidswap": True, - "SubvolumePBC": "XY", - "SubVolumeChemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumeresiduekind'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "Subvolumebox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [1, 1, 1], - "SubVolumeresidueKind": "ETH", - "SubVolumeRigidswap": True, - "SubvolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumebox'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "Subvolumebox": 1, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [1, 1, 1], - "SubVolumeresidueKind": "all", - "SubVolumeRigidswap": True, - "SubvolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumebox'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.10, - "IntraTargetedSwapFreq": 0.10, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "Subvolumebox": 1, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [1, 1, 1], - "SubVolumeresidueKind": "all", - "SubVolumeRigidswap": True, - "SubVolumeFugacity": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - # "SubVolumeFugacity" not a list - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumefugacity'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.10, - "IntraTargetedSwapFreq": 0.10, - "Fugacity": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "Subvolumebox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [1, 1, 1], - "SubVolumeresidueKind": "all", - "SubVolumeRigidswap": True, - "SubVolumeFugacity": ["ETH"], - }, - }, - }, - ) - - # "SubVolumeFugacity" not a list - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumechempot'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GCMC", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.10, - "IntraTargetedSwapFreq": 0.10, - "ChemPot": {"ETH": 4.44, "ETO": 5.55}, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "Subvolumebox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [1, 1, 1], - "SubVolumeresidueKind": "all", - "SubVolumeRigidswap": True, - "SubVolumeChemPot": ["ETH"], - }, - }, - }, - ) - - def test_failures_targetedswap_GEMC_NVT(self, ethane_gomc, ethanol_gomc): - test_box_ethane_gomc_ethanol_gomc = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[10, 10], - box=[2, 2, 2], - ) - - charmm = Charmm( - test_box_ethane_gomc_ethanol_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=test_box_ethane_gomc_ethanol_gomc, - filename_box_1="ethane_box_1", - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The TargetedSwap_DataInput variable is equal to None, " - r"but the TargetedSwapFreq or IntraTargetedSwapFreq move ratio is non-zero.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GEMC_NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.00, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.20, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.10, - "IntraTargetedSwapFreq": 0.10, - }, - ) - - with pytest.raises( - ValueError, - match=r"The TargetedSwap_DataInput is not formatted correctly as a dictionary" - r" or has the wrong input keys, values, or types.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GEMC_NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - "x": { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match="Either the ChemPot and Fugacity were used in the " - "TargetedSwap_DataInput dictionaries, " - "which can not be used for the 'NPT', 'NVT', 'GEMC_NVT', " - "or 'GEMC_NPT' ensembles.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GEMC_NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeChemPot": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - # This is missing the "SubVolumeDim" in the "TargetedSwap_DataInput" - with pytest.raises( - ValueError, - match=f"The TargetedSwap_DataInput dictionaries do not have all the required " - f"keys or inputs per the subvolumetype and specified ensemble. " - f"Remember that the 'subvolumetype' values are 'static' and 'dynamic', " - f"which must only have the cooresponding " - f"'subvolumecenter' and 'subvolumecenterlist' values, respectively," - f" in each subvolume.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GEMC_NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "static", - "SubVolumeBox": 1, - "SubVolumeCenter": [1, 7, 8], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - }, - }, - ) - - # This box "SubVolumeBox" is not 0 or 1 - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumebox'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "GEMC_NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.20, - "SwapFreq": 0.20, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "static", - "SubVolumeBox": 4, - "SubVolumeCenter": [1, 7, 8], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - }, - }, - ) - - def test_failures_targetedswap_NVT(self, ethane_gomc, ethanol_gomc): - test_box_ethane_gomc_ethanol_gomc = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - n_compounds=[10, 10], - box=[2, 2, 2], - ) - - charmm = Charmm( - test_box_ethane_gomc_ethanol_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=None, - filename_box_1=None, - residues=[ethane_gomc.name, ethanol_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The TargetedSwap_DataInput variable is equal to None, " - r"but the TargetedSwapFreq or IntraTargetedSwapFreq move ratio is non-zero.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.00, - "RotFreq": 0.20, - "IntraSwapFreq": 0.40, - "SwapFreq": 0.00, - "RegrowthFreq": 0.20, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.00, - "IntraTargetedSwapFreq": 0.20, - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumebox'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.40, - "SwapFreq": 0.00, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.00, - "IntraTargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 1, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - }, - }, - ) - - with pytest.raises( - ValueError, - match="Either the ChemPot and Fugacity were used in the " - "TargetedSwap_DataInput dictionaries, " - "which can not be used for the 'NPT', 'NVT', 'GEMC_NVT', " - "or 'GEMC_NPT' ensembles.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.40, - "SwapFreq": 0.00, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.00, - "IntraTargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - "SubVolumeFugacity": {"ETH": 4.44, "ETO": 5.55}, - }, - }, - }, - ) - - # This is missing the "SubVolumeDim" in the "TargetedSwap_DataInput" - with pytest.raises( - ValueError, - match=f"The TargetedSwap_DataInput dictionaries do not have all the required " - f"keys or inputs per the subvolumetype and specified ensemble. " - f"Remember that the 'subvolumetype' values are 'static' and 'dynamic', " - f"which must only have the cooresponding " - f"'subvolumecenter' and 'subvolumecenterlist' values, respectively," - f" in each subvolume.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.40, - "SwapFreq": 0.00, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.00, - "IntraTargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": ["1-6", 7, 8], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - }, - }, - ) - - # TargetedSwap_DataInput is a list not a dict - with pytest.raises( - ValueError, - match="The TargetedSwap_DataInput is not formatted correctly as a dictionary" - " or has the wrong input keys, values, or types.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.40, - "SwapFreq": 0.00, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.00, - "IntraTargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": ["s"], - }, - ) - - # This "SubVolumeCenterList" is negative - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenterlist'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.40, - "SwapFreq": 0.00, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.00, - "IntraTargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": [-7, 8, "1-6"], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - }, - }, - ) - - # This "SubVolumeCenterList" is missing a value in the - separator - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenterlist'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.40, - "SwapFreq": 0.00, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.00, - "IntraTargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": [1, 8, "1-"], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - }, - }, - ) - - # This "SubVolumeCenterList" is same value on both sides of - symbol - with pytest.raises( - ValueError, - match=r"ERROR: The following input variables have " - r"bad values \(check spelling and for empty spaces in the keys or that " - r"the values are in the correct form with the acceptable values\)" - r": \['subvolumecenterlist'\]", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_failures_targetedswap", - "NVT", - 1000, - 500, - ExpertMode=False, - check_input_files_exist=False, - input_variables_dict={ - "DisFreq": 0.20, - "RotFreq": 0.20, - "IntraSwapFreq": 0.40, - "SwapFreq": 0.00, - "RegrowthFreq": 0.00, - "VolFreq": 0.0, - "TargetedSwapFreq": 0.00, - "IntraTargetedSwapFreq": 0.20, - "TargetedSwap_DataInput": { - 0: { - "SubVolumeType": "dynamic", - "SubVolumeBox": 0, - "SubVolumeCenterList": [1, 8, "1-1"], - "SubVolumeDim": [3, 2, 1], - "SubVolumeResidueKind": ["ETH", "ETO"], - "SubVolumeRigidSwap": True, - "SubVolumePBC": "XY", - }, - }, - }, - ) - - def test_IPC_input_errors(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[1, 1, 1] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - structure_box_1=None, - filename_box_1=None, - ff_filename="ethane_FF", - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The impulse correction term \(IPC\) can not be set as True " - r"if the LRC=True or the Potential is SHIFT or SWITCH.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_IPC_input_errors", - "NVT", - 1000, - 300, - check_input_files_exist=False, - input_variables_dict={ - "IPC": True, - "LRC": True, - "Potential": "VDW", - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The impulse correction term \(IPC\) can not be set as True " - r"if the LRC=True or the Potential is SHIFT or SWITCH.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_IPC_input_errors", - "NVT", - 1000, - 300, - check_input_files_exist=False, - input_variables_dict={ - "IPC": True, - "LRC": False, - "Potential": "SHIFT", - }, - ) - - with pytest.raises( - ValueError, - match=r"ERROR: The impulse correction term \(IPC\) can not be set as True " - r"if the LRC=True or the Potential is SHIFT or SWITCH.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_IPC_input_errors", - "NVT", - 1000, - 300, - check_input_files_exist=False, - input_variables_dict={ - "IPC": True, - "LRC": False, - "Potential": "SWITCH", - }, - ) - - with pytest.warns( - UserWarning, - match=r"WARNING: The impulse correction term \(IPC\) is False, but likely needs to be True, " - r"as the LRC=False when the Potential is VDW or EXP6.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_IPC_input_errors", - "NVT", - 1000, - 300, - check_input_files_exist=False, - input_variables_dict={ - "IPC": False, - "LRC": False, - "Potential": "VDW", - }, - ) - - with pytest.warns( - UserWarning, - match=r"WARNING: The impulse correction term \(IPC\) is False, but likely needs to be True, " - r"as the LRC=False when the Potential is VDW or EXP6.", - ): - gomc_control.write_gomc_control_file( - charmm, - "test_IPC_input_errors", - "NVT", - 1000, - 300, - check_input_files_exist=False, - input_variables_dict={ - "IPC": False, - "LRC": False, - "Potential": "EXP6", - }, - ) - - def test_NVT_runstep_equibsteps_adjsteps(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 2, 2] - ) - charmm = Charmm( - test_box_ethane_gomc, - "ethane_box_0", - ff_filename="ethane", - structure_box_1=None, - filename_box_1=None, - residues=[ethane_gomc.name], - forcefield_selection="oplsaa", - ) - - run_steps = 10000 - equilb_steps = 10001 - adjust_steps = 1000 - with pytest.raises( - ValueError, - match=r"ERROR: When starting a simulation, the values must be in this order " - r"RunSteps > EqSteps >= AdjSteps " - "\({} > {} >= {}\)".format(run_steps, equilb_steps, adjust_steps), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_NVT_runstep_equibsteps_adjsteps.conf", - "NVT", - run_steps, - 500, - Restart=False, - check_input_files_exist=False, - input_variables_dict={ - "EqSteps": equilb_steps, - "AdjSteps": adjust_steps, - }, - ) - - run_steps = 10000 - equilb_steps = 1000 - adjust_steps = 1001 - with pytest.raises( - ValueError, - match=r"ERROR: When starting a simulation, the values must be in this order " - r"RunSteps > EqSteps >= AdjSteps " - "\({} > {} >= {}\)".format(run_steps, equilb_steps, adjust_steps), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_NVT_runstep_equibsteps_adjsteps.conf", - "NVT", - run_steps, - 500, - Restart=False, - check_input_files_exist=False, - input_variables_dict={ - "EqSteps": equilb_steps, - "AdjSteps": adjust_steps, - }, - ) - - run_steps = 100 - equilb_steps = 101 - adjust_steps = 1000 - with pytest.raises( - ValueError, - match=r"ERROR: When restarting a simulation, this must be true RunSteps > EqSteps " - "\({} > {}\)".format(run_steps, equilb_steps), - ): - gomc_control.write_gomc_control_file( - charmm, - "test_NVT_runstep_equibsteps_adjsteps.conf", - "NVT", - run_steps, - 500, - Restart=True, - check_input_files_exist=False, - input_variables_dict={ - "EqSteps": equilb_steps, - "AdjSteps": adjust_steps, - }, - ) diff --git a/mosdef_gomc/tests/test_specific_ff_to_residue.py b/mosdef_gomc/tests/test_specific_ff_to_residue.py deleted file mode 100644 index b19b3bc3..00000000 --- a/mosdef_gomc/tests/test_specific_ff_to_residue.py +++ /dev/null @@ -1,606 +0,0 @@ -import mbuild as mb -import pytest -from foyer.forcefields import forcefields -from gmso.exceptions import GMSOError -from mbuild import Box, Compound -from mbuild.utils.io import has_foyer - -from mosdef_gomc.tests.base_test import BaseTest -from mosdef_gomc.utils.gmso_specific_ff_to_residue import specific_ff_to_residue -from mosdef_gomc.utils.io import get_mosdef_gomc_fn - - -@pytest.mark.skipif(not has_foyer, reason="Foyer package not installed") -class TestSpecificFFToResidue(BaseTest): - # Tests for the mbuild.utils.specific_FF_to_residue.Specific_FF_to_residue() function - def test_specific_ff_ff_is_none(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"Please the force field selection \(forcefield_selection\) as a " - r"dictionary with all the residues specified to a force field " - '-> Ex: {"Water": "oplsaa", "OCT": "path/trappe-ua.xml"}, ' - "Note: the file path must be specified the force field file " - "or by using the standard force field name provided the `foyer` package.", - ): - box_0 = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - specific_ff_to_residue( - box_0, - forcefield_selection=None, - residues=[ethane_gomc.name], - boxes_for_simulation=1, - ) - - def test_specific_ff_wrong_ff_extention(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"Please make sure you are entering the correct " - r"foyer FF name and not a path to a FF file. " - r"If you are entering a path to a FF file, " - r"please use the forcefield_files variable with the " - r"proper XML extension \(.xml\).", - ): - box_0 = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - specific_ff_to_residue( - box_0, - forcefield_selection={ethane_gomc.name: "oplsaa.pdb"}, - residues=[ethane_gomc.name], - boxes_for_simulation=1, - ) - - def test_specific_all_residue_not_input(self, ethane_gomc, ethanol_gomc): - with pytest.raises( - GMSOError, - match=f"A particle named C cannot be associated with the\n " - f"custom_groups \['ETH'\]. " - f"Be sure to specify a list of group names that will cover\n " - f"all particles in the compound. This particle is one level below ETO.", - ): - box = mb.fill_box( - compound=[ethane_gomc, ethanol_gomc], - box=[1, 1, 1], - n_compounds=[1, 1], - ) - - specific_ff_to_residue( - box, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[ethane_gomc.name], - boxes_for_simulation=2, - ) - - def test_specific_ff_to_residue_ff_selection_not_dict(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"The force field selection \(forcefield_selection\) " - "is not a dictionary. Please enter a dictionary " - "with all the residues specified to a force field " - '-> Ex: {"Water": "oplsaa", "OCT": "path/trappe-ua.xml"}, ' - "Note: the file path must be specified the force field file " - "or by using the standard force field name provided the `foyer` package.", - ): - box_0 = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - specific_ff_to_residue( - box_0, - forcefield_selection="oplsaa", - residues=[ethane_gomc.name], - boxes_for_simulation=1, - ) - - def test_specific_ff_to_residue_is_none(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"Please enter the residues in the Specific_FF_to_residue function.", - ): - box_0 = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - specific_ff_to_residue( - box_0, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=None, - boxes_for_simulation=1, - ) - - def test_specific_ff_to_simulation_boxes_not_1_or_2(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"Please enter boxes_for_simulation equal the integer 1 or 2.", - ): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[2, 3, 4] - ) - - specific_ff_to_residue( - test_box_ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[ethane_gomc.name], - boxes_for_simulation=3, - ) - - def test_specific_ff_to_residue_ffselection_wrong_path(self, ethane_gomc): - with pytest.raises( - ValueError, - # match=r"FileNotFoundError: \[Errno 2\] No such file or directory: 'oplsaa.xml'" - match=r"Please make sure you are entering the correct foyer FF path, " - r"including the FF file name.xml. " - r"If you are using the pre-build FF files in foyer, " - r"only use the string name without any extension. " - r"The selected FF file could also could not formated properly, " - r"or there may be errors in the FF file itself.", - ): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 5, 6] - ) - - specific_ff_to_residue( - test_box_ethane_gomc, - forcefield_selection={ethane_gomc.name: "oplsaa.xml"}, - residues=[ethane_gomc.name], - boxes_for_simulation=1, - ) - - def test_specific_ff_wrong_path(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"Please make sure you are entering the correct foyer FF path, " - r"including the FF file name.xml. " - r"If you are using the pre-build FF files in foyer, " - r"only use the string name without any extension. " - r"The selected FF file could also could not formated properly, " - r"or there may be errors in the FF file itself.", - ): - box_0 = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - specific_ff_to_residue( - box_0, - forcefield_selection={ethane_gomc.name: "oplsaa.xml"}, - residues=[ethane_gomc.name], - boxes_for_simulation=1, - ) - - def test_specific_ff_to_residue_input_string_as_compound(self, ethane_gomc): - with pytest.raises( - TypeError, - match=r"ERROR: The structure expected to be of type: " - r" or , " - r"received: ", - ): - specific_ff_to_residue( - "ethane_gomc", - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[ethane_gomc.name], - boxes_for_simulation=1, - ) - - def test_specific_ff_to_residue_boxes_for_simulation_not_int( - self, ethane_gomc - ): - with pytest.raises( - TypeError, - match=r"ERROR: Please enter boxes_for_simulation equal " - "the integer 1 or 2.", - ): - box_0 = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - specific_ff_to_residue( - box_0, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[ethane_gomc.name], - boxes_for_simulation=1.1, - ) - - def test_specific_ff_to_residues_no_ff(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"The forcefield_selection variable are not provided, " - r"but there are residues provided.", - ): - box_0 = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - specific_ff_to_residue( - box_0, - forcefield_selection={}, - residues=[ethane_gomc.name], - boxes_for_simulation=1, - ) - - def test_specific_ff_to_no_residues(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"The residues variable is an empty list but there are " - "forcefield_selection variables provided.", - ): - box_0 = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - specific_ff_to_residue( - box_0, - forcefield_selection={ethane_gomc.name: "oplsaa"}, - residues=[], - boxes_for_simulation=1, - ) - - def test_specific_ff_wrong_foyer_name(self, ethane_gomc): - with pytest.raises( - ValueError, - match=r"Please make sure you are entering the correct foyer FF name, " - r"or the correct file extension \(i.e., .xml, if required\).", - ): - box_0 = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 4, 4] - ) - - specific_ff_to_residue( - box_0, - forcefield_selection={ethane_gomc.name: "xxx"}, - residues=[ethane_gomc.name], - boxes_for_simulation=1, - ) - - def test_specific_ff_to_residue_ffselection_run(self, ethane_gomc): - test_box_ethane_gomc = mb.fill_box( - compound=[ethane_gomc], n_compounds=[1], box=[4, 5, 6] - ) - - [ - test_topology, - test_residues_applied_list, - test_electrostatics14Scale_dict, - test_nonBonded14Scale_dict, - test_atom_types_dict, - test_bond_types_dict, - test_angle_types_dict, - test_dihedral_types_dict, - test_improper_types_dict, - test_combining_rule_dict, - ] = specific_ff_to_residue( - test_box_ethane_gomc, - forcefield_selection={ - ethane_gomc.name: f"{forcefields.get_ff_path()[0]}/xml/oplsaa.xml" - }, - residues=[ethane_gomc.name], - boxes_for_simulation=1, - ) - assert test_electrostatics14Scale_dict == {"ETH": 0.5} - assert test_nonBonded14Scale_dict == {"ETH": 0.5} - assert test_residues_applied_list == ["ETH"] - - def test_specific_ff_to_no_atoms_no_box_dims_in_residue(self): - with pytest.raises( - TypeError, - match=r"ERROR: The structure, {} or {}, needs to have have box lengths and angles.".format( - type(Compound()), - type(Box(lengths=[1, 1, 1])), - ), - ): - empty_compound = mb.Compound() - - specific_ff_to_residue( - empty_compound, - forcefield_selection={"empty_compound": "oplsaa"}, - residues=[], - boxes_for_simulation=1, - ) - - def test_specific_ff_to_no_atoms_in_residue(self): - with pytest.raises( - ValueError, - match=r"The residues variable is an empty list but there " - r"are forcefield_selection variables provided.", - ): - empty_compound = mb.Compound() - empty_compound.box = Box([4, 4, 4]) - - specific_ff_to_residue( - empty_compound, - forcefield_selection={"empty_compound": "oplsaa"}, - residues=[], - boxes_for_simulation=1, - ) - - # this test is not usable until the individual mb.Compounds can be force fielded in MosDeF-GOMC - def test_charmm_empty_compound_test_no_children(self, methane_ua_gomc): - empty_box = mb.Compound() - empty_box.box = mb.Box(lengths=[4, 4, 4]) - - with pytest.raises( - TypeError, - match=r"ERROR: If you are not providing an empty box, " - r"you need to specify the atoms/beads as children in the mb.Compound. " - r"If you are providing and empty box, please do so by specifying and " - r"mbuild Box \({}\)".format(type(Box(lengths=[1, 1, 1]))), - ): - specific_ff_to_residue( - empty_box, - forcefield_selection={"AAA": "trappe-ua"}, - residues=["AAA"], - boxes_for_simulation=1, - ) - - def test_charmm_a_few_mbuild_layers(self, ethane_gomc, ethanol_gomc): - box_reservior_1 = mb.fill_box( - compound=[ethane_gomc], box=[1, 1, 1], n_compounds=[1] - ) - box_reservior_1.name = ethane_gomc.name - box_reservior_1.periodicity = (True, True, True) - box_reservior_2 = mb.fill_box( - compound=[ethanol_gomc], box=[1, 1, 1], n_compounds=[1] - ) - box_reservior_2.name = ethanol_gomc.name - box_reservior_2.translate([0, 0, 1]) - - box_reservior_3 = mb.Compound() - box_reservior_3.name = "A" - box_reservior_3.box = Box(lengths=[3, 3, 3]) - box_reservior_3.add(box_reservior_1, inherit_periodicity=False) - box_reservior_3.add(box_reservior_2, inherit_periodicity=False) - - [ - test_topology, - test_residues_applied_list, - test_electrostatics14Scale_dict, - test_nonBonded14Scale_dict, - test_atom_types_dict, - test_bond_types_dict, - test_angle_types_dict, - test_dihedral_types_dict, - test_improper_types_dict, - test_combining_rule_dict, - ] = specific_ff_to_residue( - box_reservior_3, - forcefield_selection={ - ethanol_gomc.name: "oplsaa", - ethane_gomc.name: "oplsaa", - # box_reservior_3.name: "oplsaa", - }, - residues=[ethanol_gomc.name, ethane_gomc.name], - # residues=[box_reservior_3.name], - boxes_for_simulation=1, - ) - - assert test_topology.n_sites == 17 - assert test_electrostatics14Scale_dict == {"ETO": 0.5, "ETH": 0.5} - assert test_nonBonded14Scale_dict == {"ETO": 0.5, "ETH": 0.5} - assert test_residues_applied_list.sort() == ["ETO", "ETH"].sort() - - def test_charmm_all_residues_not_in_dict_boxes_for_simulation_1( - self, ethane_gomc, ethanol_gomc - ): - with pytest.raises( - ValueError, - match=f"The {'ETO'} residues were not used from the forcefield_selection string or dictionary. " - "All the residues were not used from the forcefield_selection " - "string or dictionary. There may be residues below other " - "specified residues in the mbuild.Compound hierarchy. " - "If so, all the highest listed residues pass down the force " - "fields through the hierarchy. Alternatively, residues that " - "are not in the structure may have been specified. ", - ): - box_reservior_0 = mb.fill_box( - compound=[ethane_gomc], box=[1, 1, 1], n_compounds=[1] - ) - specific_ff_to_residue( - box_reservior_0, - forcefield_selection={ethanol_gomc.name: "oplsaa"}, - residues=[ethanol_gomc.name, ethane_gomc.name], - boxes_for_simulation=1, - ) - - def test_charmm_all_residues_not_in_dict_boxes_for_simulation_2( - self, ethane_gomc, ethanol_gomc - ): - with pytest.warns( - UserWarning, - match=f"The {'ETO'} residues were not used from the forcefield_selection string or dictionary. " - "All the residues were not used from the forcefield_selection " - "string or dictionary. There may be residues below other " - "specified residues in the mbuild.Compound hierarchy. " - "If so, all the highest listed residues pass down the force " - "fields through the hierarchy. Alternatively, residues that " - "are not in the structure may have been specified. " - f"NOTE: This warning will appear if you are using the CHARMM pdb and psf writers " - f"2 boxes, and the boxes do not contain all the residues in each box.", - ): - box_reservior_0 = mb.fill_box( - compound=[ethane_gomc], box=[1, 1, 1], n_compounds=[1] - ) - specific_ff_to_residue( - box_reservior_0, - forcefield_selection={ethanol_gomc.name: "oplsaa"}, - residues=[ethanol_gomc.name, ethane_gomc.name], - boxes_for_simulation=2, - ) - - def test_specific_ff_params_benzene_water_aa(self): - benzene_aa = mb.load(get_mosdef_gomc_fn("benzene_aa.mol2")) - benzene_aa.name = "BEN" - water_aa = mb.load("O", smiles=True) - water_aa.name = "WAT" - test_box = mb.fill_box( - compound=[benzene_aa, water_aa], n_compounds=[1, 1], box=[4, 4, 4] - ) - - [ - test_topology, - test_residues_applied_list, - test_electrostatics14Scale_dict, - test_nonBonded14Scale_dict, - test_atom_types_dict, - test_bond_types_dict, - test_angle_types_dict, - test_dihedral_types_dict, - test_improper_types_dict, - test_combining_rule_dict, - ] = specific_ff_to_residue( - test_box, - forcefield_selection={ - benzene_aa.name: f"{get_mosdef_gomc_fn('benzene_GAFF.xml')}", - water_aa.name: f"{get_mosdef_gomc_fn('gmso_spce_water__lorentz_combining.xml')}", - }, - residues=[benzene_aa.name, water_aa.name], - boxes_for_simulation=1, - ) - assert test_topology.n_sites == 15 - assert test_topology.n_bonds == 14 - assert test_topology.n_angles == 19 - assert test_topology.n_dihedrals == 24 - assert test_topology.n_impropers == 6 - - assert test_electrostatics14Scale_dict == {"BEN": 0.833333333, "WAT": 0} - assert test_nonBonded14Scale_dict == {"BEN": 0.5, "WAT": 0} - assert test_residues_applied_list == ["BEN", "WAT"] - assert test_combining_rule_dict == "lorentz" - - # atom tests - assert ( - str(test_atom_types_dict["BEN"]["expression"]) - == "4*epsilon*(-sigma**6/r**6 + sigma**12/r**12)" - ) - assert ( - len(list(test_atom_types_dict["BEN"]["atom_types"].yield_view())) - == 2 - ) - - assert ( - str(test_atom_types_dict["WAT"]["expression"]) - == "4*epsilon*(-sigma**6/r**6 + sigma**12/r**12)" - ) - assert ( - len(list(test_atom_types_dict["WAT"]["atom_types"].yield_view())) - == 2 - ) - - # bond tests - assert ( - str(test_bond_types_dict["BEN"]["expression"]) - == "k*(r - r_eq)**2/2" - ) - assert ( - len(list(test_bond_types_dict["BEN"]["bond_types"].yield_view())) - == 2 - ) - - assert ( - str(test_bond_types_dict["WAT"]["expression"]) == "k*(r - r_eq)**2" - ) - assert ( - len(list(test_bond_types_dict["WAT"]["bond_types"].yield_view())) - == 1 - ) - - # angle tests - assert ( - str(test_angle_types_dict["BEN"]["expression"]) - == "k*(theta - theta_eq)**2/2" - ) - assert ( - len(list(test_angle_types_dict["BEN"]["angle_types"].yield_view())) - == 2 - ) - - assert ( - str(test_angle_types_dict["WAT"]["expression"]) - == "k*(theta - theta_eq)**2" - ) - assert ( - len(list(test_angle_types_dict["WAT"]["angle_types"].yield_view())) - == 1 - ) - - # dihedral tests - assert ( - str(test_dihedral_types_dict["BEN"]["expression"]) - == "k*(cos(n*phi - phi_eq) + 1)" - ) - assert ( - len( - list( - test_dihedral_types_dict["BEN"][ - "dihedral_types" - ].yield_view() - ) - ) - == 3 - ) - - # improper tests - assert ( - str(test_improper_types_dict["BEN"]["expression"]) - == "k*(cos(n*phi - phi_eq) + 1)" - ) - assert ( - len( - list( - test_improper_types_dict["BEN"][ - "improper_types" - ].yield_view() - ) - ) - == 1 - ) - - def test_specific_ff_params_benzene_aa_grouped(self): - methane_ua_bead_name = "_CH4" - methane_child_bead = mb.Compound(name=methane_ua_bead_name) - methane_box = mb.fill_box( - compound=methane_child_bead, n_compounds=4, box=[1, 2, 3] - ) - methane_box.name = "MET" - - [ - test_topology, - test_residues_applied_list, - test_electrostatics14Scale_dict, - test_nonBonded14Scale_dict, - test_atom_types_dict, - test_bond_types_dict, - test_angle_types_dict, - test_dihedral_types_dict, - test_improper_types_dict, - test_combining_rule_dict, - ] = specific_ff_to_residue( - methane_box, - forcefield_selection={ - methane_box.name: "trappe-ua", - }, - residues=[methane_box.name], - gmso_match_ff_by="group", - boxes_for_simulation=1, - ) - assert test_topology.n_sites == 4 - assert test_topology.n_bonds == 0 - assert test_topology.n_angles == 0 - assert test_topology.n_dihedrals == 0 - assert test_topology.n_impropers == 0 - - assert test_electrostatics14Scale_dict == {"MET": 0} - assert test_nonBonded14Scale_dict == {"MET": 0} - assert test_residues_applied_list == ["MET"] - assert test_combining_rule_dict == "lorentz" - - # atom tests - assert ( - str(test_atom_types_dict["MET"]["expression"]) - == "4*epsilon*(-sigma**6/r**6 + sigma**12/r**12)" - ) - assert ( - len(list(test_atom_types_dict["MET"]["atom_types"].yield_view())) - == 1 - ) diff --git a/mosdef_gomc/utils/specific_ff_to_residue.py b/mosdef_gomc/utils/specific_ff_to_residue.py deleted file mode 100644 index 3d5b9023..00000000 --- a/mosdef_gomc/utils/specific_ff_to_residue.py +++ /dev/null @@ -1,419 +0,0 @@ -import os -from warnings import warn -from xml.dom import minidom - -import mbuild as mb -import parmed as pmd -from mbuild.compound import Compound -from mbuild.utils.io import has_foyer - - -def specific_ff_to_residue( - structure, - forcefield_selection=None, - residues=None, - reorder_res_in_pdb_psf=False, - boxes_for_simulation=1, -): - """ - Takes the mbuild Compound or mbuild Box structure and applies the selected - force field to the corresponding residue via foyer. - Note: a residue is defined as a molecule in this case, so it is not - designed for applying a force field to a protein. - - Parameters - ---------- - structure: mbuild Compound object or mbuild Box object; - The mBuild Compound object or mbuild Box object, which contains the molecules - (or empty box) that will have the force field applied to them. - forcefield_selection: str or dictionary, default=None - Apply a forcefield to the output file by selecting a force field xml file with - its path or by using the standard force field name provided the `foyer` package. - Example dict for FF file: {'ETH' : 'oplsaa.xml', 'OCT': 'path_to file/trappe-ua.xml'} - Example str for FF file: 'path_to file/trappe-ua.xml' - Example dict for standard FF names : {'ETH' : 'oplsaa', 'OCT': 'trappe-ua'} - Example str for standard FF names: 'trappe-ua' - Example of a mixed dict with both : {'ETH' : 'oplsaa', 'OCT': 'path_to file/'trappe-ua.xml'} - residues: list, [str, ..., str], default=None - Labels of unique residues in the Compound. Residues are assigned by - checking against Compound.name. Only supply residue names as 4 characters - strings, as the residue names are truncated to 4 characters to fit in the - psf and pdb file. - reorder_res_in_pdb_psf: bool, default=False - This option provides the ability to reorder the residues/molecules from the original - structure's order. If True, the residues will be reordered as they appear in the residues - variable. If False, the order will be the same as entered in the original structure. - boxes_for_simulation: int [1, 2], default = 1 - Gibbs (GEMC) or grand canonical (GCMC) ensembles are examples of where the boxes_for_simulation would be 2. - Canonical (NVT) or isothermal–isobaric (NPT) ensembles are example with the boxes_for_simulation equal to 1. - Note: the only valid options are 1 or 2. - - Returns - ------- - list, [structure, coulomb14scalar_dict, lj14_scalar_dict, residues_applied_list] - structure: parmed.Structure - parmed structure with applied force field - coulomb14scalar_dict: dict - a dictionary with the 1,4-colombic scalars for each residue - (i.e., a different force field could on each residue) - lj14_scalar_dict: dict - a dictionary with the 1,4-LJ scalars for each residue - (i.e., a different force field could on each residue) - residues_applied_list: list - list of residues (i.e., list of stings). - These are all the residues in which the force field actually applied - - Notes - ----- - To write the NAMD/GOMC force field, pdb, psf, and force field - (.inp) files, the residues and forcefields must be provided in - a str or dictionary. If a dictionary is provided all residues must - be specified to a force field if the boxes_for_simulation is equal to 1. - - Generating an empty box (i.e., pdb and psf files): - Enter residues = [], but the accompanying structure must be an empty mb.Box. - However, when doing this, the forcefield_selection must be supplied, - or it will provide an error (i.e., forcefield_selection can not be equal to None). - - In this current FF/psf/pdb writer, a residue type is essentially a molecule type. - Therefore, it can only correctly write systems where every bead/atom in the molecule - has the same residue name, and the residue name is specific to that molecule type. - For example: a protein molecule with many residue names is not currently supported, - but is planned to be supported in the future. - """ - - if has_foyer: - from foyer import Forcefield - from foyer.forcefields import forcefields - else: - print_error_message = ( - "Package foyer is not installed. " - "Please install it using conda install -c conda-forge foyer" - ) - raise ImportError(print_error_message) - - if not isinstance(structure, (Compound, mb.Box)): - print_error_message = ( - "ERROR: The structure expected to be of type: " - "{} or {}, received: {}".format( - type(Compound()), - type(mb.Box(lengths=[1, 1, 1])), - type(structure), - ) - ) - raise TypeError(print_error_message) - - print("forcefield_selection = " + str(forcefield_selection)) - if forcefield_selection is None: - print_error_message = ( - "Please the force field selection (forcefield_selection) as a dictionary " - "with all the residues specified to a force field " - '-> Ex: {"Water" : "oplsaa", "OCT": "path/trappe-ua.xml"}, ' - "Note: the file path must be specified the force field file " - "or by using the standard force field name provided the `foyer` package." - ) - raise TypeError(print_error_message) - - elif forcefield_selection is not None and not isinstance( - forcefield_selection, dict - ): - print_error_message = ( - "The force field selection (forcefield_selection) " - "is not a dictionary. Please enter a dictionary " - "with all the residues specified to a force field " - '-> Ex: {"Water" : "oplsaa", "OCT": "path/trappe-ua.xml"}, ' - "Note: the file path must be specified the force field file " - "or by using the standard force field name provided the `foyer` package." - ) - raise TypeError(print_error_message) - - if residues is None or not isinstance(residues, list): - print_error_message = ( - "Please enter the residues in the Specific_FF_to_residue function." - ) - raise TypeError(print_error_message) - - if not isinstance(reorder_res_in_pdb_psf, bool): - print_error_message = ( - "Please enter the reorder_res_in_pdb_psf " - "in the Specific_FF_to_residue function (i.e., True or False)." - ) - raise TypeError(print_error_message) - - print_error_message_for_boxes_for_simulatiion = ( - "ERROR: Please enter boxes_for_simulation equal " "the integer 1 or 2." - ) - if not isinstance(boxes_for_simulation, int): - raise TypeError(print_error_message_for_boxes_for_simulatiion) - - elif isinstance(boxes_for_simulation, int) and boxes_for_simulation not in [ - 1, - 2, - ]: - raise ValueError(print_error_message_for_boxes_for_simulatiion) - - forcefield_keys_list = [] - if forcefield_selection is not None: - for res in forcefield_selection.keys(): - forcefield_keys_list.append(res) - ff_data = forcefield_selection - - if forcefield_keys_list == [] and len(residues) != 0: - print_error_message = "The forcefield_selection variable are not provided, but there are residues provided." - raise ValueError(print_error_message) - - elif forcefield_keys_list != [] and len(residues) == 0: - print_error_message = ( - "The residues variable is an empty list but there are " - "forcefield_selection variables provided." - ) - raise ValueError(print_error_message) - - user_entered_ff_with_path_dict = ( - {} - ) # True means user entered the path, False is a standard foyer FF with no path - for z in range(0, len(forcefield_keys_list)): - for res_i in range(0, len(residues)): - if residues[res_i] == forcefield_keys_list[z]: - if ( - os.path.splitext(ff_data[forcefield_keys_list[z]])[1] - == ".xml" - and len(residues) != 0 - ): - user_entered_ff_with_path_dict.update( - {residues[res_i]: True} - ) - elif ( - os.path.splitext(ff_data[forcefield_keys_list[z]])[1] == "" - and len(residues) != 0 - ): - user_entered_ff_with_path_dict.update( - {residues[res_i]: False} - ) - else: - print_error_message = ( - r"Please make sure you are entering the correct " - "foyer FF name and not a path to a FF file. " - "If you are entering a path to a FF file, " - "please use the forcefield_files variable with the " - "proper XML extension (.xml)." - ) - raise ValueError(print_error_message) - - coulomb14scalar_dict = {} - lj14_scalar_dict = {} - for j in range(0, len(forcefield_keys_list)): - residue_iteration = forcefield_keys_list[j] - if user_entered_ff_with_path_dict[residue_iteration]: - ff_for_residue_iteration = ff_data[residue_iteration] - try: - read_xlm_iteration = minidom.parse(ff_for_residue_iteration) - - except: - print_error_message = ( - "Please make sure you are entering the correct foyer FF path, " - "including the FF file name.xml " - "If you are using the pre-build FF files in foyer, " - "only use the string name without any extension." - ) - raise ValueError(print_error_message) - elif not user_entered_ff_with_path_dict[residue_iteration]: - ff_for_residue_iteration = ff_data[residue_iteration] - ff_names_path_iteration = ( - forcefields.get_ff_path()[0] - + "/xml/" - + ff_for_residue_iteration - + ".xml" - ) - try: - read_xlm_iteration = minidom.parse(ff_names_path_iteration) - except: - print_error_message = ( - "Please make sure you are entering the correct foyer FF name, or the " - "correct file extension (i.e., .xml, if required)." - ) - raise ValueError(print_error_message) - lj_coul_1_4_values = read_xlm_iteration.getElementsByTagName( - "NonbondedForce" - ) - - for Scalar in lj_coul_1_4_values: - coulomb14scalar_dict.update( - { - residue_iteration: float( - Scalar.getAttribute("coulomb14scale") - ) - } - ) - lj14_scalar_dict.update( - {residue_iteration: float(Scalar.getAttribute("lj14scale"))} - ) - - # Check to see if it is an empty mbuild.Compound and set intial atoms to 0 - # note empty mbuild.Compound will read 1 atoms but there is really noting there - if isinstance(structure, Compound): - if len(structure.children) == 0: - # there are no real atoms in the Compound so the test fails. User should use mbuild.Box - print_error_message = ( - "ERROR: If you are not providing an empty box, " - "you need to specify the atoms/beads as children in the mb.Compound. " - "If you are providing and empty box, please do so by specifying and " - "mbuild Box ({})".format(type(mb.Box(lengths=[1, 1, 1]))) - ) - raise TypeError(print_error_message) - else: - initial_no_atoms = structure.n_particles - - # calculate the initial number of atoms for later comparison - if isinstance(structure, mb.Box): - lengths = structure.lengths - angles = structure.angles - - structure = mb.Compound() - structure.box = mb.Box(lengths=lengths, angles=angles) - initial_no_atoms = 0 - - # add the FF to the residues - compound_box_infor = structure.to_parmed(residues=residues) - new_structure = pmd.Structure() - new_structure.box = compound_box_infor.box - - # prepare all compound and remove nested compounds - no_layers_to_check_for_residues = 3 - - print_error_message_all_res_not_specified = ( - "ERROR: All the residues are not specified, or " - "the residues entered does not match the residues that " - "were found and built for structure." - ) - for j in range(0, no_layers_to_check_for_residues): - new_compound_iter = mb.Compound() - new_compound_iter.periodicity = structure.periodicity - if structure.name in residues: - if len(structure.children) == 0: - warn( - "Warning: This residue is the atom, and is a single atom., " - + str(structure.name) - ) - new_compound_iter.add(mb.compound.clone(structure)) - - elif len(structure.children) > 0: - new_compound_iter.add(mb.compound.clone(structure)) - - else: - for child in structure.children: - if len(child.children) == 0: - if child.name not in residues: - raise ValueError( - print_error_message_all_res_not_specified - ) - - else: - new_compound_iter.add(mb.compound.clone(child)) - - elif len(child.children) > 0: - if child.name in residues: - new_compound_iter.add(mb.compound.clone(child)) - else: - for sub_child in child.children: - if sub_child.name in residues: - new_compound_iter.add( - mb.compound.clone(sub_child) - ) - - else: - if len(sub_child.children) == 0 and ( - child.name not in residues - ): - raise ValueError( - print_error_message_all_res_not_specified - ) - - structure = new_compound_iter - - residues_applied_list = [] - residue_orig_order_list = [] - for child in structure.children: - if child.name not in residue_orig_order_list: - residue_orig_order_list.append(child.name) - for res_reorder_iter in range(0, len(residues)): - if residues[res_reorder_iter] not in residue_orig_order_list: - text_to_print_1 = ( - "All the residues were not used from the forcefield_selection " - "string or dictionary. There may be residues below other " - "specified residues in the mbuild.Compound hierarchy. " - "If so, all the highest listed residues pass down the force " - "fields through the hierarchy. Alternatively, residues that " - "are not in the structure may have been specified. " - ) - text_to_print_2 = ( - "Note: This warning will appear if you are using the CHARMM pdb and psf writers " - + "2 boxes, and the boxes do not contain all the residues in each box." - ) - if boxes_for_simulation == 1: - warn(text_to_print_1) - raise ValueError(text_to_print_1) - if boxes_for_simulation == 2: - warn(text_to_print_1 + text_to_print_2) - - if not reorder_res_in_pdb_psf: - residues = residue_orig_order_list - elif reorder_res_in_pdb_psf: - print( - "INFO: the output file are being reordered in via the residues list's sequence." - ) - - for i in range(0, len(residues)): - children_in_iteration = False - new_compound_iteration = mb.Compound() - new_compound_iter.periodicity = structure.periodicity - new_structure_iteration = pmd.Structure() - new_structure_iteration.box = compound_box_infor.box - for child in structure.children: - if ff_data.get(child.name) is None: - print_error_message = "ERROR: All residues are not specified in the force_field dictionary" - raise ValueError(print_error_message) - - if child.name == residues[i]: - children_in_iteration = True - new_compound_iteration.add(mb.compound.clone(child)) - - if children_in_iteration: - if user_entered_ff_with_path_dict[residues[i]]: - ff_iteration = Forcefield(ff_data[residues[i]]) - residues_applied_list.append(residues[i]) - elif not user_entered_ff_with_path_dict[residues[i]]: - print(residues[i], ff_data) - ff_iteration = Forcefield(name=ff_data[residues[i]]) - residues_applied_list.append(residues[i]) - - new_compound_iteration.box = None - new_structure_iteration = ff_iteration.apply( - new_compound_iteration, residues=[residues[i]] - ) - new_structure = new_structure + new_structure_iteration - - structure = new_structure - - # calculate the final number of atoms - final_no_atoms = len(structure.atoms) - - if final_no_atoms != initial_no_atoms: - print_error_message = ( - "ERROR: The initial number of atoms sent to the force field analysis is " - "not the same as the final number of atoms analyzed. " - "The initial number of atoms was {} and the final number of atoms was {}. " - "Please ensure that all the residues names that are in the initial " - "Compound are listed in the residues list " - "(i.e., the residues variable).".format( - initial_no_atoms, final_no_atoms - ) - ) - raise ValueError(print_error_message) - - return [ - structure, - coulomb14scalar_dict, - lj14_scalar_dict, - residues_applied_list, - ]