Skip to content

Commit b597d5e

Browse files
authored
Merge pull request #391 from OpenBioSim/backport_390
Backport fix from PR #390
2 parents b467435 + e0efe9a commit b597d5e

7 files changed

Lines changed: 46 additions & 32 deletions

File tree

doc/source/changelog.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ company supporting open-source development of fostering academic/industrial coll
99
within the biomolecular simulation community. Our software is hosted via the `OpenBioSim`
1010
`GitHub <https://github.com/OpenBioSim/biosimspace>`__ organisation.
1111

12+
`2024.4.1 <https://github.com/openbiosim/biosimspace/compare/2024.4.0...2024.4.1>`_ - Feb 13 2025
13+
-------------------------------------------------------------------------------------------------
14+
15+
* Add ``force_stereo_inference`` keyword argument to :func:`BioSimSpace.Convert.toRDKit <BioSimSpace.Convert.toRDKit>` to allow control over stereochemistry inference. This allows a user to match the old ``sire`` behaviour, where stereochemistry was always infered, which would override any information already present in a molecule (`#388 <https://github.com/OpenBioSim/biosimspace/pull/388>`__).
16+
* Port optimised ``SOMD`` configuration settings to the Exscientia sandpit.
17+
1218
`2024.4.0 <https://github.com/openbiosim/biosimspace/compare/2024.3.0...2024.4.0>`_ - Feb 04 2025
1319
-------------------------------------------------------------------------------------------------
1420

python/BioSimSpace/Sandpit/Exscientia/Protocol/_config.py

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -743,51 +743,52 @@ def generateSomdConfig(
743743
# Get the report and restart intervals.
744744
report_interval = self._report_interval
745745
restart_interval = self._restart_interval
746-
runtime = self.protocol.getRunTime()
747746

748-
# Get the timestep.
749-
timestep = self.protocol._timestep
750-
751-
# Work out the number of cycles.
752-
ncycles = (runtime / timestep) / report_interval
753-
754-
# If the number of cycles isn't integer valued, adjust the report
755-
# interval so that we match specified the run time.
756-
if ncycles - _math.floor(ncycles) != 0:
757-
ncycles = _math.floor(ncycles)
758-
if ncycles == 0:
759-
ncycles = 1
760-
report_interval = _math.ceil((runtime / timestep) / ncycles)
747+
# Work out the number of cycles. We want one per nanosecond of simulation.
748+
if self.protocol.getRunTime().nanoseconds().value() < 2:
749+
ncycles = 1
750+
moves_per_cycle = self._steps
751+
else:
752+
ncycles = _math.ceil(self.protocol.getRunTime().nanoseconds().value())
753+
moves_per_cycle = _math.ceil(self._steps / ncycles)
761754

762-
# For free energy simulations, the report interval must be a multiple
763-
# of the energy frequency which is 250 steps.
764-
if isinstance(self.protocol, _Protocol._FreeEnergyMixin):
765-
if report_interval % 250 != 0:
766-
report_interval = 250 * _math.ceil(report_interval / 250)
755+
# The number of moves needs to be multiple of the report interval.
756+
if moves_per_cycle % report_interval != 0:
757+
moves_per_cycle = (
758+
_math.ceil(moves_per_cycle / report_interval) * report_interval
759+
)
767760

768761
# Work out the number of cycles per frame.
769-
cycles_per_frame = restart_interval / report_interval
762+
cycles_per_frame = restart_interval / moves_per_cycle
770763

771764
# Work out whether we need to adjust the buffer frequency.
772765
buffer_freq = 0
773766
if cycles_per_frame < 1:
774-
buffer_freq = cycles_per_frame * restart_interval
767+
buffer_freq = restart_interval
775768
cycles_per_frame = 1
776-
self._buffer_freq = buffer_freq
777769
else:
778770
cycles_per_frame = _math.floor(cycles_per_frame)
779771

772+
# Make sure that we aren't buffering more than 1000 frames per cycle.
773+
if buffer_freq > 0 and moves_per_cycle / buffer_freq > 1000:
774+
_warnings.warn(
775+
"Trajectory buffering will exceed limit. Reducing buffer frequency."
776+
)
777+
buffer_freq = moves_per_cycle / 1000
778+
780779
# For free energy simulations, the buffer frequency must be an integer
781780
# multiple of the frequency at which free energies are written, which
782-
# is 250 steps. Round down to the closest multiple.
781+
# is report interval. Round down to the closest multiple.
783782
if isinstance(self.protocol, _Protocol._FreeEnergyMixin):
784783
if buffer_freq > 0:
785-
buffer_freq = 250 * _math.floor(buffer_freq / 250)
784+
buffer_freq = report_interval * _math.floor(
785+
buffer_freq / report_interval
786+
)
786787

787788
# The number of SOMD cycles.
788-
protocol_dict["ncycles"] = int(ncycles)
789+
protocol_dict["ncycles"] = ncycles
789790
# The number of moves per cycle.
790-
protocol_dict["nmoves"] = report_interval
791+
protocol_dict["nmoves"] = moves_per_cycle
791792
# Cycles per trajectory write.
792793
protocol_dict["ncycles_per_snap"] = cycles_per_frame
793794
# Buffering frequency.
@@ -862,7 +863,7 @@ def generateSomdConfig(
862863
"hbonds-notperturbed" # Handle hydrogen perturbations.
863864
)
864865
protocol_dict["energy frequency"] = (
865-
250 # Write gradients every 250 steps.
866+
report_interval # Write gradients at report interval.
866867
)
867868

868869
protocol = [str(x) for x in self.protocol.getLambdaValues()]

python/BioSimSpace/Sandpit/Exscientia/_SireWrappers/_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# You should have received a copy of the GNU General Public License
1919
# along with BioSimSpace. If not, see <http://www.gnu.org/licenses/>.
2020
#####################################################################
21-
"""
21+
"""
2222
Utilities.
2323
"""
2424

python/BioSimSpace/_SireWrappers/_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# You should have received a copy of the GNU General Public License
1919
# along with BioSimSpace. If not, see <http://www.gnu.org/licenses/>.
2020
#####################################################################
21-
"""
21+
"""
2222
Utilities.
2323
"""
2424

recipes/biosimspace/template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ test:
2727
- SIRE_SILENT_PHONEHOME
2828
requires:
2929
- pytest <8
30-
- black 24 # [linux and x86_64 and py==312]
30+
- black 25 # [linux and x86_64 and py==312]
3131
- pytest-black # [linux and x86_64 and py==312]
3232
- ambertools # [linux and x86_64]
3333
- gromacs # [linux and x86_64]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# BioSimSpace runtime requirements.
22

33
# main
4-
sire~=2024.4.0
4+
sire~=2024.4.1
55

66
# devel
77
#sire==2025.1.0.dev

tests/Sandpit/Exscientia/Protocol/test_config.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,14 +480,21 @@ def system_and_boresch_restraint():
480480
def test_turn_on_restraint_boresch(self, system_and_boresch_restraint):
481481
"""Test for turning on multiple distance restraints"""
482482
system, restraint = system_and_boresch_restraint
483-
protocol = FreeEnergy(perturbation_type="restraint")
483+
protocol = FreeEnergy(perturbation_type="restraint",
484+
runtime=1*BSS.Units.Time.nanosecond,
485+
timestep=2*BSS.Units.Time.femtosecond)
484486
freenrg = BSS.FreeEnergy.AlchemicalFreeEnergy(
485487
system, protocol, engine="SOMD", restraint=restraint
486488
)
487489

488490
# Test .cfg file
489491
with open(f"{freenrg._work_dir}/lambda_0.0000/somd.cfg", "r") as f:
490492
cfg_text = f.read()
493+
assert "nmoves = 500000" in cfg_text
494+
assert "ncycles_per_snap = 1" in cfg_text
495+
assert "buffered coordinates frequency = 1000" in cfg_text
496+
assert "timestep = 2.00 femtosecond" in cfg_text
497+
assert "energy frequency = 200" in cfg_text
491498
assert "use boresch restraints = True" in cfg_text
492499
assert 'boresch restraints dictionary = {"anchor_points":{"r1":1,'
493500
' "r2":2, "r3":3, "l1":4, "l2":5, "l3":6}, "equilibrium_values"'

0 commit comments

Comments
 (0)