Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature exclude opposite ghosts #204

Merged
merged 10 commits into from
Jun 22, 2024
34 changes: 23 additions & 11 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,29 @@
`Sire <https://sire.openbiosim.org>`__
======================================

.. image:: https://github.com/openbiosim/sire/workflows/Build/badge.svg
:target: https://github.com/openbiosim/sire/actions?query=workflow%3ABuild
:alt: Build status

.. image:: https://anaconda.org/openbiosim/sire/badges/downloads.svg
:target: https://anaconda.org/openbiosim/sire
:alt: Downloads

.. image:: https://img.shields.io/badge/License-GPL%20v3-blue.svg
:target: https://www.gnu.org/licenses/gpl-3.0.en.html
:alt: License
Citation
========

If you use sire in your work, please cite the
`following paper <https://doi.org/10.1063/5.0200458>`__:

.. code-block:: bibtex

@article{10.1063/5.0200458,
author = {Woods, Christopher J. and Hedges, Lester O. and Mulholland, Adrian J. and Malaisree, Maturos and Tosco, Paolo and Loeffler, Hannes H. and Suruzhon, Miroslav and Burman, Matthew and Bariami, Sofia and Bosisio, Stefano and Calabro, Gaetano and Clark, Finlay and Mey, Antonia S. J. S. and Michel, Julien},
title = "{Sire: An interoperability engine for prototyping algorithms and exchanging information between molecular simulation programs}",
journal = {The Journal of Chemical Physics},
volume = {160},
number = {20},
pages = {202503},
year = {2024},
month = {05},
abstract = "{Sire is a Python/C++ library that is used both to prototype new algorithms and as an interoperability engine for exchanging information between molecular simulation programs. It provides a collection of file parsers and information converters that together make it easier to combine and leverage the functionality of many other programs and libraries. This empowers researchers to use sire to write a single script that can, for example, load a molecule from a PDBx/mmCIF file via Gemmi, perform SMARTS searches via RDKit, parameterize molecules using BioSimSpace, run GPU-accelerated molecular dynamics via OpenMM, and then display the resulting dynamics trajectory in a NGLView Jupyter notebook 3D molecular viewer. This functionality is built on by BioSimSpace, which uses sire’s molecular information engine to interconvert with programs such as GROMACS, NAMD, Amber, and AmberTools for automated molecular parameterization and the running of molecular dynamics, metadynamics, and alchemical free energy workflows. Sire comes complete with a powerful molecular information search engine, plus trajectory loading and editing, analysis, and energy evaluation engines. This, when combined with an in-built computer algebra system, gives substantial flexibility to researchers to load, search for, edit, and combine molecular information from multiple sources and use that to drive novel algorithms by combining functionality from other programs. Sire is open source (GPL3) and is available via conda and at a free Jupyter notebook server at https://try.openbiosim.org. Sire is supported by the not-for-profit OpenBioSim community interest company.}",
issn = {0021-9606},
doi = {10.1063/5.0200458},
url = {https://doi.org/10.1063/5.0200458},
eprint = {https://pubs.aip.org/aip/jcp/article-pdf/doi/10.1063/5.0200458/19969848/202503\_1\_5.0200458.pdf},
}

About
=====
Expand Down
11 changes: 9 additions & 2 deletions doc/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ organisation on `GitHub <https://github.com/openbiosim/sire>`__.
-----------------------------------------------------------------------------------------

* Correctly set the ``element1`` property in ``sire.morph.create_from_pertfile``.

* Added mising :meth:`~sire.vol.TriclinicBox.maximum_cutoff` method so that
the cutoff is set correctly when creating a :obj:`~sire.system.ForceFieldInfo`
object.
Expand All @@ -42,11 +43,17 @@ organisation on `GitHub <https://github.com/openbiosim/sire>`__.
standard trajectory save functions, e.g.
``sire.save(mols.trajectory(), "output", format=["PRMTOP", "RST"])``.

* Added code that automatically excludes non-bonded interactions between
from_ghost and to_ghost atoms in the OpenMM layer. This is to prevent
crashes caused by poor interactions between from_ghost atoms appearing
over the top of to_ghost atoms during a perturbation where one group
is grown over another.

* Ignore BioSimSpace format position restraint include directives when
parsing GROMACS topology files.

* Add a map option to prevent perturbation of the Lennard-Jones sigma
parameter for ghost atoms during alchemical free energy simulations.
* Added a map option (fix_perturbable_zero_sigmas) to prevent perturbation of
the Lennard-Jones sigma parameter for ghost atoms during alchemical free energy simulations.

* Please add an item to this changelog when you create your PR

Expand Down
24 changes: 24 additions & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,30 @@ It is used as a key component of `BioSimSpace <https://biosimspace.org>`__,
and is distributed and supported as an open source community project by
`OpenBioSim <https://openbiosim.org>`__.

Citation
========

If you use sire in your work, please cite the
`following paper <https://doi.org/10.1063/5.0200458>`__:

.. code-block:: bibtex

@article{10.1063/5.0200458,
author = {Woods, Christopher J. and Hedges, Lester O. and Mulholland, Adrian J. and Malaisree, Maturos and Tosco, Paolo and Loeffler, Hannes H. and Suruzhon, Miroslav and Burman, Matthew and Bariami, Sofia and Bosisio, Stefano and Calabro, Gaetano and Clark, Finlay and Mey, Antonia S. J. S. and Michel, Julien},
title = "{Sire: An interoperability engine for prototyping algorithms and exchanging information between molecular simulation programs}",
journal = {The Journal of Chemical Physics},
volume = {160},
number = {20},
pages = {202503},
year = {2024},
month = {05},
abstract = "{Sire is a Python/C++ library that is used both to prototype new algorithms and as an interoperability engine for exchanging information between molecular simulation programs. It provides a collection of file parsers and information converters that together make it easier to combine and leverage the functionality of many other programs and libraries. This empowers researchers to use sire to write a single script that can, for example, load a molecule from a PDBx/mmCIF file via Gemmi, perform SMARTS searches via RDKit, parameterize molecules using BioSimSpace, run GPU-accelerated molecular dynamics via OpenMM, and then display the resulting dynamics trajectory in a NGLView Jupyter notebook 3D molecular viewer. This functionality is built on by BioSimSpace, which uses sire’s molecular information engine to interconvert with programs such as GROMACS, NAMD, Amber, and AmberTools for automated molecular parameterization and the running of molecular dynamics, metadynamics, and alchemical free energy workflows. Sire comes complete with a powerful molecular information search engine, plus trajectory loading and editing, analysis, and energy evaluation engines. This, when combined with an in-built computer algebra system, gives substantial flexibility to researchers to load, search for, edit, and combine molecular information from multiple sources and use that to drive novel algorithms by combining functionality from other programs. Sire is open source (GPL3) and is available via conda and at a free Jupyter notebook server at https://try.openbiosim.org. Sire is supported by the not-for-profit OpenBioSim community interest company.}",
issn = {0021-9606},
doi = {10.1063/5.0200458},
url = {https://doi.org/10.1063/5.0200458},
eprint = {https://pubs.aip.org/aip/jcp/article-pdf/doi/10.1063/5.0200458/19969848/202503\_1\_5.0200458.pdf},
}

Quick Start
===========

Expand Down
28 changes: 7 additions & 21 deletions src/sire/utils/_try_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,7 @@ def _find_conda():
)
return None

if conda.endswith(".exe"):
m = os.path.join(os.path.dirname(conda), "mamba.exe")
else:
m = os.path.join(os.path.dirname(conda), "mamba")

if os.path.exists(m):
return m
else:
return conda
return conda


def _install_package(name, package_registry, version=None):
Expand Down Expand Up @@ -98,18 +90,15 @@ def _install_package(name, package_registry, version=None):
except Exception:
pass

print(
"\nWARNING: Unable to install '%s' from package '%s'\n"
% (name, package)
)
print("\nWARNING: Unable to install '%s' from package '%s'\n" % (name, package))


class _ModuleStub:
def __init__(self, name: str, install_command: str = None):
self._name = name

if install_command is None:
self._install_command = f"mamba install {name}"
self._install_command = f"conda install {name}"
else:
self._install_command = install_command

Expand All @@ -135,7 +124,7 @@ def try_import(name, package_registry=_module_to_package, version=None):
the package to install using "package_registry"
(or if this is not available, using just the name
of the module). This will then be installed using
"mamba", then "conda" (first one that works will return).
"conda" (first one that works will return).

For example, use this via

Expand Down Expand Up @@ -176,9 +165,7 @@ def try_import(name, package_registry=_module_to_package, version=None):
return _ModuleStub(name)


def try_import_from(
name, fromlist, package_registry=_module_to_package, version=None
):
def try_import_from(name, fromlist, package_registry=_module_to_package, version=None):
"""Try to import from the module called 'name' the passed symbol
(or list of symbols) contained in 'fromlist', returning
the symbol (or list of symbols).
Expand Down Expand Up @@ -224,15 +211,14 @@ def try_import_from(
return try_import_from(name, fromlist, package_registry=None)
else:
m = " ".join(fromlist)
return _ModuleStub(name, f"mamba install {m}")
return _ModuleStub(name, f"conda install {m}")

if nsyms == 1:
try:
return getattr(mod, fromlist[0])
except Exception:
raise ImportError(
"Cannot find the symbol '%s' in module '%s'"
% (fromlist[0], name)
"Cannot find the symbol '%s' in module '%s'" % (fromlist[0], name)
)
else:
ret = []
Expand Down
2 changes: 2 additions & 0 deletions wrapper/AutoGenerate/create_wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,7 @@ def fixMB(mb):
define_symbols=[
"GCCXML_PARSE",
"__PIC__",
"QT_NO_SIGNALS_SLOTS_KEYWORDS=1",
"SIRE_ALWAYS_INLINE=inline",
"SIRE_SKIP_INLINE_FUNCTIONS",
"SIREN_SKIP_INLINE_FUNCTIONS",
Expand All @@ -854,6 +855,7 @@ def fixMB(mb):
define_symbols=[
"GCCXML_PARSE",
"__PIC__",
"QT_NO_SIGNALS_SLOTS_KEYWORDS=1",
"SIRE_USE_OPENMM",
"SIRE_ALWAYS_INLINE=inline",
"SIRE_SKIP_INLINE_FUNCTIONS",
Expand Down
37 changes: 28 additions & 9 deletions wrapper/Convert/SireOpenMM/openmmmolecule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1193,15 +1193,22 @@ void OpenMMMolecule::alignInternals(const PropertyMap &map)
{
if (is_ghost(clj0))
{
from_ghost_idxs.insert(i);
// ghost atoms are only ghosts is they are real in at
// least one end state (cannot be both a to_ghost and
// a from_ghost atom - this is also implicitly tested
// for above in the clj0 != clj1)
if (not is_ghost(clj1))
{
from_ghost_idxs.insert(i);

// alpha is 1 for the reference state for ghost atoms
// (and will be 0 for the perturbed state)
this->alphas[i] = 1.0;
// alpha is 1 for the reference state for ghost atoms
// (and will be 0 for the perturbed state)
this->alphas[i] = 1.0;

// kappa is 1 for both end states for ghost atoms
this->kappas[i] = 1.0;
this->perturbed->kappas[i] = 1.0;
// kappa is 1 for both end states for ghost atoms
this->kappas[i] = 1.0;
this->perturbed->kappas[i] = 1.0;
}
}
else if (is_ghost(clj1))
{
Expand Down Expand Up @@ -1795,6 +1802,18 @@ void OpenMMMolecule::copyInCoordsAndVelocities(OpenMM::Vec3 *c, OpenMM::Vec3 *v)
}
}

/** Return the number of atoms in this molecule */
int OpenMMMolecule::nAtoms() const
{
return this->coords.count();
}

/** Return the number of ghost atoms (sum of to_ghosts and from_ghosts) */
int OpenMMMolecule::nGhostAtoms() const
{
return from_ghost_idxs.count() + to_ghost_idxs.count();
}

/** Return the alpha parameters of all atoms in atom order for
* this molecule
*/
Expand Down Expand Up @@ -2203,12 +2222,12 @@ PerturbableOpenMMMolecule::PerturbableOpenMMMolecule(const OpenMMMolecule &mol,

for (int i = 0; i < nats; ++i)
{
if (std::abs(sig0_data[i]) < 1e-9)
if (std::abs(sig0_data[i]) <= 1e-9)
{
sig0[i] = sig1_data[i];
sig0_data = sig0.constData();
}
else if (std::abs(sig1_data[i] < 1e-9))
else if (std::abs(sig1_data[i] <= 1e-9))
{
sig1[i] = sig0_data[i];
sig1_data = sig1.constData();
Expand Down
3 changes: 3 additions & 0 deletions wrapper/Convert/SireOpenMM/openmmmolecule.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ namespace SireOpenMM

bool isGhostAtom(int atom) const;

int nAtoms() const;
int nGhostAtoms() const;

boost::tuple<int, int, double, double, double>
getException(int atom0, int atom1,
int start_index,
Expand Down
Loading