hillclimber 0.1.0a1__py3-none-any.whl → 0.1.0a2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of hillclimber might be problematic. Click here for more details.
- hillclimber/__init__.py +16 -5
- hillclimber/actions.py +29 -3
- hillclimber/biases.py +293 -0
- hillclimber/cvs.py +630 -238
- hillclimber/interfaces.py +45 -5
- hillclimber/metadynamics.py +11 -9
- hillclimber/opes.py +342 -0
- hillclimber/selectors.py +127 -2
- hillclimber/virtual_atoms.py +335 -0
- {hillclimber-0.1.0a1.dist-info → hillclimber-0.1.0a2.dist-info}/METADATA +1 -1
- hillclimber-0.1.0a2.dist-info/RECORD +16 -0
- hillclimber-0.1.0a1.dist-info/RECORD +0 -13
- {hillclimber-0.1.0a1.dist-info → hillclimber-0.1.0a2.dist-info}/WHEEL +0 -0
- {hillclimber-0.1.0a1.dist-info → hillclimber-0.1.0a2.dist-info}/entry_points.txt +0 -0
- {hillclimber-0.1.0a1.dist-info → hillclimber-0.1.0a2.dist-info}/licenses/LICENSE +0 -0
hillclimber/__init__.py
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
|
-
from hillclimber.actions import
|
|
2
|
-
from hillclimber.
|
|
3
|
-
from hillclimber.
|
|
1
|
+
from hillclimber.actions import PrintAction
|
|
2
|
+
from hillclimber.biases import RestraintBias, UpperWallBias, LowerWallBias
|
|
3
|
+
from hillclimber.cvs import DistanceCV, AngleCV, CoordinationNumberCV, TorsionCV, RadiusOfGyrationCV
|
|
4
|
+
from hillclimber.metadynamics import MetadBias, MetaDynamicsConfig, MetaDynamicsModel
|
|
5
|
+
from hillclimber.opes import OPESBias, OPESConfig, OPESModel
|
|
4
6
|
from hillclimber.selectors import IndexSelector, SMARTSSelector, SMILESSelector
|
|
7
|
+
from hillclimber.virtual_atoms import VirtualAtom
|
|
5
8
|
|
|
6
9
|
__all__ = [
|
|
7
|
-
"
|
|
10
|
+
"PrintAction",
|
|
8
11
|
"DistanceCV",
|
|
12
|
+
"AngleCV",
|
|
9
13
|
"CoordinationNumberCV",
|
|
10
14
|
"TorsionCV",
|
|
11
15
|
"RadiusOfGyrationCV",
|
|
12
16
|
"IndexSelector",
|
|
13
17
|
"SMILESSelector",
|
|
14
18
|
"SMARTSSelector",
|
|
19
|
+
"VirtualAtom",
|
|
15
20
|
"MetaDynamicsModel",
|
|
16
|
-
"
|
|
21
|
+
"MetadBias",
|
|
17
22
|
"MetaDynamicsConfig",
|
|
23
|
+
"OPESModel",
|
|
24
|
+
"OPESBias",
|
|
25
|
+
"OPESConfig",
|
|
26
|
+
"RestraintBias",
|
|
27
|
+
"UpperWallBias",
|
|
28
|
+
"LowerWallBias",
|
|
18
29
|
]
|
hillclimber/actions.py
CHANGED
|
@@ -2,12 +2,38 @@ import dataclasses
|
|
|
2
2
|
|
|
3
3
|
import ase
|
|
4
4
|
|
|
5
|
-
from hillclimber.interfaces import CollectiveVariable
|
|
5
|
+
from hillclimber.interfaces import CollectiveVariable, PlumedGenerator
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
@dataclasses.dataclass
|
|
9
|
-
class
|
|
10
|
-
"""
|
|
9
|
+
class PrintAction(PlumedGenerator):
|
|
10
|
+
"""PLUMED PRINT action for outputting collective variables.
|
|
11
|
+
|
|
12
|
+
This action prints the values of collective variables to a file during
|
|
13
|
+
the simulation. Multiple CVs can be printed to the same file.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
cvs : list[CollectiveVariable]
|
|
18
|
+
List of collective variables to print.
|
|
19
|
+
stride : int, optional
|
|
20
|
+
Print every N steps, by default 1.
|
|
21
|
+
file : str, optional
|
|
22
|
+
Output file name, by default "COLVAR".
|
|
23
|
+
|
|
24
|
+
Examples
|
|
25
|
+
--------
|
|
26
|
+
>>> import hillclimber as hc
|
|
27
|
+
>>> print_action = hc.PrintAction(
|
|
28
|
+
... cvs=[cv1, cv2, cv3],
|
|
29
|
+
... stride=100,
|
|
30
|
+
... file="COLVAR"
|
|
31
|
+
... )
|
|
32
|
+
|
|
33
|
+
Resources
|
|
34
|
+
---------
|
|
35
|
+
- https://www.plumed.org/doc-master/user-doc/html/PRINT/
|
|
36
|
+
"""
|
|
11
37
|
|
|
12
38
|
cvs: list[CollectiveVariable]
|
|
13
39
|
stride: int = 1
|
hillclimber/biases.py
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"""Bias potentials and restraints for collective variables.
|
|
2
|
+
|
|
3
|
+
This module provides classes for applying bias potentials to collective variables,
|
|
4
|
+
including harmonic restraints and wall potentials.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# --- IMPORTS ---
|
|
8
|
+
import dataclasses
|
|
9
|
+
|
|
10
|
+
import ase
|
|
11
|
+
|
|
12
|
+
from hillclimber.interfaces import BiasProtocol, CollectiveVariable
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# --- RESTRAINT ---
|
|
16
|
+
@dataclasses.dataclass
|
|
17
|
+
class RestraintBias(BiasProtocol):
|
|
18
|
+
"""Apply a harmonic restraint to a collective variable.
|
|
19
|
+
|
|
20
|
+
This class implements the BiasProtocol interface and can be used in the
|
|
21
|
+
`actions` parameter of MetaDynamicsModel.
|
|
22
|
+
|
|
23
|
+
The restraint creates a harmonic potential that restrains a collective variable
|
|
24
|
+
around a specified value. The restraint potential has the form:
|
|
25
|
+
V(s) = (1/2) * kappa * (s - at)^2
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
cv : CollectiveVariable
|
|
30
|
+
The collective variable to restrain.
|
|
31
|
+
kappa : float
|
|
32
|
+
The force constant of the restraint in kJ/(mol·unit^2), where unit
|
|
33
|
+
depends on the CV (e.g., Å for distances, radians for angles).
|
|
34
|
+
at : float
|
|
35
|
+
The center/target value of the restraint.
|
|
36
|
+
label : str, optional
|
|
37
|
+
A custom label for this restraint. If not provided, uses cv.prefix + "_restraint".
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
>>> import hillclimber as hc
|
|
42
|
+
>>> # Restrain a distance around 2.5 Å
|
|
43
|
+
>>> distance_cv = hc.DistanceCV(...)
|
|
44
|
+
>>> restraint = hc.RestraintBias(cv=distance_cv, kappa=200.0, at=2.5)
|
|
45
|
+
|
|
46
|
+
Resources
|
|
47
|
+
---------
|
|
48
|
+
- https://www.plumed.org/doc-master/user-doc/html/RESTRAINT/
|
|
49
|
+
|
|
50
|
+
Notes
|
|
51
|
+
-----
|
|
52
|
+
The force constant kappa is in kJ/(mol·unit^2). For typical CV units:
|
|
53
|
+
- Distances (Å): kappa in kJ/(mol·Å^2)
|
|
54
|
+
- Angles (radians): kappa in kJ/(mol·rad^2)
|
|
55
|
+
- Dimensionless CVs: kappa in kJ/mol
|
|
56
|
+
|
|
57
|
+
The restraint creates a bias force: F = -kappa * (s - at)
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
cv: CollectiveVariable
|
|
61
|
+
kappa: float
|
|
62
|
+
at: float
|
|
63
|
+
label: str | None = None
|
|
64
|
+
|
|
65
|
+
def to_plumed(self, atoms: ase.Atoms) -> list[str]:
|
|
66
|
+
"""Generate PLUMED input strings for the harmonic restraint.
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
atoms : ase.Atoms
|
|
71
|
+
The atomic structure to use for generating the PLUMED string.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
list[str]
|
|
76
|
+
List of PLUMED command strings. First defines the CV (if needed),
|
|
77
|
+
then applies the restraint.
|
|
78
|
+
"""
|
|
79
|
+
# Get CV definition
|
|
80
|
+
cv_labels, cv_commands = self.cv.to_plumed(atoms)
|
|
81
|
+
|
|
82
|
+
# Determine restraint label
|
|
83
|
+
restraint_label = self.label if self.label else f"{self.cv.prefix}_restraint"
|
|
84
|
+
|
|
85
|
+
# Build restraint command
|
|
86
|
+
# PLUMED expects ARG to be comma-separated CV labels
|
|
87
|
+
arg_str = ",".join(cv_labels)
|
|
88
|
+
restraint_cmd = f"{restraint_label}: RESTRAINT ARG={arg_str} KAPPA={self.kappa} AT={self.at}"
|
|
89
|
+
|
|
90
|
+
# Combine CV commands and restraint
|
|
91
|
+
commands = cv_commands + [restraint_cmd]
|
|
92
|
+
return commands
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# --- WALLS ---
|
|
96
|
+
@dataclasses.dataclass
|
|
97
|
+
class UpperWallBias(BiasProtocol):
|
|
98
|
+
"""Apply an upper wall restraint to a collective variable.
|
|
99
|
+
|
|
100
|
+
This class implements the BiasProtocol interface and can be used in the
|
|
101
|
+
`actions` parameter of MetaDynamicsModel.
|
|
102
|
+
|
|
103
|
+
The wall creates a repulsive bias potential that acts when a collective
|
|
104
|
+
variable exceeds a specified threshold. The wall potential has the form:
|
|
105
|
+
V(s) = kappa * ((s - at) / offset)^exp if s > at, else 0
|
|
106
|
+
|
|
107
|
+
Parameters
|
|
108
|
+
----------
|
|
109
|
+
cv : CollectiveVariable
|
|
110
|
+
The collective variable to apply the wall to.
|
|
111
|
+
at : float
|
|
112
|
+
The position of the wall (threshold value).
|
|
113
|
+
kappa : float
|
|
114
|
+
The force constant of the wall in kJ/mol.
|
|
115
|
+
exp : int, optional
|
|
116
|
+
The exponent of the wall potential. Default is 2 (harmonic).
|
|
117
|
+
Higher values create steeper walls.
|
|
118
|
+
eps : float, optional
|
|
119
|
+
A small offset to avoid numerical issues. Default is 0.0.
|
|
120
|
+
offset : float, optional
|
|
121
|
+
The offset parameter for the wall. Default is 0.0.
|
|
122
|
+
label : str, optional
|
|
123
|
+
A custom label for this wall. If not provided, uses cv.prefix + "_uwall".
|
|
124
|
+
|
|
125
|
+
Examples
|
|
126
|
+
--------
|
|
127
|
+
>>> import hillclimber as hc
|
|
128
|
+
>>> # Prevent distance from exceeding 3.0 Å
|
|
129
|
+
>>> distance_cv = hc.DistanceCV(...)
|
|
130
|
+
>>> upper_wall = hc.UpperWallBias(cv=distance_cv, at=3.0, kappa=100.0, exp=2)
|
|
131
|
+
|
|
132
|
+
Resources
|
|
133
|
+
---------
|
|
134
|
+
- https://www.plumed.org/doc-master/user-doc/html/UPPER_WALLS/
|
|
135
|
+
|
|
136
|
+
Notes
|
|
137
|
+
-----
|
|
138
|
+
The wall only acts when the CV value exceeds 'at'. The steepness of the
|
|
139
|
+
wall is controlled by both 'kappa' and 'exp':
|
|
140
|
+
- exp=2: harmonic wall (smooth)
|
|
141
|
+
- exp=4,6,...: steeper walls
|
|
142
|
+
- Higher exp values create harder walls but may cause numerical issues
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
cv: CollectiveVariable
|
|
146
|
+
at: float
|
|
147
|
+
kappa: float
|
|
148
|
+
exp: int = 2
|
|
149
|
+
eps: float = 0.0
|
|
150
|
+
offset: float = 0.0
|
|
151
|
+
label: str | None = None
|
|
152
|
+
|
|
153
|
+
def to_plumed(self, atoms: ase.Atoms) -> list[str]:
|
|
154
|
+
"""Generate PLUMED input strings for the upper wall.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
atoms : ase.Atoms
|
|
159
|
+
The atomic structure to use for generating the PLUMED string.
|
|
160
|
+
|
|
161
|
+
Returns
|
|
162
|
+
-------
|
|
163
|
+
list[str]
|
|
164
|
+
List of PLUMED command strings. First defines the CV (if needed),
|
|
165
|
+
then applies the upper wall.
|
|
166
|
+
"""
|
|
167
|
+
# Get CV definition
|
|
168
|
+
cv_labels, cv_commands = self.cv.to_plumed(atoms)
|
|
169
|
+
|
|
170
|
+
# Determine wall label
|
|
171
|
+
wall_label = self.label if self.label else f"{self.cv.prefix}_uwall"
|
|
172
|
+
|
|
173
|
+
# Build wall command
|
|
174
|
+
arg_str = ",".join(cv_labels)
|
|
175
|
+
wall_parts = [
|
|
176
|
+
f"{wall_label}: UPPER_WALLS",
|
|
177
|
+
f"ARG={arg_str}",
|
|
178
|
+
f"AT={self.at}",
|
|
179
|
+
f"KAPPA={self.kappa}",
|
|
180
|
+
f"EXP={self.exp}",
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
# Add optional parameters only if non-zero
|
|
184
|
+
if self.eps != 0.0:
|
|
185
|
+
wall_parts.append(f"EPS={self.eps}")
|
|
186
|
+
if self.offset != 0.0:
|
|
187
|
+
wall_parts.append(f"OFFSET={self.offset}")
|
|
188
|
+
|
|
189
|
+
wall_cmd = " ".join(wall_parts)
|
|
190
|
+
|
|
191
|
+
# Combine CV commands and wall
|
|
192
|
+
commands = cv_commands + [wall_cmd]
|
|
193
|
+
return commands
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@dataclasses.dataclass
|
|
197
|
+
class LowerWallBias(BiasProtocol):
|
|
198
|
+
"""Apply a lower wall restraint to a collective variable.
|
|
199
|
+
|
|
200
|
+
This class implements the BiasProtocol interface and can be used in the
|
|
201
|
+
`actions` parameter of MetaDynamicsModel.
|
|
202
|
+
|
|
203
|
+
The wall creates a repulsive bias potential that acts when a collective
|
|
204
|
+
variable falls below a specified threshold. The wall potential has the form:
|
|
205
|
+
V(s) = kappa * ((at - s) / offset)^exp if s < at, else 0
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
cv : CollectiveVariable
|
|
210
|
+
The collective variable to apply the wall to.
|
|
211
|
+
at : float
|
|
212
|
+
The position of the wall (threshold value).
|
|
213
|
+
kappa : float
|
|
214
|
+
The force constant of the wall in kJ/mol.
|
|
215
|
+
exp : int, optional
|
|
216
|
+
The exponent of the wall potential. Default is 2 (harmonic).
|
|
217
|
+
Higher values create steeper walls.
|
|
218
|
+
eps : float, optional
|
|
219
|
+
A small offset to avoid numerical issues. Default is 0.0.
|
|
220
|
+
offset : float, optional
|
|
221
|
+
The offset parameter for the wall. Default is 0.0.
|
|
222
|
+
label : str, optional
|
|
223
|
+
A custom label for this wall. If not provided, uses cv.prefix + "_lwall".
|
|
224
|
+
|
|
225
|
+
Examples
|
|
226
|
+
--------
|
|
227
|
+
>>> import hillclimber as hc
|
|
228
|
+
>>> # Prevent distance from going below 1.0 Å
|
|
229
|
+
>>> distance_cv = hc.DistanceCV(...)
|
|
230
|
+
>>> lower_wall = hc.LowerWallBias(cv=distance_cv, at=1.0, kappa=100.0, exp=2)
|
|
231
|
+
|
|
232
|
+
Resources
|
|
233
|
+
---------
|
|
234
|
+
- https://www.plumed.org/doc-master/user-doc/html/LOWER_WALLS
|
|
235
|
+
|
|
236
|
+
Notes
|
|
237
|
+
-----
|
|
238
|
+
The wall only acts when the CV value falls below 'at'. The steepness of the
|
|
239
|
+
wall is controlled by both 'kappa' and 'exp':
|
|
240
|
+
- exp=2: harmonic wall (smooth)
|
|
241
|
+
- exp=4,6,...: steeper walls
|
|
242
|
+
- Higher exp values create harder walls but may cause numerical issues
|
|
243
|
+
"""
|
|
244
|
+
|
|
245
|
+
cv: CollectiveVariable
|
|
246
|
+
at: float
|
|
247
|
+
kappa: float
|
|
248
|
+
exp: int = 2
|
|
249
|
+
eps: float = 0.0
|
|
250
|
+
offset: float = 0.0
|
|
251
|
+
label: str | None = None
|
|
252
|
+
|
|
253
|
+
def to_plumed(self, atoms: ase.Atoms) -> list[str]:
|
|
254
|
+
"""Generate PLUMED input strings for the lower wall.
|
|
255
|
+
|
|
256
|
+
Parameters
|
|
257
|
+
----------
|
|
258
|
+
atoms : ase.Atoms
|
|
259
|
+
The atomic structure to use for generating the PLUMED string.
|
|
260
|
+
|
|
261
|
+
Returns
|
|
262
|
+
-------
|
|
263
|
+
list[str]
|
|
264
|
+
List of PLUMED command strings. First defines the CV (if needed),
|
|
265
|
+
then applies the lower wall.
|
|
266
|
+
"""
|
|
267
|
+
# Get CV definition
|
|
268
|
+
cv_labels, cv_commands = self.cv.to_plumed(atoms)
|
|
269
|
+
|
|
270
|
+
# Determine wall label
|
|
271
|
+
wall_label = self.label if self.label else f"{self.cv.prefix}_lwall"
|
|
272
|
+
|
|
273
|
+
# Build wall command
|
|
274
|
+
arg_str = ",".join(cv_labels)
|
|
275
|
+
wall_parts = [
|
|
276
|
+
f"{wall_label}: LOWER_WALLS",
|
|
277
|
+
f"ARG={arg_str}",
|
|
278
|
+
f"AT={self.at}",
|
|
279
|
+
f"KAPPA={self.kappa}",
|
|
280
|
+
f"EXP={self.exp}",
|
|
281
|
+
]
|
|
282
|
+
|
|
283
|
+
# Add optional parameters only if non-zero
|
|
284
|
+
if self.eps != 0.0:
|
|
285
|
+
wall_parts.append(f"EPS={self.eps}")
|
|
286
|
+
if self.offset != 0.0:
|
|
287
|
+
wall_parts.append(f"OFFSET={self.offset}")
|
|
288
|
+
|
|
289
|
+
wall_cmd = " ".join(wall_parts)
|
|
290
|
+
|
|
291
|
+
# Combine CV commands and wall
|
|
292
|
+
commands = cv_commands + [wall_cmd]
|
|
293
|
+
return commands
|