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

1""" 

2.. class:: RadiusOfGyration 

3 :platform: Linux, MacOS, Windows 

4 :synopsis: The radius of gyration of a group of atoms 

5 

6.. classauthor:: Charlles Abreu <craabreu@gmail.com> 

7 

8""" 

9 

10import typing as t 

11 

12from openmm import unit as mmunit 

13 

14from .base_radius_of_gyration import BaseRadiusOfGyration 

15 

16 

17class RadiusOfGyration(BaseRadiusOfGyration): 

18 r""" 

19 The radius of gyration of a group of :math:`n` atoms: 

20 

21 .. math:: 

22 

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 }. 

26 

27 where :math:`{\bf r}_c({\bf r})` is the geometric center of the group: 

28 

29 .. math:: 

30 

31 {\bf r}_c({\bf r}) = \frac{1}{n} \sum_{i=j}^n {\bf r}_j 

32 

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: 

35 

36 .. math:: 

37 

38 {\bf r}_m({\bf r}) = \frac{1}{M} \sum_{i=1}^n m_i {\bf r}_i 

39 

40 where :math:`M = \sum_{i=1}^n m_i` is the total mass of the group. 

41 

42 .. note:: 

43 

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. 

46 

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. 

57 

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 

73 

74 """ 

75 

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 ) 

96 

97 

98RadiusOfGyration.registerTag("!cvpack.RadiusOfGyration")