Skip to content
Snippets Groups Projects
Commit a2f5790f authored by James Graham's avatar James Graham
Browse files

Match equation in paper for BI - factor 2 and sin

Use default fc on bond lengths too if chosen
parent 6bb0458b
Branches
No related tags found
No related merge requests found
...@@ -22,21 +22,22 @@ if __name__ == "__main__": ...@@ -22,21 +22,22 @@ if __name__ == "__main__":
input_files.add_argument('--end', type=int, default=-1, help="Frame number to end") input_files.add_argument('--end', type=int, default=-1, help="Frame number to end")
args = parser.parse_args() args = parser.parse_args()
config = Options([("output_name", "out"), config = Options([
("output_name", "out"),
("output", "gro"), ("output", "gro"),
("output_xtc", args.outputxtc), ("output_xtc", args.outputxtc),
("map_only", not bool(args.bnd)), ("map_only", not bool(args.bnd)),
("map_center", "geom"), ("map_center", "geom"),
("constr_threshold", 100000), ("constr_threshold", 100000),
("dump_measurements", bool(args.bnd) and not bool(args.map)), ("dump_measurements", bool(args.bnd) and not bool(args.map)),
("dump_n_values", 100000), ("dump_n_values", 10000),
("output_forcefield", False), ("output_forcefield", False),
("temperature", 310), ("temperature", 310),
("angle_default_fc", True), ("default_fc", False),
("generate_angles", True), ("generate_angles", True),
("generate_dihedrals", False), ("generate_dihedrals", False),
("empirical_corr", False)], ("empirical_corr", False)
args) ], args)
if not args.map and not args.bnd: if not args.map and not args.bnd:
parser.error("One or both of -m and -b is required.") parser.error("One or both of -m and -b is required.")
......
...@@ -47,23 +47,20 @@ class Bond: ...@@ -47,23 +47,20 @@ class Bond:
def __len__(self): def __len__(self):
return len(self.atoms) return len(self.atoms)
def boltzmann_invert(self, temp=310, angle_default_fc=True): def boltzmann_invert(self, temp=310, default_fc=True):
""" """
Perform Boltzmann Inversion using measured values of this bond to calculate equilibrium value and force constant. Perform Boltzmann Inversion using measured values of bond to calculate equilibrium value and force constant.
:param temp: Temperature at which the simulation was performed :param temp: Temperature at which the simulation was performed
:param angle_default_fc: Use default value of 25 kJ mol-1 rad-2 for angle force constants :param default_fc: Use default value of 1250 kJ mol-1 nm-2 for length fc and 25 kJ mol-1 for angle fc
""" """
mean, var = stat_moments(self.values) mean, var = stat_moments(self.values)
rt = 8.314 * temp / 1000. rt = 8.314 * temp / 1000.
rad2 = np.pi * np.pi / (180. * 180.) rad2 = np.pi * np.pi / (180. * 180.)
conv = {2: lambda: rt / var, conv = {2: lambda: 1250. if default_fc else rt / (2 * var),
3: lambda: 25. if angle_default_fc else rt * np.sin(np.radians(mean))**2 / (var * rad2), 3: lambda: 25. if default_fc else rt / (2 * np.sin(np.radians(mean))**2 * var * rad2),
4: lambda: rt / (var * rad2)} 4: lambda: rt / (2 * var * rad2)}
# conv = {2: lambda: rt / (2 * var),
# 3: lambda: 25. if angle_default_fc else rt / (2 * np.sin(np.radians(mean))**2 * var * rad2),
# 4: lambda: rt / (var * rad2)}
self.eqm = mean self.eqm = mean
try: try:
...@@ -115,9 +112,9 @@ class BondSet: ...@@ -115,9 +112,9 @@ class BondSet:
self._temperature = 310. self._temperature = 310.
try: try:
self._angle_default_fc = options.angle_default_fc self._default_fc = options.default_fc
except AttributeError: except AttributeError:
self._angle_default_fc = True self._default_fc = False
with CFG(filename) as cfg: with CFG(filename) as cfg:
for mol in cfg: for mol in cfg:
...@@ -237,16 +234,17 @@ class BondSet: ...@@ -237,16 +234,17 @@ class BondSet:
self._populate_atom_numbers(mapping) self._populate_atom_numbers(mapping)
backup_file(filename, verbose=True) backup_file(filename, verbose=True)
def write_bond_angle_dih(bonds, section_header, itp, fconst=True, multiplicity=None): def write_bond_angle_dih(bonds, section_header, itp, print_fconst=True, multiplicity=None):
if bonds: if bonds:
print("\n[ {0:s} ]".format(section_header), file=itp) print("\n[ {0:s} ]".format(section_header), file=itp)
for bond in bonds: for bond in bonds:
# Factor is usually 1, unless doing correction # Factor is usually 1, unless doing correction
eqm = bond.eqm * self._empirical_correction_factor eqm = bond.eqm * self._empirical_correction_factor
fconst = bond.fconst * self._empirical_correction_factor
line = " ".join(["{0:4d}".format(atnum + 1) for atnum in bond.atom_numbers]) line = " ".join(["{0:4d}".format(atnum + 1) for atnum in bond.atom_numbers])
line += " {0:4d} {1:12.5f}".format(1, eqm) line += " {0:4d} {1:12.5f}".format(1, eqm)
if fconst: if print_fconst:
line += " {0:12.5f}".format(bond.fconst) line += " {0:12.5f}".format(fconst)
if multiplicity is not None: if multiplicity is not None:
line += " {0:4d}".format(multiplicity) line += " {0:4d}".format(multiplicity)
print(line, file=itp) print(line, file=itp)
...@@ -275,7 +273,7 @@ class BondSet: ...@@ -275,7 +273,7 @@ class BondSet:
write_bond_angle_dih(self.get_bond_lengths(mol), "bonds", itp) write_bond_angle_dih(self.get_bond_lengths(mol), "bonds", itp)
write_bond_angle_dih(self.get_bond_angles(mol), "angles", itp) write_bond_angle_dih(self.get_bond_angles(mol), "angles", itp)
write_bond_angle_dih(self.get_bond_dihedrals(mol), "dihedrals", itp, multiplicity=1) write_bond_angle_dih(self.get_bond_dihedrals(mol), "dihedrals", itp, multiplicity=1)
write_bond_angle_dih(self.get_bond_length_constraints(mol), "constraints", itp, fconst=False) write_bond_angle_dih(self.get_bond_length_constraints(mol), "constraints", itp, print_fconst=False)
def apply(self, frame): def apply(self, frame):
""" """
...@@ -343,7 +341,7 @@ class BondSet: ...@@ -343,7 +341,7 @@ class BondSet:
for bond in bond_iter_wrap: for bond in bond_iter_wrap:
bond.boltzmann_invert(temp=self._temperature, bond.boltzmann_invert(temp=self._temperature,
angle_default_fc=self._angle_default_fc) default_fc=self._default_fc)
def dump_values(self, target_number=10000): def dump_values(self, target_number=10000):
""" """
......
...@@ -63,6 +63,8 @@ def main(args, config): ...@@ -63,6 +63,8 @@ def main(args, config):
if args.map: if args.map:
logger.info("Beginning Boltzmann inversion") logger.info("Beginning Boltzmann inversion")
bonds.boltzmann_invert(progress=True) bonds.boltzmann_invert(progress=True)
print("Note: charges are not currently handled")
print("If your CG molecule should contain charges the itp will need to be edited")
if config.output_forcefield: if config.output_forcefield:
logger.info("Creating GROMACS forcefield directory") logger.info("Creating GROMACS forcefield directory")
ff = ForceField("ff" + config.output_name + ".ff") ff = ForceField("ff" + config.output_name + ".ff")
......
...@@ -17,27 +17,27 @@ ALLA 1 ...@@ -17,27 +17,27 @@ ALLA 1
6 P4 1 ALLA O5 6 0.000 6 P4 1 ALLA O5 6 0.000
[ bonds ] [ bonds ]
2 3 1 0.21998 35162.10022 1 2 1 0.22209 88271.49992
3 4 1 0.21648 65545.10313 2 3 1 0.21998 17581.05011
4 5 1 0.26454 19022.17121 3 4 1 0.21648 32772.55156
5 6 1 0.20452 53457.20659 4 5 1 0.26454 9511.08560
5 6 1 0.20452 26728.60329
[ angles ] [ angles ]
1 2 3 1 77.69557 383.16060 1 2 3 1 77.69557 210.24268
2 3 4 1 115.59599 262.66648 2 3 4 1 115.59599 198.52391
3 4 5 1 108.51038 698.56915 3 4 5 1 108.51038 431.97481
4 5 6 1 81.23827 1098.41706 4 5 6 1 81.23827 575.61056
5 6 1 1 146.49898 48.08599 5 6 1 1 146.49898 259.05013
6 1 2 1 99.84045 1571.73513 6 1 2 1 99.84045 833.86832
[ dihedrals ] [ dihedrals ]
1 2 3 4 1 -85.45004 234.10405 1 1 2 3 4 1 -85.45004 117.05203 1
2 3 4 5 1 65.21378 117.46132 1 2 3 4 5 1 65.21378 58.73066 1
3 4 5 6 1 -22.73796 94.20175 1 3 4 5 6 1 -22.73796 47.10087 1
4 5 6 1 1 55.18087 37.92107 1 4 5 6 1 1 55.18087 18.96053 1
5 6 1 2 1 -96.52349 40.73340 1 5 6 1 2 1 -96.52349 20.36670 1
6 1 2 3 1 73.82477 259.20126 1 6 1 2 3 1 73.82477 129.60063 1
[ constraints ] [ constraints ]
1 2 1 0.22209
6 1 1 0.17931 6 1 1 0.17931
...@@ -48,24 +48,24 @@ class BondSetTest(unittest.TestCase): ...@@ -48,24 +48,24 @@ class BondSetTest(unittest.TestCase):
self.assertEqual(0, len(angles)) self.assertEqual(0, len(angles))
def test_bondset_boltzmann_invert(self): def test_bondset_boltzmann_invert(self):
ref = [(0.222817161647, 19116816.3363), ref = [( 0.222817161647, 9560719),
(0.216766804211, 55835643.1619), ( 0.216766804211, 27930081),
(0.223815134299, 6199518.81029), ( 0.223815134299, 3099614),
(0.239439104442, 642593936.491), ( 0.239439104442, 322294637),
(0.215497208685, 7366326.46847), ( 0.215497208685, 3683331),
(0.179544192953, 20521533.3397), ( 0.179544192953, 10260492),
(76.9617550012, 23447621.6268), ( 76.9617550012, 13048242),
(116.009786726, 1210005.81229), (116.009786726, 927619),
(109.247878273, 311284.586971), (109.247878273, 195899),
(84.4955293511, 1713127.90333), ( 84.4955293511, 871991),
(149.557001531, 62116.1326728), (149.557001531, 471274),
(99.0524708671, 192028.755165), ( 99.0524708671, 100943),
(-89.5321545897, 182481.962675), (-89.5321545897, 91248),
(70.040930903, 337940.374373), ( 70.040930903, 169002),
(-21.1194544981, 1990817.75509), (-21.1194544981, 995309),
(48.3727747848, 71424.537429), ( 48.3727747848, 35712),
(-85.923133935, 124765.874439), (-85.923133935, 62394),
(70.3195444564, 1555761.24713)] ( 70.3195444564, 778389)]
measure = BondSet("test/data/sugar.bnd", DummyOptions) measure = BondSet("test/data/sugar.bnd", DummyOptions)
frame = Frame("test/data/sugar.gro", xtc="test/data/sugar.xtc") frame = Frame("test/data/sugar.gro", xtc="test/data/sugar.xtc")
...@@ -78,7 +78,7 @@ class BondSetTest(unittest.TestCase): ...@@ -78,7 +78,7 @@ class BondSetTest(unittest.TestCase):
measure.boltzmann_invert() measure.boltzmann_invert()
for i, bond in enumerate(measure["ALLA"]): for i, bond in enumerate(measure["ALLA"]):
# Require accuracy to 0.5% # Require accuracy to 0.5%
# Allows for slight modifications to algorithm # Allows for slight modifications to code
self.assertAlmostEqual(ref[i][0], bond.eqm, delta=abs(ref[i][0] / 200)) self.assertAlmostEqual(ref[i][0], bond.eqm, delta=abs(ref[i][0] / 200))
self.assertAlmostEqual(ref[i][1], bond.fconst, delta=abs(ref[i][1] / 200)) self.assertAlmostEqual(ref[i][1], bond.fconst, delta=abs(ref[i][1] / 200))
......
...@@ -38,7 +38,7 @@ class PycgtoolTest(unittest.TestCase): ...@@ -38,7 +38,7 @@ class PycgtoolTest(unittest.TestCase):
("dump_n_values", 100000), ("dump_n_values", 100000),
("output_forcefield", False), ("output_forcefield", False),
("temperature", 310), ("temperature", 310),
("angle_default_fc", True), ("default_fc", False),
("generate_angles", True), ("generate_angles", True),
("generate_dihedrals", False)]) ("generate_dihedrals", False)])
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment