Skip to content

Commit 4306a00

Browse files
committed
Merge remote-tracking branch 'exscientia/devel'
2 parents 8a04567 + 98f4484 commit 4306a00

3 files changed

Lines changed: 63 additions & 18 deletions

File tree

.github/workflows/Sandpit_exs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
fail-fast: false
2020
matrix:
2121
os: ["ubuntu-latest", ]
22-
python-version: ["3.10",]
22+
python-version: ["3.11",]
2323

2424
steps:
2525
- uses: actions/checkout@v2
@@ -33,7 +33,7 @@ jobs:
3333

3434
- name: Install dependency
3535
run: |
36-
conda install -c conda-forge -c openbiosim/label/main biosimspace python=3.10 ambertools gromacs "sire=2024.2.0" "alchemlyb>=2.1" pytest openff-interchange pint=0.21 rdkit "jaxlib>0.3.7" tqdm
36+
conda install -c conda-forge -c openbiosim/label/main biosimspace python=3.11 ambertools gromacs "sire=2024.3.0" "alchemlyb>=2.1" pytest openff-interchange pint=0.21 rdkit "jaxlib>0.3.7" tqdm
3737
python -m pip install git+https://github.com/Exscientia/MDRestraintsGenerator.git
3838
# For the testing of BSS.FreeEnergy.AlchemicalFreeEnergy.analysis
3939
python -m pip install https://github.com/alchemistry/alchemtest/archive/master.zip

python/BioSimSpace/Sandpit/Exscientia/FreeEnergy/_restraint.py

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
)
3838
from sire.units import GeneralUnit as _sire_GeneralUnit
3939

40-
from BioSimSpace.Sandpit.Exscientia.Types._general_unit import (
40+
from ..Types._general_unit import (
4141
GeneralUnit as _GeneralUnit,
4242
)
4343
from ..Types import Angle as _Angle, Length as _Length, Temperature as _Temperature
@@ -450,7 +450,7 @@ def format_bond(equilibrium_values, force_constants):
450450
)
451451

452452
# Format the parameters for the angles and dihedrals
453-
def format_angle(equilibrium_values, force_constants, restraint_lambda):
453+
def format_angle(equilibrium_values, force_constants, restraint_lambda, perturbed=True):
454454
"""
455455
Format the angle equilibrium values and force constant
456456
in into the Gromacs topology format.
@@ -465,20 +465,30 @@ def format_angle(equilibrium_values, force_constants, restraint_lambda):
465465
466466
When restraint_lambda is True, the dihedrals will be stored in the dihedral_restraints.
467467
"""
468-
converted_equ_val = (
468+
if isinstance(equilibrium_values, _Angle):
469+
converted_equ_val = equilibrium_values / _degree
470+
else:
471+
converted_equ_val = (
469472
self._restraint_dict["equilibrium_values"][equilibrium_values] / _degree
470473
)
471-
converted_fc = self._restraint_dict["force_constants"][force_constants] / (
472-
_kj_per_mol / (_radian * _radian)
473-
)
474+
475+
if isinstance(force_constants, _GeneralUnit):
476+
converted_fc = force_constants / (
477+
_kj_per_mol / (_radian * _radian)
478+
)
479+
else:
480+
converted_fc = self._restraint_dict["force_constants"][force_constants] / (
481+
_kj_per_mol / (_radian * _radian)
482+
)
483+
474484
par_string = (
475485
dihedral_restraints_parameters_string
476486
if restraint_lambda
477487
else parameters_string
478488
)
479489
return par_string.format(
480490
eq0="{:.3f}".format(converted_equ_val),
481-
fc0="{:.2f}".format(0),
491+
fc0="{:.2f}".format(0 if perturbed else converted_fc),
482492
eq1="{:.3f}".format(converted_equ_val),
483493
fc1="{:.2f}".format(converted_fc),
484494
)
@@ -493,12 +503,12 @@ def write_bond(key_list, equilibrium_values, force_constants):
493503
parameters=format_bond(equilibrium_values, force_constants),
494504
)
495505

496-
def write_angle(key_list, equilibrium_values, force_constants):
506+
def write_angle(key_list, equilibrium_values, force_constants, func_type=1, perturbed=True):
497507
return master_string.format(
498508
index=format_index(key_list),
499-
func_type=1,
509+
func_type=func_type,
500510
parameters=format_angle(
501-
equilibrium_values, force_constants, restraint_lambda=False
511+
equilibrium_values, force_constants, restraint_lambda=False, perturbed=perturbed
502512
),
503513
)
504514

@@ -539,6 +549,22 @@ def write_dihedral(
539549
output.append(write_angle(("r2", "r1", "l1"), "thetaA0", "kthetaA"))
540550
# Angles: r1-l1-l2 (thetaB0, kthetaB)
541551
output.append(write_angle(("r1", "l1", "l2"), "thetaB0", "kthetaB"))
552+
# Bent angle: r2-r1-l1
553+
# Center is 90 degree
554+
# force constant is set by evaluating the free energy of adding a harmonic angle potential with fc at kcal/mol/rad2 at 135 degree
555+
#| fc (kcal/mol/rad2) | FE (kcal/mol) |
556+
#|--------------------|---------------|
557+
#| control | 1.05 |
558+
#| 0 | 1.05 |
559+
#| 0.1 | 0.99 |
560+
#| 1 | 1.17 |
561+
#| 5 | 2.14 |
562+
#| 10 | 3.46 |
563+
#| 100 | 14.92 |
564+
# Thus 1 kcal/mol/rad2 is choosen
565+
output.append(write_angle(("r2", "r1", "l1"), 90 * _degree, 1 * _kcal_per_mol / _radian**2, func_type=10, perturbed=False))
566+
# Bent angle: r2-r1-l1
567+
output.append(write_angle(("r1", "l1", "l2"), 90 * _degree, 1 * _kcal_per_mol / _radian**2, func_type=10, perturbed=False))
542568

543569
if restraint_lambda:
544570
output.append("[ dihedral_restraints ]")

tests/Sandpit/Exscientia/FreeEnergy/test_restraint.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from BioSimSpace.Sandpit.Exscientia.Units.Energy import kcal_per_mol
1515
from BioSimSpace.Sandpit.Exscientia.Units.Length import angstrom
1616
from BioSimSpace.Sandpit.Exscientia.Units.Temperature import kelvin
17-
1817
from tests.conftest import has_gromacs
1918

2019
# Store the tutorial URL.
@@ -201,8 +200,28 @@ def test_angle(self, Topology):
201200
assert aj == "1496"
202201
assert ak == "1497"
203202

203+
def test_bented_angle(self, Topology):
204+
ai, aj, ak, type, thA, kA, thB, kB = Topology[8].split()
205+
assert ai == "2"
206+
assert aj == "1"
207+
assert ak == "1496"
208+
assert type == "10"
209+
assert thA == "90.000"
210+
assert kA == "4.18"
211+
assert thB == "90.000"
212+
assert kB == "4.18"
213+
ai, aj, ak, type, thA, kA, thB, kB = Topology[9].split()
214+
assert ai == "1"
215+
assert aj == "1496"
216+
assert ak == "1497"
217+
assert type == "10"
218+
assert thA == "90.000"
219+
assert kA == "4.18"
220+
assert thB == "90.000"
221+
assert kB == "4.18"
222+
204223
def test_dihedral(self, Topology):
205-
ai, aj, ak, al, type, phiA, kA, phiB, kB = Topology[10].split()
224+
ai, aj, ak, al, type, phiA, kA, phiB, kB = Topology[12].split()
206225
assert ai == "3"
207226
assert aj == "2"
208227
assert ak == "1"
@@ -212,12 +231,12 @@ def test_dihedral(self, Topology):
212231
assert kA == "0.00"
213232
assert phiB == "148.396"
214233
assert kB == "41.84"
215-
ai, aj, ak, al, type, phiA, kA, phiB, kB = Topology[11].split()
234+
ai, aj, ak, al, type, phiA, kA, phiB, kB = Topology[13].split()
216235
assert ai == "2"
217236
assert aj == "1"
218237
assert ak == "1496"
219238
assert al == "1497"
220-
ai, aj, ak, al, type, phiA, kA, phiB, kB = Topology[12].split()
239+
ai, aj, ak, al, type, phiA, kA, phiB, kB = Topology[14].split()
221240
assert ai == "1"
222241
assert aj == "1496"
223242
assert ak == "1497"
@@ -233,8 +252,8 @@ def Topology(boresch_restraint):
233252
).split("\n")
234253

235254
def test_dihedral(self, Topology):
236-
assert "dihedral_restraints" in Topology[8]
237-
ai, aj, ak, al, type, phiA, dphiA, kA, phiB, dphiB, kB = Topology[10].split()
255+
assert "dihedral_restraints" in Topology[10]
256+
ai, aj, ak, al, type, phiA, dphiA, kA, phiB, dphiB, kB = Topology[12].split()
238257
assert ai == "3"
239258
assert aj == "2"
240259
assert ak == "1"

0 commit comments

Comments
 (0)