jflows-md 0.5.3__tar.gz
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.
- jflows_md-0.5.3/LICENSE +21 -0
- jflows_md-0.5.3/PKG-INFO +455 -0
- jflows_md-0.5.3/README.md +420 -0
- jflows_md-0.5.3/jflows_md/__init__.py +121 -0
- jflows_md-0.5.3/jflows_md/artifacts.py +19 -0
- jflows_md-0.5.3/jflows_md/boltzmann/__init__.py +904 -0
- jflows_md-0.5.3/jflows_md/boltzmann/load.py +322 -0
- jflows_md-0.5.3/jflows_md/boltzmann/write.py +547 -0
- jflows_md-0.5.3/jflows_md/bundle_build/__init__.py +6 -0
- jflows_md-0.5.3/jflows_md/bundle_build/__main__.py +262 -0
- jflows_md-0.5.3/jflows_md/bundle_build/builder.py +851 -0
- jflows_md-0.5.3/jflows_md/bundle_build/zmatrix.py +162 -0
- jflows_md-0.5.3/jflows_md/core/__init__.py +6 -0
- jflows_md-0.5.3/jflows_md/core/coordinates.py +564 -0
- jflows_md-0.5.3/jflows_md/core/domain.py +40 -0
- jflows_md-0.5.3/jflows_md/core/flow.py +212 -0
- jflows_md-0.5.3/jflows_md/core/forcefield.py +359 -0
- jflows_md-0.5.3/jflows_md/flow.py +181 -0
- jflows_md-0.5.3/jflows_md/openmm/__init__.py +7 -0
- jflows_md-0.5.3/jflows_md/openmm/potential.py +240 -0
- jflows_md-0.5.3/jflows_md/openmm/sampling.py +154 -0
- jflows_md-0.5.3/jflows_md/potential.py +179 -0
- jflows_md-0.5.3/jflows_md/source.py +67 -0
- jflows_md-0.5.3/jflows_md/system.py +83 -0
- jflows_md-0.5.3/jflows_md/train.py +364 -0
- jflows_md-0.5.3/jflows_md/utils/__init__.py +28 -0
- jflows_md-0.5.3/jflows_md/utils/anneal.py +189 -0
- jflows_md-0.5.3/jflows_md/utils/quench.py +85 -0
- jflows_md-0.5.3/jflows_md/utils/rejuvenation.py +142 -0
- jflows_md-0.5.3/jflows_md/version.py +1 -0
- jflows_md-0.5.3/jflows_md.egg-info/PKG-INFO +455 -0
- jflows_md-0.5.3/jflows_md.egg-info/SOURCES.txt +35 -0
- jflows_md-0.5.3/jflows_md.egg-info/dependency_links.txt +1 -0
- jflows_md-0.5.3/jflows_md.egg-info/requires.txt +12 -0
- jflows_md-0.5.3/jflows_md.egg-info/top_level.txt +1 -0
- jflows_md-0.5.3/pyproject.toml +55 -0
- jflows_md-0.5.3/setup.cfg +4 -0
jflows_md-0.5.3/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Xuda
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
jflows_md-0.5.3/PKG-INFO
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: jflows-md
|
|
3
|
+
Version: 0.5.3
|
|
4
|
+
Summary: Mixed-domain molecular potentials, flows, and samplers for jflows.
|
|
5
|
+
Author-email: Xuda <abneryepku@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/xuda-ye-math/jflows_md
|
|
8
|
+
Project-URL: Repository, https://github.com/xuda-ye-math/jflows_md
|
|
9
|
+
Keywords: normalizing-flows,boltzmann-generator,molecular-dynamics,jax,openmm
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: jflows>=0.5.3
|
|
25
|
+
Requires-Dist: jax>=0.6.0
|
|
26
|
+
Requires-Dist: equinox>=0.13.0
|
|
27
|
+
Requires-Dist: numpy>=2.0.0
|
|
28
|
+
Provides-Extra: openmm
|
|
29
|
+
Requires-Dist: openmm>=8.5.0; extra == "openmm"
|
|
30
|
+
Provides-Extra: bundles
|
|
31
|
+
Requires-Dist: openmm>=8.5.0; extra == "bundles"
|
|
32
|
+
Requires-Dist: parmed>=4.3.1; extra == "bundles"
|
|
33
|
+
Requires-Dist: ambertools-unofficial>=26.0.0; extra == "bundles"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# jflows_md
|
|
37
|
+
|
|
38
|
+
`jflows_md` 0.5.3 is the mixed-domain molecular companion to `jflows` 0.5.3.
|
|
39
|
+
It supplies bundle-backed molecular potentials, flows on
|
|
40
|
+
`R^p x T^q`, molecular KLX/KLXX training, sampling kernels, linear
|
|
41
|
+
regularization sharpening, and complete-stage resume.
|
|
42
|
+
|
|
43
|
+
The numerical core is intentionally a raw-performance layer. Constructors and
|
|
44
|
+
compiled kernels assume valid shapes, dtypes, schedules, chunk counts, and
|
|
45
|
+
physical parameters. Bundle construction and structural validation are
|
|
46
|
+
offline concerns; persistence is separate from computation.
|
|
47
|
+
|
|
48
|
+
## Reduced potential and inverse temperature
|
|
49
|
+
|
|
50
|
+
`Molecular_Potential` owns the inverse temperature. For internal coordinates
|
|
51
|
+
`q` and their canonical Cartesian representative `x(q)`, it evaluates
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
U(q) = beta E(x(q)) - log J(q),
|
|
55
|
+
beta = 1 / (k_B T).
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The trainers and Boltzmann controllers consume reduced potentials and do not
|
|
59
|
+
apply another temperature factor. A regularized potential modifies the
|
|
60
|
+
Cartesian energy first and then applies the same `beta`; the coordinate
|
|
61
|
+
Jacobian is never regularized.
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
import jax
|
|
65
|
+
|
|
66
|
+
from jflows_md import Mixed_NSF, Molecular_Potential
|
|
67
|
+
|
|
68
|
+
target = Molecular_Potential.from_bundle("adp_ff96_obc1")
|
|
69
|
+
source = target.source()
|
|
70
|
+
samples = source.samples(jax.random.key(0), 32)
|
|
71
|
+
|
|
72
|
+
flow = Mixed_NSF(
|
|
73
|
+
jax.random.key(1),
|
|
74
|
+
target.domain,
|
|
75
|
+
bins=32,
|
|
76
|
+
transforms=6,
|
|
77
|
+
hidden_features=(256, 256),
|
|
78
|
+
).zeros()
|
|
79
|
+
|
|
80
|
+
soft = target.regularized((50.0, 0.10)) # (e [kJ/mol], r [nm])
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
For `rg_param=(e,r)`, `r` floors only the regular and exception Amber
|
|
84
|
+
Coulomb/Lennard-Jones pair distances. If `E_r` is that floor-aware energy and
|
|
85
|
+
`E_ref,r` its value at the bundle reference, the excess `d=E_r-E_ref,r` is
|
|
86
|
+
mapped by
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
R_e(d) = d if d <= e
|
|
90
|
+
= e [1 + log(d/e)] if d > e.
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The regularized reduced potential is
|
|
94
|
+
`U_rg(q)=beta[E_ref,r+R_e(d)]-log J(q)`. The pair `(e,r)` is the complete
|
|
95
|
+
regularization state; no optimizer clipping parameter participates in this
|
|
96
|
+
definition.
|
|
97
|
+
|
|
98
|
+
## Layout
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
jflows_md/
|
|
102
|
+
├── artifacts.py generic template-based artifacts
|
|
103
|
+
├── boltzmann/
|
|
104
|
+
│ ├── __init__.py pure adaptive-staging BG computation
|
|
105
|
+
│ ├── write.py atomic complete-stage writer
|
|
106
|
+
│ └── load.py load, inspect, fork, and resume
|
|
107
|
+
├── bundle_build/ optional OpenMM-side construction
|
|
108
|
+
├── core/ BAT, Amber/OBC, domain, and spline kernels
|
|
109
|
+
├── flow.py Mixed_Identity and Mixed_NSF
|
|
110
|
+
├── openmm/ native OpenMM potential and samplers
|
|
111
|
+
├── potential.py physical and regularized potentials
|
|
112
|
+
├── source.py Gaussian x uniform-torus source
|
|
113
|
+
├── system.py minimal runtime-bundle loading
|
|
114
|
+
├── train.py compiled molecular KLX/KLXX trainers
|
|
115
|
+
└── utils/
|
|
116
|
+
├── anneal.py SMC and AIS
|
|
117
|
+
├── quench.py quench-and-temper
|
|
118
|
+
└── rejuvenation.py wrapped mixed-domain MALA
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Eager Python controllers split work into chunks; compiled kernels operate on
|
|
122
|
+
fixed array shapes. Filesystem paths, manifests, and resume policy never enter
|
|
123
|
+
the computation functions.
|
|
124
|
+
|
|
125
|
+
The complete low-/medium-/high-level interface manual is in
|
|
126
|
+
[`doc/`](doc/README.md). Narrow executable contracts are organized under
|
|
127
|
+
[`smoke/`](smoke/).
|
|
128
|
+
|
|
129
|
+
## Native OpenMM
|
|
130
|
+
|
|
131
|
+
The same bundle can instantiate an independent Cartesian OpenMM potential.
|
|
132
|
+
It evaluates `beta E(x)` without JAX or the internal-coordinate Jacobian, and
|
|
133
|
+
its `(e,r)` regularization matches `Molecular_Potential.regularized`. Native
|
|
134
|
+
Langevin and replica-exchange runs accept either the physical or regularized
|
|
135
|
+
potential.
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
from jflows_md.openmm import OpenMM_Potential, langevin, parallel_tempering
|
|
139
|
+
|
|
140
|
+
target = OpenMM_Potential.from_bundle("adp_ff96_obc1")
|
|
141
|
+
soft = target.regularized((50.0, 0.10))
|
|
142
|
+
|
|
143
|
+
trajectory, energy = langevin(soft, steps=10000, sample_interval=100)
|
|
144
|
+
replicas, energy, swap_acceptance = parallel_tempering(
|
|
145
|
+
target,
|
|
146
|
+
(300.0, 360.0, 432.0, 518.4),
|
|
147
|
+
rounds=1000,
|
|
148
|
+
steps_per_round=100,
|
|
149
|
+
)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The samplers use fresh OpenMM systems and contexts; `platform="Reference"`,
|
|
153
|
+
`"CPU"`, `"CUDA"`, or `"OpenCL"` can be selected explicitly.
|
|
154
|
+
|
|
155
|
+
## Direct training
|
|
156
|
+
|
|
157
|
+
`train_forward_KLX_G` and `train_forward_KLXX_G` train the molecular `G`
|
|
158
|
+
direction: the flow maps target-like samples toward the source and `flow.inv`
|
|
159
|
+
generates target-like proposals. Both functions return only
|
|
160
|
+
`(trained_flow, batch_ess_history)`.
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
from jflows_md.train import train_forward_KLX_G
|
|
164
|
+
|
|
165
|
+
trained, batch_ess = train_forward_KLX_G(
|
|
166
|
+
target_samples,
|
|
167
|
+
source_samples,
|
|
168
|
+
source,
|
|
169
|
+
target,
|
|
170
|
+
flow,
|
|
171
|
+
batch_size=128,
|
|
172
|
+
train_steps=1000,
|
|
173
|
+
lr=1e-3,
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Direct trainers default to `initialize_from_identity=False`. Adaptive-staging
|
|
178
|
+
trained Boltzmann functions default to `True`, so each accepted-stage attempt
|
|
179
|
+
starts from an identity parameterization unless warm-starting is explicitly
|
|
180
|
+
selected. `boltzmann_identity` performs no flow training at all.
|
|
181
|
+
|
|
182
|
+
## Linear sharpening
|
|
183
|
+
|
|
184
|
+
All three adaptive-staging entry points require two regularization states. The
|
|
185
|
+
identity-only form is:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
from jflows_md.boltzmann import boltzmann_identity
|
|
189
|
+
|
|
190
|
+
particles, stages = boltzmann_identity(
|
|
191
|
+
x_valid,
|
|
192
|
+
source,
|
|
193
|
+
target,
|
|
194
|
+
ladder=16,
|
|
195
|
+
mc_dt=1e-4,
|
|
196
|
+
mc_steps=4,
|
|
197
|
+
rg_param_0=(20.0, 0.15),
|
|
198
|
+
rg_param_1=(1000.0, 0.0),
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
It omits every flow, training, optimizer, pool, and checkpoint argument.
|
|
203
|
+
Identity removes only the learned proposal: SMC endpoint selection, complete
|
|
204
|
+
population identity ESS, resampling, pre-sharpen MALA, exact regularization
|
|
205
|
+
sharpening, its ESS gate, and final MALA remain active.
|
|
206
|
+
|
|
207
|
+
The trained form is:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
from jflows_md.boltzmann import boltzmann_forward_KLX_G
|
|
211
|
+
|
|
212
|
+
particles, stages = boltzmann_forward_KLX_G(
|
|
213
|
+
x_valid,
|
|
214
|
+
source,
|
|
215
|
+
target,
|
|
216
|
+
flow,
|
|
217
|
+
pool_size=4096,
|
|
218
|
+
batch_size=256,
|
|
219
|
+
train_steps=1000,
|
|
220
|
+
lr=1e-3,
|
|
221
|
+
ladder=16,
|
|
222
|
+
mc_dt=1e-4,
|
|
223
|
+
mc_steps=4,
|
|
224
|
+
rg_param_0=(20.0, 0.15),
|
|
225
|
+
rg_param_1=(1000.0, 0.0),
|
|
226
|
+
)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The controller uses
|
|
230
|
+
|
|
231
|
+
```text
|
|
232
|
+
rg(t) = rg_param_0 + t [rg_param_1 - rg_param_0].
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Here `t` is a dimensionless stage-interpolation parameter. It does not change
|
|
236
|
+
the physical `temperature_kelvin` or inverse temperature `beta`, which remain
|
|
237
|
+
properties of the molecular target.
|
|
238
|
+
|
|
239
|
+
Let `U_s` be the source reduced potential. For an accepted step `a -> b`, it
|
|
240
|
+
trains and selects a proposal between
|
|
241
|
+
|
|
242
|
+
```text
|
|
243
|
+
B_a = (1-a) U_s + a U_rg(a)
|
|
244
|
+
B_b^- = (1-b) U_s + b U_rg(a).
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
It then sharpens the particles exactly to
|
|
248
|
+
|
|
249
|
+
```text
|
|
250
|
+
B_b^+ = (1-b) U_s + b U_rg(b)
|
|
251
|
+
log w_sharp = B_b^- - B_b^+,
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
followed by resampling and MALA at `B_b^+`. Thus the emitted population at
|
|
255
|
+
`t=1` targets `target.regularized(rg_param_1)`.
|
|
256
|
+
|
|
257
|
+
The flow and sharpening transitions form one accepted stage. Both the
|
|
258
|
+
selected-flow ESS and the sharpening ESS must reach `bg_param["tau_ess"]`
|
|
259
|
+
(default `0.6`). If either gate fails, the controller applies the configured
|
|
260
|
+
`shrink_factor` to `b-a` and retries the complete stage. A stage is emitted
|
|
261
|
+
and made available to persistence only after both gates pass.
|
|
262
|
+
|
|
263
|
+
Each stage record deliberately distinguishes:
|
|
264
|
+
|
|
265
|
+
- `flow_rg` and `flow_endpoint="pre_sharpen"`: the law used to train the
|
|
266
|
+
proposal flow;
|
|
267
|
+
- `population_rg`: the law of the emitted post-sharpen particles;
|
|
268
|
+
- `sharpen_ess_hist`: attempt-aligned sharpening ESS (`NaN` when the flow
|
|
269
|
+
gate rejected before sharpening was evaluated);
|
|
270
|
+
- `sharpen_ess` and `sharpen_mala_acceptance`: accepted sharpening
|
|
271
|
+
diagnostics.
|
|
272
|
+
|
|
273
|
+
The per-stage flows are proposal maps for this particle algorithm. They do not
|
|
274
|
+
compose into a deterministic source-to-final generator because sharpening is
|
|
275
|
+
a stochastic transition between stages.
|
|
276
|
+
|
|
277
|
+
## Complete-stage resume
|
|
278
|
+
|
|
279
|
+
Persistence mirrors `jflows` 0.5 and remains outside the compute API.
|
|
280
|
+
`jflows_md.boltzmann.write` atomically writes the post-sharpen population,
|
|
281
|
+
histories, and stage metadata before publishing the stage in `run.json`.
|
|
282
|
+
Trained runs additionally write both flow artifacts; identity runs write no
|
|
283
|
+
`.eqx` files. `jflows_md.boltzmann.load.run` resumes from the last published
|
|
284
|
+
stage; an incomplete unpublished directory is ignored and recomputed.
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
from jflows_md.boltzmann import iterate_boltzmann
|
|
288
|
+
from jflows_md.boltzmann.load import run
|
|
289
|
+
|
|
290
|
+
def iterate(samples, continuation, accepted_t, start_stage):
|
|
291
|
+
return iterate_boltzmann(
|
|
292
|
+
samples,
|
|
293
|
+
source,
|
|
294
|
+
target,
|
|
295
|
+
continuation,
|
|
296
|
+
objective="forward_klx",
|
|
297
|
+
accepted_t=accepted_t,
|
|
298
|
+
start_stage=start_stage,
|
|
299
|
+
# supply the same numerical controls used for a direct run
|
|
300
|
+
**controls,
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
config = {
|
|
304
|
+
"target": "adp_ff96_obc1",
|
|
305
|
+
"seed": 0,
|
|
306
|
+
"rg_param_0": (20.0, 0.15),
|
|
307
|
+
"rg_param_1": (1000.0, 0.0),
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
particles, stages = run(
|
|
311
|
+
"runs/adp",
|
|
312
|
+
"adp-regularization",
|
|
313
|
+
config,
|
|
314
|
+
x_valid,
|
|
315
|
+
flow,
|
|
316
|
+
iterate,
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
# After interruption, `flow` is the same architecture template.
|
|
320
|
+
particles, stages = run(
|
|
321
|
+
"runs/adp",
|
|
322
|
+
"adp-regularization",
|
|
323
|
+
config,
|
|
324
|
+
None,
|
|
325
|
+
flow,
|
|
326
|
+
iterate,
|
|
327
|
+
resume=True,
|
|
328
|
+
)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Resume requires the same problem identifier, complete numerical configuration,
|
|
332
|
+
and exact static flow template; mismatches are rejected. The saved population,
|
|
333
|
+
not flow-only replay, is the continuation state. Use
|
|
334
|
+
`manifest`, `validate`, `load`, `load_stage_flow`,
|
|
335
|
+
`load_validation_samples`, `load_training_history`, and `fork` for inspection
|
|
336
|
+
and run management.
|
|
337
|
+
|
|
338
|
+
## Bundles and installation
|
|
339
|
+
|
|
340
|
+
Runtime bundles contain exactly:
|
|
341
|
+
|
|
342
|
+
```text
|
|
343
|
+
coordinates.json
|
|
344
|
+
manifest.json
|
|
345
|
+
reference.pdb
|
|
346
|
+
system.json
|
|
347
|
+
system.xml
|
|
348
|
+
validation.json
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
A source checkout includes these seven audited named bundles:
|
|
352
|
+
|
|
353
|
+
| CLI preset | Bundle | Model | Domain | Fixed centers |
|
|
354
|
+
|---|---|---|---|---:|
|
|
355
|
+
| `adp` | `adp_ff96_obc1` | ff96; OBC1/ACE | `R^42 x T^18` | 1 (L-Ala) |
|
|
356
|
+
| `glycerol` | `glycerol_gaff2_am1bcc_obc1` | GAFF2/AM1-BCC; OBC1/ACE | `R^25 x T^11` | 0 |
|
|
357
|
+
| `diethanolamine` | `diethanolamine_gaff2_am1bcc_obc1` | GAFF2/AM1-BCC; OBC1/ACE | `R^33 x T^15` | 0 |
|
|
358
|
+
| `nma` | `nma_ff96_obc1` | ff96; OBC1/ACE | `R^21 x T^9` | 0 |
|
|
359
|
+
| `s_2_butanol` | `s_2_butanol_gaff2_am1bcc_obc1` | GAFF2/AM1-BCC; OBC1/ACE | `R^28 x T^11` | 1 (S) |
|
|
360
|
+
| `rr_2_3_butanediol` | `rr_2_3_butanediol_gaff2_am1bcc_obc1` | GAFF2/AM1-BCC; OBC1/ACE | `R^31 x T^11` | 2 (R,R) |
|
|
361
|
+
| `cyclohexane` | `cyclohexane_gaff2_am1bcc_obc1` | GAFF2/AM1-BCC; OBC1/ACE | `R^33 x T^15` | 0 |
|
|
362
|
+
|
|
363
|
+
NMA keeps its amide cis/trans coordinate periodic and unrestricted; the
|
|
364
|
+
force field assigns its energetic preference. Cyclohexane likewise has no
|
|
365
|
+
stereochemical support restriction, so ring conformations and chair inversion
|
|
366
|
+
are not split into artificial components. The two alcohol presets restrict
|
|
367
|
+
the chart to their named absolute configurations.
|
|
368
|
+
Candidate manifests pin AmberTools 26.0.0 and their structure/parameter
|
|
369
|
+
provenance. The two alcohol `parmchk2` files add no terms; cyclohexane records
|
|
370
|
+
the zero-penalty transfer of its `c6` terms from the GAFF2 `c3` types.
|
|
371
|
+
|
|
372
|
+
Wheels contain Python code only; bundle data must be downloaded or prepared
|
|
373
|
+
separately. An installed user can search an external directory and select a
|
|
374
|
+
bundle by name:
|
|
375
|
+
|
|
376
|
+
```python
|
|
377
|
+
from jflows_md import Molecular_Bundle, available_bundles
|
|
378
|
+
|
|
379
|
+
bundle_root = "/path/to/downloaded/bundles"
|
|
380
|
+
names = available_bundles(bundle_root)
|
|
381
|
+
bundle = Molecular_Bundle.load(names[0], root=bundle_root)
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
The same `root=` keyword is accepted by `Molecular_Potential.from_bundle` and
|
|
385
|
+
`OpenMM_Potential.from_bundle`. `available_bundles()` returns an empty tuple
|
|
386
|
+
when the requested directory is absent or contains no bundles.
|
|
387
|
+
|
|
388
|
+
Install matching JAX and OpenMM accelerator wheels separately. Choose one CUDA
|
|
389
|
+
toolkit generation:
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
pip install "jax[cuda13]" "openmm[cuda13]"
|
|
393
|
+
# or: pip install "jax[cuda12]" "openmm[cuda12]"
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
Installing a JAX CUDA extra does not install the OpenMM CUDA plugin, and the
|
|
397
|
+
OpenMM extra does not install the JAX plugin. These extras select the
|
|
398
|
+
independently packaged JAX and OpenMM CUDA wheels; they must use the same CUDA
|
|
399
|
+
generation. Then install both projects:
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
pip install -e /path/to/jflows
|
|
403
|
+
pip install -e /path/to/jflows_md
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Inspect the installed runtimes without creating a JAX client or OpenMM
|
|
407
|
+
context:
|
|
408
|
+
|
|
409
|
+
```python
|
|
410
|
+
import jflows_md
|
|
411
|
+
|
|
412
|
+
jflows_md.backend()
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Base OpenMM-side construction is optional and CPU-capable; select a CUDA extra
|
|
416
|
+
above when native GPU execution is required:
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
pip install -e "/path/to/jflows_md[openmm]"
|
|
420
|
+
pip install -e "/path/to/jflows_md[bundles]"
|
|
421
|
+
python -m jflows_md.bundle_build \
|
|
422
|
+
glycerol molecule.prmtop molecule.rst7 generated/glycerol
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
From a source checkout, the equivalent wrapper is
|
|
426
|
+
`python -m bundles.build_molecular_bundles ...`.
|
|
427
|
+
|
|
428
|
+
The command-line presets above carry explicit coordinate configurations.
|
|
429
|
+
Programmatic `jflows_md.bundle_build.write_bundle(...)` calls may provide
|
|
430
|
+
`zmatrix`, `fixed_stereocenters`, and `signed_volume_diagnostics` for any
|
|
431
|
+
additional explicitly prepared molecule, but that low-level route is not a
|
|
432
|
+
claim of curated target support. Multiple fixed tetrahedral centers use
|
|
433
|
+
multiple half-chart torsions; no center is inferred from the molecule name.
|
|
434
|
+
For named chiral presets, caller-supplied CIP-priority atom orders make bundle
|
|
435
|
+
construction reject a reference with the wrong requested R/S configuration.
|
|
436
|
+
Legacy schema-v2 achiral and single-center bundles remain runtime compatible.
|
|
437
|
+
For source compatibility, a target-only builder call with all new coordinate
|
|
438
|
+
options at their defaults still reproduces the historical schema-v2 defaults
|
|
439
|
+
for `adp`, `glycerol`, and `diethanolamine`; any non-default coordinate option
|
|
440
|
+
uses the new schema-v3 route.
|
|
441
|
+
See `doc/01-low-level.md` for the configuration contract.
|
|
442
|
+
|
|
443
|
+
## Verification
|
|
444
|
+
|
|
445
|
+
Run the complete local suite from the repository root only when the accelerator
|
|
446
|
+
is available:
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
PYTHONPATH=/path/to/jflows:/path/to/jflows_md \
|
|
450
|
+
XLA_PYTHON_CLIENT_PREALLOCATE=false \
|
|
451
|
+
python /path/to/jflows_md/smoke/run_all.py
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
`smoke/benchmark_compile.py` is an opt-in compilation benchmark and is not part
|
|
455
|
+
of `run_all.py`.
|