Skip to content

Commit

Permalink
Merge pull request #55 from OpenBioSim/feature_ghost_handling
Browse files Browse the repository at this point in the history
Add support for Boresch modifications to ghost atom bonded terms
  • Loading branch information
lohedges authored Sep 27, 2024
2 parents eaed3ab + def7b49 commit 666f707
Show file tree
Hide file tree
Showing 9 changed files with 1,624 additions and 165 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ jobs:
max-parallel: 9
fail-fast: false
matrix:
python-version: ["3.12"]
python-version: ["3.11"]
platform:
- { name: "windows", os: "windows-latest", shell: "pwsh" }
#- { name: "windows", os: "windows-latest", shell: "pwsh" }
- { name: "linux", os: "ubuntu-latest", shell: "bash -l {0}" }
- { name: "macos", os: "macos-latest", shell: "bash -l {0}" }
defaults:
Expand All @@ -48,7 +48,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
if: github.event_name == 'pull_request'
#
- uses: conda-incubator/setup-miniconda@v2
- uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: true
python-version: ${{ matrix.python-version }}
Expand Down
138 changes: 138 additions & 0 deletions src/somd2/_utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
######################################################################
# SOMD2: GPU accelerated alchemical free-energy engine.
#
# Copyright: 2023-2024
#
# Authors: The OpenBioSim Team <[email protected]>
#
# SOMD2 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SOMD2 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SOMD2. If not, see <http://www.gnu.org/licenses/>.
#####################################################################

import platform as _platform

if _platform.system() == "Windows":
_lam_sym = "lambda"
else:
_lam_sym = "λ"

del _platform


def _has_ghost(mol, idxs, is_lambda1=False):
"""
Internal function to check whether any atom is a ghost.
Parameters
----------
mol : sire.legacy.Mol.Molecule
The molecule.
idxs : [sire.legacy.Mol.AtomIdx]
A list of atom indices.
is_lambda1 : bool
Whether to check the lambda = 1 state.
Returns
-------
has_ghost : bool
Whether a ghost atom is present.
"""

import sire.legacy.Mol as _SireMol

# We need to check by ambertype too since this molecule may have been
# created via sire.morph.create_from_pertfile, in which case the element
# property will have been set to the end state with the largest mass, i.e.
# may no longer by a ghost.
if is_lambda1:
element_prop = "element1"
ambertype_prop = "ambertype1"
else:
element_prop = "element0"
ambertype_prop = "ambertype0"

element_ghost = _SireMol.Element(0)
ambertype_ghost = "du"

# Check whether an of the atoms is a ghost.
for idx in idxs:
if (
mol.atom(idx).property(element_prop) == element_ghost
or mol.atom(idx).property(ambertype_prop) == ambertype_ghost
):
return True

return False


def _is_ghost(mol, idxs, is_lambda1=False):
"""
Internal function to return whether each atom is a ghost.
Parameters
----------
mol : sire.legacy.Mol.Molecule
The molecule.
idxs : [sire.legacy.Mol.AtomIdx]
A list of atom indices.
is_lambda1 : bool
Whether to check the lambda = 1 state.
Returns
-------
is_ghost : [bool]
Whether each atom is a ghost.
"""

import sire.legacy.Mol as _SireMol

# We need to check by ambertype too since this molecule may have been
# created via sire.morph.create_from_pertfile, in which case the element
# property will have been set to the end state with the largest mass, i.e.
# may no longer by a ghost.
if is_lambda1:
element_prop = "element1"
ambertype_prop = "ambertype1"
else:
element_prop = "element0"
ambertype_prop = "ambertype0"

if is_lambda1:
element_prop = "element1"
ambertype_prop = "ambertype1"
else:
element_prop = "element0"
ambertype_prop = "ambertype0"

element_ghost = _SireMol.Element(0)
ambertype_ghost = "du"

# Initialise a list to store the state of each atom.
is_ghost = []

# Check whether each of the atoms is a ghost.
for idx in idxs:
is_ghost.append(
mol.atom(idx).property(element_prop) == element_ghost
or mol.atom(idx).property(ambertype_prop) == ambertype_ghost
)

return is_ghost
Loading

0 comments on commit 666f707

Please sign in to comment.