Coverage for cvpack/radius_of_gyration.py: 100%
13 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-09 16:14 +0000
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-09 16:14 +0000
1"""
2.. class:: RadiusOfGyration
3 :platform: Linux, MacOS, Windows
4 :synopsis: The radius of gyration of a group of atoms
6.. classauthor:: Charlles Abreu <craabreu@gmail.com>
8"""
10import typing as t
12from openmm import unit as mmunit
14from .base_radius_of_gyration import BaseRadiusOfGyration
17class RadiusOfGyration(BaseRadiusOfGyration):
18 r"""
19 The radius of gyration of a group of :math:`n` atoms:
21 .. math::
23 r_g({\bf r}) = \sqrt{ \frac{1}{n} \sum_{i=1}^n \left\|
24 {\bf r}_i - {\bf r}_c({\bf r})
25 \right\|^2 }.
27 where :math:`{\bf r}_c({\bf r})` is the geometric center of the group:
29 .. math::
31 {\bf r}_c({\bf r}) = \frac{1}{n} \sum_{i=j}^n {\bf r}_j
33 Optionally, the radius of gyration can be computed with respect to the center of
34 mass of the group. In this case, the geometric center is replaced by:
36 .. math::
38 {\bf r}_m({\bf r}) = \frac{1}{M} \sum_{i=1}^n m_i {\bf r}_i
40 where :math:`M = \sum_{i=1}^n m_i` is the total mass of the group.
42 .. note::
44 This collective variable lacks parallelization and might be slow when the group
45 of atoms is large. In this case, :class:`RadiusOfGyrationSq` might be preferred.
47 Parameters
48 ----------
49 group
50 The indices of the atoms in the group.
51 pbc
52 Whether to use periodic boundary conditions.
53 weighByMass
54 Whether to use the center of mass of the group instead of its geometric center.
55 name
56 The name of the collective variable.
58 Example
59 -------
60 >>> import cvpack
61 >>> import openmm
62 >>> from openmmtools import testsystems
63 >>> model = testsystems.AlanineDipeptideVacuum()
64 >>> num_atoms = model.system.getNumParticles()
65 >>> radius_of_gyration = cvpack.RadiusOfGyration(list(range(num_atoms)))
66 >>> radius_of_gyration.addToSystem(model.system)
67 >>> platform = openmm.Platform.getPlatformByName('Reference')
68 >>> integrator = openmm.VerletIntegrator(0)
69 >>> context = openmm.Context(model.system, integrator, platform)
70 >>> context.setPositions(model.positions)
71 >>> radius_of_gyration.getValue(context)
72 0.2951... nm
74 """
76 def __init__(
77 self,
78 group: t.Iterable[int],
79 pbc: bool = False,
80 weighByMass: bool = False,
81 name: str = "radius_of_gyration",
82 ) -> None:
83 group = list(group)
84 num_atoms = len(group)
85 num_groups = num_atoms + 1
86 sum_dist_sq = "+".join(
87 [f"distance(g{i+1}, g{num_atoms + 1})^2" for i in range(num_atoms)]
88 )
89 super().__init__(
90 num_groups, f"sqrt(({sum_dist_sq})/{num_atoms})", group, pbc, weighByMass
91 )
92 self.addBond(list(range(num_groups)))
93 self._registerCV(
94 name, mmunit.nanometers, group=group, pbc=pbc, weighByMass=weighByMass
95 )
98RadiusOfGyration.registerTag("!cvpack.RadiusOfGyration")