mempro 0.2.1__tar.gz → 0.3.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mempro
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: Membrane Protein Orientation in Lipid Bilayers
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -14,6 +14,8 @@ Dynamic: license-file
14
14
  # MemPrO
15
15
  Membrane Protein Orientation in Lipid Bilayers. The paper associated with this code can be found [here](https://doi.org/10.1021/acs.jctc.5c01433).
16
16
 
17
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pstansfeld/MemPrO/blob/main/MemPrO_Colab.ipynb)
18
+
17
19
  Code and parameters from the following were used to help write this code:
18
20
 
19
21
  **Insane:**
@@ -56,7 +58,9 @@ pip install "matplotlib>=3.8.4"
56
58
 
57
59
  The Martini 3 force field file (`martini_v3.itp`) is included in `mempro/`. To use a different one, supply its path with the `-itp` flag; the standard file can be downloaded from [here](https://cgmartini.nl/docs/downloads/force-field-parameters/martini3/particle-definitions.html).
58
60
 
59
- MemPrO is also accessible on Google Colab via the link [ADD LINK]. The Colab will contain instructions for use. (Currently the Colab is WIP and this will be updated.)
61
+ ### Google Colab
62
+
63
+ MemPrO can also be run without installing anything locally, using the [MemPrO Colab notebook](https://colab.research.google.com/github/pstansfeld/MemPrO/blob/main/MemPrO_Colab.ipynb). It installs MemPrO from PyPI, orients a structure from the PDB, AlphaFold DB or your own upload, shows the results (including a 3D view of the top-ranked orientation), and can optionally predict membrane deformations with MemPrOD. It runs on both CPU and GPU runtimes.
60
64
 
61
65
  ## Running MemPrO
62
66
 
@@ -72,7 +76,7 @@ python PATH/TO/MemPrO.py -f input_file.pdb
72
76
  mempro -f input_file.pdb
73
77
  ```
74
78
 
75
- No environment variables are required. By default MemPrO will use all available CPU cores and look for `Insane4MemPrO.py` and `martini_v3.itp` in the same directory as the script (or the installed package directory). These paths can be overridden with the `-insane` and `-itp` flags if needed.
79
+ No environment variables are required. By default MemPrO will use a GPU if JAX can see one, otherwise one CPU device per performance core (see `-nc`), and will look for `Insane4MemPrO.py` and `martini_v3.itp` in the same directory as the script (or the installed package directory). These paths can be overridden with the `-insane` and `-itp` flags if needed.
76
80
 
77
81
  Compiled code is cached in `~/.cache/mempro/jax`, so runs after the first one start about 15 s faster. Set `JAX_COMPILATION_CACHE_DIR` to put the cache somewhere else, or `MEMPRO_NO_JAX_CACHE=1` to turn it off.
78
82
 
@@ -82,6 +86,8 @@ MemPrO is intended to be run on PDB files, and will output the following files:
82
86
 
83
87
  * **orientation.txt** — Contains general information about all of the final minima. In general rank 1 is the best orientation, however there are cases where this is not true. `orientation.txt` can then be used to determine the best orientation.
84
88
 
89
+ * **orientations.pdb** — All final orientations in a single PDB file, one model per rank, ordered by rank.
90
+
85
91
  * **local_minima_orientation.png** — A representation of how spread out the local minima are. The more white the image, the more confidence can be placed in rank 1. This is only true in general and there are some cases where this can be safely ignored.
86
92
 
87
93
  * **local_minima_potential.png** — A representation of the potential of the final configuration from a given starting configuration. This complements `local_minima_orientation.png` but in general does not provide much additional information.
@@ -93,7 +99,7 @@ MemPrO is intended to be run on PDB files, and will output the following files:
93
99
  * `PG_potential_curve.png` — The potential curve for the position of the PG cell wall. Only produced with `-pg`.
94
100
  * `cross-section_area_curve.png` — The cross-sectional area of the segment of the protein passing through the PG layer. Only produced with `-pg`.
95
101
  * `Z_potential_curve.png` — Potential against Z position of the final orientation. Gives an idea of the nature of the minima.
96
- * `curv_potential_curve.png` — Potential against global membrane curvature for the final orientation. Can indicate whether curvature minimisation should be used.
102
+ * `curv_potential_curve.png` — Potential against global membrane curvature for the final orientation. Can indicate whether curvature minimisation should be used. Not produced with `-dm`.
97
103
 
98
104
  ## Flags
99
105
 
@@ -107,7 +113,7 @@ MemPrO is intended to be run on PDB files, and will output the following files:
107
113
 
108
114
  **-ng, --grid_size** — Number of initial starting configurations. Defaults to 36. For best efficiency this should be a multiple of the number of CPUs being used. More starting configurations sample the space of minima better, but there are diminishing returns and generally no more than 40 are needed.
109
115
 
110
- **-nc, --num_cpus** — Number of CPU cores to use. Defaults to the number of performance cores where the system reports them (e.g. 4 on an Apple M4, whose 6 efficiency cores would slow each batch down), otherwise all available cores. For best performance with `-ng`, set `-nc` to a value that divides `-ng` evenly.
116
+ **-nc, --num_cpus** — Number of CPU cores to use. Defaults to the number of performance cores where the system reports them (currently macOS, e.g. 4 on an Apple M4, whose 6 efficiency cores would slow each batch down), otherwise all available cores. For best performance with `-ng`, set `-nc` to a value that divides `-ng` evenly.
111
117
 
112
118
  **-dev, --device** — Device to run on: `auto` (default; GPU if JAX can see one, otherwise CPU), `cpu` or `gpu`. On GPU, all starting configurations are minimised together in a single batch. GPU support needs `pip install "mempro[gpu]"` (Linux, NVIDIA).
113
119
 
@@ -115,6 +121,8 @@ MemPrO is intended to be run on PDB files, and will output the following files:
115
121
 
116
122
  **-rank, --rank** — Ranking method for minima: `h` ranks by percentage hits, `p` ranks by potential, `auto` (default) ranks by a value calculated from approximate minima depth and potential.
117
123
 
124
+ **-seed, --seed** — Seed for the random number generators. Runs with the same seed, input and flags give identical results, provided the number of devices (`-nc`, or the number of GPUs) is also the same. Default is unseeded.
125
+
118
126
  **-dm, --dual_membrane** — Toggles dual membrane minimisation. Splits the membrane into an inner and outer membrane and minimises the distance between them. Only use this if your protein spans the periplasm or is a gap junction etc.
119
127
 
120
128
  **-ch, --charge** — Partial charge of the (inner) membrane. The value corresponds to the average charge on a lipid divided by the average area per lipid, representing the average charge across the bilayer sheet. For an E. coli inner membrane this is around -0.008. Default is 0, which gives the best performance in most cases.
@@ -147,7 +155,7 @@ MemPrO is intended to be run on PDB files, and will output the following files:
147
155
 
148
156
  **-insane, --insane_path** — Path to `Insane4MemPrO.py`. Defaults to the same directory as `MemPrO.py` (or the installed package directory). Only required when using `-bd`.
149
157
 
150
- **-bd, --build_system** — Number of final ranked configurations to build as CG MD-ready systems using Insane4MemPrO. Currently only works with coarse grain input files.
158
+ **-bd, --build_system** — Number of final ranked configurations to build as CG MD-ready systems using Insane4MemPrO. Default is 0 (no systems built). Currently only works with coarse grain input files.
151
159
 
152
160
  **-bd_args, --build_arguments** — Arguments to pass to Insane4MemPrO, primarily lipid composition, solvent type etc. Required when using `-bd`.
153
161
 
@@ -167,10 +175,16 @@ Orient `input_file.pdb` on a grid of 40 starting configurations with 150 minimis
167
175
  python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150
168
176
  ```
169
177
 
170
- Orient with global curvature minimisation and write per-bead potentials to b-factors:
178
+ Orient with global curvature minimisation:
179
+
180
+ ```
181
+ python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150 -c
182
+ ```
183
+
184
+ Orient and write per-bead potentials to b-factors (`-wb` is not compatible with `-c`):
171
185
 
172
186
  ```
173
- python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150 -c -wb
187
+ python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150 -wb
174
188
  ```
175
189
 
176
190
  Orient with a dual membrane system, then build the top 2 ranked configurations as CG systems. The inner membrane contains POPE, POPG and CARD; the outer membrane contains LIPA:
@@ -255,29 +269,29 @@ MemPrO comes with Insane4MemPrO, a CG system builder based on [Insane](https://g
255
269
 
256
270
  #### Peptidoglycan layer options
257
271
 
258
- **-pgl** — (Optional) Number of PG layers to place at `-pgl_z`.
272
+ **-pgl** — (Default: 0) Number of PG layers to place at `-pgl_z`.
259
273
 
260
- **-pgl_z** — (Optional) Z position of the PG layer relative to the centre of the periplasmic space.
274
+ **-pgl_z** — (Default: 0) Z position of the PG layer relative to the centre of the periplasmic space.
261
275
 
262
- **-cper** — (Optional) Percentage of cross-links.
276
+ **-cper** — (Default: 0.4) Percentage of cross-links.
263
277
 
264
- **-lper** — (Optional) Percentage of cross-links that are between layers.
278
+ **-lper** — (Default: 0.1) Percentage of cross-links that are between layers.
265
279
 
266
- **-per33** — (Optional) Percentage of 3-3 cross-links; all other cross-links will be 3-4.
280
+ **-per33** — (Default: 0.03) Percentage of 3-3 cross-links; all other cross-links will be 3-4.
267
281
 
268
- **-oper** — (Optional) Percentage chance of a monomer linking with an oligomer. (Actual chance of link is `cper * oper`.)
282
+ **-oper** — (Default: 1) Percentage chance of a monomer linking with an oligomer. (Actual chance of link is `cper * oper`.)
269
283
 
270
284
  **-gdist** — (Default: 0.75,4,8.9,0.25,10,45) Distribution of glycan strand lengths. Format as `weight1,stddev1,mean1,weight2,...` where each triple describes a Gaussian. The sum of these Gaussians forms the distribution.
271
285
 
272
286
  #### Protein options
273
287
 
274
- **-fudge** — (Default: 0.3) Fudge factor for allowing lipid-protein overlap.
288
+ **-fudge** — (Default: 0.3) Fudge factor for allowing lipid-protein overlap. A value of 0.15 is recommended when using `-def`.
275
289
 
276
290
  #### Solvent options
277
291
 
278
292
  **-sol** — (Required) Solvent type.
279
293
 
280
- **-sold** — (Default: 0.5) Solvent packing density.
294
+ **-sold** — (Default: 0.5) Solvent diameter.
281
295
 
282
296
  **-solr** — (Default: 0.1) Magnitude of random deviations to solvent positions.
283
297
 
@@ -331,7 +345,7 @@ More detailed tutorials are available [here](Insane4MemPrO_tutorials.md).
331
345
 
332
346
  If your protein hasn't oriented correctly there are a number of things to try:
333
347
 
334
- * Check all orientations by loading `orientations.pdb` and reviewing `orientations.txt`. The correct orientation may not be rank 1.
348
+ * Check all orientations by loading `orientations.pdb` and reviewing `orientation.txt`. The correct orientation may not be rank 1.
335
349
  * Check `curv_potential_curve.png` to see if your protein prefers a curved membrane. If so, using `-c` will help.
336
350
  * Check the PDB file for missing atoms or residues, which can cause the surface to be incorrectly evaluated. Missing atoms should be fixed before orientation.
337
351
  * Using `-wb` can be helpful for diagnosing missing atoms — it writes the potential contribution of each residue as a b-factor, viewable in PyMOL.
@@ -1,6 +1,8 @@
1
1
  # MemPrO
2
2
  Membrane Protein Orientation in Lipid Bilayers. The paper associated with this code can be found [here](https://doi.org/10.1021/acs.jctc.5c01433).
3
3
 
4
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pstansfeld/MemPrO/blob/main/MemPrO_Colab.ipynb)
5
+
4
6
  Code and parameters from the following were used to help write this code:
5
7
 
6
8
  **Insane:**
@@ -43,7 +45,9 @@ pip install "matplotlib>=3.8.4"
43
45
 
44
46
  The Martini 3 force field file (`martini_v3.itp`) is included in `mempro/`. To use a different one, supply its path with the `-itp` flag; the standard file can be downloaded from [here](https://cgmartini.nl/docs/downloads/force-field-parameters/martini3/particle-definitions.html).
45
47
 
46
- MemPrO is also accessible on Google Colab via the link [ADD LINK]. The Colab will contain instructions for use. (Currently the Colab is WIP and this will be updated.)
48
+ ### Google Colab
49
+
50
+ MemPrO can also be run without installing anything locally, using the [MemPrO Colab notebook](https://colab.research.google.com/github/pstansfeld/MemPrO/blob/main/MemPrO_Colab.ipynb). It installs MemPrO from PyPI, orients a structure from the PDB, AlphaFold DB or your own upload, shows the results (including a 3D view of the top-ranked orientation), and can optionally predict membrane deformations with MemPrOD. It runs on both CPU and GPU runtimes.
47
51
 
48
52
  ## Running MemPrO
49
53
 
@@ -59,7 +63,7 @@ python PATH/TO/MemPrO.py -f input_file.pdb
59
63
  mempro -f input_file.pdb
60
64
  ```
61
65
 
62
- No environment variables are required. By default MemPrO will use all available CPU cores and look for `Insane4MemPrO.py` and `martini_v3.itp` in the same directory as the script (or the installed package directory). These paths can be overridden with the `-insane` and `-itp` flags if needed.
66
+ No environment variables are required. By default MemPrO will use a GPU if JAX can see one, otherwise one CPU device per performance core (see `-nc`), and will look for `Insane4MemPrO.py` and `martini_v3.itp` in the same directory as the script (or the installed package directory). These paths can be overridden with the `-insane` and `-itp` flags if needed.
63
67
 
64
68
  Compiled code is cached in `~/.cache/mempro/jax`, so runs after the first one start about 15 s faster. Set `JAX_COMPILATION_CACHE_DIR` to put the cache somewhere else, or `MEMPRO_NO_JAX_CACHE=1` to turn it off.
65
69
 
@@ -69,6 +73,8 @@ MemPrO is intended to be run on PDB files, and will output the following files:
69
73
 
70
74
  * **orientation.txt** — Contains general information about all of the final minima. In general rank 1 is the best orientation, however there are cases where this is not true. `orientation.txt` can then be used to determine the best orientation.
71
75
 
76
+ * **orientations.pdb** — All final orientations in a single PDB file, one model per rank, ordered by rank.
77
+
72
78
  * **local_minima_orientation.png** — A representation of how spread out the local minima are. The more white the image, the more confidence can be placed in rank 1. This is only true in general and there are some cases where this can be safely ignored.
73
79
 
74
80
  * **local_minima_potential.png** — A representation of the potential of the final configuration from a given starting configuration. This complements `local_minima_orientation.png` but in general does not provide much additional information.
@@ -80,7 +86,7 @@ MemPrO is intended to be run on PDB files, and will output the following files:
80
86
  * `PG_potential_curve.png` — The potential curve for the position of the PG cell wall. Only produced with `-pg`.
81
87
  * `cross-section_area_curve.png` — The cross-sectional area of the segment of the protein passing through the PG layer. Only produced with `-pg`.
82
88
  * `Z_potential_curve.png` — Potential against Z position of the final orientation. Gives an idea of the nature of the minima.
83
- * `curv_potential_curve.png` — Potential against global membrane curvature for the final orientation. Can indicate whether curvature minimisation should be used.
89
+ * `curv_potential_curve.png` — Potential against global membrane curvature for the final orientation. Can indicate whether curvature minimisation should be used. Not produced with `-dm`.
84
90
 
85
91
  ## Flags
86
92
 
@@ -94,7 +100,7 @@ MemPrO is intended to be run on PDB files, and will output the following files:
94
100
 
95
101
  **-ng, --grid_size** — Number of initial starting configurations. Defaults to 36. For best efficiency this should be a multiple of the number of CPUs being used. More starting configurations sample the space of minima better, but there are diminishing returns and generally no more than 40 are needed.
96
102
 
97
- **-nc, --num_cpus** — Number of CPU cores to use. Defaults to the number of performance cores where the system reports them (e.g. 4 on an Apple M4, whose 6 efficiency cores would slow each batch down), otherwise all available cores. For best performance with `-ng`, set `-nc` to a value that divides `-ng` evenly.
103
+ **-nc, --num_cpus** — Number of CPU cores to use. Defaults to the number of performance cores where the system reports them (currently macOS, e.g. 4 on an Apple M4, whose 6 efficiency cores would slow each batch down), otherwise all available cores. For best performance with `-ng`, set `-nc` to a value that divides `-ng` evenly.
98
104
 
99
105
  **-dev, --device** — Device to run on: `auto` (default; GPU if JAX can see one, otherwise CPU), `cpu` or `gpu`. On GPU, all starting configurations are minimised together in a single batch. GPU support needs `pip install "mempro[gpu]"` (Linux, NVIDIA).
100
106
 
@@ -102,6 +108,8 @@ MemPrO is intended to be run on PDB files, and will output the following files:
102
108
 
103
109
  **-rank, --rank** — Ranking method for minima: `h` ranks by percentage hits, `p` ranks by potential, `auto` (default) ranks by a value calculated from approximate minima depth and potential.
104
110
 
111
+ **-seed, --seed** — Seed for the random number generators. Runs with the same seed, input and flags give identical results, provided the number of devices (`-nc`, or the number of GPUs) is also the same. Default is unseeded.
112
+
105
113
  **-dm, --dual_membrane** — Toggles dual membrane minimisation. Splits the membrane into an inner and outer membrane and minimises the distance between them. Only use this if your protein spans the periplasm or is a gap junction etc.
106
114
 
107
115
  **-ch, --charge** — Partial charge of the (inner) membrane. The value corresponds to the average charge on a lipid divided by the average area per lipid, representing the average charge across the bilayer sheet. For an E. coli inner membrane this is around -0.008. Default is 0, which gives the best performance in most cases.
@@ -134,7 +142,7 @@ MemPrO is intended to be run on PDB files, and will output the following files:
134
142
 
135
143
  **-insane, --insane_path** — Path to `Insane4MemPrO.py`. Defaults to the same directory as `MemPrO.py` (or the installed package directory). Only required when using `-bd`.
136
144
 
137
- **-bd, --build_system** — Number of final ranked configurations to build as CG MD-ready systems using Insane4MemPrO. Currently only works with coarse grain input files.
145
+ **-bd, --build_system** — Number of final ranked configurations to build as CG MD-ready systems using Insane4MemPrO. Default is 0 (no systems built). Currently only works with coarse grain input files.
138
146
 
139
147
  **-bd_args, --build_arguments** — Arguments to pass to Insane4MemPrO, primarily lipid composition, solvent type etc. Required when using `-bd`.
140
148
 
@@ -154,10 +162,16 @@ Orient `input_file.pdb` on a grid of 40 starting configurations with 150 minimis
154
162
  python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150
155
163
  ```
156
164
 
157
- Orient with global curvature minimisation and write per-bead potentials to b-factors:
165
+ Orient with global curvature minimisation:
166
+
167
+ ```
168
+ python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150 -c
169
+ ```
170
+
171
+ Orient and write per-bead potentials to b-factors (`-wb` is not compatible with `-c`):
158
172
 
159
173
  ```
160
- python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150 -c -wb
174
+ python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150 -wb
161
175
  ```
162
176
 
163
177
  Orient with a dual membrane system, then build the top 2 ranked configurations as CG systems. The inner membrane contains POPE, POPG and CARD; the outer membrane contains LIPA:
@@ -242,29 +256,29 @@ MemPrO comes with Insane4MemPrO, a CG system builder based on [Insane](https://g
242
256
 
243
257
  #### Peptidoglycan layer options
244
258
 
245
- **-pgl** — (Optional) Number of PG layers to place at `-pgl_z`.
259
+ **-pgl** — (Default: 0) Number of PG layers to place at `-pgl_z`.
246
260
 
247
- **-pgl_z** — (Optional) Z position of the PG layer relative to the centre of the periplasmic space.
261
+ **-pgl_z** — (Default: 0) Z position of the PG layer relative to the centre of the periplasmic space.
248
262
 
249
- **-cper** — (Optional) Percentage of cross-links.
263
+ **-cper** — (Default: 0.4) Percentage of cross-links.
250
264
 
251
- **-lper** — (Optional) Percentage of cross-links that are between layers.
265
+ **-lper** — (Default: 0.1) Percentage of cross-links that are between layers.
252
266
 
253
- **-per33** — (Optional) Percentage of 3-3 cross-links; all other cross-links will be 3-4.
267
+ **-per33** — (Default: 0.03) Percentage of 3-3 cross-links; all other cross-links will be 3-4.
254
268
 
255
- **-oper** — (Optional) Percentage chance of a monomer linking with an oligomer. (Actual chance of link is `cper * oper`.)
269
+ **-oper** — (Default: 1) Percentage chance of a monomer linking with an oligomer. (Actual chance of link is `cper * oper`.)
256
270
 
257
271
  **-gdist** — (Default: 0.75,4,8.9,0.25,10,45) Distribution of glycan strand lengths. Format as `weight1,stddev1,mean1,weight2,...` where each triple describes a Gaussian. The sum of these Gaussians forms the distribution.
258
272
 
259
273
  #### Protein options
260
274
 
261
- **-fudge** — (Default: 0.3) Fudge factor for allowing lipid-protein overlap.
275
+ **-fudge** — (Default: 0.3) Fudge factor for allowing lipid-protein overlap. A value of 0.15 is recommended when using `-def`.
262
276
 
263
277
  #### Solvent options
264
278
 
265
279
  **-sol** — (Required) Solvent type.
266
280
 
267
- **-sold** — (Default: 0.5) Solvent packing density.
281
+ **-sold** — (Default: 0.5) Solvent diameter.
268
282
 
269
283
  **-solr** — (Default: 0.1) Magnitude of random deviations to solvent positions.
270
284
 
@@ -318,7 +332,7 @@ More detailed tutorials are available [here](Insane4MemPrO_tutorials.md).
318
332
 
319
333
  If your protein hasn't oriented correctly there are a number of things to try:
320
334
 
321
- * Check all orientations by loading `orientations.pdb` and reviewing `orientations.txt`. The correct orientation may not be rank 1.
335
+ * Check all orientations by loading `orientations.pdb` and reviewing `orientation.txt`. The correct orientation may not be rank 1.
322
336
  * Check `curv_potential_curve.png` to see if your protein prefers a curved membrane. If so, using `-c` will help.
323
337
  * Check the PDB file for missing atoms or residues, which can cause the surface to be incorrectly evaluated. Missing atoms should be fixed before orientation.
324
338
  * Using `-wb` can be helpful for diagnosing missing atoms — it writes the potential contribution of each residue as a b-factor, viewable in PyMOL.
@@ -13,6 +13,8 @@ from functools import partial, lru_cache
13
13
  import datetime
14
14
  from jax import tree_util
15
15
  import shutil
16
+ import shlex
17
+ import sys
16
18
  from collections import defaultdict
17
19
 
18
20
  PATH_TO_INSANE = os.environ.get("PATH_TO_INSANE", "")
@@ -365,17 +367,21 @@ class PDB_helper:
365
367
  with open(os.path.join(self.fn), "r") as lfile:
366
368
  content = lfile.read().split("\n")
367
369
 
368
- # Group atom lines by (residue name, residue ID)
369
- residue_atoms = defaultdict(list)
370
+ # Group consecutive atom lines into residues. A residue ends when the residue name, chain or
371
+ # number changes, so repeated residue numbers in a chain (e.g. martinize2's default
372
+ # renumbering of multi-chain proteins) stay separate residues. write_oriented() writes one
373
+ # line per bead in file order, so there must be exactly one bead per valid ATOM line.
374
+ residues = []
375
+ prev_key = None
370
376
  for c in content:
371
377
  if len(c) > 54 and "[" not in c and c.startswith("ATOM"):
372
- resname = c[17:21].strip()
373
- resid = int(c[22:26].strip())
374
- chain_id = c[21].strip()
375
- residue_atoms[(resname, chain_id, resid)].append(c)
378
+ key = (c[17:21].strip(), c[21].strip(), c[22:27])
379
+ if key != prev_key:
380
+ residues.append((key[0], int(c[22:26].strip()), []))
381
+ prev_key = key
382
+ residues[-1][2].append(c)
376
383
 
377
- for (resname, chain_id, resid), atoms in residue_atoms.items():
378
- original_resname = resname
384
+ for resname, resid, atoms in residues:
379
385
  if resname not in Reses:
380
386
  print(f"Unknown residue {resname}, using UNK")
381
387
  resname = "UNK"
@@ -385,7 +391,7 @@ class PDB_helper:
385
391
  # Collect atom positions
386
392
  atom_pos_list = []
387
393
  atom_bval_list = []
388
- atom_nums = []
394
+ atom_names = []
389
395
 
390
396
  for c in atoms:
391
397
  try:
@@ -393,13 +399,12 @@ class PDB_helper:
393
399
  y = float(c[38:46].strip())
394
400
  z = float(c[46:54].strip())
395
401
  b = float(c[60:66].strip())
396
- atom_num = int(c[22:26].strip())
397
402
  pos = np.array([x, y, z])
398
403
 
399
404
  if not np.any(np.isnan(pos)):
400
405
  atom_pos_list.append(pos)
401
406
  atom_bval_list.append(b)
402
- atom_nums.append(atom_num)
407
+ atom_names.append(c[12:16].strip())
403
408
  except ValueError:
404
409
  continue
405
410
 
@@ -407,36 +412,25 @@ class PDB_helper:
407
412
  print(f"Skipping residue {resname} {resid} due to no valid positions.")
408
413
  continue
409
414
 
410
- # Fallback mean values
411
- mean_pos = np.mean(atom_pos_list, axis=0)
412
- mean_b = np.mean(atom_bval_list) if atom_bval_list else 0.0
413
-
414
- # Use quick hack: match bead types with atom positions by order
415
- if len(bead_list) != len(atom_pos_list):
416
- #print(f"Mismatch in bead count vs atom count for {resname} {resid}. Using mean positions. Expecting {len(bead_list)}, found {len(atom_pos_list)}")
417
- if resname == "UNK":
418
- bead_list = np.arange(len(atom_pos_list))
419
- else:
420
- print(atom_pos_list)
421
- print(f"Mismatch in bead count vs atom count for {resname} {resid}. Using mean positions. Expecting {len(bead_list)}, found {len(atom_pos_list)}")
422
- for bead_type in bead_list:
423
- if resname == "UNK":
424
- bead_index == 22
425
- else:
426
- bead_index = Beadtype.get(bead_type, -1)
427
- if bead_index == -1:
428
- raise ValueError(f"Unknown bead type: {bead_type}")
429
- self.bead_types.append(bead_index)
430
- self.reses.append(res_index)
431
- if resname == "UNK":
432
- self.poses.append(atom_pos_list[bead_type])
433
- self.b_vals.append(atom_bval_list[bead_type])
415
+ if resname == "UNK":
416
+ res_bead_types = ["GHOST"]*len(atom_pos_list)
417
+ elif len(bead_list) == len(atom_pos_list):
418
+ res_bead_types = bead_list
419
+ else:
420
+ # Match beads by Martini name (BB, SC1, SC2, ...), falling back to file order
421
+ print(f"Mismatch in bead count vs atom count for {resname} {resid}. Expecting {len(bead_list)}, found {len(atom_pos_list)}. Matching beads by name.")
422
+ res_bead_types = []
423
+ for j, name in enumerate(atom_names):
424
+ if name == "BB":
425
+ k = 0
426
+ elif name.startswith("SC") and name[2:].isdigit():
427
+ k = int(name[2:])
434
428
  else:
435
- self.poses.append(mean_pos)
436
- self.b_vals.append(mean_b)
437
- continue
429
+ k = j
430
+ res_bead_types.append(bead_list[min(k, len(bead_list)-1)])
438
431
 
439
- for bead_type, pos, b_val in zip(bead_list, atom_pos_list, atom_bval_list):
432
+ in_range = self.ranges.size != 0 and self.in_ranges(resid)
433
+ for bead_type, pos, b_val in zip(res_bead_types, atom_pos_list, atom_bval_list):
440
434
  bead_index = Beadtype.get(bead_type, -1)
441
435
  if bead_index == -1:
442
436
  raise ValueError(f"Unknown bead type: {bead_type}")
@@ -445,7 +439,6 @@ class PDB_helper:
445
439
  self.poses.append(pos)
446
440
 
447
441
  if self.ranges.size != 0:
448
- in_range = any(self.in_ranges(num) for num in atom_nums)
449
442
  self.b_vals.append(1.0 if in_range else 0.0)
450
443
  else:
451
444
  self.b_vals.append(b_val)
@@ -2571,7 +2564,7 @@ class MemBrain:
2571
2564
 
2572
2565
 
2573
2566
  #Builds a CG system using insane
2574
- def build_oriented(self,orient_dir,build_args):
2567
+ def build_oriented(self,orient_dir,build_args,insane_path):
2575
2568
  mins = np.array(self.minima)
2576
2569
  no_mins = (mins.shape[0]//5)
2577
2570
  min_poses = mins[:no_mins]
@@ -2594,14 +2587,14 @@ class MemBrain:
2594
2587
  curv_str = " -curv "+str(10*np.abs(min_curvs[i]))+",0.1,"+str(np.sign(min_curvs[i]-1e-9))
2595
2588
  print("Building rank "+str(i+1)+" with Insane4MemPrO:")
2596
2589
  cg_sys_dir = rank_dir+"CG_System_rank_"+str(i+1)+"/"
2597
- run_str = "python "+PATH_TO_INSANE+" "+build_args.strip()+" -o "+cg_sys_dir+"CG-system.gro -p "+cg_sys_dir+"topol.top -f "+cg_sys_dir+"protein-cg.pdb "+"-x "+str(x_range)+" -y "+str(y_range)+" -z "+str(z_range)+curv_str
2590
+ run_str = shlex.quote(sys.executable)+" "+shlex.quote(insane_path)+" "+build_args.strip()+" -o "+shlex.quote(cg_sys_dir+"CG-system.gro")+" -p "+shlex.quote(cg_sys_dir+"topol.top")+" -f "+shlex.quote(cg_sys_dir+"protein-cg.pdb")+" -x "+str(x_range)+" -y "+str(y_range)+" -z "+str(z_range)+curv_str
2598
2591
  if(zdist > 1e-6):
2599
2592
  run_str += " -ps "+str(zdist)
2600
2593
  if(self.pg_layer_pred):
2601
2594
  ps = self.pg_poses[i][0]
2602
2595
  xs_pg = self.pg_poses[i][1]
2603
2596
  pg_pos = -xs_pg[jnp.argmin(ps)]
2604
- run_str += " -pgl_z "+str(pg_pos/10.0)+" -o_f "+cg_sys_dir
2597
+ run_str += " -pgl_z "+str(pg_pos/10.0)+" -o_f "+shlex.quote(cg_sys_dir)
2605
2598
  #print()
2606
2599
  err_val = os.system(run_str)
2607
2600
  if(err_val != 0):
@@ -3478,14 +3471,14 @@ def main():
3478
3471
  os.environ["TF_CPP_MIN_LOG_LEVEL"]="3"
3479
3472
 
3480
3473
  #Reading command line args
3481
- parser = argparse.ArgumentParser(prog="MemPrO",description="Orients a protein in a membrane. Currently only for E-coli membranes, but this will change in future updates. Currently flags -c -c_ni -ps -fc are WIP, these can still be used at the your own peril.")
3474
+ parser = argparse.ArgumentParser(prog="MemPrO",description="Orients a protein in a membrane. Currently only for E-coli membranes, but this will change in future updates.")
3482
3475
  parser.add_argument("-f", "--file_name",help = "Input file name (.pdb)")
3483
3476
  parser.add_argument("-o","--output",help="Name of the output directory (Default: Orient)")
3484
3477
  parser.add_argument("-ni","--iters",help="Number of minimisation iterations (Default: 150)")
3485
3478
  parser.set_defaults(iters=150)
3486
3479
  parser.add_argument("-ng","--grid_size",help="Number of starting configurations (Default: 36)")
3487
3480
  parser.set_defaults(grid_size=36)
3488
- parser.add_argument("-nc","--num_cpus",help="Number of CPU cores to use (Default: all available)",type=int)
3481
+ parser.add_argument("-nc","--num_cpus",help="Number of CPU cores to use (Default: performance cores on macOS, otherwise all available)",type=int)
3489
3482
  parser.set_defaults(num_cpus=None)
3490
3483
  parser.add_argument("-dev","--device",help="Device to run on: auto (GPU if available, otherwise CPU), cpu or gpu (Default: auto)",choices=["auto","cpu","gpu"])
3491
3484
  parser.set_defaults(device="auto")
@@ -3508,7 +3501,7 @@ def main():
3508
3501
  parser.add_argument("-itp","--itp_file",help="Path to force field (martini_v3.itp)")
3509
3502
  parser.set_defaults(itp_file=_default_itp)
3510
3503
  parser.add_argument("-insane","--insane_path",help="Path to Insane4MemPrO.py")
3511
- parser.set_defaults(insane_path=_default_insane)
3504
+ parser.set_defaults(insane_path=PATH_TO_INSANE or _default_insane)
3512
3505
  parser.add_argument("-bd","--build_system",help = "Build a MD ready CG-system for ranks < n (Default: n=0)")
3513
3506
  parser.set_defaults(build_system=0)
3514
3507
  parser.add_argument("-bd_args","--build_arguments",help="Arguments to pass to insane when building system")
@@ -3535,12 +3528,21 @@ def main():
3535
3528
  parser.set_defaults(write_bfactors=False)
3536
3529
  parser.add_argument("-rank","--rank",help="Ranking method: auto (default), h (hits), p (potential)")
3537
3530
  parser.set_defaults(rank="auto")
3531
+ parser.add_argument("-seed","--seed",type=int,help="Seed for the random number generators, for reproducible runs. Results also depend on the number of devices (-nc) (Default: unseeded)")
3532
+ parser.set_defaults(seed=None)
3538
3533
  args = parser.parse_args()
3539
3534
 
3540
3535
  if args.file_name is None:
3541
3536
  parser.print_help()
3542
3537
  sys.exit(0)
3543
3538
 
3539
+ #All random draws in MemPrO use NumPy's global generator
3540
+ if args.seed is not None:
3541
+ if not 0 <= args.seed < 2**32:
3542
+ print("ERROR: Could not read value of -seed. Must be an integer between 0 and 2^32-1.")
3543
+ exit()
3544
+ np.random.seed(args.seed)
3545
+
3544
3546
  fliper = 1
3545
3547
  if args.flip:
3546
3548
  fliper = -1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mempro
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: Membrane Protein Orientation in Lipid Bilayers
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -14,6 +14,8 @@ Dynamic: license-file
14
14
  # MemPrO
15
15
  Membrane Protein Orientation in Lipid Bilayers. The paper associated with this code can be found [here](https://doi.org/10.1021/acs.jctc.5c01433).
16
16
 
17
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pstansfeld/MemPrO/blob/main/MemPrO_Colab.ipynb)
18
+
17
19
  Code and parameters from the following were used to help write this code:
18
20
 
19
21
  **Insane:**
@@ -56,7 +58,9 @@ pip install "matplotlib>=3.8.4"
56
58
 
57
59
  The Martini 3 force field file (`martini_v3.itp`) is included in `mempro/`. To use a different one, supply its path with the `-itp` flag; the standard file can be downloaded from [here](https://cgmartini.nl/docs/downloads/force-field-parameters/martini3/particle-definitions.html).
58
60
 
59
- MemPrO is also accessible on Google Colab via the link [ADD LINK]. The Colab will contain instructions for use. (Currently the Colab is WIP and this will be updated.)
61
+ ### Google Colab
62
+
63
+ MemPrO can also be run without installing anything locally, using the [MemPrO Colab notebook](https://colab.research.google.com/github/pstansfeld/MemPrO/blob/main/MemPrO_Colab.ipynb). It installs MemPrO from PyPI, orients a structure from the PDB, AlphaFold DB or your own upload, shows the results (including a 3D view of the top-ranked orientation), and can optionally predict membrane deformations with MemPrOD. It runs on both CPU and GPU runtimes.
60
64
 
61
65
  ## Running MemPrO
62
66
 
@@ -72,7 +76,7 @@ python PATH/TO/MemPrO.py -f input_file.pdb
72
76
  mempro -f input_file.pdb
73
77
  ```
74
78
 
75
- No environment variables are required. By default MemPrO will use all available CPU cores and look for `Insane4MemPrO.py` and `martini_v3.itp` in the same directory as the script (or the installed package directory). These paths can be overridden with the `-insane` and `-itp` flags if needed.
79
+ No environment variables are required. By default MemPrO will use a GPU if JAX can see one, otherwise one CPU device per performance core (see `-nc`), and will look for `Insane4MemPrO.py` and `martini_v3.itp` in the same directory as the script (or the installed package directory). These paths can be overridden with the `-insane` and `-itp` flags if needed.
76
80
 
77
81
  Compiled code is cached in `~/.cache/mempro/jax`, so runs after the first one start about 15 s faster. Set `JAX_COMPILATION_CACHE_DIR` to put the cache somewhere else, or `MEMPRO_NO_JAX_CACHE=1` to turn it off.
78
82
 
@@ -82,6 +86,8 @@ MemPrO is intended to be run on PDB files, and will output the following files:
82
86
 
83
87
  * **orientation.txt** — Contains general information about all of the final minima. In general rank 1 is the best orientation, however there are cases where this is not true. `orientation.txt` can then be used to determine the best orientation.
84
88
 
89
+ * **orientations.pdb** — All final orientations in a single PDB file, one model per rank, ordered by rank.
90
+
85
91
  * **local_minima_orientation.png** — A representation of how spread out the local minima are. The more white the image, the more confidence can be placed in rank 1. This is only true in general and there are some cases where this can be safely ignored.
86
92
 
87
93
  * **local_minima_potential.png** — A representation of the potential of the final configuration from a given starting configuration. This complements `local_minima_orientation.png` but in general does not provide much additional information.
@@ -93,7 +99,7 @@ MemPrO is intended to be run on PDB files, and will output the following files:
93
99
  * `PG_potential_curve.png` — The potential curve for the position of the PG cell wall. Only produced with `-pg`.
94
100
  * `cross-section_area_curve.png` — The cross-sectional area of the segment of the protein passing through the PG layer. Only produced with `-pg`.
95
101
  * `Z_potential_curve.png` — Potential against Z position of the final orientation. Gives an idea of the nature of the minima.
96
- * `curv_potential_curve.png` — Potential against global membrane curvature for the final orientation. Can indicate whether curvature minimisation should be used.
102
+ * `curv_potential_curve.png` — Potential against global membrane curvature for the final orientation. Can indicate whether curvature minimisation should be used. Not produced with `-dm`.
97
103
 
98
104
  ## Flags
99
105
 
@@ -107,7 +113,7 @@ MemPrO is intended to be run on PDB files, and will output the following files:
107
113
 
108
114
  **-ng, --grid_size** — Number of initial starting configurations. Defaults to 36. For best efficiency this should be a multiple of the number of CPUs being used. More starting configurations sample the space of minima better, but there are diminishing returns and generally no more than 40 are needed.
109
115
 
110
- **-nc, --num_cpus** — Number of CPU cores to use. Defaults to the number of performance cores where the system reports them (e.g. 4 on an Apple M4, whose 6 efficiency cores would slow each batch down), otherwise all available cores. For best performance with `-ng`, set `-nc` to a value that divides `-ng` evenly.
116
+ **-nc, --num_cpus** — Number of CPU cores to use. Defaults to the number of performance cores where the system reports them (currently macOS, e.g. 4 on an Apple M4, whose 6 efficiency cores would slow each batch down), otherwise all available cores. For best performance with `-ng`, set `-nc` to a value that divides `-ng` evenly.
111
117
 
112
118
  **-dev, --device** — Device to run on: `auto` (default; GPU if JAX can see one, otherwise CPU), `cpu` or `gpu`. On GPU, all starting configurations are minimised together in a single batch. GPU support needs `pip install "mempro[gpu]"` (Linux, NVIDIA).
113
119
 
@@ -115,6 +121,8 @@ MemPrO is intended to be run on PDB files, and will output the following files:
115
121
 
116
122
  **-rank, --rank** — Ranking method for minima: `h` ranks by percentage hits, `p` ranks by potential, `auto` (default) ranks by a value calculated from approximate minima depth and potential.
117
123
 
124
+ **-seed, --seed** — Seed for the random number generators. Runs with the same seed, input and flags give identical results, provided the number of devices (`-nc`, or the number of GPUs) is also the same. Default is unseeded.
125
+
118
126
  **-dm, --dual_membrane** — Toggles dual membrane minimisation. Splits the membrane into an inner and outer membrane and minimises the distance between them. Only use this if your protein spans the periplasm or is a gap junction etc.
119
127
 
120
128
  **-ch, --charge** — Partial charge of the (inner) membrane. The value corresponds to the average charge on a lipid divided by the average area per lipid, representing the average charge across the bilayer sheet. For an E. coli inner membrane this is around -0.008. Default is 0, which gives the best performance in most cases.
@@ -147,7 +155,7 @@ MemPrO is intended to be run on PDB files, and will output the following files:
147
155
 
148
156
  **-insane, --insane_path** — Path to `Insane4MemPrO.py`. Defaults to the same directory as `MemPrO.py` (or the installed package directory). Only required when using `-bd`.
149
157
 
150
- **-bd, --build_system** — Number of final ranked configurations to build as CG MD-ready systems using Insane4MemPrO. Currently only works with coarse grain input files.
158
+ **-bd, --build_system** — Number of final ranked configurations to build as CG MD-ready systems using Insane4MemPrO. Default is 0 (no systems built). Currently only works with coarse grain input files.
151
159
 
152
160
  **-bd_args, --build_arguments** — Arguments to pass to Insane4MemPrO, primarily lipid composition, solvent type etc. Required when using `-bd`.
153
161
 
@@ -167,10 +175,16 @@ Orient `input_file.pdb` on a grid of 40 starting configurations with 150 minimis
167
175
  python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150
168
176
  ```
169
177
 
170
- Orient with global curvature minimisation and write per-bead potentials to b-factors:
178
+ Orient with global curvature minimisation:
179
+
180
+ ```
181
+ python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150 -c
182
+ ```
183
+
184
+ Orient and write per-bead potentials to b-factors (`-wb` is not compatible with `-c`):
171
185
 
172
186
  ```
173
- python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150 -c -wb
187
+ python PATH/TO/MemPrO.py -f input_file.pdb -o Output_dir/ -ng 40 -ni 150 -wb
174
188
  ```
175
189
 
176
190
  Orient with a dual membrane system, then build the top 2 ranked configurations as CG systems. The inner membrane contains POPE, POPG and CARD; the outer membrane contains LIPA:
@@ -255,29 +269,29 @@ MemPrO comes with Insane4MemPrO, a CG system builder based on [Insane](https://g
255
269
 
256
270
  #### Peptidoglycan layer options
257
271
 
258
- **-pgl** — (Optional) Number of PG layers to place at `-pgl_z`.
272
+ **-pgl** — (Default: 0) Number of PG layers to place at `-pgl_z`.
259
273
 
260
- **-pgl_z** — (Optional) Z position of the PG layer relative to the centre of the periplasmic space.
274
+ **-pgl_z** — (Default: 0) Z position of the PG layer relative to the centre of the periplasmic space.
261
275
 
262
- **-cper** — (Optional) Percentage of cross-links.
276
+ **-cper** — (Default: 0.4) Percentage of cross-links.
263
277
 
264
- **-lper** — (Optional) Percentage of cross-links that are between layers.
278
+ **-lper** — (Default: 0.1) Percentage of cross-links that are between layers.
265
279
 
266
- **-per33** — (Optional) Percentage of 3-3 cross-links; all other cross-links will be 3-4.
280
+ **-per33** — (Default: 0.03) Percentage of 3-3 cross-links; all other cross-links will be 3-4.
267
281
 
268
- **-oper** — (Optional) Percentage chance of a monomer linking with an oligomer. (Actual chance of link is `cper * oper`.)
282
+ **-oper** — (Default: 1) Percentage chance of a monomer linking with an oligomer. (Actual chance of link is `cper * oper`.)
269
283
 
270
284
  **-gdist** — (Default: 0.75,4,8.9,0.25,10,45) Distribution of glycan strand lengths. Format as `weight1,stddev1,mean1,weight2,...` where each triple describes a Gaussian. The sum of these Gaussians forms the distribution.
271
285
 
272
286
  #### Protein options
273
287
 
274
- **-fudge** — (Default: 0.3) Fudge factor for allowing lipid-protein overlap.
288
+ **-fudge** — (Default: 0.3) Fudge factor for allowing lipid-protein overlap. A value of 0.15 is recommended when using `-def`.
275
289
 
276
290
  #### Solvent options
277
291
 
278
292
  **-sol** — (Required) Solvent type.
279
293
 
280
- **-sold** — (Default: 0.5) Solvent packing density.
294
+ **-sold** — (Default: 0.5) Solvent diameter.
281
295
 
282
296
  **-solr** — (Default: 0.1) Magnitude of random deviations to solvent positions.
283
297
 
@@ -331,7 +345,7 @@ More detailed tutorials are available [here](Insane4MemPrO_tutorials.md).
331
345
 
332
346
  If your protein hasn't oriented correctly there are a number of things to try:
333
347
 
334
- * Check all orientations by loading `orientations.pdb` and reviewing `orientations.txt`. The correct orientation may not be rank 1.
348
+ * Check all orientations by loading `orientations.pdb` and reviewing `orientation.txt`. The correct orientation may not be rank 1.
335
349
  * Check `curv_potential_curve.png` to see if your protein prefers a curved membrane. If so, using `-c` will help.
336
350
  * Check the PDB file for missing atoms or residues, which can cause the surface to be incorrectly evaluated. Missing atoms should be fixed before orientation.
337
351
  * Using `-wb` can be helpful for diagnosing missing atoms — it writes the potential contribution of each residue as a b-factor, viewable in PyMOL.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mempro"
7
- version = "0.2.1"
7
+ version = "0.3.0"
8
8
  description = "Membrane Protein Orientation in Lipid Bilayers"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes