Skip to content

Commit 6b9ae00

Browse files
authored
Merge pull request #525 from OpenBioSim/release_2026.1.0
2 parents f0d1b57 + 5b7c748 commit 6b9ae00

57 files changed

Lines changed: 3264 additions & 325 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

doc/source/changelog.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,25 @@ 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+
`2026.1.0 <https://github.com/openbiosim/biosimspace/compare/2025.4.0...2026.1.0>`_ - Jun 29 2026
13+
-------------------------------------------------------------------------------------------------
14+
15+
* Improve ring break and size change detection during molecule merging (`#502 <https://github.com/OpenBioSim/biosimspace/pull/502>`__).
16+
* Add support for merging molecules with non-default intramolecular scaling factors (`#506 <https://github.com/OpenBioSim/biosimspace/pull/506>`__).
17+
* Add support for perturbable CMAP terms during molecule merging (`#508 <https://github.com/OpenBioSim/biosimspace/pull/508>`__).
18+
* Normalise ``SOMD2`` Parquet file metadata to avoid rounding issues (`#510 <https://github.com/OpenBioSim/biosimspace/pull/510>`__).
19+
* Update the ``prepareFEP`` helper script to generate ``SOMD1`` and ``SOMD2`` inputs simultaneously (`#516 <https://github.com/OpenBioSim/biosimspace/pull/516>`__).
20+
* Remove cross-bond angle and torsion terms for ring-making/breaking perturbations (`#517 <https://github.com/OpenBioSim/biosimspace/pull/517>`__).
21+
* Added functionaltiy for adding ions to an existing system (`#518 <https://github.com/OpenBioSim/biosimspace/pull/518>`__).
22+
* Expose the ``max_path`` and ``max_ring_size`` kwargs used for ring break and size change detection in the :func:`BioSimSpace.Align.generateNetwork <BioSimSpace.Align.merge>` function (`#520 <https://github.com/OpenBioSim/biosimspace/pull/520>`__).
23+
* Add support for user-defined "region-of-interest" merges (`#522 <https://github.com/OpenBioSim/biosimspace/pull/522>`__).
24+
* Add pins to handle OpenForceField Python version deprecations (`#524 <https://github.com/OpenBioSim/biosimspace/pull/524>`__).
25+
1226
`2025.4.0 <https://github.com/openbiosim/biosimspace/compare/2025.3.0...2025.4.0>`_ - Feb 17 2026
1327
-------------------------------------------------------------------------------------------------
1428

1529
* Fixed centre of mass restraints for alchemical transfer method (ATM) simulations (`@mb2055 <https://github.com/mb2055>`__) (`#471 <https://github.com/OpenBioSim/biosimspace/pull/471>`__).
1630
* Add experimental :class:`ReplicaSystem` class to speed up handling of replica exchange simulations (`#473 <https://github.com/OpenBioSim/biosimspace/pull/473>`__).
17-
* Add experimental :class:`ReplicaSystem` class to speed up handling of replica exchange simulations (`#473 <https://github.com/OpenBioSim/biosimspace/pull/473>`__).
1831
* Removed lazy imports from sub-modules that don't use Sire (`#475 <https://github.com/OpenBioSim/biosimspace/pull/475>`__).
1932
* Allow translation of a custom ``coordinates`` property for perturbable molecules (`#477 <https://github.com/OpenBioSim/biosimspace/pull/477>`__).
2033
* Added a kwarg to make zeroing of LJ sigma values for ghost atoms optional (`#482 <https://github.com/OpenBioSim/biosimspace/pull/482>`__).
32.7 KB
Loading
32 KB
Loading
27.3 KB
Loading

doc/source/tutorials/protein_mutations.rst

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ figure out the residue index of our residue of interest (ROI):
198198
199199
We can see that the residue with the index value of 8 are different
200200
between the two proteins. Let’s pass this value to the
201-
```BioSimSpace.Align.matchAtoms`` <https://biosimspace.openbiosim.org/api/generated/BioSimSpace.Align.matchAtoms.html#BioSimSpace.Align.matchAtoms>`__
201+
`BioSimSpace.Align.matchAtoms <https://biosimspace.openbiosim.org/api/generated/BioSimSpace.Align.matchAtoms.html>`__
202202
function:
203203

204204
.. code:: ipython3
@@ -398,3 +398,169 @@ simulations <https://github.com/OpenBioSim/biosimspace_tutorials/tree/main/04_fe
398398
solvated_system = BSS.Solvent.tip3p(molecule=merged_system, box=box, angles=angles, ion_conc=0.15)
399399
400400
BSS.IO.saveMolecules("holo_aldose_reductase_v47i", solvated_system, ["gro87", "grotop"])
401+
402+
Advanced Case - Bond Creation/Annihilation Transformations
403+
==========================================================
404+
405+
In this tutorial we will use BioSimSpace’s mapping functionality to set
406+
up alchemical calculations involving proline mutations in a protein.
407+
Specifically, we will look at the Leu-to-Pro mutations in OMTKY3 to its
408+
receptors as `detailed in this
409+
study <https://pubs.acs.org/doi/full/10.1021/acs.jctc.1c00214>`__.
410+
411+
.. code:: ipython3
412+
413+
wt = BSS.IO.readMolecules(
414+
BSS.IO.expand(BSS.tutorialUrl(), f"1choFH_apo_wt_flare_processed.pdb")
415+
)[0]
416+
mut = BSS.IO.readMolecules(
417+
BSS.IO.expand(BSS.tutorialUrl(), f"1choFH_apo_mut_flare_processed.pdb")
418+
)[0]
419+
420+
wt = BSS.Parameters.ff14SB(wt, ensure_compatible=False).getMolecule()
421+
mut = BSS.Parameters.ff14SB(mut, ensure_compatible=False).getMolecule()
422+
423+
424+
425+
Comparing the residues between two proteins shows us that the residues
426+
at index 15 are different between the proteins
427+
428+
.. code:: ipython3
429+
430+
roi = []
431+
for i, res in enumerate(wt.getResidues()):
432+
if res.name() != mut.getResidues()[i].name():
433+
print(res, mut.getResidues()[i])
434+
roi.append(res.index())
435+
436+
437+
.. parsed-literal::
438+
439+
<BioSimSpace.Residue: name='LEU', molecule=5, index=15, nAtoms=19> <BioSimSpace.Residue: name='PRO', molecule=7, index=15, nAtoms=14>
440+
441+
442+
By default, the
443+
`BioSimSpace.Align.matchAtoms <https://biosimspace.openbiosim.org/api/generated/BioSimSpace.Align.matchAtoms.html>`__
444+
would fail to create a mapping for the ROI region, as the underlying
445+
RDKit MCS algorithm would be unable to determine a mapping between two
446+
molecular graphs with a fundamental topological mismatch. Because
447+
Proline’s sidechain forms a cyclic system with the backbone, its atoms
448+
exist in a ring topology. The algorithm restricts the mapping of cyclic
449+
atoms to acyclic atoms (a behavior governed by parameters like
450+
``ringMatchesRingOnly``) to preserve the chemical integrity of the
451+
substructure. Consequently, a 1:1 mapping between the ring-bound
452+
sidechain of Proline and the acyclic sidechain of the Leucine residue
453+
cannot be determined.
454+
455+
Instead we can use the ``custom_roi_map`` argument of the
456+
`BioSimSpace.Align.matchAtoms <https://biosimspace.openbiosim.org/api/generated/BioSimSpace.Align.matchAtoms.html>`__
457+
to override the RDKit MCS mapping. For example we can force an empty
458+
mapping between the two residues:
459+
460+
.. code:: ipython3
461+
462+
mapping = BSS.Align.matchAtoms(molecule0=wt, molecule1=mut, roi=[15], custom_roi_map={})
463+
464+
.. code:: ipython3
465+
466+
BSS.Align.viewMapping(wt, mut, mapping, roi=15, pixels=500)
467+
468+
469+
470+
.. image:: images/custom_roi_no_map.png
471+
:width: 800
472+
473+
474+
If we know the correct 1:1 atom mapping between the two residues, we can
475+
pass that to the ``custom_roi_map`` which will allows us to setup an
476+
alchemical bond transformation for mutating the leucine residue to
477+
proline. Note that **absolute atom indices need to be passed, i.e the
478+
indices of the residues in the context of the whole protein**. We can
479+
use something like PyMol to help us map the atoms in the right order:
480+
481+
.. image:: images/1choFH_mapping_pymol.png
482+
:width: 800
483+
484+
.. code:: ipython3
485+
486+
mapping = BSS.Align.matchAtoms(molecule0=wt, molecule1=mut, roi=[15], custom_roi_map={204:204,205:205,203:203,202:202,211:208,206:206,213:210,207:207,214:211,210:213})
487+
488+
.. code:: ipython3
489+
490+
BSS.Align.viewMapping(wt, mut, mapping, roi=15, pixels=500)
491+
492+
493+
494+
.. image:: images/custom_roi_ring_break_map.png
495+
:width: 800
496+
497+
498+
We can then use ``allow_ring_breaking=True`` argument of the
499+
`BioSimSpace.Align.merge <https://biosimspace.openbiosim.org/api/generated/BioSimSpace.Align.merge.html>`__
500+
to create the required alchemical transformation:
501+
502+
.. code:: ipython3
503+
504+
aligned_wt = BSS.Align.rmsdAlign(molecule0=wt, mapping=mapping, molecule1=mut)
505+
merged_protein = BSS.Align.merge(aligned_wt, mut, mapping, allow_ring_breaking=True, roi=[15])
506+
507+
But how do we actually know that the merge has built a perturbable
508+
molecule that now has a bond annihilation or creation involved? We can
509+
use Sire’s conversion features to check what kinds of alchemical
510+
modifications are happening in our perturbable molecule. You can check
511+
out the corresponding `Sire
512+
tutorial <https://sire.openbiosim.org/tutorial/part07/04_merge.html>`__
513+
for more details.
514+
515+
.. code:: ipython3
516+
517+
merged_protein_sire = merged_protein._sire_object
518+
pert = merged_protein_sire.perturbation()
519+
pert_omm = pert.to_openmm(map={"coordinates":"coordinates0"})
520+
521+
pert_omm.changed_bonds(to_pandas=True)
522+
523+
524+
525+
526+
527+
.. raw:: html
528+
529+
<div>
530+
<table border="1" class="dataframe">
531+
<thead>
532+
<tr style="text-align: right;">
533+
<th></th>
534+
<th>bond</th>
535+
<th>length0</th>
536+
<th>length1</th>
537+
<th>k0</th>
538+
<th>k1</th>
539+
</tr>
540+
</thead>
541+
<tbody>
542+
<tr>
543+
<th>0</th>
544+
<td>N:203-H:211</td>
545+
<td>0.1010</td>
546+
<td>0.1449</td>
547+
<td>363171.2</td>
548+
<td>282001.6</td>
549+
</tr>
550+
<tr>
551+
<th>1</th>
552+
<td>CG:208-H:211</td>
553+
<td>0.1526</td>
554+
<td>0.1526</td>
555+
<td>0.0</td>
556+
<td>259408.0</td>
557+
</tr>
558+
</tbody>
559+
</table>
560+
</div>
561+
562+
563+
564+
By comparing the ``k0`` and ``k1`` values in the changed bond dataframe,
565+
we can see that the transformation is going to result in a bond being
566+
created.

0 commit comments

Comments
 (0)