bentopy 0.2.0a10__cp313-cp313-manylinux_2_34_x86_64.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.
Files changed (58) hide show
  1. bentopy-0.2.0a10.data/scripts/bentopy-init +0 -0
  2. bentopy-0.2.0a10.data/scripts/bentopy-pack +0 -0
  3. bentopy-0.2.0a10.data/scripts/bentopy-render +0 -0
  4. bentopy-0.2.0a10.data/scripts/bentopy-solvate +0 -0
  5. bentopy-0.2.0a10.dist-info/METADATA +358 -0
  6. bentopy-0.2.0a10.dist-info/RECORD +58 -0
  7. bentopy-0.2.0a10.dist-info/WHEEL +5 -0
  8. bentopy-0.2.0a10.dist-info/entry_points.txt +4 -0
  9. bentopy-0.2.0a10.dist-info/licenses/LICENSE.txt +13 -0
  10. bentopy-0.2.0a10.dist-info/top_level.txt +8 -0
  11. check/check.py +128 -0
  12. core/config/bent/lexer.rs +338 -0
  13. core/config/bent/parser.rs +1180 -0
  14. core/config/bent/writer.rs +205 -0
  15. core/config/bent.rs +149 -0
  16. core/config/compartment_combinations.rs +300 -0
  17. core/config/legacy.rs +768 -0
  18. core/config.rs +362 -0
  19. core/mod.rs +4 -0
  20. core/placement.rs +100 -0
  21. core/utilities.rs +1 -0
  22. core/version.rs +32 -0
  23. init/example.bent +74 -0
  24. init/main.rs +235 -0
  25. mask/config.py +153 -0
  26. mask/mask.py +308 -0
  27. mask/utilities.py +38 -0
  28. merge/merge.py +175 -0
  29. pack/args.rs +77 -0
  30. pack/main.rs +121 -0
  31. pack/mask.rs +940 -0
  32. pack/session.rs +176 -0
  33. pack/state/combinations.rs +31 -0
  34. pack/state/compartment.rs +44 -0
  35. pack/state/mask.rs +196 -0
  36. pack/state/pack.rs +187 -0
  37. pack/state/segment.rs +72 -0
  38. pack/state/space.rs +98 -0
  39. pack/state.rs +440 -0
  40. pack/structure.rs +185 -0
  41. pack/voxelize.rs +85 -0
  42. render/args.rs +109 -0
  43. render/limits.rs +73 -0
  44. render/main.rs +12 -0
  45. render/render.rs +393 -0
  46. render/structure.rs +264 -0
  47. solvate/args.rs +324 -0
  48. solvate/convert.rs +25 -0
  49. solvate/cookies.rs +185 -0
  50. solvate/main.rs +177 -0
  51. solvate/placement.rs +380 -0
  52. solvate/solvate.rs +244 -0
  53. solvate/structure.rs +160 -0
  54. solvate/substitute.rs +113 -0
  55. solvate/water/martini.rs +409 -0
  56. solvate/water/models.rs +150 -0
  57. solvate/water/tip3p.rs +658 -0
  58. solvate/water.rs +115 -0
@@ -0,0 +1,358 @@
1
+ Metadata-Version: 2.4
2
+ Name: bentopy
3
+ Version: 0.2.0a10
4
+ Summary: Packs stuff in boxes
5
+ Author-email: Marieke Westendorp <ma3ke.cyber@gmail.com>, Jan Stevens <j.a.stevens@rug.nl>, Bart Bruininks <bartbruininks@gmail.com>
6
+ Project-URL: Homepage, https://github.com/marrink-lab/bentopy
7
+ Project-URL: Issues, https://github.com/marrink-lab/bentopy/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.12
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE.txt
13
+ Requires-Dist: numpy>=2.2.3
14
+ Requires-Dist: scipy>=1.15
15
+ Requires-Dist: freud-analysis>=3.2.0
16
+ Requires-Dist: MDAnalysis>=2.8
17
+ Requires-Dist: mdvcontainment>=2.0.0a1
18
+ Dynamic: license-file
19
+
20
+ # _bentopy_&mdash;packs stuff in boxes
21
+
22
+ ![Bentopy](figures/logo_header.png)
23
+
24
+ Bentopy packs molecules to assemble models for molecular dynamics simulations.
25
+ It uses a voxel-based approach to place molecules into arbitrary geometries,
26
+ handling systems from simple boxes to cellular-scale models. Additional tools
27
+ provide efficient solvation and ion placement. Bentopy is force-field agnostic
28
+ and integrates with existing molecular dynamics workflows. Example systems
29
+ built with bentopy include entire cell models in the Martini force field and
30
+ all-atom aerosols.
31
+
32
+ - Build models at vast scales, quickly.
33
+ - Powerful and flexible integration of spatial information.
34
+ - Works with any forcefield, from Martini to all-atom.
35
+
36
+ ## Information
37
+
38
+ A number of resources explaining how to build systems using bentopy are
39
+ available.
40
+
41
+ - The [_bentopy_ wiki][wiki] gives in-depth descriptions of different commands
42
+ and concepts.
43
+ - This includes [Examples][wiki-examples] of how different _bentopy_
44
+ tools can be used to construct simple and more sophisticated systems.
45
+ - Martini Workshop 2025: [Bentopy: from simple packing to building cellular
46
+ models][workshop], an in-depth tutorial. (Note that its current state is
47
+ outdated, and relies on _bentopy_ v0.1.0. An updated tutorial is in progress
48
+ and will soon be published.)
49
+
50
+ [wiki]: https://github.com/marrink-lab/bentopy/wiki
51
+ [wiki-examples]: https://github.com/marrink-lab/bentopy/wiki/Examples
52
+ [workshop]: https://cgmartini.nl/docs/tutorials/Martini3/Bentopy
53
+
54
+ ## Citation
55
+
56
+ If you use bentopy to set up your molecular dynamics system in a publication, please cite our work.
57
+
58
+ <!-- TODO: Apa style citation with doi link. -->
59
+
60
+ > Westendorp, M.S.S, Stevens, J.A. et al. Bentopy: building molecular dynamics simulations with cellular complexity and scale. _In preparation._
61
+
62
+ <!-- TODO: Fill when paper is going to print.
63
+
64
+ ```
65
+ @article{...}
66
+ ```
67
+
68
+ -->
69
+
70
+ ## Installation
71
+
72
+ _Bentopy_ can be installed through `pip`.
73
+
74
+ ```console
75
+ pip install bentopy
76
+ ```
77
+
78
+ For most Linux platforms, pre-built binaries are available and will be
79
+ installed automatically through `pip`. For other platforms, such as macOS, a
80
+ Rust compiler is required. See the [detailed installation
81
+ instructions](#detailed-installation-instructions) below.
82
+
83
+ ## The _bentopy_ tools
84
+
85
+ _Bentopy_ currently features five subcommands:
86
+
87
+ - [_init_](#init): Initialize and validate bentopy input files.
88
+ - [_mask_](#mask): Create masks based on voxel containments.
89
+ - [_pack_](#pack): Pack a space and produce a placement list.
90
+ - [_render_](#render): Write a structure file and topology based on a placement list.
91
+ - [_solvate_](#solvate): Solvate large models, including very fast ion substitution.
92
+ - [_merge_](#merge): Merge structure files.
93
+
94
+ Each subcommand has detailed `--help` information.
95
+
96
+ ### Workflow
97
+
98
+ A typical _bentopy_ workflow may look like this.
99
+
100
+ ![bentopy-merge -> bentopy-mask -> bentopy-pack -> bentopy-render -> bentopy-merge -> bentopy-solvate](figures/bentopy_workflow.png)
101
+
102
+ The _init_ and _mask_ tools help prepare the configuration and masks for
103
+ packing. Based on the input configuration and masks, _pack_ will create a
104
+ placement list. Using _render_, you can create a structure file and system
105
+ topology from the placement list. The _merge_ and _solvate_ tools help you
106
+ prepare the model for simulation.
107
+
108
+ What follows is a brief explanation and example invocation of these
109
+ subcommands. A more detailed walkthrough can be found in the
110
+ [Examples][wiki-examples] on the wiki.
111
+
112
+ ### Pre-processing
113
+
114
+ #### _init_
115
+
116
+ The _init_ subcommand serves to make setting up a new _bentopy_ project easy.
117
+ It can be used to create an [example configuration file][example] with
118
+ placeholder values or to validate input files.
119
+
120
+ [example]: https://github.com/marrink-lab/bentopy/blob/main/src/init/example.bent
121
+
122
+ ```console
123
+ bentopy-init example -o input.bent
124
+ ```
125
+
126
+ Read more about the [_init_ command](https://github.com/marrink-lab/bentopy/wiki/bentopy-init).
127
+
128
+ #### _mask_
129
+
130
+ While simple shapes can be defined directly in a `bent` file, **space masks**
131
+ enable you to capture the complex geometries of curved membranes and large
132
+ complexes. This allows you to create models based on existing structures or
133
+ empirical evidence, making sophisticated integrative modeling workflows
134
+ possible.
135
+
136
+ The _mask_ subcommand offers a powerful tool for creating these masks. It is
137
+ built on top of a versatile library for segmenting point clouds and molecular
138
+ structures, called [mdvcontainment][mdvc].
139
+
140
+ With _mask_ you can take a structure or point cloud and determine the different
141
+ compartments within it.
142
+
143
+ ```console
144
+ bentopy-mask membrane.gro masks/inside.npz --autofill
145
+ ```
146
+
147
+ _Determine the compartments contained by the structure in `membrane.gro` and
148
+ automatically select the innermost compartment (`--autofill`). From that
149
+ selected compartment, write a mask to `masks/inside.npz`._
150
+
151
+ The masks created with `bentopy-mask` can be imported as a compartment in a
152
+ `bent` file.
153
+
154
+ ```ini
155
+ [ compartment ]
156
+ cytoplasm from "masks/inside.npz"
157
+ ```
158
+
159
+ Note that any boolean _numpy_ array [stored as a compressed file
160
+ (`npz`)][numpy-npz] of the correct dimensions can function as a valid mask.
161
+ This makes it possible to create custom scripts and techniques for preparing
162
+ masks as well.
163
+
164
+ ### Packing the structure
165
+
166
+ #### _pack_
167
+
168
+ The _pack_ subcommand provides the core functionality of _bentopy_. Given an
169
+ **input configuration file** (`bent`), the input structures will be packed and
170
+ their positions and orientations are written to a **placement list**.
171
+
172
+ ```console
173
+ bentopy-pack input.bent placements.json
174
+ ```
175
+
176
+ The _placement list_ can be converted to a structure and associated topology
177
+ using [_render_](#render).
178
+
179
+ #### The `bent` input configuration file
180
+
181
+ _On the wiki, a [detailed reference] for the `bent` configuration input file is
182
+ available._
183
+
184
+ This is a minimal but complete `bent` file.
185
+
186
+ ```ini
187
+ [ general ]
188
+ title "Lysozymes in a sphere"
189
+
190
+ [ space ]
191
+ dimensions 100, 100, 100
192
+ resolution 0.5
193
+
194
+ [ compartments ]
195
+ ball as sphere at center with diameter 80
196
+
197
+ [ segments ]
198
+ 3lyz 2000 from "structures/3lyz.pdb" in ball
199
+ ```
200
+
201
+ Provided you have the structure file, this configuration can be used to create
202
+ an 80 nm diameter sphere filled with lysozyme structures. This is a minimal
203
+ version of the system described and explained in [Example 1: Simple
204
+ sphere][wiki-example-1] on the wiki.
205
+
206
+ [wiki-example-1]: https://github.com/marrink-lab/bentopy/wiki/Example-1:-Simple-sphere
207
+
208
+ ### Post-processing
209
+
210
+ #### _render_
211
+
212
+ The result of the packing process is stored as a **placement list**, which is a
213
+ `json` file that describes _which structures_ at _what rotations_ are _placed
214
+ where_. In order to create a structure file (and topology file) from this
215
+ placement list, the _render_ subcommand can be used.
216
+
217
+ ```console
218
+ bentopy-render placements.json structure.gro -t topol.top
219
+ ```
220
+
221
+ _Render `placements.json` created by _pack_ to a `gro` file at `structure.gro`
222
+ and write a topology file to `topol.top`._
223
+
224
+ This is a separate operation from _packing_, since the packed systems can
225
+ become very large. Storing the placement list as an intermediate result
226
+ decouples the hard task of packing from the simple work of writing it into a
227
+ structure file.
228
+
229
+ #### _merge_
230
+
231
+ As the name suggests, _merge_ is a tool for concatenating `gro` files. Though
232
+ this is a relatively simple operation, _merge_ provides a convenient way of
233
+ telling apart different sections of large models by optionally specifying a new
234
+ residue name for a whole file in the argument list by appending
235
+ `:<residue name>` to a file path.
236
+
237
+ ```console
238
+ bentopy-merge chromosome.gro:CHROM membrane.gro:MEM -o chrom_mem.gro
239
+ ```
240
+
241
+ _Concatenate `chromosome.gro` and `membrane.gro` into `chrom_mem.gro`, setting
242
+ the residue names of the chromosome atoms to `CHROM` and those of the membrane
243
+ to `MEM` in the concatenated structure._
244
+
245
+ #### _solvate_
246
+
247
+ With _solvate_, large boxes can be solvated quickly and conveniently, with
248
+ one-step ion substitutions. _Solvate_ enables cellular-scale solvation and is
249
+ designed to run very fast while having a low memory footprint. Both atomistic
250
+ and coarse-grained Martini water placement is supported.
251
+
252
+ ```console
253
+ bentopy-solvate -i packed.gro -o solvated.gro \
254
+ -s NA:0.15M -s CL:0.15M --charge 5172 \
255
+ --water-type tip3p
256
+ ```
257
+
258
+ _Solvate the structure in `packed.gro` and output the result to `solvated.gro`.
259
+ Substitute water residues for ions at 0.15M NaCl. Compensate the charge of
260
+ `packed.gro` with 5172 additional Cl substitutions. Use Tip3P waters
261
+ (atomistic)._
262
+
263
+ A thorough description of the command is [provided in the `bentopy-solvate`
264
+ README](src/solvate/README.md).
265
+
266
+ ## Why was _bentopy_ created?
267
+
268
+ With _bentopy_, we address the lack of dedicated and generalized tools for
269
+ packing detailed and MD-ready models while not sacrificing scale or
270
+ efficiency.
271
+
272
+ _Bentopy_ was created the goal of improving the workflow for building
273
+ whole-cell models at the Marrink lab. While tools for preparing individual
274
+ structures, polymers, and the cell membrane at that large scale were available,
275
+ the procedure for packing the already crowded cytosol was slow and inflexible.
276
+ As _bentopy_ was developed, it fulfilled this task excellently, and it quickly
277
+ became clear that this is a tool that many people had their own creative
278
+ applications for.
279
+
280
+ Another problem with setting up large-scale molecular dynamics simulations is
281
+ addressed by `bentopy-solvate`. Tools designed for boxes on the order of tens
282
+ of nanometers start to break down at the mesoscale. With _solvate_, we
283
+ introduce a well-considered and thoughtfully optimized tool. The improvement of
284
+ the solvation stage for coarse-grained models has been excellent, but the
285
+ improvement in performance and ergonomics is reported to be especially
286
+ impressive for all-atom solvation.
287
+
288
+ We want to thank the many fantastic researchers who are creating beautiful
289
+ models with _bentopy_ for expressing their enthusiasm and providing hands-on
290
+ feedback.
291
+
292
+ ## Detailed installation instructions
293
+
294
+ If pre-built binaries are not available for your platform, you need access to
295
+ `cargo`. First, you can check if Rust's build system `cargo` is installed.
296
+
297
+ ```console
298
+ cargo --version
299
+ ```
300
+
301
+ Make sure that this is at least `1.88`, the minimum supported rust version for
302
+ this project. If this is not the case, update using `rustup update`.
303
+
304
+ If `cargo` is not present, [you can install it][rust-installation] by any means
305
+ you prefer. Installation through [_rustup_][rust-rustup] is very easy!
306
+
307
+ Once `cargo` is installed, installing _bentopy_ using `pip` should work.
308
+
309
+ ### Install from source
310
+
311
+ Installing bentopy from source gives you access to the very latest changes.
312
+ Though the main branch of this project is generally stable, installation from
313
+ releases is recommended.
314
+
315
+ To install _bentopy_ from source, you need access to cargo, as described
316
+ earlier. You can use `pip` directly to install the project right from the
317
+ repository.
318
+
319
+ ```console
320
+ pip install git+https://github.com/marrink-lab/bentopy
321
+ ```
322
+
323
+ Alternatively, you can clone the repository somewhere, and build from there.
324
+
325
+ ```console
326
+ git clone https://github.com/marrink-lab/bentopy
327
+ cd bentopy
328
+ pip install .
329
+ ```
330
+
331
+ ## License
332
+
333
+ > Copyright 2024 Marieke S.S. Westendorp, Jan A. Stevens
334
+ >
335
+ > Licensed under the Apache License, Version 2.0 (the "License");
336
+ > you may not use this file except in compliance with the License.
337
+ > You may obtain a copy of the License at
338
+ >
339
+ > <http://www.apache.org/licenses/LICENSE-2.0>
340
+ >
341
+ > Unless required by applicable law or agreed to in writing, software
342
+ > distributed under the License is distributed on an "AS IS" BASIS,
343
+ > WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
344
+ > See the License for the specific language governing permissions and
345
+ > limitations under the License.
346
+
347
+ [rust]: https://rust-lang.org/
348
+ [rust-installation]: https://www.rust-lang.org/learn/get-started
349
+ [rust-rustup]: https://rustup.rs/
350
+ [numpy-npz]: https://numpy.org/doc/stable/reference/generated/numpy.savez.html
351
+ [mdvc]: https://github.com/BartBruininks/mdvcontainment
352
+ [gromacs-gro]: https://manual.gromacs.org/current/reference-manual/file-formats.html#gro
353
+ [gromacs-top]: https://manual.gromacs.org/current/reference-manual/file-formats.html#top
354
+ [gromacs-itp]: https://manual.gromacs.org/current/reference-manual/file-formats.html#itp
355
+ [3lyz]: https://www.rcsb.org/structure/3LYZ
356
+ [1ubq]: https://www.rcsb.org/structure/1UBQ
357
+ [jq]: https://github.com/jqlang/jq
358
+ [np-load]: https://numpy.org/doc/stable/reference/generated/numpy.load.html
@@ -0,0 +1,58 @@
1
+ bentopy-0.2.0a10.data/scripts/bentopy-init,sha256=lmW0W6U_Zm_PJ351j7HQ51kEkQwu0Fubkx1S9TTDHWA,4976544
2
+ bentopy-0.2.0a10.data/scripts/bentopy-pack,sha256=NxXc_ofmFG0WGJsRrLp9p_lcJ3yoi8aSGQ3vgC3kWvk,6046680
3
+ bentopy-0.2.0a10.data/scripts/bentopy-render,sha256=LgrLaPLoZJxihxEPHHKnqxCWNB5ss1ImH0dREUoHjC8,1778520
4
+ bentopy-0.2.0a10.data/scripts/bentopy-solvate,sha256=5d3GC3SzNDd11Jeeg7N-TbwzO2v9_JZ9H0rEJ8C2yBI,1900736
5
+ check/check.py,sha256=xbr4rL73t6gokB3sfZGpM-mCn6yccP2ew1HBMeBTen0,4510
6
+ core/config.rs,sha256=UCldTCse3VrVyNm_chvC5nv83mDekRsLLNEuaCI-rME,8944
7
+ core/mod.rs,sha256=D-P2C__zGtu275Zgsy9lv3iS2wpJThTkzg5U2RmtLUk,71
8
+ core/placement.rs,sha256=R3Lo1wSrO6EWbIB7T38uin3XnddfYGwEFTCTrafU5CE,3082
9
+ core/utilities.rs,sha256=PULJnA6hsGojkkse5GVTSZiftx5FQBoLVExMPy4TQhg,44
10
+ core/version.rs,sha256=0aNOr-89Bj7Y3sEP3Ap4YyaiVPp9IdP23X4jdaFw8mE,883
11
+ core/config/bent.rs,sha256=fwg3w7ibKcGN7Yf332O_V9xnPpVGlyfcm_kImn6H46Y,5220
12
+ core/config/compartment_combinations.rs,sha256=d6scW7oaFwfkYXBS8rcESfd41LVWEUqaojAMSZSE-nQ,8940
13
+ core/config/legacy.rs,sha256=I6yZf8AT0M6hCbCb1TPJPKYwY3rIim1Ws9NIu_vma3s,29719
14
+ core/config/bent/lexer.rs,sha256=X629G3VOGlYWdi8NNZqxGq0Y_O5ORU7ETM17HzcH5zU,10118
15
+ core/config/bent/parser.rs,sha256=wYW81KzMM037AZnbITkwTrzn6CVMIFCSyLPwKouIyaY,37563
16
+ core/config/bent/writer.rs,sha256=T-DZpwrg_QbhVKd55FypbN0oID_7rdZyGvxUoMxw71o,5699
17
+ init/example.bent,sha256=B6sGXAxDIZSc1OvFcXBGDf2YbZtOMsmY2gEf43lrbm8,2990
18
+ init/main.rs,sha256=B-cJ-Apvz-eu53OCzuur9mXIhLC18UO_Ld-wRebR_Rw,8468
19
+ mask/config.py,sha256=zf1lwGZ3G5btVNMlt4Ii4op2x_uyNNMtkdxJjt5wuIs,5410
20
+ mask/mask.py,sha256=qLblYC7PT6E-RJw9dQcyhktsMMKZcM6Km1slsLPV-5k,12709
21
+ mask/utilities.py,sha256=Yj8CAuUUZ34gUrbtQRIUf_bNKek_10_tI0V6In0UOtU,1192
22
+ merge/merge.py,sha256=Kj83y99lrEYkxRnoQjT4zObN9NgKZCvlLEvKQpTe4WQ,5315
23
+ pack/args.rs,sha256=gWb-eL5DgrAtt6rPoTrJTRl2ouCECg530qJEf7a7CMs,2775
24
+ pack/main.rs,sha256=kdZ24eZ8cSPnZbojel5joufwqn8Fd0LI5Hv0_-2ywxE,4329
25
+ pack/mask.rs,sha256=F2ePcar50lU3V4MA_uYWlXaJaemnprDelqsYbaUoaow,30883
26
+ pack/session.rs,sha256=xELEdg_XjoqyeeNOV_EFRQDJiy5h6M5jjbtHaTQEutk,5874
27
+ pack/state.rs,sha256=UkPsAX5LFzFPA84-UABTcubaU5KYg08GUe1FuhfhaW8,17134
28
+ pack/structure.rs,sha256=ZeTO5zChlJCzmcSTfU7GV0CvLtSvRbfLG8UyNAM2e48,5760
29
+ pack/voxelize.rs,sha256=JDHqYqcBKBH2l78ECL6R6spbvGSw4SDR8WNEX6umeMs,3426
30
+ pack/state/combinations.rs,sha256=4FtCR9WHjkSPylRUOTV8Ob4waUHo2hUjOQhwWnNCBuY,1100
31
+ pack/state/compartment.rs,sha256=W0IOaLFnWHJny1b83iknBO0yuoJevvSwZiMA8IgHevQ,1504
32
+ pack/state/mask.rs,sha256=xykxkCKPy5D-Fk6Zgwp8lGzb2e8NydyyC8VgFV1NMc8,8150
33
+ pack/state/pack.rs,sha256=l73gXqRethwh1RwXVTANv_OBIxvkIUhCy8UrcFfoasE,8108
34
+ pack/state/segment.rs,sha256=yVrQJPVaH3xPKR_G3ZV6bOhwWEpLw19ChfNusaQMFfw,2653
35
+ pack/state/space.rs,sha256=sexCSmJpgtgyOFEAEaXQrY-J1A2R-6s7fSMbSIRY8cI,3628
36
+ render/args.rs,sha256=ZFBWeMdWJVbnJ_4rut94M4kcifEoiqua1x11HNj1N7U,3127
37
+ render/limits.rs,sha256=Zgl4LitlkM5W_p3fZ0Y2s46bNletIXLMcU7umHxX1RI,2446
38
+ render/main.rs,sha256=7CwMRRe2uh153v46DyDd0n8dhZmiKi8LthxvWN3XV7o,247
39
+ render/render.rs,sha256=a4_orGwdsSTFcUEOsegdqdGdaY4w4GmeWJyJswWh20s,14545
40
+ render/structure.rs,sha256=0hQFg5UypyhwLTYETCGvOvoAGldlnnq6jTklaW3ynBU,9419
41
+ solvate/args.rs,sha256=5_usMAiLmf7Qx-yycf8dMeUOogkWRq639b-9J7RQKbw,10239
42
+ solvate/convert.rs,sha256=Y_rNDGEcJutzQmjt7d7TyeqvlR3hgzi5QWI3YxMeyuI,818
43
+ solvate/cookies.rs,sha256=TCcTJFZMhJNipl3JYoUb3MXGst1rihDvrp9EKcLjcls,7799
44
+ solvate/main.rs,sha256=Zco_3VclT799kzZMLNXm9d_NKLCnte0E-CSgNv4-2FE,6018
45
+ solvate/placement.rs,sha256=WOlOj8Lug5bp7w9mRrl3lTWK3MbMs4AD2F3EEnJQu0s,13004
46
+ solvate/solvate.rs,sha256=jVtvV86AmVt1Z6S8gbxiHPA74OBazSNsMJIgQdGA4Jc,9440
47
+ solvate/structure.rs,sha256=c1YBkQ35JGocGtm0ORpBUY5SKqeigYT7R44qCJVaI7Y,6355
48
+ solvate/substitute.rs,sha256=AF0X0s1BComdYaKS41Tl05ri8iHelnoBjNke-0NyEsU,3590
49
+ solvate/water.rs,sha256=ByAvd-Ncn0gMbclFoHx1wsUlSp1oTvZr_2qOxPyqgwI,3886
50
+ solvate/water/martini.rs,sha256=lSsxaHKIKy8i-GnUkOdvGJHUN0dSoA_8bnXbLMazTBE,16206
51
+ solvate/water/models.rs,sha256=-gvE0e8CC7g4WtMTAayeaafWwZdJoe511pzutYkfEuw,4119
52
+ solvate/water/tip3p.rs,sha256=9q2egM4Fj72-k7yEjracJQmh9Qq1jFq_PKwjSWmHHNI,26207
53
+ bentopy-0.2.0a10.dist-info/METADATA,sha256=kayGCEudoS4TXmAgiUy7Qt1EIDeEjgTcjPrK6d5yuTk,13165
54
+ bentopy-0.2.0a10.dist-info/WHEEL,sha256=uhLz8SDHJs36mcQZMP4tcf-dNi5WGO0r_zqro-OTbpc,113
55
+ bentopy-0.2.0a10.dist-info/entry_points.txt,sha256=3s9bQ1c4SHyXySu2dxhuMDzUQFFeZpBsDAp7m5DO-C4,114
56
+ bentopy-0.2.0a10.dist-info/top_level.txt,sha256=92l6J9HF6NcudyfLgcpRRuB-bQ788BRK2uh5FUTNyoI,47
57
+ bentopy-0.2.0a10.dist-info/RECORD,,
58
+ bentopy-0.2.0a10.dist-info/licenses/LICENSE.txt,sha256=5QaaBeiP30jt8g3jaLTorMrcgoxG5MuK-FzuIqqnGSM,580
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp313-cp313-manylinux_2_34_x86_64
5
+
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ bentopy-check = check:check.main
3
+ bentopy-mask = mask:mask.main
4
+ bentopy-merge = merge:merge.main
@@ -0,0 +1,13 @@
1
+ Copyright 2024 Marieke S.S. Westendorp, Jan A. Stevens
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,8 @@
1
+ check
2
+ core
3
+ init
4
+ mask
5
+ merge
6
+ pack
7
+ render
8
+ solvate
check/check.py ADDED
@@ -0,0 +1,128 @@
1
+ import argparse
2
+ from pathlib import Path
3
+ from time import time
4
+ from sys import stderr
5
+
6
+ import freud
7
+ import MDAnalysis as mda
8
+ import numpy as np
9
+
10
+ def log(*args, **kwargs):
11
+ print(*args, **kwargs, file=stderr)
12
+
13
+
14
+ def check(args):
15
+ # Read in structure.
16
+ structure_path = args.file
17
+ log(f"Reading in structure from {structure_path}... ", end="")
18
+ u = mda.Universe(structure_path)
19
+ log(f"done. (Read {u.atoms.n_atoms} atoms.)")
20
+
21
+ # Adjust the box for Freud and convert the cutoff distance.
22
+ box = mda_box_to_freud(u.dimensions)
23
+ cutoff_nm = args.cutoff
24
+ cutoff_A = cutoff_nm * 10.0 # Convert from nm to Å.
25
+
26
+ # Set up the locality query.
27
+ positions = u.atoms.positions
28
+ aq = freud.locality.AABBQuery(box, positions)
29
+ neighbors = aq.query(positions, {"r_max": cutoff_A}).toNeighborList()
30
+ log(f"The AABB query was set up with a {cutoff_nm} nm cutoff.")
31
+
32
+ # Sift through the neighbors to find collisions.
33
+ collision = False
34
+ min_distance = None
35
+ collisions = [] if args.output_collisions else None
36
+ try:
37
+ for id, hit in neighbors:
38
+ a = u.atoms[id]
39
+ b = u.atoms[hit]
40
+ if a.resid != b.resid:
41
+ if args.ignore_same_resname and a.resname == b.resname:
42
+ continue
43
+ collision = True
44
+ distance = np.linalg.norm(a.position - b.position) / 10.0 # From Å to nm.
45
+ new_low = min_distance is not None and min_distance > distance
46
+ if new_low or min_distance is None:
47
+ min_distance = distance
48
+ print(
49
+ f"Distance between atom {id:>6} and {hit:>6} (residue {a.resname} ({a.resid:>3}) and {b.resname} ({b.resid:>3})) is {distance:<6.3} <= {cutoff_nm} nm.",
50
+ "(new smallest distance)" if new_low else "",
51
+ )
52
+ if collisions is not None:
53
+ collisions.append(a.position )
54
+ if args.exit_early:
55
+ break
56
+ log("Done.")
57
+ except KeyboardInterrupt:
58
+ log("Stopping the search.")
59
+
60
+ # If desired, write out a structure with beads at the collision sites.
61
+ if args.output_collisions is not None:
62
+ natoms = len(collisions)
63
+ if natoms > 0:
64
+ log(f"Writing {natoms} collision coordinates to {args.output_collisions}... ", end="")
65
+ start = time()
66
+ positions = np.array(collisions)
67
+ assert positions.shape == (natoms, 3)
68
+ # Create a new Universe. We need to set trajectory to True in order to add positions.
69
+ cu = mda.Universe.empty(natoms, trajectory=True)
70
+ cu.atoms.positions = positions
71
+ cu.dimensions = u.dimensions
72
+ cu.atoms.write(args.output_collisions)
73
+ duration = time() - start
74
+ log(f"Done in {duration:.3} s.")
75
+ else:
76
+ log("No collisions were found, so no need to write out coordinates.")
77
+
78
+ # Report whether we found any collisions through the error number.
79
+ return 1 if collision else 0
80
+
81
+
82
+ def mda_box_to_freud(mda_box):
83
+ x, y, z, alpha, beta, gamma = mda_box.astype(np.float64)
84
+ cosa = np.cos(np.pi * alpha / 180)
85
+ cosb = np.cos(np.pi * beta / 180)
86
+ cosg = np.cos(np.pi * gamma / 180)
87
+ sing = np.sin(np.pi * gamma / 180)
88
+ zx = z * cosb
89
+ zy = z * (cosa - cosb * cosg) / sing
90
+ zz = np.sqrt(z**2 - zx**2 - zy**2)
91
+ matrix = np.array([[x, 0, 0], [y * cosg, y * sing, 0], [zx, zy, zz]])
92
+ return matrix.astype(np.float32).T
93
+
94
+
95
+ def main():
96
+ parser = argparse.ArgumentParser(
97
+ description="Check for collisions in rendered structures.",
98
+ )
99
+ parser.add_argument("file", type=Path, help="File to check (a structure file).")
100
+ parser.add_argument(
101
+ "--cutoff",
102
+ type=float,
103
+ default=0.4,
104
+ help="Collision distance between beads in nm. (default: %(default)s nm)",
105
+ )
106
+ parser.add_argument(
107
+ "--output-collisions",
108
+ type=Path,
109
+ help="Write out a structure file with dummy beads at the collision sites.",
110
+ )
111
+ parser.add_argument(
112
+ "--ignore-same-resname",
113
+ action="store_true",
114
+ help="Ignore collisions between particles with the same residue name.",
115
+ )
116
+ parser.add_argument(
117
+ "-e",
118
+ "--exit-early",
119
+ action="store_true",
120
+ help="Exit early at the first collision.",
121
+ )
122
+
123
+ args = parser.parse_args()
124
+ return check(args)
125
+
126
+
127
+ if __name__ == "__main__":
128
+ main()