mempro 0.0.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mempro/Insane4MemPrO.py +4533 -0
- mempro/MemPrO.py +3619 -0
- mempro/MemPrO_Script.py +360 -0
- mempro/__init__.py +0 -0
- mempro-0.0.8.dist-info/METADATA +313 -0
- mempro-0.0.8.dist-info/RECORD +10 -0
- mempro-0.0.8.dist-info/WHEEL +5 -0
- mempro-0.0.8.dist-info/entry_points.txt +3 -0
- mempro-0.0.8.dist-info/licenses/LICENSE +674 -0
- mempro-0.0.8.dist-info/top_level.txt +1 -0
mempro/Insane4MemPrO.py
ADDED
|
@@ -0,0 +1,4533 @@
|
|
|
1
|
+
import sys,math,random,os
|
|
2
|
+
import numpy as np
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
import scipy as sp
|
|
5
|
+
import jax
|
|
6
|
+
import jax.numpy as jnp
|
|
7
|
+
from functools import partial
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
|
|
12
|
+
jax.config.update("jax_enable_x64",True)
|
|
13
|
+
jax.config.update("jax_platform_name","cpu")
|
|
14
|
+
|
|
15
|
+
# Modify insane to take in arbitary lipid definition strings and use them as a template for lipids
|
|
16
|
+
# Also take in lipid name
|
|
17
|
+
# Edits: by Helgi I. Ingolfsson (all edits are marked with: # HII edit - lipid definition )
|
|
18
|
+
|
|
19
|
+
#This is a heavily modified version of Insane, called Insane4MemPrO, written to work with the orientation software MemPrO.
|
|
20
|
+
#Modifications were made by Matyas Parrag.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# PROTOLIPID (diacylglycerol), 18 beads
|
|
24
|
+
#
|
|
25
|
+
# 1-3-4-6-7--9-10-11-12-13-14
|
|
26
|
+
# \| |/ |
|
|
27
|
+
# 2 5 8-15-16-17-18-19-20
|
|
28
|
+
#
|
|
29
|
+
|
|
30
|
+
lipidsx = {}
|
|
31
|
+
lipidsy = {}
|
|
32
|
+
lipidsz = {}
|
|
33
|
+
lipidsa = {}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
#Detergent
|
|
37
|
+
|
|
38
|
+
moltype = "type_DDM"
|
|
39
|
+
lipidsx[moltype] = (0.27, -0.18, 0.43, 0.17, -0.48, -0.03, 0.42, -0.03, 0.09, 0.03, 0.01)
|
|
40
|
+
lipidsy[moltype] = (-0.32, -0.53, -0.29, -0.34, -0.04, 0.29, 0.46, 0.21, 0.21, 0.06, 0.02)
|
|
41
|
+
lipidsz[moltype] = (3.58, 3.07, 2.68, 3.10, 3.68, 3.05, 3.78, 3.50, 2.04, 1.06, 0.06)
|
|
42
|
+
lipidsa.update({ "DDM":(moltype, "A1 B1 C1 VS1 A2 B2 C2 VS2 L1 L2 L3")})
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
#For building of PG layers in CG, This is a test and currently uses M2 beads
|
|
47
|
+
moltype = "type_PEP"
|
|
48
|
+
lipidsy[moltype] = (-0.03, 0.39, -0.03, -0.03, -0.03, -0.61, -0.93, -0.03, 0.40, -0.03, -0.45, -0.04, -0.41, -0.04, -0.03, -0.03, -0.03, -0.03, -0.66, -0.79)
|
|
49
|
+
lipidsz[moltype] = (0.02, 0.15, 0.02, 0.03, 0.04, -0.12, 0.12, 0.05, 0.12, 0.06, -0.12, 0.10, -0.13, 0.10, 0.09, 0.08, 0.07, 0.06, -0.11, -0.14)
|
|
50
|
+
lipidsx[moltype] = (4.41, 4.41, 3.64, 2.93, 2.23, 2.17, 2.65, 1.44, 1.32, 0.57, 0.69, -3.69, -3.71, -2.91, -2.21, -1.50, -0.77, -0.02, -1.60, -2.02)
|
|
51
|
+
lipidsa.update({ "PEP":(moltype, "B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20")})
|
|
52
|
+
lipidsa.update({ "SPEP":(moltype, "B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 - - - - - - - - -")})
|
|
53
|
+
lipidsa.update({ "UPEP":(moltype, "B1 B2 B3 B4 B5 B6 B7 B8 B9 - - - - - - - - - - -")})
|
|
54
|
+
lipidsa.update({ "UUPEP":(moltype, "B1 B2 B3 B4 B5 B6 B7 - - - - - - - - - - - - -")})
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
moltype = "type_NAM"
|
|
59
|
+
lipidsx[moltype] = (-0.00, 0.60, -0.58, 0.01, -0.52)
|
|
60
|
+
lipidsz[moltype] = (0.03, -0.00, 0.04, 0.03, 0.05)
|
|
61
|
+
lipidsy[moltype] = (4.70, 4.44, 4.74, 4.07, 3.81)
|
|
62
|
+
lipidsa.update({ "NAM":(moltype, "B1 B2 B3 B4 B5")})
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
moltype = "type_NAG"
|
|
66
|
+
lipidsx[moltype] = (0.06, 0.65, -0.51, 0.02)
|
|
67
|
+
lipidsz[moltype] = (0.00, -0.02, 0.00, 0.00)
|
|
68
|
+
lipidsy[moltype] = (3.04, 2.74, 3.22, 2.42)
|
|
69
|
+
lipidsa.update({ "NAG":(moltype, "B1 B2 B3 B4")})
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
## Diacyl glycerols
|
|
76
|
+
moltype = "lipid"
|
|
77
|
+
lipidsx[moltype] = ( 0, .5, 0, 0, .5, 0, 0, .5, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
|
|
78
|
+
lipidsy[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
79
|
+
lipidsz[moltype] = ( 10, 9, 9, 8, 8, 7, 6, 6, 5, 4, 3, 2.5, 1, 0, 5, 4, 3, 2.5, 1, 0)
|
|
80
|
+
lipidsa.update({ # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
|
81
|
+
## Phospholipids
|
|
82
|
+
"DTPC": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A - - - - C1B C2B - - - - "),
|
|
83
|
+
"DLPC": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A C3A - - - C1B C2B C3B - - - "),
|
|
84
|
+
"DPPC": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
85
|
+
"DBPC": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A C3A C4A C5A - C1B C2B C3B C4B C5B - "),
|
|
86
|
+
"POPC": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
87
|
+
"DOPC": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B D2B C3B C4B - - "),
|
|
88
|
+
"DAPC": (moltype, " - - - NC3 - PO4 GL1 GL2 D1A D2A D3A D4A C5A - D1B D2B D3B D4B C5B - "),
|
|
89
|
+
"DIPC": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A D2A D3A C4A - - C1B D2B D3B C4B - - "),
|
|
90
|
+
"DGPC": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A D3A C4A C5A - C1B C2B D3B C4B C5B - "),
|
|
91
|
+
"DNPC": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A C3A D4A C5A C6A C1B C2B C3B D4B C5B C6B"),
|
|
92
|
+
"DTPE": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A - - - - C1B C2B - - - - "),
|
|
93
|
+
"DLPE": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A C3A - - - C1B C2B C3B - - - "),
|
|
94
|
+
"DPPE": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
95
|
+
"DBPE": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A C3A C4A C5A - C1B C2B C3B C4B C5B - "),
|
|
96
|
+
"POPE": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
97
|
+
"DOPE": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B D2B C3B C4B - - "),
|
|
98
|
+
"POPG": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
99
|
+
"DOPG": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B D2B C3B C4B - - "),
|
|
100
|
+
"POPS": (moltype, " - - - CN0 - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
101
|
+
"DOPS": (moltype, " - - - CN0 - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B D2B C3B C4B - - "),
|
|
102
|
+
"DPSM": (moltype, " - - - NC3 - PO4 AM1 AM2 T1A C2A C3A - - - C1B C2B C3B C4B - - "),
|
|
103
|
+
"DBSM": (moltype, " - - - NC3 - PO4 AM1 AM2 T1A C2A C3A C4A - - C1B C2B C3B C4B C5B - "),
|
|
104
|
+
"BNSM": (moltype, " - - - NC3 - PO4 AM1 AM2 T1A C2A C3A C4A - - C1B C2B C3B C4B C5B C6B"),
|
|
105
|
+
"APG": (moltype, " - - ALA GLX - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
106
|
+
"KPG": (moltype, "LY1 LY2 LY3 GLX - PO4 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
107
|
+
# PG for thylakoid membrane
|
|
108
|
+
"OPPG": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A C2A C3A C4A - - C1B D2B C3B C4B - - "),
|
|
109
|
+
# PG for thylakoid membrane of spinach (PPT with a trans-unsaturated bond at sn1 and a triple-unsaturated bond at sn2,
|
|
110
|
+
# and PPG with a transunsaturated bond at sn1 and a palmitoyl tail at sn2)
|
|
111
|
+
"JPPG": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A C2A C3A C4A - - D1B C2B C3B C4B - - "),
|
|
112
|
+
"JFPG": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A D2A D3A D4A - - D1B C2B C3B C4B - - "),
|
|
113
|
+
## Monoacylglycerol
|
|
114
|
+
"GMO": (moltype, " - - - - - - GL1 GL2 C1A C2A D3A C4A C5A - - - - - - - "),
|
|
115
|
+
## Templates using the old lipid names and definitions
|
|
116
|
+
"DHPC.o": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A - - - - C1B C2B - - - - "),
|
|
117
|
+
"DMPC.o": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A C3A - - - C1B C2B C3B - - - "),
|
|
118
|
+
"DSPC.o": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A C3A C4A C5A - C1B C2B C3B C4B C5B - "),
|
|
119
|
+
"POPC.o": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A C3A C4A - - C1B C2B D3B C4B C5B - "),
|
|
120
|
+
"DOPC.o": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A D3A C4A C5A - C1B C2B D3B C4B C5B - "),
|
|
121
|
+
"DUPC.o": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A D2A D3A C4A - - C1B D2B D3B C4B - - "),
|
|
122
|
+
"DEPC.o": (moltype, " - - - NC3 - PO4 GL1 GL2 C1A C2A C3A D4A C5A C6A C1B C2B C3B D4B C5B C6B"),
|
|
123
|
+
"DHPE.o": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A - - - - C1B C2B - - - - "),
|
|
124
|
+
"DLPE.o": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A C3A - - - C1B C2B C3B - - - "),
|
|
125
|
+
"DMPE.o": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A C3A - - - C1B C2B C3B - - - "),
|
|
126
|
+
"DSPE.o": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A C3A C4A C5A - C1B C2B C3B C4B C5B - "),
|
|
127
|
+
"POPE.o": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A C3A C4A - - C1B C2B D3B C4B C5B - "),
|
|
128
|
+
"DOPE.o": (moltype, " - - - NH3 - PO4 GL1 GL2 C1A C2A D3A C4A C5A - C1B C2B D3B C4B C5B - "),
|
|
129
|
+
"PPCS.o": (moltype, " - - - NC3 - PO4 AM1 AM2 C1A C2A C3A C4A - - D1B C2B C3B C4B - - "),
|
|
130
|
+
"DOPG.o": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A C2A D3A C4A C5A - C1B C2B D3B C4B C5B - "),
|
|
131
|
+
"POPG.o": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A C2A C3A C4A - - C1B C2B D3B C4B C5B - "),
|
|
132
|
+
"DOPS.o": (moltype, " - - - CN0 - PO4 GL1 GL2 C1A C2A D3A C4A C5A - C1B C2B D3B C4B C5B - "),
|
|
133
|
+
"POPS.o": (moltype, " - - - CN0 - PO4 GL1 GL2 C1A C2A C3A C4A - - C1B C2B D3B C4B C5B - "),
|
|
134
|
+
"CPG.o": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A C2A C3A C4A - - C1B C2B D3B C4B - - "),
|
|
135
|
+
"PPG.o": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A C2A C3A C4A - - D1B C2B C3B C4B - - "),
|
|
136
|
+
"PPT.o": (moltype, " - - - GL0 - PO4 GL1 GL2 C1A D2A D3A D4A - - D1B C2B C3B C4B - - "),
|
|
137
|
+
"DSMG.o": (moltype, " - - - C6 C4 C1 GL1 GL2 C1A C2A C3A C4A C5A - C1B C2B C3B C4B C5B - "),
|
|
138
|
+
"DSDG.o": (moltype, "C61 C41 C11 C62 C42 C12 GL1 GL2 C1A C2A C3A C4A C5A - C1B C2B C3B C4B C5B - "),
|
|
139
|
+
"DSSQ.o": (moltype, " - - S6 C6 C4 C1 GL1 GL2 C1A C2A C3A C4A C5A - C1B C2B C3B C4B C5B - "),
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# HII fix for PI templates and new templates PI(s) with diffrent tails, PO-PIP1(3) and POPIP2(4,5)
|
|
145
|
+
#Prototopology for phosphatidylinositol type lipids 5,6,7 are potentail phosphates (PIP1,PIP2 and PIP3)
|
|
146
|
+
# 1,2,3 - is the inositol and 4 is the phosphate that links to the tail part.
|
|
147
|
+
# 5
|
|
148
|
+
# \
|
|
149
|
+
# 6-2-1-4-8--10-11-12-13-14-15
|
|
150
|
+
# |/ |
|
|
151
|
+
# 7-3 9--16-17-18-19-20-21
|
|
152
|
+
moltype = "INOSITOLLIPIDS"
|
|
153
|
+
lipidsx[moltype] = ( .5, .5, 0, 0, 1, .5, 0, 0, .5, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
|
|
154
|
+
lipidsy[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
155
|
+
lipidsz[moltype] = ( 8, 9, 9, 7, 10, 10, 10, 6, 6, 5, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0)
|
|
156
|
+
lipidsa.update({ # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
|
157
|
+
"DPPI": (moltype, " C1 C2 C3 CP - - - GL1 GL2 C1A C2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
158
|
+
"POPI": (moltype, " C1 C2 C3 CP - - - GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - "),
|
|
159
|
+
"PIPI": (moltype, " C1 C2 C3 CP - - - GL1 GL2 C1A D2A D3A C4A - - C1B C2B C3B C4B - - "),
|
|
160
|
+
"PAPI": (moltype, " C1 C2 C3 CP - - - GL1 GL2 D1A D2A D3A D4A C5A - C1B C2B C3B C4B - - "),
|
|
161
|
+
"PUPI": (moltype, " C1 C2 C3 CP - - - GL1 GL2 D1A D2A D3A D4A D5A - C1B C2B C3B C4B - - "),
|
|
162
|
+
"POP1": (moltype, " C1 C2 C3 CP P1 - - GL1 GL2 C1A C2A D3A C4A - - C1B C2B C3B C4B - - "),
|
|
163
|
+
"POP2": (moltype, " C1 C2 C3 CP P1 P2 - GL1 GL2 C1A C2A D3A C4A - - C1B C2B C3B C4B - - "),
|
|
164
|
+
"POP3": (moltype, " C1 C2 C3 CP P1 P2 P3 GL1 GL2 C1A C2A D3A C4A - - C1B C2B C3B C4B - - "),
|
|
165
|
+
## Templates using the old lipid names and definitions
|
|
166
|
+
"PI.o" : (moltype, " C1 C2 C3 CP - - - GL1 GL2 C1A C2A C3A C4A - - CU1 CU2 CU3 CU4 CU5 - "),
|
|
167
|
+
"PI34.o": (moltype, " C1 C2 C3 CP PO1 PO2 - GL1 GL2 C1A C2A C3A C4A - - CU1 CU2 CU3 CU4 CU5 - "),
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
#Prototopology for longer and branched glycosil and ceramide based glycolipids
|
|
172
|
+
#
|
|
173
|
+
# 17-15-14-16
|
|
174
|
+
# |/
|
|
175
|
+
# 13
|
|
176
|
+
# |
|
|
177
|
+
# 12-10-9-7-6-4-3-1--18--20-21-22-23-24
|
|
178
|
+
# |/ |/ |/ |/ |
|
|
179
|
+
# 11 8 5 2 19--25-26-27-28-29
|
|
180
|
+
moltype = "GLYCOLIPIDS"
|
|
181
|
+
lipidsx[moltype] = ( 0, .5, 0, 0, .5, 0, 0, .5, 0, 0, .5, 0, 0, 0, 0, 0, 0, 0, .5, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1)
|
|
182
|
+
lipidsy[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, .5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
183
|
+
lipidsz[moltype] = ( 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 10, 9, 10, 8, 11, 5, 5, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0)
|
|
184
|
+
lipidsa.update({ # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
|
185
|
+
"DPG1": (moltype, "GM1 GM2 GM3 GM4 GM5 GM6 GM7 GM8 GM9 GM10 GM11 GM12 GM13 GM14 GM15 GM16 GM17 AM1 AM2 T1A C2A C3A - - - C1B C2B C3B C4B - - "),
|
|
186
|
+
"DXG1": (moltype, "GM1 GM2 GM3 GM4 GM5 GM6 GM7 GM8 GM9 GM10 GM11 GM12 GM13 GM14 GM15 GM16 GM17 AM1 AM2 T1A C2A C3A C4A C5A - C1B C2B C3B C4B C5B C6B"),
|
|
187
|
+
"PNG1": (moltype, "GM1 GM2 GM3 GM4 GM5 GM6 GM7 GM8 GM9 GM10 GM11 GM12 GM13 GM14 GM15 GM16 GM17 AM1 AM2 T1A C2A C3A - - - C1B C2B C3B D4B C5B C6B"),
|
|
188
|
+
"XNG1": (moltype, "GM1 GM2 GM3 GM4 GM5 GM6 GM7 GM8 GM9 GM10 GM11 GM12 GM13 GM14 GM15 GM16 GM17 AM1 AM2 T1A C2A C3A C4A C5A - C1B C2B C3B D4B C5B C6B"),
|
|
189
|
+
"DPG3": (moltype, "GM1 GM2 GM3 GM4 GM5 GM6 - - - - - - GM13 GM14 GM15 GM16 GM17 AM1 AM2 T1A C2A C3A - - - C1B C2B C3B C4B - - "),
|
|
190
|
+
"DXG3": (moltype, "GM1 GM2 GM3 GM4 GM5 GM6 - - - - - - GM13 GM14 GM15 GM16 GM17 AM1 AM2 T1A C2A C3A C4A C5A - C1B C2B C3B C4B C5B C6B"),
|
|
191
|
+
"PNG3": (moltype, "GM1 GM2 GM3 GM4 GM5 GM6 - - - - - - GM13 GM14 GM15 GM16 GM17 AM1 AM2 T1A C2A C3A - - - C1B C2B C3B D4B C5B C6B"),
|
|
192
|
+
"XNG3": (moltype, "GM1 GM2 GM3 GM4 GM5 GM6 - - - - - - GM13 GM14 GM15 GM16 GM17 AM1 AM2 T1A C2A C3A C4A C5A - C1B C2B C3B D4B C5B C6B"),
|
|
193
|
+
"DPCE": (moltype, " - - - - - - - - - - - - - - - - - AM1 AM2 T1A C2A C3A - - C1B C2B C3B C4B - "),
|
|
194
|
+
"DPGS": (moltype, " C1 C2 C3 - - - - - - - - - - - - - - AM1 AM2 T1A C2A C3A - - C1B C2B C3B C4B - "),
|
|
195
|
+
"DPMG": (moltype, " C1 C2 C3 - - - - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B C2B C3B C4B - "),
|
|
196
|
+
"DPSG": (moltype, " S1 C1 C2 C3 - - - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B C2B C3B C4B - "),
|
|
197
|
+
"DPGG": (moltype, "GB2 GB3 GB1 GA1 GA2 GA3 - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B C2B C3B C4B - "),
|
|
198
|
+
#lipids for thylakoid membrane of cyanobacteria: oleoyl tail at sn1 and palmiotyl chain at sn2. SQDG no double bonds
|
|
199
|
+
"OPMG": (moltype, " C1 C2 C3 - - - - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B D2B C3B C4B - "),
|
|
200
|
+
"OPSG": (moltype, " S1 C1 C2 C3 - - - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B D2B C3B C4B - "),
|
|
201
|
+
"OPGG": (moltype, "GB2 GB3 GB1 GA1 GA2 GA3 - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B D2B C3B C4B - "),
|
|
202
|
+
#lipids for thylakoid membrane of spinach: for the *T both chains are triple unsaturated and the *G have a triple unsaturated chain at sn1 and a palmitoyl chain at sn2.
|
|
203
|
+
"FPMG": (moltype, " C1 C2 C3 - - - - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B D2B D3B D4B - "),
|
|
204
|
+
"DFMG": (moltype, " C1 C2 C3 - - - - - - - - - - - - - - GL1 GL2 C1A D2A D3A D4A - C1B D2B D3B D4B - "),
|
|
205
|
+
"FPSG": (moltype, " S1 C1 C2 C3 - - - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B D2B D3B D4B - "),
|
|
206
|
+
"FPGG": (moltype, "GB2 GB3 GB1 GA1 GA2 GA3 - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B D2B D3B D4B - "),
|
|
207
|
+
"DFGG": (moltype, "GB2 GB3 GB1 GA1 GA2 GA3 - - - - - - - - - - - GL1 GL2 C1A D2A D3A D4A - C1B D2B D3B D4B - "),
|
|
208
|
+
## Templates using the old lipid names and definitions
|
|
209
|
+
"GM1.o" : (moltype, "GM1 GM2 GM3 GM4 GM5 GM6 GM7 GM8 GM9 GM10 GM11 GM12 GM13 GM14 GM15 GM16 GM17 AM1 AM2 C1A C2A C3A C4A C5A C1B C2B C3B C4B - "),
|
|
210
|
+
"DGDG.o": (moltype, "GB2 GB3 GB1 GA1 GA2 GA3 - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B C2B C3B C4B - "),
|
|
211
|
+
"MGDG.o": (moltype, " C1 C2 C3 - - - - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B C2B C3B C4B - "),
|
|
212
|
+
"SQDG.o": (moltype, " S1 C1 C2 C3 - - - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B C2B C3B C4B - "),
|
|
213
|
+
"CER.o" : (moltype, " - - - - - - - - - - - - - - - - - AM1 AM2 C1A C2A C3A C4A - C1B C2B C3B C4B - "),
|
|
214
|
+
"GCER.o": (moltype, " C1 C2 C3 - - - - - - - - - - - - - - AM1 AM2 C1A C2A C3A C4A - C1B C2B C3B C4B - "),
|
|
215
|
+
"DPPI.o": (moltype, " C1 C2 C3 - CP - - - - - - - - - - - - GL1 GL2 C1A C2A C3A C4A - C1B C2B C3B C4B - "),
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
moltype = "QUINONES"
|
|
220
|
+
lipidsx[moltype] = ( 0, .5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
221
|
+
lipidsy[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
222
|
+
lipidsz[moltype] = ( 6, 7, 7, 5.5, 5, 4.5, 4, 3.5, 2.5, 2, 1.5, 1)
|
|
223
|
+
lipidsa.update({ # 1 2 3 4 5 6 7 8 9 10 11 12
|
|
224
|
+
"PLQ": (moltype, " PLQ3 PLQ2 PLQ1 PLQ4 PLQ5 PLQ6 PLQ7 PLQ8 PLQ9 PLQ10 PLQ11 PLQ12"),
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
moltype = "CYSTEINES"
|
|
228
|
+
lipidsx[moltype] = ( 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1)
|
|
229
|
+
lipidsy[moltype] = ( 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0)
|
|
230
|
+
lipidsz[moltype] = ( 6, 7, 6, 6, 5, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0, 7, 6, 6, 5, 4, 3, 2, 1, 0)
|
|
231
|
+
lipidsa.update({ # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
|
232
|
+
"CYST": (moltype, " BB SC1 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - - - - C1C C2C C3C C4C - -"),
|
|
233
|
+
"CYSD": (moltype, " BB SC1 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - - - - - - - - - -"),
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
# Prototopology for cardiolipins
|
|
237
|
+
#
|
|
238
|
+
# 4-11-12-13-14-15-16
|
|
239
|
+
# |
|
|
240
|
+
# 2---3--5--6--7--8--9-10
|
|
241
|
+
# /
|
|
242
|
+
# 1
|
|
243
|
+
# \
|
|
244
|
+
# 17-18-20-21-22-23-24-25
|
|
245
|
+
# |
|
|
246
|
+
# 19-26-27-28-29-30-31
|
|
247
|
+
#
|
|
248
|
+
moltype = "CARDIOLIPINS"
|
|
249
|
+
lipidsx[moltype] = ( 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
|
|
250
|
+
lipidsy[moltype] = ( 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1)
|
|
251
|
+
lipidsz[moltype] = ( 8, 7, 6, 6, 5, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0, 7, 6, 6, 5, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0)
|
|
252
|
+
lipidsa.update({ # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
|
253
|
+
"CDL0": (moltype, "GL5 PO41 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - PO42 GL3 GL4 C1C D2C D3C C4C - - C1D C2D C3D C4D - -"), # Warning not the same names is in .itp
|
|
254
|
+
"CDL1": (moltype, "GL5 PO41 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - PO42 GL3 GL4 C1C D2C D3C C4C - - C1D C2D C3D C4D - -"), # Warning not the same names is in .itp
|
|
255
|
+
"CDL2": (moltype, "GL5 PO41 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - PO42 GL3 GL4 C1C D2C D3C C4C - - C1D C2D C3D C4D - -"), # Warning not the same names is in .itp
|
|
256
|
+
"CL4P": (moltype, "GL5 PO41 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - PO42 GL3 GL4 C1C D2C C3C C4C - - C1D C2D C3D C4D - -"),
|
|
257
|
+
"CL4M": (moltype, "GL5 PO41 GL1 GL2 C1A D2A C3A - - - C1B C2B C3B - - - PO42 GL3 GL4 C1C D2C C3C - - - C1D C2D C3D - - -"),
|
|
258
|
+
"CARD": (moltype, "GL0 PO1 GL1 GL2 C1A D2A C3A C4A - - C1B C2B C3B C4B - - PO2 GL3 GL4 C1C D2C C3C C4C - - C1D C2D C3D C4D - -"),
|
|
259
|
+
## Templates using the old lipid names and definitions
|
|
260
|
+
"CL4.o" : (moltype, "GL5 PO41 GL1 GL2 C1A C2A D3A C4A C5A - C1B C2B D3B C4B C5B - PO42 GL3 GL4 C1C C2C D3C C4C C5C - C1D C2D D3D C4D C5D -"),
|
|
261
|
+
"CL4O.o": (moltype, "GL5 PO41 GL1 GL2 C1A C2A D3A C4A C5A - C1B C2B D3B C4B C5B - PO42 GL3 GL4 C1C C2C D3C C4C C5C - C1D C2D D3D C4D C5D -"),
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
moltype = "LPS"
|
|
267
|
+
lipidsx[moltype] = (-7.97, -8.52, -7.94, -8.14, -8.52, -7.87, -8.75, -8.77, -8.61, -8.58, -8.58, -7.69, -7.53, -7.47, -7.58, -7.45, -7.46, -7.37, -7.42, -6.88, -7.56, -7.11, -7.53, -7.26, -7.32, -7.42, -7.54, -8.07, -8.19, -8.44, -7.19, -6.72, -6.82, -6.81, -7.53, -7.74, -7.88, -7.67, -7.41, -7.86, -7.65, -7.51, -7.25, -7.68, -7.39, -7.84, -7.63, -7.18, -7.29)
|
|
268
|
+
lipidsy[moltype] = (0.73, 0.52, 0.60, 0.62, 0.07, 0.51, 0.27, 0.54, 0.70, 0.96, 1.25, 0.51, 0.52, 0.58, 0.76, 0.49, 0.22, 0.10, 0.27, -0.31, -0.04, 0.72, -0.20, -0.29, -0.41, -0.51, -0.60, -0.35, -0.32, -0.13, 1.00, 1.26, 1.42, 1.75, 1.32, 1.56, 1.78, 0.33, 0.52, 0.52, 0.45, 0.85, 0.02, 0.31, -0.05, 0.19, 0.15, 0.58, -0.14)
|
|
269
|
+
lipidsz[moltype] = (5.76, 5.32, 5.25, 5.44, 5.95, 4.51, 4.75, 4.25, 3.59, 2.78, 1.97, 4.00, 3.31, 2.47, 1.63, 6.12, 6.82, 6.30, 6.41, 6.10, 5.61, 5.60, 5.04, 4.41, 3.69, 2.97, 2.11, 4.54, 3.72, 2.80, 5.03, 4.58, 3.76, 2.85, 4.46, 3.68, 2.75, 7.59, 8.18, 8.03, 7.93, 7.36, 8.26, 8.81, 9.30, 9.27, 9.13, 8.95, 9.81)
|
|
270
|
+
lipidsa.update({ "KLA":(moltype, "ZM1 ZM2 ZM3 VS1 PO1 ZM4 ZM5 CF C1F C2F C3F CE C1E C2E C3E GM1 GM2 GM3 VS2 PO2 GM4 GM5 CAB C1A C2A C3A C4A C1B C2B C3B CCD C1C C2C C3C C1D C2D C3D KR1 KR2 KR3 VS3 KS1 KS2 KR4 KR5 KR6 VS4 KS3 KS4")})
|
|
271
|
+
|
|
272
|
+
moltype = "LPS2"
|
|
273
|
+
lipidsx[moltype] = ( 0, 0, 1, 0, 0, 0, 0, 1, 2, 2, 1, 2, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 1, 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 2, 2, 2, 0, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0 )
|
|
274
|
+
lipidsy[moltype] = ( 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 2, 1, 1, 1, 1, 2, 3, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0 )
|
|
275
|
+
lipidsz[moltype] = ( 5, 5, 5, 6, 5, 6, 7, 5, 5, 5, 5, 5, 7, 8, 4, 3, 2, 1, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 3, 2, 1, 0, 4, 4, 3, 2, 1, 0, 3, 3, 2, 1, 0, 3, 2, 1, 9, 9, 8, 10, 11, 11, 12, 11, 12, 12, 13, 13, 13, 13, 13, 12, 14, 14, 14, 15, 16, 16, 15, 15, 16, 16, 17, 18, 17, 17, 18, 17 )
|
|
276
|
+
lipidsa.update({ # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 )
|
|
277
|
+
"PGIN": (moltype, " GM1 GM2 GM3 GM4 PO1 - - GM6 GM7 GM8 GM9 - - - GL1 C1A C2A C3A GL2 C1B C2B C3B C4B GL3 C1C C2C C3C C4C C1D C2D C3D C4D GL4 - C1E C2E C3E - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
278
|
+
"BPER": (moltype, " GM1 GM2 GM3 GM4 PO1 - - GM6 GM7 GM8 GM9 PO2 - - GL1 C1A C2A - GL2 C1B C2B - - GL3 C1C C2C C3C - C1D C2D C3D - GL4 - C1E C2E C3E - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
279
|
+
"BFRA": (moltype, " GM1 GM2 GM3 GM4 PO1 - - GM6 GM7 GM8 GM9 - - - GL1 C1A C2A C3A GL2 C1B C2B C3B - GL3 C1C C2C C3C C4C C1D C2D C3D - GL4 - C1E C2E C3E C4E - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
280
|
+
"CTRA": (moltype, " GM1 GM2 GM3 GM4 PO1 - - GM6 GM7 GM8 GM9 PO2 - - GL1 C1A C2A C3A GL2 C1B C2B C3B - GL3 C1C C2C C3C C4C C1D C2D C3D C4D GL4 - C1E C2E C3E - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
281
|
+
"CJEJ": (moltype, " GM1 GM2 GM3 GM4 PO1 - - GM6 GM7 GM8 GM9 PO2 - - GL1 C1A C2A - GL2 C1B C2B C3B - GL3 C1C C2C C3C - C1D C2D C3D C4D GL4 GL5 C1E C2E C3E - C1F - C2F C3F C4F - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
282
|
+
"HPYL": (moltype, " GM1 GM2 GM3 GM4 PO1 - - GM6 GM7 GM8 GM9 - - - GL1 C1A C2A C3A GL2 C1B C2B C3B C4B GL3 C1C C2C C3C C4C C1D C2D C3D C4D - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
283
|
+
"NMEN": (moltype, " GM1 GM2 GM3 GM4 PO1 PO2 QD1 GM6 GM7 GM8 GM9 PO3 PO4 QD2 GL1 C1A C2A C3A - C1B C2B C3B - GL2 C1C C2C C3C - GL3 C1D C2D C3D - - C1E C2E C3E - GL4 - C1F C2F C3F - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
284
|
+
"SMIN": (moltype, " GM1 GM2 GM3 GM4 PO1 - - GM6 GM7 GM8 GM9 PO2 - - GL1 GL2 C1A C2A - C1B C2B C3B C4B GL3 C1C C2C C3C - GL4 C1D C2D C3D - - C1E C2E C3E - GL5 GL6 C1F C2F C3F C1G C2G C3G - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
# Prototopology for mycolic acid(s)
|
|
289
|
+
#
|
|
290
|
+
# 1--2--3--4--5--6--7--8
|
|
291
|
+
# |
|
|
292
|
+
# 16-15-14-13-12-11-10--9
|
|
293
|
+
# |
|
|
294
|
+
# 17-18-19-20-21-22-23-24
|
|
295
|
+
# /
|
|
296
|
+
# 32-31-30-29-28-27-25-26
|
|
297
|
+
#
|
|
298
|
+
|
|
299
|
+
moltype = "MYCOLIC ACIDS"
|
|
300
|
+
lipidsx[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
|
|
301
|
+
lipidsy[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
302
|
+
lipidsz[moltype] = ( 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 1, 0, 2, 3, 4, 5, 6, 7)
|
|
303
|
+
lipidsa.update({ # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
|
304
|
+
"AMA": (moltype, " - - - C1A C2A C3A C4A C5A M1A C1B C2B C3B C4B - - - - - M1B C1C C2C C3C - - COH OOH C1D C2D C3D C4D C5D C6D"),
|
|
305
|
+
"AMA.w": (moltype, " - - - C1A C2A C3A C4A C5A M1A C1B C2B C3B C4B - - - - - M1B C1C C2C C3C - - COH OOH C1D C2D C3D C4D C5D C6D"),
|
|
306
|
+
"KMA": (moltype, " - - - C1A C2A C3A C4A C5A M1A C1B C2B C3B C4B - - - - - M1B C1C C2C C3C - - COH OOH C1D C2D C3D C4D C5D C6D"),
|
|
307
|
+
"MMA": (moltype, " - - - C1A C2A C3A C4A C5A M1A C1B C2B C3B C4B - - - - - M1B C1C C2C C3C - - COH OOH C1D C2D C3D C4D C5D C6D"),
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
# Sterols
|
|
312
|
+
moltype = "sterol"
|
|
313
|
+
lipidsx[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0)
|
|
314
|
+
lipidsy[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
315
|
+
lipidsz[moltype] = ( 0, 0, 0, 0, 0, 0, 5.3,4.5,3.9,3.3, 3 ,2.6,1.4, 0, 0, 0, 0, 0)
|
|
316
|
+
lipidsa.update({
|
|
317
|
+
"CHOL": (moltype, " - - - - - - ROH R1 R2 R3 R4 R5 C1 C2 - - - - "),
|
|
318
|
+
"ERGO": (moltype, " - - - - - - ROH R1 R2 R3 R4 R5 C1 C2 - - - - "),
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
# Hopanoids
|
|
323
|
+
moltype = "Hopanoids"
|
|
324
|
+
lipidsx[moltype] = ( 0, 0, 0, 0, 0.5,-0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
325
|
+
lipidsy[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
326
|
+
lipidsz[moltype] = ( 0, 0, 0, 0, 0.5, 1.4, 2.6, 3, 3.3, 3.9, 4.5, 5.0, 5.5, 6.0, 0, 0, 0, 0)
|
|
327
|
+
lipidsa.update({
|
|
328
|
+
"HOPR": (moltype, " - - - R1 R2 R3 R4 R5 R6 R7 R8 - - - - - - - "),
|
|
329
|
+
"HHOP": (moltype, " - - - R1 R2 R3 R4 R5 R6 R7 R8 C1 - - - - - - "),
|
|
330
|
+
"HDPT": (moltype, " - - - R1 R2 R3 R4 R5 R6 R7 R8 C1 - - - - - - "),
|
|
331
|
+
"HBHT": (moltype, " - - - R1 R2 R3 R4 R5 R6 R7 R8 C1 C2 C3 - - - - "),
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
#Higher lipids in a different order
|
|
336
|
+
moltype = "Isoprenyls-m3-further"
|
|
337
|
+
lipidsx[moltype] = ( 0, 0.5, 0, 0, 0, 0, 0,0.5, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1, 1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,1.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5, 1, 1, 0, 0, 0, 1, 0, 1, 2, 1,1.5, 2, 2, 2, 1, 1, 2,2.5, 2,2.5)
|
|
338
|
+
lipidsy[moltype] = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2, 1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2,1.5, 2, 2, 1, 2, 2, 1,1.5, 2,2.5)
|
|
339
|
+
lipidsz[moltype] = ( 8, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 11, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 17, 17, 17, 17, 17, 19, 19, 19, 19, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 20, 20, 20, 20, 20, 22, 22, 22, 22, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 23, 23, 23, 23, 23, 25, 25, 25, 25, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 26, 26, 26, 26, 26, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 29, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 32, 32, 32, 32, 32, 34, 34, 34, 34, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 35, 35, 35, 35, 35, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 38, 38, 38, 38, 38, 40, 40, 40, 40, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 41, 41, 41, 41, 41)
|
|
340
|
+
lipidsa.update({ # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
|
|
341
|
+
# "LIP2": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
342
|
+
"LIP4": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
343
|
+
"LIP6": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
344
|
+
"LIP8": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
345
|
+
"LI10": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 B00 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
346
|
+
"LI12": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 B00 B01 B02 B03 B04 B05 B06 B07 B08 B09 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
347
|
+
"LI14": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 B00 B01 B02 B03 B04 B05 B06 B07 B08 B09 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
348
|
+
"LI16": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 B00 B01 B02 B03 B04 B05 B06 B07 B08 B09 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
349
|
+
"LI18": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 B00 B01 B02 B03 B04 B05 B06 B07 B08 B09 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "),
|
|
350
|
+
"LI20": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 B00 B01 B02 B03 B04 B05 B06 B07 B08 B09 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 B00 - - - - - - - - - - - - - - - - - - - - "),
|
|
351
|
+
"LI22": (moltype,"PO1 PO2 CP1 CP2 CP3 CP4 CP5 CP6 CP7 CP8 CP9 CP10 CP11 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 B00 B01 B02 B03 B04 B05 B06 B07 B08 B09 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 B39 B40 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B51 B52 B53 B54 B55 B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B80 B81 B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 B00 B01 B02 B03 B04 B05 B06 B07 B08 B09 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20"),
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
# Lists for automatic charge determination
|
|
356
|
+
charges = {"HPPA":-1,"4HPA":-1,"UDP2":-2,"UDP1":-1, "GLYP":-1, "GLYM":-1, "ARG":1, "LYS":1, "ASP":-1, "GLU":-1, "DOPG":-1, "POPG":-1, "DOPS":-1, "POPS":-1, "DSSQ":-1, "KPG":+1, "LIPA":-2, "PGIN":-1, "REMP":-6, "RAMP":-10, "OANT":-10, "CARD":-2, "A2P2":-1, "APM2":-1, "APM6":-1, "LIP2":-4, "LIP4":-6, "LIP6":-8, "LIP8":-10, "LI10":-12, "LI12":-14, "LI14":-16, "LI16":-18, "LI18":-20, "LI20":-22, "LI22":-24,"UPEP":-1,"SPEP":-2,"UUPEP":-1,"KLA":-6}
|
|
357
|
+
ion_charges = {"NA" :1,"CL":-1,"CA":2}
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
a, b = math.sqrt(2)/20, math.sqrt(2)/60
|
|
361
|
+
ct, st = math.cos(math.pi*109.47/180), math.sin(math.pi*109.47/180) # Tetrahedral
|
|
362
|
+
|
|
363
|
+
# Get a set of coordinates for a solvent particle with a given name
|
|
364
|
+
# Dictionary of solvents; First only those with multiple atoms
|
|
365
|
+
solventParticles = {
|
|
366
|
+
"PW": (("W",(-0.07,0,0)), # Polarizable water
|
|
367
|
+
("WP",(0.07,0,0)),
|
|
368
|
+
("WM",(0.07,0,0))),
|
|
369
|
+
"BMW": (("C",(0,0,0)),
|
|
370
|
+
("Q1",(0.12,0,0)),
|
|
371
|
+
("Q2",(-0.06,math.cos(math.pi/6)*0.12,0))), # BMW water
|
|
372
|
+
"SPC": (("OW",(0,0,0)), # SPC
|
|
373
|
+
("HW1",(0.01,0,0)),
|
|
374
|
+
("HW2",(0.01*ct,0.01*st,0))),
|
|
375
|
+
"SPCM": (("OW",(0,0,0)), # Multiscale/Martini SPC
|
|
376
|
+
("HW1",(0.01,0,0)),
|
|
377
|
+
("HW2",(0.01*ct,0.01*st,0)),
|
|
378
|
+
("vW",(0,0,0))),
|
|
379
|
+
"FG4W": (("OW1",(a,a,a)), # Bundled water
|
|
380
|
+
("HW11",(a,a-b,a-b)),
|
|
381
|
+
("HW12",(a,a+b,a+b)),
|
|
382
|
+
("OW2",(a,-a,-a)),
|
|
383
|
+
("HW21",(a-b,-a,-a+b)),
|
|
384
|
+
("HW22",(a+b,-a,-a-b)),
|
|
385
|
+
("OW3",(-a,-a,a)),
|
|
386
|
+
("HW31",(-a,-a+b,a-b)),
|
|
387
|
+
("HW32",(-a,-a-b,a+b)),
|
|
388
|
+
("OW4",(-a,a,-a)),
|
|
389
|
+
("HW41",(-a+b,a,-a+b)),
|
|
390
|
+
("HW42",(-a-b,a,-a-b))),
|
|
391
|
+
"FG4W-MS": (("OW1",(a,a,a)), # Bundled water, multiscaled
|
|
392
|
+
("HW11",(a,a-b,a-b)),
|
|
393
|
+
("HW12",(a,a+b,a+b)),
|
|
394
|
+
("OW2",(a,-a,-a)),
|
|
395
|
+
("HW21",(a-b,-a,-a+b)),
|
|
396
|
+
("HW22",(a+b,-a,-a-b)),
|
|
397
|
+
("OW3",(-a,-a,a)),
|
|
398
|
+
("HW31",(-a,-a+b,a-b)),
|
|
399
|
+
("HW32",(-a,-a-b,a+b)),
|
|
400
|
+
("OW4",(-a,a,-a)),
|
|
401
|
+
("HW41",(-a+b,a,-a+b)),
|
|
402
|
+
("HW42",(-a-b,a,-a-b)),
|
|
403
|
+
("VZ",(0,0,0))),
|
|
404
|
+
"GLUC": (("B1",(-0.11, 0, 0)),
|
|
405
|
+
("B2",( 0.05, 0.16,0)),
|
|
406
|
+
("B3",( 0.05,-0.16,0))),
|
|
407
|
+
"FRUC": (("B1",(-0.11, 0, 0)),
|
|
408
|
+
("B2",( 0.05, 0.16,0)),
|
|
409
|
+
("B3",( 0.05,-0.16,0))),
|
|
410
|
+
"SUCR": (("B1",(-0.25, 0.25,0)),
|
|
411
|
+
("B2",(-0.25, 0, 0)),
|
|
412
|
+
("B3",(-0.25,-0.25,0)),
|
|
413
|
+
("B4",( 0.25, 0, 0)),
|
|
414
|
+
("B5",( 0.25, 0.25,0)),
|
|
415
|
+
("B6",( 0.25,-0.25,0))),
|
|
416
|
+
"MALT": (("B1",(-0.25, 0.25,0)),
|
|
417
|
+
("B2",(-0.25, 0, 0)),
|
|
418
|
+
("B3",(-0.25,-0.25,0)),
|
|
419
|
+
("B4",( 0.25, 0, 0)),
|
|
420
|
+
("B5",( 0.25, 0.25,0)),
|
|
421
|
+
("B6",( 0.25,-0.25,0))),
|
|
422
|
+
"CELL": (("B1",(-0.25, 0.25,0)),
|
|
423
|
+
("B2",(-0.25, 0, 0)),
|
|
424
|
+
("B3",(-0.25,-0.25,0)),
|
|
425
|
+
("B4",( 0.25, 0, 0)),
|
|
426
|
+
("B5",( 0.25, 0.25,0)),
|
|
427
|
+
("B6",( 0.25,-0.25,0))),
|
|
428
|
+
"KOJI": (("B1",(-0.25, 0.25,0)),
|
|
429
|
+
("B2",(-0.25, 0, 0)),
|
|
430
|
+
("B3",(-0.25,-0.25,0)),
|
|
431
|
+
("B4",( 0.25, 0, 0)),
|
|
432
|
+
("B5",( 0.25, 0.25,0)),
|
|
433
|
+
("B6",( 0.25,-0.25,0))),
|
|
434
|
+
"SOPH": (("B1",(-0.25, 0.25,0)),
|
|
435
|
+
("B2",(-0.25, 0, 0)),
|
|
436
|
+
("B3",(-0.25,-0.25,0)),
|
|
437
|
+
("B4",( 0.25, 0, 0)),
|
|
438
|
+
("B5",( 0.25, 0.25,0)),
|
|
439
|
+
("B6",( 0.25,-0.25,0))),
|
|
440
|
+
"NIGE": (("B1",(-0.25, 0.25,0)),
|
|
441
|
+
("B2",(-0.25, 0, 0)),
|
|
442
|
+
("B3",(-0.25,-0.25,0)),
|
|
443
|
+
("B4",( 0.25, 0, 0)),
|
|
444
|
+
("B5",( 0.25, 0.25,0)),
|
|
445
|
+
("B6",( 0.25,-0.25,0))),
|
|
446
|
+
"LAMI": (("B1",(-0.25, 0.25,0)),
|
|
447
|
+
("B2",(-0.25, 0, 0)),
|
|
448
|
+
("B3",(-0.25,-0.25,0)),
|
|
449
|
+
("B4",( 0.25, 0, 0)),
|
|
450
|
+
("B5",( 0.25, 0.25,0)),
|
|
451
|
+
("B6",( 0.25,-0.25,0))),
|
|
452
|
+
"TREH": (("B1",(-0.25, 0.25,0)),
|
|
453
|
+
("B2",(-0.25, 0, 0)),
|
|
454
|
+
("B3",(-0.25,-0.25,0)),
|
|
455
|
+
("B4",( 0.25, 0, 0)),
|
|
456
|
+
("B5",( 0.25, 0.25,0)),
|
|
457
|
+
("B6",( 0.25,-0.25,0))),
|
|
458
|
+
# Loose aminoacids
|
|
459
|
+
"GLY": (("BB", ( 0, 0, 0)),),
|
|
460
|
+
"ALA": (("BB", ( 0, 0, 0)),),
|
|
461
|
+
"ASN": (("BB", ( 0.25, 0, 0)),
|
|
462
|
+
("SC1",(-0.25, 0, 0))),
|
|
463
|
+
"ASP": (("BB", ( 0.25, 0, 0)),
|
|
464
|
+
("SC1",(-0.25, 0, 0))),
|
|
465
|
+
"GLU": (("BB", ( 0.25, 0, 0)),
|
|
466
|
+
("SC1",(-0.25, 0, 0))),
|
|
467
|
+
"GLN": (("BB", ( 0.25, 0, 0)),
|
|
468
|
+
("SC1",(-0.25, 0, 0))),
|
|
469
|
+
"LEU": (("BB", ( 0.25, 0, 0)),
|
|
470
|
+
("SC1",(-0.25, 0, 0))),
|
|
471
|
+
"ILE": (("BB", ( 0.25, 0, 0)),
|
|
472
|
+
("SC1",(-0.25, 0, 0))),
|
|
473
|
+
"VAL": (("BB", ( 0.25, 0, 0)),
|
|
474
|
+
("SC1",(-0.25, 0, 0))),
|
|
475
|
+
"SER": (("BB", ( 0.25, 0, 0)),
|
|
476
|
+
("SC1",(-0.25, 0, 0))),
|
|
477
|
+
"THR": (("BB", ( 0.25, 0, 0)),
|
|
478
|
+
("SC1",(-0.25, 0, 0))),
|
|
479
|
+
"CYS": (("BB", ( 0.25, 0, 0)),
|
|
480
|
+
("SC1",(-0.25, 0, 0))),
|
|
481
|
+
"MET": (("BB", ( 0.25, 0, 0)),
|
|
482
|
+
("SC1",(-0.25, 0, 0))),
|
|
483
|
+
"LYS": (("BB", ( 0.25, 0, 0)),
|
|
484
|
+
("SC1",(-0.25, 0, 0))),
|
|
485
|
+
"PRO": (("BB", ( 0.25, 0, 0)),
|
|
486
|
+
("SC1",(-0.25, 0, 0))),
|
|
487
|
+
"HYP": (("BB", ( 0.25, 0, 0)),
|
|
488
|
+
("SC1",(-0.25, 0, 0))),
|
|
489
|
+
"ARG": (("BB", ( 0.25, 0, 0)),
|
|
490
|
+
("SC1",( 0, 0, 0)),
|
|
491
|
+
("SC2",(-0.25, 0.125, 0))),
|
|
492
|
+
"PHE": (("BB", ( 0.25, 0, 0)),
|
|
493
|
+
("SC1",( 0, 0, 0)),
|
|
494
|
+
("SC2",(-0.25,-0.125, 0)),
|
|
495
|
+
("SC3",(-0.25, 0.125, 0))),
|
|
496
|
+
"TYR": (("BB", ( 0.25, 0, 0)),
|
|
497
|
+
("SC1",( 0, 0, 0)),
|
|
498
|
+
("SC2",(-0.25,-0.125, 0)),
|
|
499
|
+
("SC3",(-0.25, 0.125, 0))),
|
|
500
|
+
"TRP": (("BB", ( 0.25, 0.125, 0)),
|
|
501
|
+
("SC1",( 0.25, 0, 0)),
|
|
502
|
+
("SC2",( 0, -0.125, 0)),
|
|
503
|
+
("SC3",( 0, 0.125, 0)),
|
|
504
|
+
("SC4",(-0.25, 0, 0))),
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
# Update the solvents dictionary with single atom ones
|
|
508
|
+
for s in ["W","NA","CL","Mg","K","BUT"]:
|
|
509
|
+
solventParticles[s] = ((s,(0,0,0)),)
|
|
510
|
+
|
|
511
|
+
# Apolar amino acids nd stuff for orienting proteins in membrane
|
|
512
|
+
apolar = "ALA CYS PHE ILE LEU MET VAL TRP PLM CLR".split()
|
|
513
|
+
|
|
514
|
+
## PRIVATE PARTS FROM THIS POINT ON ##
|
|
515
|
+
|
|
516
|
+
S = str
|
|
517
|
+
F = float
|
|
518
|
+
I = int
|
|
519
|
+
R = random.random
|
|
520
|
+
|
|
521
|
+
def vector(v):
|
|
522
|
+
if type(v) == str and "," in v:
|
|
523
|
+
return [float(i) for i in v.split(",")]
|
|
524
|
+
return float(v)
|
|
525
|
+
|
|
526
|
+
def vvadd(a,b):
|
|
527
|
+
if type(b) in (int,float):
|
|
528
|
+
return [i+b for i in a]
|
|
529
|
+
return [i+j for i,j in list(zip(a,b))]
|
|
530
|
+
|
|
531
|
+
def vvsub(a,b):
|
|
532
|
+
if type(b) in (int,float):
|
|
533
|
+
return [i-b for i in a]
|
|
534
|
+
return [i-j for i,j in list(zip(a,b))]
|
|
535
|
+
|
|
536
|
+
def isPDBAtom(l):
|
|
537
|
+
return l.startswith("ATOM") or l.startswith("HETATM")
|
|
538
|
+
|
|
539
|
+
def pdbAtom(a):
|
|
540
|
+
##01234567890123456789012345678901234567890123456789012345678901234567890123456789
|
|
541
|
+
##ATOM 2155 HH11 ARG C 203 116.140 48.800 6.280 1.00 0.00
|
|
542
|
+
## ===> atom name, res name, res id, chain, x, y, z
|
|
543
|
+
return (S(a[12:16]),S(a[17:21]),I(a[22:26]),a[21],F(a[30:38])/10,F(a[38:46])/10,F(a[46:54])/10)
|
|
544
|
+
|
|
545
|
+
d2r = 3.14159265358979323846264338327950288/180
|
|
546
|
+
def pdbBoxRead(a):
|
|
547
|
+
# Convert a PDB CRYST1 entry to a lattice definition.
|
|
548
|
+
# Convert from Angstrom to nanometer
|
|
549
|
+
fa, fb, fc, aa, ab, ac = [float(i) for i in a.split()[1:7]]
|
|
550
|
+
ca, cb, cg, sg = math.cos(d2r*aa), math.cos(d2r*ab), math.cos(d2r*ac) , math.sin(d2r*ac)
|
|
551
|
+
wx, wy = 0.1*fc*cb, 0.1*fc*(ca-cb*cg)/sg
|
|
552
|
+
wz = math.sqrt(0.01*fc*fc - wx*wx - wy*wy)
|
|
553
|
+
return [0.1*fa, 0, 0, 0.1*fb*cg, 0.1*fb*sg, 0, wx, wy, wz]
|
|
554
|
+
|
|
555
|
+
def groAtom(a):
|
|
556
|
+
#012345678901234567890123456789012345678901234567890
|
|
557
|
+
# 1PRN N 1 4.168 11.132 5.291
|
|
558
|
+
## ===> atom name, res name, res id, chain, x, y, z
|
|
559
|
+
return (S(a[10:15]), S(a[5:10]), I(a[:5]), " ", F(a[20:28]),F(a[28:36]),F(a[36:44]))
|
|
560
|
+
|
|
561
|
+
def groBoxRead(a):
|
|
562
|
+
b = [F(i) for i in a.split()] + 6*[0] # Padding for rectangular boxes
|
|
563
|
+
return b[0],b[3],b[4],b[5],b[1],b[6],b[7],b[8],b[2]
|
|
564
|
+
|
|
565
|
+
def readBox(a):
|
|
566
|
+
x = [ float(i) for i in a.split(",") ] + 6*[0]
|
|
567
|
+
if len(x) == 12: # PDB format
|
|
568
|
+
return pdbBoxRead("CRYST1 "+" ".join([str(i) for i in x]))
|
|
569
|
+
else: # GRO format
|
|
570
|
+
return x[0],x[3],x[4],x[5],x[1],x[6],x[7],x[8],x[2]
|
|
571
|
+
#A helper function the writes and arbritrary PDB file
|
|
572
|
+
def write_point(points,fn):
|
|
573
|
+
new_file = open(fn,"w")
|
|
574
|
+
count = 0
|
|
575
|
+
for i in points:
|
|
576
|
+
count += 1
|
|
577
|
+
count_str = (6-len(str(count)))*" "+str(count)
|
|
578
|
+
c = "ATOM "+count_str+" BB DUM 1 0.000 0.000 15.000 1.00 0.00"
|
|
579
|
+
xp = np.format_float_positional(i[0],precision=3)
|
|
580
|
+
yp = np.format_float_positional(i[1],precision=3)
|
|
581
|
+
zp = np.format_float_positional(i[2],precision=3)
|
|
582
|
+
xp += "0"*(3-len((xp.split(".")[1])))
|
|
583
|
+
yp += "0"*(3-len((yp.split(".")[1])))
|
|
584
|
+
zp += "0"*(3-len((zp.split(".")[1])))
|
|
585
|
+
new_c = c[:30]+(" "*(8-len(xp)))+xp+(" "*(8-len(yp)))+yp+(" "*(8-len(zp))) +zp+c[54:]+"\n"
|
|
586
|
+
new_file.write(new_c)
|
|
587
|
+
new_file.close()
|
|
588
|
+
|
|
589
|
+
class Structure:
|
|
590
|
+
def __init__(self,filename=None):
|
|
591
|
+
self.title = ""
|
|
592
|
+
self.atoms = []
|
|
593
|
+
self.coord = []
|
|
594
|
+
self.rest = []
|
|
595
|
+
self.box = []
|
|
596
|
+
self._center = None
|
|
597
|
+
|
|
598
|
+
if filename:
|
|
599
|
+
lines = open(filename).readlines()
|
|
600
|
+
# Try extracting PDB atom/hetatm definitions
|
|
601
|
+
self.rest = []
|
|
602
|
+
self.atoms = [pdbAtom(i) for i in lines if isPDBAtom(i) or self.rest.append(i)]
|
|
603
|
+
if self.atoms:
|
|
604
|
+
# This must be a PDB file
|
|
605
|
+
self.title = "THIS IS INSANE!\n"
|
|
606
|
+
for i in self.rest:
|
|
607
|
+
if i.startswith("TITLE"):
|
|
608
|
+
self.title = i
|
|
609
|
+
self.box = [0,0,0,0,0,0,0,0,0]
|
|
610
|
+
for i in self.rest:
|
|
611
|
+
if i.startswith("CRYST1"):
|
|
612
|
+
self.box = pdbBoxRead(i)
|
|
613
|
+
else:
|
|
614
|
+
# This should be a GRO file
|
|
615
|
+
self.atoms = [groAtom(i) for i in lines[2:-1]]
|
|
616
|
+
self.rest = [lines[0],lines[1],lines[-1]]
|
|
617
|
+
self.box = groBoxRead(lines[-1])
|
|
618
|
+
self.title = lines[0]
|
|
619
|
+
self.coord = [i[4:7] for i in self.atoms]
|
|
620
|
+
self.center()
|
|
621
|
+
|
|
622
|
+
def __nonzero__(self):
|
|
623
|
+
return bool(self.atoms)
|
|
624
|
+
|
|
625
|
+
def __len__(self):
|
|
626
|
+
return len(self.atoms)
|
|
627
|
+
|
|
628
|
+
def __iadd__(self,s):
|
|
629
|
+
for i in range(len(self)):
|
|
630
|
+
self.coord[i] = vvadd(self.coord[i],s)
|
|
631
|
+
return self
|
|
632
|
+
|
|
633
|
+
def center(self,other=None):
|
|
634
|
+
if not self._center:
|
|
635
|
+
self._center = [ sum(i)/len(i) for i in list(zip(*self.coord))]
|
|
636
|
+
if other:
|
|
637
|
+
s = vvsub(other,self._center)
|
|
638
|
+
for i in range(len(self)):
|
|
639
|
+
self.coord[i] = vvadd(self.coord[i],s)
|
|
640
|
+
self._center = other
|
|
641
|
+
return s # return the shift
|
|
642
|
+
return self._center
|
|
643
|
+
|
|
644
|
+
def diam(self):
|
|
645
|
+
if self._center != (0,0,0):
|
|
646
|
+
self.center((0,0,0))
|
|
647
|
+
return 2*math.sqrt(max([i*i+j*j+k*k for i,j,k in self.coord]))
|
|
648
|
+
|
|
649
|
+
def diamxy(self):
|
|
650
|
+
if self._center != (0,0,0):
|
|
651
|
+
self.center((0,0,0))
|
|
652
|
+
return 2*math.sqrt(max([i*i+j*j for i,j,k in self.coord]))
|
|
653
|
+
|
|
654
|
+
def fun(self,fn):
|
|
655
|
+
return [fn(i) for i in list(zip(*self.coord))]
|
|
656
|
+
|
|
657
|
+
# Mean of deviations from initial value
|
|
658
|
+
def meand(v):
|
|
659
|
+
return sum([i-v[0] for i in v])/len(v)
|
|
660
|
+
|
|
661
|
+
# Sum of squares/crossproducts of deviations
|
|
662
|
+
def ssd(u,v):
|
|
663
|
+
return sum([(i-u[0])*(j-v[0]) for i,j in list(zip(u,v))])/(len(u)-1)
|
|
664
|
+
|
|
665
|
+
# Parse a string for a lipid as given on the command line (LIPID[:NUMBER])
|
|
666
|
+
def parse_mol(x):
|
|
667
|
+
l = x.split(":")
|
|
668
|
+
return l[0], len(l) == 1 and 1 or float(l[1])
|
|
669
|
+
|
|
670
|
+
## MIJN EIGEN ROUTINE ##
|
|
671
|
+
|
|
672
|
+
# Quite short piece of code for diagonalizing symmetric 3x3 matrices :)
|
|
673
|
+
|
|
674
|
+
# Analytic solution for third order polynomial
|
|
675
|
+
def solve_p3( a, b, c ):
|
|
676
|
+
Q,R,a3 = (3*b-a**2)/9.0, (-27*c+a*(9*b-2*a**2))/54.0, a/3.0
|
|
677
|
+
if Q**3 + R**2:
|
|
678
|
+
t,R13 = math.acos(R/math.sqrt(-Q**3))/3, 2*math.sqrt(-Q)
|
|
679
|
+
u,v,w = math.cos(t), math.sin(t+math.pi/6), math.cos(t+math.pi/3)
|
|
680
|
+
return R13*u-a3, -R13*v-a3, -R13*w-a3
|
|
681
|
+
else:
|
|
682
|
+
R13 = math.sqrt3(R)
|
|
683
|
+
return 2*R13-a3, -R13-a3, -R13-a3
|
|
684
|
+
|
|
685
|
+
# Normalization of 3-vector
|
|
686
|
+
def normalize(a):
|
|
687
|
+
f = 1.0/math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2])
|
|
688
|
+
return f*a[0],f*a[1],f*a[2]
|
|
689
|
+
|
|
690
|
+
# Eigenvectors for a symmetric 3x3 matrix:
|
|
691
|
+
# For symmetric matrix A the eigenvector v with root r satisfies
|
|
692
|
+
# v.Aw = Av.w = rv.w = v.rw
|
|
693
|
+
# v.(A-rI)w = v.Aw - v.rw = 0 for all w
|
|
694
|
+
# This means that for any two vectors p,q the eigenvector v follows from:
|
|
695
|
+
# (A-rI)p x (A-rI)q
|
|
696
|
+
# The input is var(x),var(y),var(z),cov(x,y),cov(x,z),cov(y,z)
|
|
697
|
+
# The routine has been checked and yields proper eigenvalues/-vectors
|
|
698
|
+
def mijn_eigen_sym_3x3(a,d,f,b,c,e):
|
|
699
|
+
a,d,f,b,c,e=1,d/a,f/a,b/a,c/a,e/a
|
|
700
|
+
b2, c2, e2, df = b*b, c*c, e*e, d*f
|
|
701
|
+
roots = list(solve_p3(-a-d-f, df-b2-c2-e2+a*(f+d), a*e2+d*c2+f*b2-a*df-2*b*c*e))
|
|
702
|
+
roots.sort(reverse=True)
|
|
703
|
+
ux, uy, uz = b*e-c*d, b*c-a*e, a*d-b*b
|
|
704
|
+
u = (ux+roots[0]*c,uy+roots[0]*e,uz+roots[0]*(roots[0]-a-d))
|
|
705
|
+
v = (ux+roots[1]*c,uy+roots[1]*e,uz+roots[1]*(roots[1]-a-d))
|
|
706
|
+
w = u[1]*v[2]-u[2]*v[1],u[2]*v[0]-u[0]*v[2],u[0]*v[1]-u[1]*v[0] # Cross product
|
|
707
|
+
return normalize(u),normalize(v),normalize(w),roots
|
|
708
|
+
|
|
709
|
+
# Very simple option class
|
|
710
|
+
class Option:
|
|
711
|
+
def __init__(self,func=str,num=1,default=None,description=""):
|
|
712
|
+
self.func = func
|
|
713
|
+
self.num = num
|
|
714
|
+
self.value = default
|
|
715
|
+
self.description = description
|
|
716
|
+
def __nonzero__(self):
|
|
717
|
+
return self.value != None
|
|
718
|
+
def __str__(self):
|
|
719
|
+
return self.value and str(self.value) or ""
|
|
720
|
+
def setvalue(self,v):
|
|
721
|
+
if len(v) == 1:
|
|
722
|
+
self.value = self.func(v[0])
|
|
723
|
+
else:
|
|
724
|
+
self.value = [ self.func(i) for i in v ]
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
def SphereGrid(n):
|
|
728
|
+
grid_points = []
|
|
729
|
+
for k in range(n):
|
|
730
|
+
y = (2.*k+1)/n-1
|
|
731
|
+
phi = k*2.3999632297286531
|
|
732
|
+
r = math.sqrt(1-y*y)
|
|
733
|
+
grid_points.append([math.cos(phi)*r, math.sin(phi)*r,y])
|
|
734
|
+
return grid_points
|
|
735
|
+
|
|
736
|
+
def SphereGridAng(n,ang):
|
|
737
|
+
phi = (1+np.sqrt(5))/2.0
|
|
738
|
+
grid_points = np.zeros((n,3))
|
|
739
|
+
ycut = np.sin(ang)
|
|
740
|
+
for k in range(n):
|
|
741
|
+
xi = np.modf((k/phi))[0]
|
|
742
|
+
yi = np.clip((k/(n-1))*(ycut/2),0,2)
|
|
743
|
+
grid_points[k] = np.array([np.cos(2*np.pi*xi)*np.sin(np.arccos(1-2*yi)),np.sin(2*np.pi*xi)*np.sin(np.arccos(1-2*yi)),1-2*yi])
|
|
744
|
+
return grid_points
|
|
745
|
+
|
|
746
|
+
def DiskGridFib(n,rad):
|
|
747
|
+
phi = (1+np.sqrt(5))/2.0
|
|
748
|
+
grid_points = np.zeros((n,3))
|
|
749
|
+
for k in range(n):
|
|
750
|
+
xi = np.modf((k/phi))[0]
|
|
751
|
+
yi = np.clip((k/(n-1)),0,2)
|
|
752
|
+
grid_points[k] = np.array([np.sin(2*np.pi*xi)*np.sqrt(yi)*rad,np.cos(2*np.pi*xi)*np.sqrt(yi)*rad,0])
|
|
753
|
+
return grid_points
|
|
754
|
+
|
|
755
|
+
#All functions that follow return a set of 3d coordinates and normals. This is all that is needs for later in the code
|
|
756
|
+
#where the actaul lipids are built
|
|
757
|
+
|
|
758
|
+
#This function creates a set of points with inverted curvature. The points are placed such that they are evenly distributed.
|
|
759
|
+
def InvSphereGrid(den,inner_rad,start_ang,orad):
|
|
760
|
+
grid_points = []
|
|
761
|
+
direcs = []
|
|
762
|
+
frden = int(-orad*den*2*(start_ang-np.pi/2)/np.pi)+1
|
|
763
|
+
rings = np.linspace(start_ang,np.pi/2,frden)
|
|
764
|
+
for xr,r in enumerate(rings[1:]):
|
|
765
|
+
rad = inner_rad+(1-np.cos(r))*orad
|
|
766
|
+
rden = int(rad*den)+1
|
|
767
|
+
new_ring = np.linspace(0,np.pi*2,4*rden)[:-1]
|
|
768
|
+
rrand = random.random()
|
|
769
|
+
for nr in new_ring:
|
|
770
|
+
ang1 = xr*rrand+nr
|
|
771
|
+
grid_points.append([np.cos(ang1)*rad,np.sin(ang1)*rad,orad*np.sin(r)])
|
|
772
|
+
direcs.append([np.cos(ang1)*np.cos(r),np.sin(ang1)*np.cos(r),np.sin(r)])
|
|
773
|
+
return grid_points,direcs
|
|
774
|
+
|
|
775
|
+
#Same as above but for the usual curvature
|
|
776
|
+
def SphereGridN(den,end_ang,orad):
|
|
777
|
+
grid_points = []
|
|
778
|
+
direcs = []
|
|
779
|
+
frden = int(orad*den*2*(end_ang)/np.pi)+1
|
|
780
|
+
rings = np.linspace(0,end_ang,frden)
|
|
781
|
+
for xr,r in enumerate(rings):
|
|
782
|
+
rad = np.sin(r)*orad
|
|
783
|
+
rden = int(rad*den)
|
|
784
|
+
new_ring = np.linspace(0,np.pi*2,4*rden+2)[:-1]
|
|
785
|
+
rrand = random.random()
|
|
786
|
+
for nr in new_ring:
|
|
787
|
+
ang1 = xr*rrand+nr
|
|
788
|
+
grid_points.append([np.cos(ang1)*rad,np.sin(ang1)*rad,orad-orad*np.cos(r)])
|
|
789
|
+
direcs.append([np.cos(ang1)*np.sin(r),np.sin(ang1)*np.sin(r),np.cos(r)])
|
|
790
|
+
|
|
791
|
+
return grid_points,direcs
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
#Same as above two but for a disk
|
|
795
|
+
def DiskGridFB(den,outer_rad):
|
|
796
|
+
gr = (1+np.sqrt(5))/2.0
|
|
797
|
+
grid_points = []
|
|
798
|
+
direcs = []
|
|
799
|
+
N = int((outer_rad*outer_rad*np.pi)*den)
|
|
800
|
+
for i in range(N):
|
|
801
|
+
ang1 = 2*np.pi*np.fmod((i/gr),1)
|
|
802
|
+
rad = np.sqrt(i/(N-1))*outer_rad
|
|
803
|
+
grid_points.append([np.cos(ang1)*rad,np.sin(ang1)*rad,0])
|
|
804
|
+
direcs.append([0,0,1])
|
|
805
|
+
return grid_points,direcs
|
|
806
|
+
|
|
807
|
+
#Same as above two but for a disk
|
|
808
|
+
def DiskGrid(den,inner_rad,xbox,ybox,outer_rad):
|
|
809
|
+
grid_points = []
|
|
810
|
+
direcs = []
|
|
811
|
+
if outer_rad<0:
|
|
812
|
+
outer_rad = np.sqrt(xbox*xbox+ybox*ybox)
|
|
813
|
+
else:
|
|
814
|
+
new_den =2*den/np.pi
|
|
815
|
+
new_den = new_den*new_den
|
|
816
|
+
return DiskGridFB(new_den,outer_rad)
|
|
817
|
+
frden = int(den*2*(outer_rad-inner_rad)/np.pi)
|
|
818
|
+
rings = np.linspace(inner_rad,outer_rad,frden)
|
|
819
|
+
for xr,r in enumerate(rings[1:]):
|
|
820
|
+
rad = r
|
|
821
|
+
rden = int(rad*den)+1
|
|
822
|
+
new_ring = np.linspace(0,np.pi*2,4*rden)[:-1]
|
|
823
|
+
rrand = random.random()
|
|
824
|
+
for nr in new_ring:
|
|
825
|
+
ang1 = xr*rrand+nr
|
|
826
|
+
if(-xbox <np.cos(ang1)*rad < xbox-0.2 and -ybox < np.sin(ang1)*rad < ybox-0.2):
|
|
827
|
+
grid_points.append([np.cos(ang1)*rad,np.sin(ang1)*rad,0])
|
|
828
|
+
direcs.append([0,0,1])
|
|
829
|
+
return grid_points,direcs
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
#Same as above but for a tube
|
|
833
|
+
def TubeGrid(den,rad,leng,keep_end):
|
|
834
|
+
grid_points = []
|
|
835
|
+
direcs = []
|
|
836
|
+
frden = int(den*2*(leng)/np.pi)+1
|
|
837
|
+
rings = np.linspace(0,leng,frden)
|
|
838
|
+
if(not keep_end):
|
|
839
|
+
rings = rings[:-1]
|
|
840
|
+
for xr,r in enumerate(rings):
|
|
841
|
+
lenny = r
|
|
842
|
+
rden = int(rad*den)+1
|
|
843
|
+
new_ring = np.linspace(0,np.pi*2,4*rden)[:-1]
|
|
844
|
+
rrand = random.random()
|
|
845
|
+
for nr in new_ring:
|
|
846
|
+
ang1 = xr*rrand+nr
|
|
847
|
+
grid_points.append([np.cos(ang1)*rad,np.sin(ang1)*rad,-lenny])
|
|
848
|
+
direcs.append([np.cos(ang1),np.sin(ang1),0])
|
|
849
|
+
return grid_points,direcs
|
|
850
|
+
|
|
851
|
+
#standard deviation for gaussians
|
|
852
|
+
stand = 0.5
|
|
853
|
+
|
|
854
|
+
#function that evalualtes a gaussian on a grid (points)
|
|
855
|
+
def eval_gaussian(points,cen,std,height):
|
|
856
|
+
return height*np.exp(-np.linalg.norm((points-cen[None,None,:]),axis=2)/(2*std*std))
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
#function that evaluates a sum of gaussians at a single point
|
|
860
|
+
@jax.jit
|
|
861
|
+
def eval_gaussianj(point,all_cens,std,height):
|
|
862
|
+
ret_val = 0
|
|
863
|
+
def egj_loop(ret_val,ind):
|
|
864
|
+
ret_val += height*jnp.exp(-jnp.linalg.norm(point-all_cens[ind])/(2*std*std))
|
|
865
|
+
return ret_val,ind
|
|
866
|
+
ret_val,_ = jax.lax.scan(egj_loop,ret_val,jnp.arange(all_cens.shape[0]))
|
|
867
|
+
return ret_val
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
#gradient of above
|
|
872
|
+
eval_g_grad = jax.grad(eval_gaussianj,argnums=0)
|
|
873
|
+
|
|
874
|
+
#this function evalualtes a sum of gaussians on a grid
|
|
875
|
+
def gaussian_grid(points,xstart,ystart,xend,yend,xnum,ynum):
|
|
876
|
+
grid_vals = np.zeros((xnum,ynum,2))
|
|
877
|
+
grid_vals[:,:,0] += np.linspace(xstart,xend,xnum)[None,:]
|
|
878
|
+
grid_vals[:,:,1] += np.linspace(ystart,yend,ynum)[:,None]
|
|
879
|
+
|
|
880
|
+
ret_vals = np.zeros((xnum,ynum))
|
|
881
|
+
count =0
|
|
882
|
+
for i in points:
|
|
883
|
+
count += 1
|
|
884
|
+
ret_vals += eval_gaussian(grid_vals,i,stand,1)
|
|
885
|
+
return ret_vals,grid_vals
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
#This takes a grid of values and draws along a contour at value coff, points are places along this with a given spacing
|
|
889
|
+
#This contour can be draw further a constant width out from coff. This is the main part of building a micelle
|
|
890
|
+
#This works by taking a step defined by (df/dy,-df/dx )*ds which by definition os along the contour
|
|
891
|
+
def draw_along(spacing,all_cens,grid,grid_vals,coff,rad_plus,z):
|
|
892
|
+
max_iter = 100000
|
|
893
|
+
tol = 0.1
|
|
894
|
+
ds = 0.01
|
|
895
|
+
tot_ds = 0
|
|
896
|
+
start = jnp.array(grid_vals[jnp.logical_and(grid > coff-tol,grid < coff+tol)][0])
|
|
897
|
+
grad = eval_g_grad(start,all_cens,stand,1)
|
|
898
|
+
grad_dir = -grad/jnp.linalg.norm(grad)
|
|
899
|
+
start_p = start+rad_plus*grad_dir
|
|
900
|
+
prev_start = start_p.copy()
|
|
901
|
+
all_cens = jnp.array(all_cens)
|
|
902
|
+
path=jnp.zeros((int(max_iter*ds/spacing)+1,2))
|
|
903
|
+
normals=jnp.zeros((int(max_iter*ds/spacing)+1,2))
|
|
904
|
+
def da_loop(path_data,ind):
|
|
905
|
+
path = path_data[0]
|
|
906
|
+
tot_ds = path_data[1]
|
|
907
|
+
count = path_data[2]
|
|
908
|
+
normals = path_data[3]
|
|
909
|
+
start = path_data[4]
|
|
910
|
+
prev_start = path_data[5]
|
|
911
|
+
def early_term(path,tot_ds,count,normals,start,prev_start):
|
|
912
|
+
return path,tot_ds,count,normals,start,prev_start
|
|
913
|
+
def nearly_term(path,tot_ds,count,normals,start,prev_start):
|
|
914
|
+
grad = eval_g_grad(start,all_cens,stand,1)
|
|
915
|
+
grad_dir = -grad/jnp.linalg.norm(grad)
|
|
916
|
+
norm = jnp.array([grad[1],-grad[0]])
|
|
917
|
+
norm /= jnp.linalg.norm(norm)
|
|
918
|
+
start += norm*ds
|
|
919
|
+
tot_ds += jnp.linalg.norm(prev_start-(start+rad_plus*grad_dir))
|
|
920
|
+
prev_start = start+rad_plus*grad_dir
|
|
921
|
+
def adder(path,tot_ds,count,normals):
|
|
922
|
+
path = path.at[count].set(start+rad_plus*grad_dir)
|
|
923
|
+
normals = normals.at[count].set(grad_dir)
|
|
924
|
+
count +=1
|
|
925
|
+
tot_ds = 0.0
|
|
926
|
+
return path,tot_ds,count,normals
|
|
927
|
+
def nadder(path,tot_ds,count,normals):
|
|
928
|
+
return path,tot_ds,count,normals
|
|
929
|
+
|
|
930
|
+
path,tot_ds,count,normals = jax.lax.cond(tot_ds>spacing,adder,nadder,path,tot_ds,count,normals)
|
|
931
|
+
return path,tot_ds,count,normals,start,prev_start
|
|
932
|
+
path,tot_ds,count,normals,start,prev_start = jax.lax.cond(jnp.logical_and(jnp.linalg.norm(path[count-1]-start_p) < spacing/2,count > 5),early_term,nearly_term,path,tot_ds,count,normals,start,prev_start)
|
|
933
|
+
return (path,tot_ds,count,normals,start,prev_start),ind
|
|
934
|
+
path_data,_=jax.lax.scan(da_loop,(path,0.0,0,normals,start,prev_start),jnp.arange(max_iter))
|
|
935
|
+
path = np.array(path_data[0])[:path_data[2]]
|
|
936
|
+
normals = np.array(path_data[3])[:path_data[2]]
|
|
937
|
+
path = np.pad(path,((0,0),(0,1)),"constant",constant_values=(z,z))
|
|
938
|
+
return path,normals
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
#gets the average length of lipids for building an accurate micelle.
|
|
942
|
+
def get_avlip_len(lipids):
|
|
943
|
+
liplens = 0
|
|
944
|
+
for lipid in lipids:
|
|
945
|
+
lipidsplit = lipid.split(":")[0]
|
|
946
|
+
atoms = list(zip(lipidsa[lipidsplit][1].split(),lipidsx[lipidsa[lipidsplit][0]],lipidsy[lipidsa[lipidsplit][0]],lipidsz[lipidsa[lipidsplit][0]]))
|
|
947
|
+
at,ax,ay,az = list(zip(*[i for i in atoms if i[0] != "-"]))
|
|
948
|
+
az = [(0.5+(i-min(az)))*options["-bd"].value for i in az ]
|
|
949
|
+
|
|
950
|
+
lipLen = max(az)-min(az)
|
|
951
|
+
liplens += lipLen
|
|
952
|
+
return liplens/len(lipids)
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
#This uses all the above to build the micelle. Using contours with radius and height varing as a semi circle
|
|
956
|
+
#Additionally the center is filled with a disc of lipids
|
|
957
|
+
def build_micelle(area_l,all_cens,grid,grid_vals,coff,pbcx,pbcy,avlip_len):
|
|
958
|
+
dims = np.array([pbcx,pbcy,0])
|
|
959
|
+
orad = 2.2
|
|
960
|
+
end_ang = np.pi
|
|
961
|
+
den = np.pi/2*np.sqrt(1/area_l)
|
|
962
|
+
frden = int(orad*den*2*(end_ang)/np.pi)+1
|
|
963
|
+
rings = np.linspace(0,end_ang,frden)
|
|
964
|
+
gpoints = np.zeros((0,3))
|
|
965
|
+
normals = np.zeros((0,3))
|
|
966
|
+
sp = (0.5*(1.15-avlip_len)/(-0.65))+(0.15*(1.8-avlip_len)/0.65)
|
|
967
|
+
if sp < 0.15:
|
|
968
|
+
sp = 0.15
|
|
969
|
+
zpush = 1.8-avlip_len
|
|
970
|
+
for xr,r in enumerate(rings):
|
|
971
|
+
rad = np.sin(r)*orad
|
|
972
|
+
rad_a = sp*(frden/2)-np.abs(sp*(frden/2)-sp*xr)
|
|
973
|
+
rad_z = zpush*np.cos(r)
|
|
974
|
+
znorm = np.array([0,0,1])
|
|
975
|
+
z = np.cos(r)*orad
|
|
976
|
+
r1,nms = draw_along(np.sqrt(area_l),all_cens,grid,grid_vals,coff,rad,z)
|
|
977
|
+
nms_a = np.pad(nms,((0,0),(0,1)),"constant",constant_values=(0,0))
|
|
978
|
+
gpoints = np.concatenate((gpoints,np.array(r1+nms_a*rad_a+znorm*rad_z)))
|
|
979
|
+
norms = nms*np.sin(r)
|
|
980
|
+
norms = np.pad(norms,((0,0),(0,1)),"constant",constant_values=(np.cos(r),np.cos(r)))
|
|
981
|
+
normals = np.concatenate((normals,norms))
|
|
982
|
+
|
|
983
|
+
disk_lips = []
|
|
984
|
+
disk_dirs = []
|
|
985
|
+
disk_grid,disc_direcs = DiskGrid(den,0,pbcx,pbcy,-1)
|
|
986
|
+
disc_direcs = np.array(disc_direcs)
|
|
987
|
+
|
|
988
|
+
for i,d in enumerate(disk_grid):
|
|
989
|
+
val = eval_gaussianj(jnp.array(d[:2]),jnp.array(all_cens),stand,1)
|
|
990
|
+
if(val > coff+5):
|
|
991
|
+
disk_lips.append(d-np.array([0,0,2+zpush]))
|
|
992
|
+
disk_dirs.append(-disc_direcs[i])
|
|
993
|
+
disk_lips.append(d+np.array([0,0,2+zpush]))
|
|
994
|
+
disk_dirs.append(disc_direcs[i])
|
|
995
|
+
disk_lips = np.array(disk_lips)
|
|
996
|
+
disk_dirs = np.array(disk_dirs)
|
|
997
|
+
gpoints = np.concatenate((gpoints,disk_lips))
|
|
998
|
+
normals = np.concatenate((normals,disk_dirs))
|
|
999
|
+
|
|
1000
|
+
gpoints_max_rad = np.max(np.linalg.norm(disk_lips[:,:2]-dims[:2]/2,axis=1))
|
|
1001
|
+
|
|
1002
|
+
return gpoints,normals,gpoints_max_rad+1.5
|
|
1003
|
+
|
|
1004
|
+
#This is an implementation of the KL divergence
|
|
1005
|
+
def kl_d(a,b):
|
|
1006
|
+
kl = np.where(a != 0, a * np.log(a / b), 0)
|
|
1007
|
+
kl = kl[np.isfinite(kl)]
|
|
1008
|
+
return np.sum(kl)
|
|
1009
|
+
#another gaussian
|
|
1010
|
+
def gaussian(x,sig,mu):
|
|
1011
|
+
return (1/(sig*np.sqrt(2*np.pi)))*np.exp(-0.5*np.power(((x-mu)/sig),2))
|
|
1012
|
+
#The distribution of glycan strands in ecoli
|
|
1013
|
+
def ecoli_gdist(x):
|
|
1014
|
+
return 0.75*gaussian(x,4,8.9)+0.25*gaussian(x,10,45)
|
|
1015
|
+
|
|
1016
|
+
#a function that evalualtes a custom glycan distribution
|
|
1017
|
+
def glycan_dist(x,gdist):
|
|
1018
|
+
total = 0
|
|
1019
|
+
for gd in gdist:
|
|
1020
|
+
total += gd[0]*gaussian(x,gd[1],gd[2])
|
|
1021
|
+
return total
|
|
1022
|
+
|
|
1023
|
+
#a function that gets the KDE for a given set of glycan lengths
|
|
1024
|
+
def eval_kde(all_linesT):
|
|
1025
|
+
lengs = []
|
|
1026
|
+
leng = 0
|
|
1027
|
+
zero = False
|
|
1028
|
+
prev = 2
|
|
1029
|
+
for line in all_linesT:
|
|
1030
|
+
pos_start = np.where(line == 0)[0]
|
|
1031
|
+
if(len(list(pos_start)) < 1):
|
|
1032
|
+
start = 0
|
|
1033
|
+
else:
|
|
1034
|
+
start = pos_start[0]
|
|
1035
|
+
for ind in range(line.shape[0]):
|
|
1036
|
+
sind = (ind+start)%(line.shape[0])
|
|
1037
|
+
if(line[sind] == 1):
|
|
1038
|
+
leng += 1
|
|
1039
|
+
zero = False
|
|
1040
|
+
elif(line[sind] == 0):
|
|
1041
|
+
lengs.append(leng)
|
|
1042
|
+
leng = 0
|
|
1043
|
+
zero = True
|
|
1044
|
+
else:
|
|
1045
|
+
if(prev != 2):
|
|
1046
|
+
lengs.append(leng)
|
|
1047
|
+
leng = 0
|
|
1048
|
+
zero = True
|
|
1049
|
+
prev = line[sind]
|
|
1050
|
+
if(not zero):
|
|
1051
|
+
lengs.append(leng)
|
|
1052
|
+
return sp.stats.gaussian_kde(lengs)
|
|
1053
|
+
|
|
1054
|
+
#MCMC to obtain a glycan strand distribution close to the target
|
|
1055
|
+
def MC_Glycan_Strands(pbcy,pbcx,zpos,xoff,yoff,prot_coords,gdist,num):
|
|
1056
|
+
no_gly = int(pbcy/0.9)-2
|
|
1057
|
+
no_lines = int(pbcx/2.8)
|
|
1058
|
+
all_linesT = np.zeros((no_lines-1,no_gly-1))+1
|
|
1059
|
+
prot_block = np.zeros((no_lines-1,no_gly-1))
|
|
1060
|
+
|
|
1061
|
+
yspace = np.linspace(0,pbcy,all_linesT.shape[1]+1)[:-1]
|
|
1062
|
+
xspace = np.linspace(0,pbcx,all_linesT.shape[0]+1)[:-1]
|
|
1063
|
+
|
|
1064
|
+
if(prot_coords.size > 0):
|
|
1065
|
+
prot_coords_zslice = prot_coords[prot_coords[:,2] > zpos-0.5]
|
|
1066
|
+
prot_coords_zslice = prot_coords_zslice[prot_coords_zslice[:,2] < zpos+0.5]
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
for l in range(prot_block.shape[0]):
|
|
1071
|
+
for g in range(prot_block[l].shape[0]):
|
|
1072
|
+
for pc in prot_coords_zslice:
|
|
1073
|
+
pos = np.array([xspace[l]+xoff,yspace[g]+yoff+0.5,zpos])
|
|
1074
|
+
if(np.linalg.norm(pc-pos) < 1):
|
|
1075
|
+
prot_block[l,g] = 1
|
|
1076
|
+
for l in range(prot_block.shape[0]):
|
|
1077
|
+
ones = False
|
|
1078
|
+
ones_end = False
|
|
1079
|
+
indg = 0
|
|
1080
|
+
for g in range(prot_block[l].shape[0]):
|
|
1081
|
+
if prot_block[l,g] == 1:
|
|
1082
|
+
if ones_end:
|
|
1083
|
+
prot_block[l,indg:g] = 1
|
|
1084
|
+
ones = True
|
|
1085
|
+
ones_end = False
|
|
1086
|
+
else:
|
|
1087
|
+
ones = True
|
|
1088
|
+
if ones:
|
|
1089
|
+
if prot_block[l,g] != 1:
|
|
1090
|
+
indg = g
|
|
1091
|
+
ones_end = True
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
#plt.imshow(prot_block)
|
|
1096
|
+
#plt.show()
|
|
1097
|
+
|
|
1098
|
+
line_index = np.arange(no_gly-1)
|
|
1099
|
+
|
|
1100
|
+
all_linesT += prot_block
|
|
1101
|
+
|
|
1102
|
+
test_kde = eval_kde(all_linesT)
|
|
1103
|
+
testx = np.linspace(0,65,100)
|
|
1104
|
+
prev_kld = kl_d(glycan_dist(testx,gdist),test_kde(testx))
|
|
1105
|
+
for i in range(30000):
|
|
1106
|
+
rlind = random.randint(0,no_lines-2)
|
|
1107
|
+
|
|
1108
|
+
line_block = prot_block[rlind]
|
|
1109
|
+
none_blocked = line_block[line_block==0]
|
|
1110
|
+
nb_ind = random.randint(0,none_blocked.shape[0]-1)
|
|
1111
|
+
glind = line_index[line_block==0][nb_ind]
|
|
1112
|
+
|
|
1113
|
+
all_linesT[rlind][glind] = (all_linesT[rlind][glind]+1)%2
|
|
1114
|
+
|
|
1115
|
+
test_kde = eval_kde(all_linesT)
|
|
1116
|
+
testx = np.linspace(0,65,100)
|
|
1117
|
+
kld = kl_d(glycan_dist(testx,gdist),test_kde(testx))
|
|
1118
|
+
|
|
1119
|
+
kT = 0.0025
|
|
1120
|
+
|
|
1121
|
+
accept = 1-np.exp(-(kld-prev_kld)/kT)
|
|
1122
|
+
|
|
1123
|
+
if(np.random.random() < accept):
|
|
1124
|
+
all_linesT[rlind][glind] = (all_linesT[rlind][glind]+1)%2
|
|
1125
|
+
else:
|
|
1126
|
+
prev_kld = kld
|
|
1127
|
+
test_kde = eval_kde(all_linesT)
|
|
1128
|
+
testx = np.linspace(0,65,100)
|
|
1129
|
+
plt.plot(test_kde(testx))
|
|
1130
|
+
plt.plot(glycan_dist(testx,gdist))
|
|
1131
|
+
plt.savefig(out_folder+"Dist"+str(num)+".svg")
|
|
1132
|
+
plt.clf()
|
|
1133
|
+
|
|
1134
|
+
for l in all_linesT:
|
|
1135
|
+
l[l==2] = 0
|
|
1136
|
+
if(np.sum(l) == l.shape[0]):
|
|
1137
|
+
l[random.randint(0,l.shape[0]-1)] = 0
|
|
1138
|
+
|
|
1139
|
+
return all_linesT,prot_coords_zslice
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
#This function uses data from the above to generate the coordinates for glycan strands
|
|
1143
|
+
def Create_Glycan_strands2(pgl_no,pbcy,pbcx,z_poses,xoff,yoff,pcoords, gdist):
|
|
1144
|
+
#x y z dir type place linked 3-3
|
|
1145
|
+
no_gly = int(pbcy/0.9)-2-1
|
|
1146
|
+
no_lines = int(pbcx/2.8)-1
|
|
1147
|
+
all_lines = np.zeros((pgl_no,no_lines,no_gly*2,14))
|
|
1148
|
+
all_pc_slices = []
|
|
1149
|
+
if pcoords.shape[0] == 0:
|
|
1150
|
+
pcoords = np.zeros((1,3))
|
|
1151
|
+
for pn in range(pgl_no):
|
|
1152
|
+
z = pbcz/2+z_poses[pn]+Pos_PGL
|
|
1153
|
+
chain_lens,pc_zslice = MC_Glycan_Strands(pbcy,pbcx,z,1.25*(pn%2)+xoff,yoff,pcoords+np.array([0,0,pbcz/2]),gdist,pn)
|
|
1154
|
+
all_pc_slices.append(pc_zslice)
|
|
1155
|
+
yspace = np.linspace(0,pbcy,chain_lens.shape[1]*2+1)[:-1]
|
|
1156
|
+
xspace = np.linspace(0,pbcx,chain_lens.shape[0]+1)[:-1]
|
|
1157
|
+
|
|
1158
|
+
for l in range(chain_lens.shape[0]):
|
|
1159
|
+
y_shift = 0#np.random.random()*0.5
|
|
1160
|
+
for g in range(chain_lens[l].shape[0]):
|
|
1161
|
+
direc = random.randint(0,1)*2-1
|
|
1162
|
+
x = xspace[l]+1.25*(pn%2)
|
|
1163
|
+
y2 = yspace[2*g+1]+y_shift
|
|
1164
|
+
y1 = yspace[2*g]+y_shift
|
|
1165
|
+
all_lines[pn,l,2*g] = np.array([x+xoff,y1+yoff,z,direc,1,chain_lens[l,g],-1,-1,-1,-1,-1,-1,0,0])
|
|
1166
|
+
all_lines[pn,l,2*g+1] = np.array([x+xoff,y2+yoff,z,direc,0,chain_lens[l,g],-1,-1,-1,-1,-1,-1,0,0])
|
|
1167
|
+
return all_lines,all_pc_slices
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
#enforces pbc
|
|
1172
|
+
def enforce_pbc(pbcv,points):
|
|
1173
|
+
points = np.where(points >= pbcv, points-pbcv, points)
|
|
1174
|
+
points = np.where(points <0, points+pbcv, points)
|
|
1175
|
+
return points
|
|
1176
|
+
|
|
1177
|
+
#This function joins cross-links that are already cross-linked. (This flips that way they are linked)
|
|
1178
|
+
def flip_link(all_lines,lyind,lind,bind):
|
|
1179
|
+
done = False
|
|
1180
|
+
all_linesT = all_lines.copy()
|
|
1181
|
+
if(all_linesT[lyind][lind][bind][13] == 1):
|
|
1182
|
+
return all_lines, False
|
|
1183
|
+
tmp = all_linesT[lyind,lind,bind,6:9].copy()
|
|
1184
|
+
all_linesT[lyind,lind,bind,6:9] = all_linesT[lyind,lind,bind,9:12].copy()
|
|
1185
|
+
all_linesT[lyind,lind,bind,9:12] = tmp.copy()
|
|
1186
|
+
if(all_linesT[lyind,lind,bind,6] > -0.5):
|
|
1187
|
+
tnlind = int(all_linesT[lyind,lind,bind,6])
|
|
1188
|
+
tnbind = int(all_linesT[lyind,lind,bind,7])
|
|
1189
|
+
tnlyind = int(all_linesT[lyind,lind,bind,8])
|
|
1190
|
+
nlind = tnlind
|
|
1191
|
+
nbind = tnbind
|
|
1192
|
+
nlyind = tnlyind
|
|
1193
|
+
switcher = 6
|
|
1194
|
+
elif(all_linesT[lyind,lind,bind,9] > -0.5):
|
|
1195
|
+
tnlind = int(all_linesT[lyind,lind,bind,9])
|
|
1196
|
+
tnbind = int(all_linesT[lyind,lind,bind,10])
|
|
1197
|
+
tnlyind = int(all_linesT[lyind,lind,bind,11])
|
|
1198
|
+
nlind = tnlind
|
|
1199
|
+
nbind = tnbind
|
|
1200
|
+
nlyind = tnlyind
|
|
1201
|
+
switcher = 9
|
|
1202
|
+
while not done:
|
|
1203
|
+
if(all_linesT[nlyind,nlind,nbind,13] == 1):
|
|
1204
|
+
return all_lines,False
|
|
1205
|
+
tmp = all_linesT[nlyind,nlind,nbind,6:9].copy()
|
|
1206
|
+
all_linesT[nlyind,nlind,nbind,6:9] = all_linesT[nlyind,nlind,nbind,9:12].copy()
|
|
1207
|
+
all_linesT[nlyind,nlind,nbind,9:12] = tmp.copy()
|
|
1208
|
+
tnlind = int(all_linesT[nlyind,nlind,nbind,switcher])
|
|
1209
|
+
tnbind = int(all_linesT[nlyind,nlind,nbind,switcher+1])
|
|
1210
|
+
tnlyind = int(all_linesT[nlyind,nlind,nbind,switcher+2])
|
|
1211
|
+
nlind = tnlind
|
|
1212
|
+
nbind = tnbind
|
|
1213
|
+
nlyind = tnlyind
|
|
1214
|
+
if(nlind < 0):
|
|
1215
|
+
done = True
|
|
1216
|
+
break
|
|
1217
|
+
return all_linesT, True
|
|
1218
|
+
|
|
1219
|
+
#Similar algo to above, but doesn't flip. This is used to determin the length of oligomers
|
|
1220
|
+
def count_olig(all_lines,lyind,lind,bind):
|
|
1221
|
+
done = False
|
|
1222
|
+
count = 1
|
|
1223
|
+
all_linesT = all_lines.copy()
|
|
1224
|
+
if(all_linesT[lyind][lind][bind][13] == 1):
|
|
1225
|
+
return 2, False
|
|
1226
|
+
if(all_linesT[lyind,lind,bind,6] > -0.5):
|
|
1227
|
+
tnlind = int(all_linesT[lyind,lind,bind,6])
|
|
1228
|
+
tnbind = int(all_linesT[lyind,lind,bind,7])
|
|
1229
|
+
tnlyind = int(all_linesT[lyind,lind,bind,8])
|
|
1230
|
+
nlind = tnlind
|
|
1231
|
+
nbind = tnbind
|
|
1232
|
+
nlyind = tnlyind
|
|
1233
|
+
switcher = 6
|
|
1234
|
+
elif(all_linesT[lyind,lind,bind,9] > -0.5):
|
|
1235
|
+
tnlind = int(all_linesT[lyind,lind,bind,9])
|
|
1236
|
+
tnbind = int(all_linesT[lyind,lind,bind,10])
|
|
1237
|
+
tnlyind = int(all_linesT[lyind,lind,bind,11])
|
|
1238
|
+
nlind = tnlind
|
|
1239
|
+
nbind = tnbind
|
|
1240
|
+
nlyind = tnlyind
|
|
1241
|
+
switcher = 9
|
|
1242
|
+
else:
|
|
1243
|
+
return 1,False
|
|
1244
|
+
while not done:
|
|
1245
|
+
count += 1
|
|
1246
|
+
if(all_linesT[nlyind,nlind,nbind,13] == 1):
|
|
1247
|
+
return count,False
|
|
1248
|
+
|
|
1249
|
+
tnlind = int(all_linesT[nlyind,nlind,nbind,switcher])
|
|
1250
|
+
tnbind = int(all_linesT[nlyind,nlind,nbind,switcher+1])
|
|
1251
|
+
tnlyind = int(all_linesT[nlyind,nlind,nbind,switcher+2])
|
|
1252
|
+
nlind = tnlind
|
|
1253
|
+
nbind = tnbind
|
|
1254
|
+
nlyind = tnlyind
|
|
1255
|
+
if(nlind < 0):
|
|
1256
|
+
done = True
|
|
1257
|
+
break
|
|
1258
|
+
return count, True
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
#This function prevents knotting of the cross-links
|
|
1262
|
+
def get_allowed_beads(cind,clinks_np,bead,inder,no_gly):
|
|
1263
|
+
eq = np.where(clinks_np[cind][:,inder] == bead)[0]
|
|
1264
|
+
greater = np.where(clinks_np[cind][:,inder] > bead)[0]
|
|
1265
|
+
less = np.where(clinks_np[cind][:,inder] < bead)[0]
|
|
1266
|
+
if(len(greater) == 0):
|
|
1267
|
+
if(len(less) == 0):
|
|
1268
|
+
urange = 0
|
|
1269
|
+
else:
|
|
1270
|
+
urange = less[0]
|
|
1271
|
+
else:
|
|
1272
|
+
urange = greater[0]
|
|
1273
|
+
if(len(less) == 0):
|
|
1274
|
+
if(len(greater) == 0):
|
|
1275
|
+
lrange = -1
|
|
1276
|
+
else:
|
|
1277
|
+
lrange = greater[-1]
|
|
1278
|
+
else:
|
|
1279
|
+
lrange = less[-1]
|
|
1280
|
+
if(clinks_np[cind].size > 0):
|
|
1281
|
+
if(clinks_np[cind].shape[0] == 1):
|
|
1282
|
+
other_bead = clinks_np[cind][0,(inder+1)%2]
|
|
1283
|
+
if(bead > clinks_np[cind][0,inder]):
|
|
1284
|
+
if(other_bead > no_gly-2):
|
|
1285
|
+
allowed_beads = np.arange(0,int(no_gly/2))
|
|
1286
|
+
else:
|
|
1287
|
+
allowed_beads = np.arange(other_bead,no_gly)
|
|
1288
|
+
elif(bead < clinks_np[cind][0,inder]):
|
|
1289
|
+
if(other_bead < 3):
|
|
1290
|
+
allowed_beads = np.arange(int(no_gly/2),no_gly)
|
|
1291
|
+
else:
|
|
1292
|
+
allowed_beads = np.arange(0,other_bead)
|
|
1293
|
+
else:
|
|
1294
|
+
allowed_beads = np.arange(0,no_gly)
|
|
1295
|
+
return allowed_beads
|
|
1296
|
+
else:
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
lrange_b2 = clinks_np[cind][lrange,inder]
|
|
1300
|
+
urange_b2 = clinks_np[cind][urange,inder]
|
|
1301
|
+
|
|
1302
|
+
db_l = np.where(clinks_np[cind][:,inder] == lrange_b2)[0]
|
|
1303
|
+
db_u = np.where(clinks_np[cind][:,inder] == urange_b2)[0]
|
|
1304
|
+
|
|
1305
|
+
poss_lrb = clinks_np[cind][db_l,(inder+1)%2]
|
|
1306
|
+
poss_urb = clinks_np[cind][db_u,(inder+1)%2]
|
|
1307
|
+
|
|
1308
|
+
if(np.min(poss_lrb) == 1):
|
|
1309
|
+
lrange_b = no_gly+1
|
|
1310
|
+
else:
|
|
1311
|
+
lrange_b = np.max(poss_lrb)
|
|
1312
|
+
lrange_b = np.max((poss_lrb+3)%no_gly-3)%no_gly
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
if(np.max(poss_urb) == no_gly-1):
|
|
1318
|
+
urange_b = 0
|
|
1319
|
+
else:
|
|
1320
|
+
urange_b = np.min(poss_urb)
|
|
1321
|
+
urange_b = np.min((poss_urb-3)%no_gly+3)%no_gly
|
|
1322
|
+
|
|
1323
|
+
inc_l = np.where(clinks_np[cind][:,(inder+1)%2] == lrange_b)[0]
|
|
1324
|
+
inc_u = np.where(clinks_np[cind][:,(inder+1)%2] == urange_b)[0]
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
if(len(inc_l) == 2):
|
|
1328
|
+
lrange_b_adj = (lrange_b + 1)%no_gly
|
|
1329
|
+
else:
|
|
1330
|
+
lrange_b_adj = lrange_b
|
|
1331
|
+
if(len(inc_u) == 2):
|
|
1332
|
+
urange_b_adj = (urange_b - 1)%no_gly
|
|
1333
|
+
else:
|
|
1334
|
+
urange_b_adj = urange_b
|
|
1335
|
+
if(lrange_b != urange_b):
|
|
1336
|
+
if(lrange_b_adj < urange_b_adj):
|
|
1337
|
+
allowed_beads = np.arange(lrange_b_adj,urange_b_adj+1)
|
|
1338
|
+
elif(lrange_b_adj > urange_b_adj):
|
|
1339
|
+
allowed_beads = np.concatenate([np.arange(0,urange_b_adj+1),np.arange(lrange_b_adj,no_gly)])
|
|
1340
|
+
else:
|
|
1341
|
+
allowed_beads = np.array([lrange_b_adj])
|
|
1342
|
+
else:
|
|
1343
|
+
if((len(greater) >= 1 and len(less) > 0) or (len(greater) > 0 and len(less) >= 1)):
|
|
1344
|
+
allowed_beads = np.array([2])
|
|
1345
|
+
else:
|
|
1346
|
+
allowed_beads = np.arange(0,no_gly)
|
|
1347
|
+
if(len(eq) > 0):
|
|
1348
|
+
not_allow = clinks_np[cind][eq[0],(inder+1)%2]
|
|
1349
|
+
delind = np.where(allowed_beads == not_allow)[0]
|
|
1350
|
+
if(len(delind > 0)):
|
|
1351
|
+
allowed_beads = np.delete(allowed_beads,delind[0])
|
|
1352
|
+
return allowed_beads
|
|
1353
|
+
else:
|
|
1354
|
+
return np.arange(0,no_gly)
|
|
1355
|
+
|
|
1356
|
+
#Uses all of the above to create cross-links between glycan strands
|
|
1357
|
+
#This is fairly complicated to describe so I will not for now
|
|
1358
|
+
def cross_link(all_lines,pbcy,cper,per33,lper,oper):
|
|
1359
|
+
no_layers = all_lines.shape[0]
|
|
1360
|
+
no_lines = all_lines.shape[1]
|
|
1361
|
+
no_gly = all_lines.shape[2]
|
|
1362
|
+
clinks = []
|
|
1363
|
+
clinks_np0 = []
|
|
1364
|
+
clinks_np1 = []
|
|
1365
|
+
for l in range(no_lines):
|
|
1366
|
+
clinks.append([])
|
|
1367
|
+
for cl in clinks:
|
|
1368
|
+
if(len(cl) > 0):
|
|
1369
|
+
cl_np = np.array(cl)
|
|
1370
|
+
sort_ind0 = np.lexsort((cl_np[:,1],cl_np[:,0]))
|
|
1371
|
+
sort_ind1 = np.lexsort((cl_np[:,0],cl_np[:,1]))
|
|
1372
|
+
clinks_np0.append(cl_np[sort_ind0])
|
|
1373
|
+
clinks_np1.append(cl_np[sort_ind1])
|
|
1374
|
+
else:
|
|
1375
|
+
clinks_np0.append(np.empty((0,2)))
|
|
1376
|
+
clinks_np1.append(np.empty((0,2)))
|
|
1377
|
+
for i in range(20*no_layers*no_gly*no_lines):
|
|
1378
|
+
layer_ind = random.randint(0,no_layers-1)
|
|
1379
|
+
line_ind = random.randint(0,no_lines-1)
|
|
1380
|
+
line1 = all_lines[layer_ind,line_ind]
|
|
1381
|
+
line1_nam = line1[line1[:,4]==0]
|
|
1382
|
+
line1_nam = line1_nam[line1_nam[:,5]==1]
|
|
1383
|
+
line1_nam = line1_nam[line1_nam[:,12]<2]
|
|
1384
|
+
try:
|
|
1385
|
+
b1ind = random.randint(0,line1_nam.shape[0]-1)
|
|
1386
|
+
except:
|
|
1387
|
+
continue
|
|
1388
|
+
passed = False
|
|
1389
|
+
flipped = 1
|
|
1390
|
+
for fl in [1,-1]:
|
|
1391
|
+
bead1 = line1_nam[b1ind]
|
|
1392
|
+
direc = bead1[3]*fl
|
|
1393
|
+
layer_ind2 = layer_ind
|
|
1394
|
+
if(layer_ind != no_layers-1 and random.random() < lper and bead1[12] == 0):
|
|
1395
|
+
layer_ind2 = layer_ind+1
|
|
1396
|
+
if(layer_ind%2 == 0):
|
|
1397
|
+
acc_direc = (direc+1)/2
|
|
1398
|
+
else:
|
|
1399
|
+
acc_direc = (direc-1)/2
|
|
1400
|
+
else:
|
|
1401
|
+
acc_direc = direc
|
|
1402
|
+
ypos = bead1[1]
|
|
1403
|
+
bead1_t = np.where(np.logical_and(all_lines[layer_ind,line_ind][:,1] > ypos-1e-7,all_lines[layer_ind,line_ind][:,1] < ypos+1e-7))[0][0]
|
|
1404
|
+
if(layer_ind == layer_ind2):
|
|
1405
|
+
if(direc == -1):
|
|
1406
|
+
allowed_beads = get_allowed_beads(line_ind,clinks_np0,bead1_t,0,no_gly)
|
|
1407
|
+
elif(direc == 1):
|
|
1408
|
+
allowed_beads = get_allowed_beads((line_ind-int(direc))%no_lines,clinks_np1,bead1_t,1,no_gly)
|
|
1409
|
+
else:
|
|
1410
|
+
allowed_beads = np.arange(0,no_gly)
|
|
1411
|
+
line2 = all_lines[layer_ind2,(line_ind-int(acc_direc))%no_lines,allowed_beads]
|
|
1412
|
+
line2_nam = line2[line2[:,4]==0]
|
|
1413
|
+
line2_nam = line2_nam[line2_nam[:,5]==1]
|
|
1414
|
+
if(layer_ind != layer_ind2):
|
|
1415
|
+
line2_nam = line2_nam[line2_nam[:,12]<1]
|
|
1416
|
+
else:
|
|
1417
|
+
line2_nam = line2_nam[line2_nam[:,12]<2]
|
|
1418
|
+
line2_nam[:,1] -= ypos-pbcy/2
|
|
1419
|
+
line2_nam[:,1] = enforce_pbc(pbcy,line2_nam[:,1])
|
|
1420
|
+
rangee = 1.5
|
|
1421
|
+
if(layer_ind != layer_ind2):
|
|
1422
|
+
rangee = 0.75
|
|
1423
|
+
line2_seg = line2_nam[line2_nam[:,1] > pbcy/2-rangee]
|
|
1424
|
+
line2_seg = line2_seg[line2_seg[:,1] < pbcy/2+rangee]
|
|
1425
|
+
line2_seg = line2_seg[np.logical_or(line2_seg[:,3] == -direc,np.logical_and(line2_seg[:,6] < 0,line2_seg[:,9] < 0))]
|
|
1426
|
+
line2_seg[:,1] += ypos-pbcy/2
|
|
1427
|
+
line2_seg[:,1] = enforce_pbc(pbcy,line2_seg[:,1])
|
|
1428
|
+
try:
|
|
1429
|
+
bead2_ind = random.randint(0,line2_seg.shape[0]-1)
|
|
1430
|
+
passed = True
|
|
1431
|
+
break
|
|
1432
|
+
except:
|
|
1433
|
+
bead1_t = np.where(np.logical_and(all_lines[layer_ind,line_ind][:,1] > ypos-1e-7,all_lines[layer_ind,line_ind][:,1] < ypos+1e-7))[0][0]
|
|
1434
|
+
if(all_lines[layer_ind,line_ind,bead1_t,6] > -1 or all_lines[layer_ind,line_ind,bead1_t,9] > -1):
|
|
1435
|
+
break
|
|
1436
|
+
flipped = -1
|
|
1437
|
+
continue
|
|
1438
|
+
if(not passed):
|
|
1439
|
+
bead1_t = np.where(np.logical_and(all_lines[layer_ind,line_ind][:,1] > ypos-1e-7,all_lines[layer_ind,line_ind][:,1] < ypos+1e-7))[0][0]
|
|
1440
|
+
if(layer_ind == layer_ind2):
|
|
1441
|
+
all_lines[layer_ind,line_ind,bead1_t,12] += 2
|
|
1442
|
+
continue
|
|
1443
|
+
bead2 = line2_seg[bead2_ind]
|
|
1444
|
+
ypos2 = bead2[1]
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
all_lines[layer_ind,line_ind,bead1_t,3] *= flipped
|
|
1449
|
+
ndirec = all_lines[layer_ind,line_ind,bead1_t,3]
|
|
1450
|
+
if(layer_ind != layer_ind2):
|
|
1451
|
+
if(layer_ind%2 == 0):
|
|
1452
|
+
ndirec = (ndirec+1)/2
|
|
1453
|
+
else:
|
|
1454
|
+
ndirec = (ndirec-1)/2
|
|
1455
|
+
fndirec = all_lines[layer_ind,line_ind,bead1_t,3]
|
|
1456
|
+
bead2_t = np.where(np.logical_and(all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines][:,1] > ypos2-1e-7,all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines][:,1] < ypos2+1e-7))[0][0]
|
|
1457
|
+
|
|
1458
|
+
|
|
1459
|
+
|
|
1460
|
+
lind1 = line_ind
|
|
1461
|
+
lind2 = (line_ind-int(ndirec))%no_lines
|
|
1462
|
+
|
|
1463
|
+
if(abs(lind1-lind2) > 1):
|
|
1464
|
+
if(lind1 > lind2):
|
|
1465
|
+
clind = lind1
|
|
1466
|
+
bind1 = bead1_t
|
|
1467
|
+
bind2 = bead2_t
|
|
1468
|
+
else:
|
|
1469
|
+
clind = lind2
|
|
1470
|
+
bind1 = bead2_t
|
|
1471
|
+
bind2 = bead1_t
|
|
1472
|
+
else:
|
|
1473
|
+
if(lind1 < lind2):
|
|
1474
|
+
clind = lind1
|
|
1475
|
+
bind1 = bead1_t
|
|
1476
|
+
bind2 = bead2_t
|
|
1477
|
+
else:
|
|
1478
|
+
clind = lind2
|
|
1479
|
+
bind1 = bead2_t
|
|
1480
|
+
bind2 = bead1_t
|
|
1481
|
+
rand33 = random.random()
|
|
1482
|
+
if(random.random() < cper):
|
|
1483
|
+
if(all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,6] < 0 and all_lines[layer_ind,line_ind,bead1_t,9] < 0):
|
|
1484
|
+
if(all_lines[layer_ind,line_ind,bead1_t,6] != lind2 or all_lines[layer_ind,line_ind,bead1_t,7] != bead2_t):
|
|
1485
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,6] = lind1
|
|
1486
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,7] = bead1_t
|
|
1487
|
+
if(all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] == 0 and rand33 < per33 and all_lines[layer_ind,line_ind,bead1_t,9] < 0):
|
|
1488
|
+
all_lines[layer_ind,line_ind,bead1_t,12] +=1
|
|
1489
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] +=2
|
|
1490
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,13] = 1
|
|
1491
|
+
all_lines[layer_ind,line_ind,bead1_t,13] = 2
|
|
1492
|
+
else:
|
|
1493
|
+
all_lines[layer_ind,line_ind,bead1_t,12] +=1
|
|
1494
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] +=1
|
|
1495
|
+
|
|
1496
|
+
if(layer_ind != layer_ind2 or random.random() > oper):
|
|
1497
|
+
all_lines[layer_ind,line_ind,bead1_t,12] = 2
|
|
1498
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] = 2
|
|
1499
|
+
|
|
1500
|
+
all_lines[layer_ind,line_ind,bead1_t,9] = lind2
|
|
1501
|
+
all_lines[layer_ind,line_ind,bead1_t,10] = bead2_t
|
|
1502
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,8] = layer_ind
|
|
1503
|
+
all_lines[layer_ind,line_ind,bead1_t,11] = layer_ind2
|
|
1504
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,3] =-fndirec
|
|
1505
|
+
clinks[clind].append([bind1,bind2])
|
|
1506
|
+
elif(all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,9] < 0 and all_lines[layer_ind,line_ind,bead1_t,6] < 0):
|
|
1507
|
+
if(all_lines[layer_ind,line_ind,bead1_t,9] != lind2 or all_lines[layer_ind,line_ind,bead1_t,10] != bead2_t):
|
|
1508
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,9] = lind1
|
|
1509
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,10] = bead1_t
|
|
1510
|
+
if(all_lines[layer_ind,line_ind,bead1_t,12] == 0 and rand33 < per33 and all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,9] < 0):
|
|
1511
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] +=1
|
|
1512
|
+
all_lines[layer_ind,line_ind,bead1_t,12] +=2
|
|
1513
|
+
all_lines[layer_ind,line_ind,bead1_t,13] = 1
|
|
1514
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,13] = 2
|
|
1515
|
+
else:
|
|
1516
|
+
all_lines[layer_ind,line_ind,bead1_t,12] +=1
|
|
1517
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] +=1
|
|
1518
|
+
|
|
1519
|
+
if(layer_ind != layer_ind2 or random.random() > oper):
|
|
1520
|
+
all_lines[layer_ind,line_ind,bead1_t,12] = 2
|
|
1521
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] = 2
|
|
1522
|
+
|
|
1523
|
+
all_lines[layer_ind,line_ind,bead1_t,6] = lind2
|
|
1524
|
+
all_lines[layer_ind,line_ind,bead1_t,7] = bead2_t
|
|
1525
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,11] = layer_ind
|
|
1526
|
+
all_lines[layer_ind,line_ind,bead1_t,8] = layer_ind2
|
|
1527
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,3] =-fndirec
|
|
1528
|
+
clinks[clind].append([bind1,bind2])
|
|
1529
|
+
else:
|
|
1530
|
+
all_lines,is_flipped = flip_link(all_lines,layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t)
|
|
1531
|
+
if(not is_flipped):
|
|
1532
|
+
all_lines,is_flipped = flip_link(all_lines,layer_ind,line_ind,bead1_t)
|
|
1533
|
+
if(not is_flipped):
|
|
1534
|
+
all_lines[layer_ind,line_ind,bead1_t,3] *= flipped
|
|
1535
|
+
continue
|
|
1536
|
+
if(all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,6] < 0 and all_lines[layer_ind,line_ind,bead1_t,9] < 0):
|
|
1537
|
+
if(all_lines[layer_ind,line_ind,bead1_t,6] != lind2 or all_lines[layer_ind,line_ind,bead1_t,7] != bead2_t):
|
|
1538
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,6] = lind1
|
|
1539
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,7] = bead1_t
|
|
1540
|
+
if(all_lines[layer_ind,line_ind,bead1_t,12] == 0 and rand33 < per33 and all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,9] < 0):
|
|
1541
|
+
all_lines[layer_ind,line_ind,bead1_t,12] +=2
|
|
1542
|
+
all_lines[layer_ind,line_ind,bead1_t,13] = 1
|
|
1543
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,11] = 2
|
|
1544
|
+
else:
|
|
1545
|
+
all_lines[layer_ind,line_ind,bead1_t,12] +=1
|
|
1546
|
+
if(all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] == 0 and rand33 < per33 and all_lines[layer_ind,line_ind,bead1_t,9] < 0):
|
|
1547
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] +=2
|
|
1548
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,13] = 1
|
|
1549
|
+
all_lines[layer_ind,line_ind,bead1_t,13] = 2
|
|
1550
|
+
else:
|
|
1551
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] +=1
|
|
1552
|
+
|
|
1553
|
+
if(layer_ind != layer_ind2 or random.random() > oper):
|
|
1554
|
+
all_lines[layer_ind,line_ind,bead1_t,12] = 2
|
|
1555
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] = 2
|
|
1556
|
+
all_lines[layer_ind,line_ind,bead1_t,9] = lind2
|
|
1557
|
+
all_lines[layer_ind,line_ind,bead1_t,10] = bead2_t
|
|
1558
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,8] = layer_ind
|
|
1559
|
+
all_lines[layer_ind,line_ind,bead1_t,11] = layer_ind2
|
|
1560
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,3] =-fndirec
|
|
1561
|
+
clinks[clind].append([bind1,bind2])
|
|
1562
|
+
elif(all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,9] < 0 and all_lines[layer_ind,line_ind,bead1_t,6] < 0):
|
|
1563
|
+
if(all_lines[layer_ind,line_ind,bead1_t,9] != lind2 or all_lines[layer_ind,line_ind,bead1_t,10] != bead2_t):
|
|
1564
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,9] = lind1
|
|
1565
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,10] = bead1_t
|
|
1566
|
+
if(all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] == 0 and rand33 < per33 and all_lines[layer_ind,line_ind,bead1_t,9] < 0):
|
|
1567
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] +=2
|
|
1568
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,13] = 1
|
|
1569
|
+
all_lines[layer_ind,line_ind,bead1_t,13] = 2
|
|
1570
|
+
else:
|
|
1571
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] +=1
|
|
1572
|
+
if(all_lines[layer_ind,line_ind,bead1_t,12] == 0 and rand33 < per33 and all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,9] < 0):
|
|
1573
|
+
all_lines[layer_ind,line_ind,bead1_t,12] +=2
|
|
1574
|
+
all_lines[layer_ind,line_ind,bead1_t,13] = 1
|
|
1575
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,13] = 2
|
|
1576
|
+
else:
|
|
1577
|
+
all_lines[layer_ind,line_ind,bead1_t,12] +=1
|
|
1578
|
+
if(layer_ind != layer_ind2 or random.random() > oper):
|
|
1579
|
+
all_lines[layer_ind,line_ind,bead1_t,12] = 2
|
|
1580
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] = 2
|
|
1581
|
+
all_lines[layer_ind,line_ind,bead1_t,6] = lind2
|
|
1582
|
+
all_lines[layer_ind,line_ind,bead1_t,7] = bead2_t
|
|
1583
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,11] = layer_ind
|
|
1584
|
+
all_lines[layer_ind,line_ind,bead1_t,8] = layer_ind2
|
|
1585
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,3] =-fndirec
|
|
1586
|
+
clinks[clind].append([bind1,bind2])
|
|
1587
|
+
|
|
1588
|
+
else:
|
|
1589
|
+
all_lines[layer_ind,line_ind,bead1_t,3] *= flipped
|
|
1590
|
+
all_lines[layer_ind2,(line_ind-int(ndirec))%no_lines,bead2_t,12] += 1
|
|
1591
|
+
all_lines[layer_ind,line_ind,bead1_t,12] +=1
|
|
1592
|
+
|
|
1593
|
+
clinks_np0 = []
|
|
1594
|
+
clinks_np1 = []
|
|
1595
|
+
for cl in clinks:
|
|
1596
|
+
if(len(cl) > 0):
|
|
1597
|
+
cl_np = np.array(cl)
|
|
1598
|
+
sort_ind0 = np.lexsort((cl_np[:,1],cl_np[:,0]))
|
|
1599
|
+
sort_ind1 = np.lexsort((cl_np[:,0],cl_np[:,1]))
|
|
1600
|
+
clinks_np0.append(cl_np[sort_ind0])
|
|
1601
|
+
clinks_np1.append(cl_np[sort_ind1])
|
|
1602
|
+
else:
|
|
1603
|
+
clinks_np0.append(np.empty((0,2)))
|
|
1604
|
+
clinks_np1.append(np.empty((0,2)))
|
|
1605
|
+
|
|
1606
|
+
return all_lines
|
|
1607
|
+
|
|
1608
|
+
#uses count_olig to determin distribution of oligomer lengths
|
|
1609
|
+
def count_all_olig(all_lines):
|
|
1610
|
+
test_lines = all_lines[np.logical_and(all_lines[:,:,:,5] == 1,all_lines[:,:,:,4] == 0),:]
|
|
1611
|
+
olig_lens = np.zeros(test_lines.shape[0])
|
|
1612
|
+
olig_count = 0
|
|
1613
|
+
for ly in range(all_lines.shape[0]):
|
|
1614
|
+
for l in range(all_lines[ly].shape[0]):
|
|
1615
|
+
for b in range(all_lines[ly,l].shape[0]):
|
|
1616
|
+
if(all_lines[ly,l,b,5] == 1 and all_lines[ly,l,b,4] == 0):
|
|
1617
|
+
num,_ = count_olig(all_lines,ly,l,b)
|
|
1618
|
+
olig_lens[olig_count] = num
|
|
1619
|
+
olig_count += 1
|
|
1620
|
+
return olig_lens
|
|
1621
|
+
|
|
1622
|
+
#loads an itp file
|
|
1623
|
+
def load_itp(fn):
|
|
1624
|
+
tmp_f = open(fn,"r")
|
|
1625
|
+
tmp_lines = tmp_f.readlines()
|
|
1626
|
+
tmp_f.close()
|
|
1627
|
+
|
|
1628
|
+
data = [[],[],[],[],[]]
|
|
1629
|
+
|
|
1630
|
+
data_ind = -1
|
|
1631
|
+
for lines in tmp_lines:
|
|
1632
|
+
if lines == "[ atoms ]\n":
|
|
1633
|
+
data_ind = 0
|
|
1634
|
+
elif lines == "[ bonds ]\n":
|
|
1635
|
+
data_ind = 1
|
|
1636
|
+
elif lines == "[ constraints ]\n":
|
|
1637
|
+
data_ind = 2
|
|
1638
|
+
elif lines == "[ angles ]\n":
|
|
1639
|
+
data_ind = 3
|
|
1640
|
+
elif lines == "[ dihedrals ]\n":
|
|
1641
|
+
data_ind = 4
|
|
1642
|
+
elif len(lines) < 5:
|
|
1643
|
+
data_ind = -1
|
|
1644
|
+
elif lines[0] != ";":
|
|
1645
|
+
if(data_ind > -1):
|
|
1646
|
+
data[data_ind].append(lines.split())
|
|
1647
|
+
return data
|
|
1648
|
+
|
|
1649
|
+
#flattens glycan strand data into 2d array
|
|
1650
|
+
def lines_to_coords(all_lines):
|
|
1651
|
+
old_shape = all_lines.shape
|
|
1652
|
+
all_lines = all_lines.reshape(int(all_lines.size/14),14)
|
|
1653
|
+
#sind = np.argsort(all_lines[:,4])
|
|
1654
|
+
return all_lines,old_shape
|
|
1655
|
+
|
|
1656
|
+
#Writes the itp file for PG
|
|
1657
|
+
def write_PGL_itp(all_lines,nam_itp,nag_itp,spep_itp,upep_itp,uupep_itp,prev_str,prev_nos):
|
|
1658
|
+
nam_data = load_itp(nam_itp)
|
|
1659
|
+
nag_data = load_itp(nag_itp)
|
|
1660
|
+
upep_data = load_itp(upep_itp)
|
|
1661
|
+
uupep_data = load_itp(uupep_itp)
|
|
1662
|
+
spep_data = load_itp(spep_itp)
|
|
1663
|
+
|
|
1664
|
+
|
|
1665
|
+
data = [nam_data,nag_data]
|
|
1666
|
+
atoms_str = prev_str[0]#"[ atoms ]\n"
|
|
1667
|
+
bonds_str = prev_str[1]#"[ bonds ]\n"
|
|
1668
|
+
constraints_str = prev_str[2]#"[ constraints ]\n"
|
|
1669
|
+
angles_str = prev_str[3]#"[ angles ]\n"
|
|
1670
|
+
dihedrals_str = prev_str[4]#"[ dihedrals ]\n"
|
|
1671
|
+
|
|
1672
|
+
resno = prev_nos[0]
|
|
1673
|
+
atm_no = prev_nos[1]
|
|
1674
|
+
#x y z dir type place linked
|
|
1675
|
+
#0 1 2 3 4 5 6
|
|
1676
|
+
ang_link1=[
|
|
1677
|
+
[2, 1, 8, 2, 90.000, 130.00],
|
|
1678
|
+
[3, 1, 8, 2, 118.000, 100.00],
|
|
1679
|
+
[4, 1, 8, 10, 151.000, 170.00],
|
|
1680
|
+
[1, 8, 6, 10, 70.000, 600.00],
|
|
1681
|
+
[1, 8, 9, 10, 93.000, 180.00],
|
|
1682
|
+
[1, 8, 5, 10, 160.000, 555.00]]
|
|
1683
|
+
a_link_add1 = [[0,0,-1],[0,0,-1],[0,0,-1],[0,-1,-1],[0,-1,-1],[0,-1,-1]]
|
|
1684
|
+
dihedral_link1=[
|
|
1685
|
+
[2, 1, 8, 5, 9, 0.000, 3.50, 1],
|
|
1686
|
+
[2, 1, 8, 5, 9, 0.000, 3.00, 2],
|
|
1687
|
+
[2, 1, 8, 6, 9, 0.000, 3.50, 1],
|
|
1688
|
+
[2, 1, 8, 6, 9, 0.000, 3.00, 2],
|
|
1689
|
+
[3, 1, 8, 9, 9, 0.000, 8.00, 1],
|
|
1690
|
+
[3, 1, 8, 9, 9, 0.000, 2.00, 2],
|
|
1691
|
+
[4, 1, 8, 6, 9, 0.000, 7.00, 1],
|
|
1692
|
+
[4, 1, 8, 6, 9, 0.000, 3.00, 2],
|
|
1693
|
+
[4, 1, 8, 9, 9, 180.000, 2.00, 2],
|
|
1694
|
+
[4, 1, 8, 9, 9, 180.000, 3.00, 3]]
|
|
1695
|
+
ang_link2=[
|
|
1696
|
+
[2, 1, 9, 10, 113.000, 90.00],
|
|
1697
|
+
[3, 1, 9, 10, 99.000, 100.00],
|
|
1698
|
+
[4, 1, 9, 10, 145.000, 250.00],
|
|
1699
|
+
[1, 9, 7, 10, 76.000, 400.00],
|
|
1700
|
+
[1, 9, 6, 10, 135.000, 970.00]]
|
|
1701
|
+
|
|
1702
|
+
a_link_add2 = [[0,0,-1],[0,0,-1],[0,0,-1],[0,-1,-1],[0,-1,-1]]
|
|
1703
|
+
|
|
1704
|
+
dihedral_link2=[
|
|
1705
|
+
[4, 1, 9, 6, 9, 0.000, 8.00, 1],
|
|
1706
|
+
[4, 1, 9, 6, 9, 0.000, 2.00, 2],
|
|
1707
|
+
[4, 1, 9, 7, 9, 0.000, 7.00, 1],
|
|
1708
|
+
[4, 1, 9, 7, 9, 0.000, 3.00, 2],
|
|
1709
|
+
[2, 1, 9, 6, 9, 180.000, 6.00, 1],
|
|
1710
|
+
[2, 1, 9, 6, 9, 0.000, 4.00, 2]]
|
|
1711
|
+
|
|
1712
|
+
atm_start = []
|
|
1713
|
+
for layer in all_lines:
|
|
1714
|
+
atm_start_p1 = []
|
|
1715
|
+
for line in layer:
|
|
1716
|
+
atm_start_p2 = []
|
|
1717
|
+
prev_p = 0
|
|
1718
|
+
for res in line:
|
|
1719
|
+
atm_start_p2.append(atm_no)
|
|
1720
|
+
if(res[5] == 1):
|
|
1721
|
+
r4 = int(res[4])
|
|
1722
|
+
|
|
1723
|
+
if(prev_p == 1):
|
|
1724
|
+
if(r4 == 0):
|
|
1725
|
+
bonds_str += "\t"+str(1+atm_no-4)+"\t"+str(8+atm_no-4)+"\t"+str(1)+"\t"+str(0.316)+"\t"+str(28500.00)+"\n"
|
|
1726
|
+
for ang in ang_link1:
|
|
1727
|
+
angles_str += "\t"+str(ang[0]+atm_no-4)+"\t"+str(ang[1]+atm_no-4)+"\t"+str(ang[2]+atm_no-4)+"\t"+str(ang[3])+"\t"+str(ang[4])+"\t"+str(ang[5])+"\n"
|
|
1728
|
+
for dih in dihedral_link1:
|
|
1729
|
+
dihedrals_str += "\t"+str(dih[0]+atm_no-4)+"\t"+str(dih[1]+atm_no-4)+"\t"+str(dih[2]+atm_no-4)+"\t"+str(dih[3]+atm_no-4)+"\t"+str(dih[4])+"\t"+str(dih[5])+"\t"+str(dih[6])+"\t"+str(dih[7])+"\n"
|
|
1730
|
+
else:
|
|
1731
|
+
bonds_str += "\t"+str(1+atm_no-5)+"\t"+str(9+atm_no-5)+"\t"+str(1)+"\t"+str(0.288)+"\t"+str(32000.00)+"\n"
|
|
1732
|
+
for ang in ang_link2:
|
|
1733
|
+
angles_str += "\t"+str(ang[0]+atm_no-5)+"\t"+str(ang[1]+atm_no-5)+"\t"+str(ang[2]+atm_no-5)+"\t"+str(ang[3])+"\t"+str(ang[4])+"\t"+str(ang[5])+"\n"
|
|
1734
|
+
for dih in dihedral_link2:
|
|
1735
|
+
dihedrals_str += "\t"+str(dih[0]+atm_no-5)+"\t"+str(dih[1]+atm_no-5)+"\t"+str(dih[2]+atm_no-5)+"\t"+str(dih[3]+atm_no-5)+"\t"+str(dih[4])+"\t"+str(dih[5])+"\t"+str(dih[6])+"\t"+str(dih[7])+"\n"
|
|
1736
|
+
|
|
1737
|
+
|
|
1738
|
+
for bd in data[r4][1]:
|
|
1739
|
+
bonds_str += "\t"+str(int(bd[0])+atm_no)+"\t"+str(int(bd[1])+atm_no)+"\t"+bd[2]+"\t"+bd[3]+"\t"+bd[4]+"\n"
|
|
1740
|
+
|
|
1741
|
+
|
|
1742
|
+
for cd in data[r4][2]:
|
|
1743
|
+
constraints_str += "\t"+str(int(cd[0])+atm_no)+"\t"+str(int(cd[1])+atm_no)+"\t"+cd[2]+"\t"+cd[3]+"\t"+cd[4]+"\n"
|
|
1744
|
+
for ad in data[r4][3]:
|
|
1745
|
+
angles_str += "\t"+str(int(ad[0])+atm_no)+"\t"+str(int(ad[1])+atm_no)+"\t"+str(int(ad[2])+atm_no)+"\t"+ad[3]+"\t"+ad[4]+"\t"+ad[5]+"\n"
|
|
1746
|
+
for dd in data[r4][4]:
|
|
1747
|
+
dihedrals_str += "\t"+str(int(dd[0])+atm_no)+"\t"+str(int(dd[1])+atm_no)+"\t"+str(int(dd[2])+atm_no)+"\t"+str(int(dd[3])+atm_no)+"\t"+dd[4]+"\t"+dd[5]+"\t"+dd[6]+"\t"+dd[7]+"\n"
|
|
1748
|
+
|
|
1749
|
+
for ad in data[r4][0]:
|
|
1750
|
+
atoms_str += "\t"+str(atm_no+1)+"\t"+ad[1]+"\t"+str(resno)+"\t"+ad[3]+"\t"+ad[4]+"\t"+str(atm_no+1)+"\t"+ad[6]+"\t"+ad[7]+"\n"
|
|
1751
|
+
atm_no += 1
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
resno += 1
|
|
1756
|
+
prev_p = res[5]
|
|
1757
|
+
|
|
1758
|
+
if(line[0][5] == 1 and line[-1][5] == 1):
|
|
1759
|
+
if(int(line[0][4]) == 0):
|
|
1760
|
+
bonds_str += "\t"+str(1+atm_start_p2[0])+"\t"+str(8+atm_start_p2[-1]-4)+"\t"+str(1)+"\t"+str(0.316)+"\t"+str(28500.00)+"\n"
|
|
1761
|
+
for nn,ang in enumerate(ang_link1):
|
|
1762
|
+
angles_str += "\t"+str(ang[0]+atm_start_p2[a_link_add1[nn][0]]+4*a_link_add1[nn][0])+"\t"+str(ang[1]+atm_start_p2[a_link_add1[nn][1]]+4*a_link_add1[nn][1])+"\t"+str(ang[2]+atm_start_p2[a_link_add1[nn][2]]+4*a_link_add1[nn][2])+"\t"+str(ang[3])+"\t"+str(ang[4])+"\t"+str(ang[5])+"\n"
|
|
1763
|
+
for dih in dihedral_link1:
|
|
1764
|
+
dihedrals_str += "\t"+str(dih[0]+atm_start_p2[0])+"\t"+str(dih[1]+atm_start_p2[0])+"\t"+str(dih[2]+atm_start_p2[-1]-4)+"\t"+str(dih[3]+atm_start_p2[-1]-4)+"\t"+str(dih[4])+"\t"+str(dih[5])+"\t"+str(dih[6])+"\t"+str(dih[7])+"\n"
|
|
1765
|
+
else:
|
|
1766
|
+
bonds_str += "\t"+str(1+atm_start_p2[0])+"\t"+str(9+atm_start_p2[-1]-5)+"\t"+str(1)+"\t"+str(0.288)+"\t"+str(32000.00)+"\n"
|
|
1767
|
+
for nn,ang in enumerate(ang_link2):
|
|
1768
|
+
angles_str += "\t"+str(ang[0]+atm_start_p2[a_link_add2[nn][0]]+5*a_link_add1[nn][0])+"\t"+str(ang[1]+atm_start_p2[a_link_add2[nn][1]]+5*a_link_add1[nn][1])+"\t"+str(ang[2]+atm_start_p2[a_link_add2[nn][2]]+5*a_link_add1[nn][2])+"\t"+str(ang[3])+"\t"+str(ang[4])+"\t"+str(ang[5])+"\n"
|
|
1769
|
+
for dih in dihedral_link2:
|
|
1770
|
+
dihedrals_str += "\t"+str(dih[0]+atm_start_p2[0])+"\t"+str(dih[1]+atm_start_p2[0])+"\t"+str(dih[2]+atm_start_p2[-1]-5)+"\t"+str(dih[3]+atm_start_p2[-1]-5)+"\t"+str(dih[4])+"\t"+str(dih[5])+"\t"+str(dih[6])+"\t"+str(dih[7])+"\n"
|
|
1771
|
+
|
|
1772
|
+
|
|
1773
|
+
atm_start_p1.append(atm_start_p2)
|
|
1774
|
+
atm_start.append(atm_start_p1)
|
|
1775
|
+
|
|
1776
|
+
|
|
1777
|
+
blink3 = [[5, 1, 1, 0.319, 14800.00]]
|
|
1778
|
+
|
|
1779
|
+
ang_link3 =[[ 4, 5, 1, 10, 104.000, 80.00],
|
|
1780
|
+
[5, 1, 3, 10, 107.000, 60.00],
|
|
1781
|
+
[5, 1, 2, 2, 100.000, 25.00]]
|
|
1782
|
+
|
|
1783
|
+
dih_link3 = [[4, 5, 1, 3, 9, 60.000, 3.00, 2],
|
|
1784
|
+
[5, 1, 3, 4, 9, 140.000, 3.00, 2]]
|
|
1785
|
+
|
|
1786
|
+
iplink = [8, 7, 1, 0.350, 1100.00]
|
|
1787
|
+
ang_iplink = [[5,8,7,10,114,75],[8,7,6,10,95,75]]
|
|
1788
|
+
|
|
1789
|
+
cl_atm_start = []
|
|
1790
|
+
|
|
1791
|
+
for lyind,layer in enumerate(all_lines):
|
|
1792
|
+
cl_atm_start_p1 = []
|
|
1793
|
+
for lind,line in enumerate(layer):
|
|
1794
|
+
cl_atm_start_p2 = []
|
|
1795
|
+
for bind,res in enumerate(line):
|
|
1796
|
+
cl_atm_start_p2.append(atm_no)
|
|
1797
|
+
if(res[5] == 1):
|
|
1798
|
+
r4 = int(res[4])
|
|
1799
|
+
if(r4 == 0):
|
|
1800
|
+
if(res[13] == 1):
|
|
1801
|
+
data = uupep_data
|
|
1802
|
+
else:
|
|
1803
|
+
if(res[6] != -1 or res[13] == 2):
|
|
1804
|
+
data = upep_data
|
|
1805
|
+
else:
|
|
1806
|
+
data = spep_data
|
|
1807
|
+
|
|
1808
|
+
b1_s = atm_start[lyind][lind][bind]
|
|
1809
|
+
for bd in blink3:
|
|
1810
|
+
bonds_str += "\t"+str(bd[0]+b1_s)+"\t"+str(bd[1]+atm_no)+"\t"+str(bd[2])+"\t"+str(bd[3])+"\t"+str(bd[4])+"\n"
|
|
1811
|
+
|
|
1812
|
+
angles_str += "\t"+str(ang_link3[0][0]+b1_s)+"\t"+str(ang_link3[0][1]+b1_s)+"\t"+str(ang_link3[0][2]+atm_no)+"\t"+str(ang_link3[0][3])+"\t"+str(ang_link3[0][4])+"\t"+str(ang_link3[0][5])+"\n"
|
|
1813
|
+
angles_str += "\t"+str(ang_link3[1][0]+b1_s)+"\t"+str(ang_link3[1][1]+atm_no)+"\t"+str(ang_link3[1][2]+atm_no)+"\t"+str(ang_link3[1][3])+"\t"+str(ang_link3[1][4])+"\t"+str(ang_link3[1][5])+"\n"
|
|
1814
|
+
angles_str += "\t"+str(ang_link3[2][0]+b1_s)+"\t"+str(ang_link3[2][1]+atm_no)+"\t"+str(ang_link3[2][2]+atm_no)+"\t"+str(ang_link3[2][3])+"\t"+str(ang_link3[2][4])+"\t"+str(ang_link3[2][5])+"\n"
|
|
1815
|
+
|
|
1816
|
+
dihedrals_str += "\t"+str(dih_link3[0][0]+b1_s)+"\t"+str(dih_link3[0][1]+b1_s)+"\t"+str(dih_link3[0][2]+atm_no)+"\t"+str(dih_link3[0][3]+atm_no)+"\t"+str(dih_link3[0][4])+"\t"+str(dih_link3[0][5])+"\t"+str(dih_link3[0][6])+"\t"+str(dih_link3[0][7])+"\n"
|
|
1817
|
+
dihedrals_str += "\t"+str(dih_link3[0][0]+b1_s)+"\t"+str(dih_link3[0][1]+atm_no)+"\t"+str(dih_link3[0][2]+atm_no)+"\t"+str(dih_link3[0][3]+atm_no)+"\t"+str(dih_link3[0][4])+"\t"+str(dih_link3[0][5])+"\t"+str(dih_link3[0][6])+"\t"+str(dih_link3[0][7])+"\n"
|
|
1818
|
+
|
|
1819
|
+
for bd in data[1]:
|
|
1820
|
+
bonds_str += "\t"+str(int(bd[0])+atm_no)+"\t"+str(int(bd[1])+atm_no)+"\t"+bd[2]+"\t"+bd[3]+"\t"+bd[4]+"\n"
|
|
1821
|
+
for cd in data[2]:
|
|
1822
|
+
constraints_str += "\t"+str(int(cd[0])+atm_no)+"\t"+str(int(cd[1])+atm_no)+"\t"+cd[2]+"\t"+cd[3]+"\t"+cd[4]+"\n"
|
|
1823
|
+
for ad in data[3]:
|
|
1824
|
+
angles_str += "\t"+str(int(ad[0])+atm_no)+"\t"+str(int(ad[1])+atm_no)+"\t"+str(int(ad[2])+atm_no)+"\t"+ad[3]+"\t"+ad[4]+"\t"+ad[5]+"\n"
|
|
1825
|
+
for dd in data[4]:
|
|
1826
|
+
dihedrals_str += "\t"+str(int(dd[0])+atm_no)+"\t"+str(int(dd[1])+atm_no)+"\t"+str(int(dd[2])+atm_no)+"\t"+str(int(dd[3])+atm_no)+"\t"+dd[4]+"\t"+dd[5]+"\t"+dd[6]+"\t"+dd[7]+"\n"
|
|
1827
|
+
|
|
1828
|
+
for ad in data[0]:
|
|
1829
|
+
atoms_str += "\t"+str(atm_no+1)+"\t"+ad[1]+"\t"+str(resno)+"\t"+ad[3]+"\t"+ad[4]+"\t"+str(atm_no+1)+"\t"+ad[6]+"\t"+ad[7]+"\n"
|
|
1830
|
+
atm_no += 1
|
|
1831
|
+
resno += 1
|
|
1832
|
+
cl_atm_start_p1.append(cl_atm_start_p2)
|
|
1833
|
+
cl_atm_start.append(cl_atm_start_p1)
|
|
1834
|
+
|
|
1835
|
+
for lyind,layer in enumerate(all_lines):
|
|
1836
|
+
for lind,line in enumerate(layer):
|
|
1837
|
+
for bind,res in enumerate(line):
|
|
1838
|
+
c_atm1 = cl_atm_start[lyind][lind][bind]
|
|
1839
|
+
ly2ind = int(res[8])
|
|
1840
|
+
l2ind = int(res[6])
|
|
1841
|
+
b2ind = int(res[7])
|
|
1842
|
+
if(l2ind != -1):
|
|
1843
|
+
c_atm2 = cl_atm_start[ly2ind][l2ind][b2ind]
|
|
1844
|
+
if(all_lines[lyind][lind][bind][13] == 1 or all_lines[ly2ind][l2ind][b2ind][13] == 1):
|
|
1845
|
+
iplink[0] = 7
|
|
1846
|
+
else:
|
|
1847
|
+
pass
|
|
1848
|
+
#angles_str += "\t"+str(ang_iplink[0][0]+c_atm1)+"\t"+str(ang_iplink[0][1]+c_atm1)+"\t"+str(ang_iplink[0][2]+c_atm2)+"\t"+str(ang_iplink[0][3])+"\t"+str(ang_iplink[0][4])+"\t"+str(ang_iplink[0][5])+"\n"
|
|
1849
|
+
angles_str += "\t"+str(ang_iplink[1][0]+c_atm1)+"\t"+str(ang_iplink[1][1]+c_atm2)+"\t"+str(ang_iplink[1][2]+c_atm2)+"\t"+str(ang_iplink[1][3])+"\t"+str(ang_iplink[1][4])+"\t"+str(ang_iplink[1][5])+"\n"
|
|
1850
|
+
|
|
1851
|
+
bonds_str += "\t"+str(iplink[0]+c_atm1)+"\t"+str(iplink[1]+c_atm2)+"\t"+str(iplink[2])+"\t"+str(iplink[3])+"\t"+str(iplink[4])+"\n"
|
|
1852
|
+
|
|
1853
|
+
return [atoms_str,bonds_str,constraints_str,angles_str,dihedrals_str],[resno,atm_no]
|
|
1854
|
+
|
|
1855
|
+
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
#write the PG itp
|
|
1860
|
+
def write_all_itp(itp_str,out_folder):
|
|
1861
|
+
pgl_file = open(out_folder+"PGL.itp","w")
|
|
1862
|
+
pgl_file.write("[ moleculetype ]\n")
|
|
1863
|
+
pgl_file.write("PGL 1\n\n")
|
|
1864
|
+
pgl_file.write(itp_str[0]+"\n")
|
|
1865
|
+
pgl_file.write(itp_str[1]+"\n")
|
|
1866
|
+
pgl_file.write(itp_str[2]+"\n")
|
|
1867
|
+
pgl_file.write(itp_str[3]+"\n")
|
|
1868
|
+
pgl_file.write(itp_str[4]+"\n")
|
|
1869
|
+
pgl_file.close()
|
|
1870
|
+
|
|
1871
|
+
|
|
1872
|
+
#Function that creates a leaflet using all of the above
|
|
1873
|
+
def create_leaflet(den,xbox,ybox,curv_A,curv_B,ch_ang,pore,leng,keep_end,mem_outer_red):
|
|
1874
|
+
if(curv_A < 1e-5 or curv_B < 1e-5):
|
|
1875
|
+
gpoints3,direcs3 = np.array(DiskGrid(den,0,xbox,ybox,mem_outer_red))
|
|
1876
|
+
return gpoints3,direcs3
|
|
1877
|
+
rad_A = 1.0/curv_A
|
|
1878
|
+
rad_B = 1.0/curv_B
|
|
1879
|
+
|
|
1880
|
+
if(pore):
|
|
1881
|
+
ch_ang=np.pi/2
|
|
1882
|
+
|
|
1883
|
+
c1 = np.cos(ch_ang)
|
|
1884
|
+
s1 = np.sin(ch_ang)
|
|
1885
|
+
|
|
1886
|
+
c2 = np.cos(np.pi/2-ch_ang)
|
|
1887
|
+
s2 = np.sin(np.pi/2-ch_ang)
|
|
1888
|
+
|
|
1889
|
+
in_rad = rad_A*s1+rad_B*(c2-1)
|
|
1890
|
+
|
|
1891
|
+
|
|
1892
|
+
if(not pore):
|
|
1893
|
+
gpoints,direcs = np.array(SphereGridN(den,ch_ang,rad_A))
|
|
1894
|
+
else:
|
|
1895
|
+
gpoints,direcs = np.array(TubeGrid(den,in_rad,leng,keep_end))
|
|
1896
|
+
|
|
1897
|
+
|
|
1898
|
+
|
|
1899
|
+
gpoints2,direcs2 = np.array(InvSphereGrid(den,in_rad,(np.pi/2-ch_ang),rad_B))
|
|
1900
|
+
gpoints3,direcs3 = np.array(DiskGrid(den,rad_B+in_rad,xbox,ybox,mem_outer_red))
|
|
1901
|
+
shift = -gpoints[-1,2]+s2*rad_B-rad_B
|
|
1902
|
+
if(pore):
|
|
1903
|
+
gpoints[:,2] = gpoints[:,2]-rad_B
|
|
1904
|
+
gpoints2[:,2] = gpoints2[:,2]-rad_B
|
|
1905
|
+
gpoints3[:,2] = gpoints3[:,2]
|
|
1906
|
+
else:
|
|
1907
|
+
gpoints2[:,2] = gpoints2[:,2]-rad_B -shift
|
|
1908
|
+
gpoints3[:,2] = gpoints3[:,2] -shift
|
|
1909
|
+
|
|
1910
|
+
gpoints = np.concatenate([gpoints,gpoints2,gpoints3])
|
|
1911
|
+
direcs = np.concatenate([direcs,direcs2,direcs3])
|
|
1912
|
+
return gpoints,direcs
|
|
1913
|
+
|
|
1914
|
+
|
|
1915
|
+
#A fully analytic function of the leaflet. This is very useful for accurate exclusion of solute
|
|
1916
|
+
def leaflet_function(x,y,curv_A,curv_B,ch_ang,pore,leng):
|
|
1917
|
+
if(curv_A < 1e-5 or curv_B < 1e-5):
|
|
1918
|
+
return 0,np.array([0,0,1])
|
|
1919
|
+
rad_p = np.sqrt(x*x+y*y)
|
|
1920
|
+
if(pore):
|
|
1921
|
+
ch_ang=np.pi/2
|
|
1922
|
+
|
|
1923
|
+
c1 = np.cos(ch_ang)
|
|
1924
|
+
s1 = np.sin(ch_ang)
|
|
1925
|
+
|
|
1926
|
+
c2 = np.cos(np.pi/2-ch_ang)
|
|
1927
|
+
s2 = np.sin(np.pi/2-ch_ang)
|
|
1928
|
+
rad_A = 1.0/curv_A
|
|
1929
|
+
rad_B = 1.0/curv_B
|
|
1930
|
+
sphere_rad = s1*rad_A
|
|
1931
|
+
in_rad = rad_A*s1+rad_B*(c2-1)
|
|
1932
|
+
shift = (1-c1)*rad_B-(s2*rad_A-rad_A)
|
|
1933
|
+
if(pore):
|
|
1934
|
+
shift = 0
|
|
1935
|
+
if(rad_p< sphere_rad):
|
|
1936
|
+
if(pore):
|
|
1937
|
+
z = leng
|
|
1938
|
+
direc = np.array([-x,-y,0])
|
|
1939
|
+
return z,direc/np.linalg.norm(direc)
|
|
1940
|
+
else:
|
|
1941
|
+
z = np.sqrt(rad_A*rad_A-rad_p*rad_p)-rad_A
|
|
1942
|
+
direc = np.array([-x,-y,z+rad_A])
|
|
1943
|
+
return z,direc/np.linalg.norm(direc)
|
|
1944
|
+
elif(rad_p < in_rad+rad_B):
|
|
1945
|
+
z = -np.sqrt(rad_B*rad_B-(rad_p-rad_B-in_rad)*(rad_p-rad_B-in_rad))+rad_B-shift
|
|
1946
|
+
xydirec = np.array([x,y])
|
|
1947
|
+
xydirec /= np.linalg.norm(xydirec)
|
|
1948
|
+
direc = np.array([(x-xydirec[0]*(rad_B+in_rad)),(y-xydirec[1]*(rad_B+in_rad)),-(z+shift-rad_B)])
|
|
1949
|
+
return z,direc/np.linalg.norm(direc)
|
|
1950
|
+
else:
|
|
1951
|
+
return -shift,np.array([0,0,1])
|
|
1952
|
+
|
|
1953
|
+
#Get the minimum dimensions required to fit all the curvature
|
|
1954
|
+
def get_box_size(curv_A,curv_B,ch_ang,pore):
|
|
1955
|
+
if(curv_A < 1e-5 or curv_B < 1e-5):
|
|
1956
|
+
return 0,0
|
|
1957
|
+
if(pore):
|
|
1958
|
+
ch_ang=np.pi/2
|
|
1959
|
+
|
|
1960
|
+
c1 = np.cos(ch_ang)
|
|
1961
|
+
s1 = np.sin(ch_ang)
|
|
1962
|
+
|
|
1963
|
+
c2 = np.cos(np.pi/2-ch_ang)
|
|
1964
|
+
s2 = np.sin(np.pi/2-ch_ang)
|
|
1965
|
+
rad_A = 1.0/curv_A
|
|
1966
|
+
rad_B = 1.0/curv_B
|
|
1967
|
+
|
|
1968
|
+
in_rad = rad_A*s1+rad_B*(c2-1)
|
|
1969
|
+
height = rad_A*(1-c1)+rad_B*(1-c1)
|
|
1970
|
+
return in_rad+rad_B,height
|
|
1971
|
+
|
|
1972
|
+
#A function for binning points into a fixed grid
|
|
1973
|
+
def put_into_grid(x,r,n,s):
|
|
1974
|
+
cx = x[0]-s[0]
|
|
1975
|
+
cy = x[1]-s[1]
|
|
1976
|
+
norm_x = cx/r[0]
|
|
1977
|
+
norm_y = cy/r[1]
|
|
1978
|
+
grid_x = n[0]*norm_x
|
|
1979
|
+
grid_y = n[1]*norm_y
|
|
1980
|
+
return int(np.floor(grid_x)),int(np.floor(grid_y))
|
|
1981
|
+
|
|
1982
|
+
#Used with above
|
|
1983
|
+
def bin_grid(grid_in,r,n,s):
|
|
1984
|
+
grid_final = np.zeros((n[0],n[1]))
|
|
1985
|
+
grid = np.zeros((n[0],n[1],grid_in.shape[0]+1))
|
|
1986
|
+
for k in range(grid_in.shape[0]):
|
|
1987
|
+
gx,gy = put_into_grid(grid_in[k,:2],r,n,s)
|
|
1988
|
+
grid[gx,gy,int(grid[gx,gy,-1])] = grid_in[k,2]
|
|
1989
|
+
grid[gx,gy,-1] += 1
|
|
1990
|
+
for i in range(n[0]):
|
|
1991
|
+
for j in range(n[1]):
|
|
1992
|
+
if(grid[i,j,-1] == 0):
|
|
1993
|
+
grid_final[i,j] = np.nan
|
|
1994
|
+
else:
|
|
1995
|
+
grid_final[i,j] = np.sum(grid[i,j,:-1])/grid[i,j,-1]
|
|
1996
|
+
return grid_final
|
|
1997
|
+
|
|
1998
|
+
#Another method of binning points.
|
|
1999
|
+
def get_box_slice(points,p,r):
|
|
2000
|
+
pslice = points[points[:,0]>p[0]-r[0]]
|
|
2001
|
+
pslice = pslice[pslice[:,0]<p[0]+r[0]]
|
|
2002
|
+
pslice = pslice[pslice[:,1]>p[1]-r[1]]
|
|
2003
|
+
pslice = pslice[pslice[:,1]<p[1]+r[1]]
|
|
2004
|
+
pslice = pslice[pslice[:,2]>p[2]-r[2]]
|
|
2005
|
+
pslice = pslice[pslice[:,2]<p[2]+r[2]]
|
|
2006
|
+
return pslice
|
|
2007
|
+
|
|
2008
|
+
|
|
2009
|
+
#This is a function for sorting atoms for a neater topology file
|
|
2010
|
+
def reorder_atoms(atoms,coords):
|
|
2011
|
+
lip_names = []
|
|
2012
|
+
lip_split = []
|
|
2013
|
+
lip_split_coords = []
|
|
2014
|
+
for i,a in enumerate(atoms):
|
|
2015
|
+
if(a[1] in lip_names):
|
|
2016
|
+
lip_split[lip_names.index(a[1])].append(list(a))
|
|
2017
|
+
lip_split_coords[lip_names.index(a[1])].append(coords[i])
|
|
2018
|
+
else:
|
|
2019
|
+
lip_names.append(a[1])
|
|
2020
|
+
lip_split.append([])
|
|
2021
|
+
lip_split_coords.append([])
|
|
2022
|
+
lip_split[-1].append(list(a))
|
|
2023
|
+
lip_split_coords[-1].append(coords[i])
|
|
2024
|
+
count = 1
|
|
2025
|
+
prev = 1
|
|
2026
|
+
for i in lip_split:
|
|
2027
|
+
for k in i:
|
|
2028
|
+
if(k[2] == prev):
|
|
2029
|
+
k[2] = count
|
|
2030
|
+
else:
|
|
2031
|
+
prev = k[2]
|
|
2032
|
+
count += 1
|
|
2033
|
+
k[2] = count
|
|
2034
|
+
new_atoms = []
|
|
2035
|
+
new_coords = []
|
|
2036
|
+
for i in range(len(lip_split)):
|
|
2037
|
+
for k in range(len(lip_split[i])):
|
|
2038
|
+
new_atoms.append(lip_split[i][k])
|
|
2039
|
+
new_coords.append(lip_split_coords[i][k])
|
|
2040
|
+
return new_atoms,new_coords
|
|
2041
|
+
|
|
2042
|
+
#Ignore this
|
|
2043
|
+
def LocBias(coords,lnums,lipids,steps,loc_lipids,bias_grid):
|
|
2044
|
+
lipids=list(lipids)
|
|
2045
|
+
lip_ranges = []
|
|
2046
|
+
total = 0
|
|
2047
|
+
for l in range(len(lipids)):
|
|
2048
|
+
lip_ranges.append([total,total+lnums[l]])
|
|
2049
|
+
total += lnums[l]
|
|
2050
|
+
swap = []
|
|
2051
|
+
nswap = []
|
|
2052
|
+
for l in range(len(lipids)):
|
|
2053
|
+
if lipids[l] in loc_lipids:
|
|
2054
|
+
swap.append(l)
|
|
2055
|
+
else:
|
|
2056
|
+
nswap.append(l)
|
|
2057
|
+
for i in range(steps):
|
|
2058
|
+
bulk = random.choice(nswap)
|
|
2059
|
+
swaper = random.choice(swap)
|
|
2060
|
+
bstart,bend = lip_ranges[bulk]
|
|
2061
|
+
sstart,send = lip_ranges[swaper]
|
|
2062
|
+
blip = random.randint(bstart,bend-1)
|
|
2063
|
+
slip = random.randint(sstart,send-1)
|
|
2064
|
+
bcoord = coords[blip]
|
|
2065
|
+
scoord = coords[slip]
|
|
2066
|
+
binda,bindb = put_into_grid(bcoord[:2],[pbcx, pbcy],[bias_grid.shape[0],bias_grid.shape[1]],[0,0])
|
|
2067
|
+
sinda,sindb = put_into_grid(scoord[:2],[pbcx, pbcy],[bias_grid.shape[0],bias_grid.shape[1]],[0,0])
|
|
2068
|
+
|
|
2069
|
+
swap_val = -bias_grid[sinda,sindb]+bias_grid[binda,bindb]
|
|
2070
|
+
swap_prob = 1/(1+np.exp(-0.3*swap_val))
|
|
2071
|
+
|
|
2072
|
+
if random.random() < swap_prob:
|
|
2073
|
+
coords[slip]=bcoord
|
|
2074
|
+
coords[blip]=scoord
|
|
2075
|
+
return coords
|
|
2076
|
+
|
|
2077
|
+
#gets charge between a lower and upper bound, for neutralising compartments
|
|
2078
|
+
def get_charge(lz,uz):
|
|
2079
|
+
last = None
|
|
2080
|
+
mcharge = 0
|
|
2081
|
+
for ind,j in enumerate(membrane.atoms):
|
|
2082
|
+
pos = membrane.coord[ind]
|
|
2083
|
+
if not j[0].strip().startswith('v') and j[1:3] != last:
|
|
2084
|
+
if(pos[2] > lz and pos[2] < uz):
|
|
2085
|
+
mcharge += charges.get(j[1].strip(),0)
|
|
2086
|
+
last = j[1:3]
|
|
2087
|
+
|
|
2088
|
+
last = None
|
|
2089
|
+
pgcharge = 0
|
|
2090
|
+
for ind,j in enumerate(PGL.atoms):
|
|
2091
|
+
pos = PGL.coord[ind]
|
|
2092
|
+
if not j[0].strip().startswith('v') and j[1:3] != last:
|
|
2093
|
+
if(pos[2] > lz and pos[2] < uz):
|
|
2094
|
+
pgcharge += charges.get(j[1].strip(),0)
|
|
2095
|
+
last = j[1:3]
|
|
2096
|
+
|
|
2097
|
+
last = None
|
|
2098
|
+
pcharge = 0
|
|
2099
|
+
for ind,j in enumerate(protein.atoms):
|
|
2100
|
+
pos = protein.coord[ind]
|
|
2101
|
+
if not j[0].strip().startswith('v') and j[1:3] != last:
|
|
2102
|
+
if(pos[2] > lz and pos[2] < uz):
|
|
2103
|
+
pcharge += charges.get(j[1].strip(),0)
|
|
2104
|
+
last = j[1:3]
|
|
2105
|
+
total_charge = mcharge+pgcharge+pcharge
|
|
2106
|
+
return total_charge,pcharge,mcharge,pgcharge
|
|
2107
|
+
|
|
2108
|
+
|
|
2109
|
+
#This function creates a list of indicies containing a PG oligomer
|
|
2110
|
+
def count_olig_list(all_lines,lyind,lind,bind):
|
|
2111
|
+
done = False
|
|
2112
|
+
count = 1
|
|
2113
|
+
all_linesT = all_lines.copy()
|
|
2114
|
+
pposes = [int(all_linesT[lyind,lind,bind,12])]
|
|
2115
|
+
if(all_linesT[lyind][lind][bind][13] == 1):
|
|
2116
|
+
if(all_linesT[lyind,lind,bind,6] > -0.5):
|
|
2117
|
+
tnlind = int(all_linesT[lyind,lind,bind,6])
|
|
2118
|
+
tnbind = int(all_linesT[lyind,lind,bind,7])
|
|
2119
|
+
tnlyind = int(all_linesT[lyind,lind,bind,8])
|
|
2120
|
+
nlind = tnlind
|
|
2121
|
+
nbind = tnbind
|
|
2122
|
+
nlyind = tnlyind
|
|
2123
|
+
switcher = 6
|
|
2124
|
+
elif(all_linesT[lyind,lind,bind,9] > -0.5):
|
|
2125
|
+
tnlind = int(all_linesT[lyind,lind,bind,9])
|
|
2126
|
+
tnbind = int(all_linesT[lyind,lind,bind,10])
|
|
2127
|
+
tnlyind = int(all_linesT[lyind,lind,bind,11])
|
|
2128
|
+
nlind = tnlind
|
|
2129
|
+
nbind = tnbind
|
|
2130
|
+
nlyind = tnlyind
|
|
2131
|
+
switcher = 9
|
|
2132
|
+
pposes.append(int(all_linesT[nlyind,nlind,nbind,12]))
|
|
2133
|
+
return pposes, False
|
|
2134
|
+
if(all_linesT[lyind,lind,bind,6] > -0.5):
|
|
2135
|
+
tnlind = int(all_linesT[lyind,lind,bind,6])
|
|
2136
|
+
tnbind = int(all_linesT[lyind,lind,bind,7])
|
|
2137
|
+
tnlyind = int(all_linesT[lyind,lind,bind,8])
|
|
2138
|
+
nlind = tnlind
|
|
2139
|
+
nbind = tnbind
|
|
2140
|
+
nlyind = tnlyind
|
|
2141
|
+
switcher = 6
|
|
2142
|
+
elif(all_linesT[lyind,lind,bind,9] > -0.5):
|
|
2143
|
+
tnlind = int(all_linesT[lyind,lind,bind,9])
|
|
2144
|
+
tnbind = int(all_linesT[lyind,lind,bind,10])
|
|
2145
|
+
tnlyind = int(all_linesT[lyind,lind,bind,11])
|
|
2146
|
+
nlind = tnlind
|
|
2147
|
+
nbind = tnbind
|
|
2148
|
+
nlyind = tnlyind
|
|
2149
|
+
switcher = 9
|
|
2150
|
+
else:
|
|
2151
|
+
return pposes,False
|
|
2152
|
+
while not done:
|
|
2153
|
+
count += 1
|
|
2154
|
+
pposes.append(int(all_linesT[nlyind,nlind,nbind,12]))
|
|
2155
|
+
if(all_linesT[nlyind,nlind,nbind,13] == 1):
|
|
2156
|
+
return pposes,False
|
|
2157
|
+
|
|
2158
|
+
tnlind = int(all_linesT[nlyind,nlind,nbind,switcher])
|
|
2159
|
+
tnbind = int(all_linesT[nlyind,nlind,nbind,switcher+1])
|
|
2160
|
+
tnlyind = int(all_linesT[nlyind,nlind,nbind,switcher+2])
|
|
2161
|
+
nlind = tnlind
|
|
2162
|
+
nbind = tnbind
|
|
2163
|
+
nlyind = tnlyind
|
|
2164
|
+
if(nlind < 0):
|
|
2165
|
+
done = True
|
|
2166
|
+
break
|
|
2167
|
+
return pposes, True
|
|
2168
|
+
|
|
2169
|
+
#Applies the above to all
|
|
2170
|
+
def count_all_olig_list(all_lines):
|
|
2171
|
+
test_lines = all_lines[np.logical_and(all_lines[:,:,:,5] == 1,all_lines[:,:,:,4] == 0),:]
|
|
2172
|
+
olig_lens = []
|
|
2173
|
+
olig_count = 0
|
|
2174
|
+
for ly in range(all_lines.shape[0]):
|
|
2175
|
+
for l in range(all_lines[ly].shape[0]):
|
|
2176
|
+
for b in range(all_lines[ly,l].shape[0]):
|
|
2177
|
+
if(all_lines[ly,l,b,5] == 1 and all_lines[ly,l,b,4] == 0):
|
|
2178
|
+
num,_ = count_olig_list(all_lines,ly,l,b)
|
|
2179
|
+
olig_lens.append(num)
|
|
2180
|
+
olig_count += 1
|
|
2181
|
+
return olig_lens
|
|
2182
|
+
|
|
2183
|
+
#Gets the distance and periodic copy that is closest
|
|
2184
|
+
def get_closest_pos(pos1,pos2,box_size):
|
|
2185
|
+
min_dist = 100000
|
|
2186
|
+
part_copy = np.array([0,0])
|
|
2187
|
+
for i in [-1,0,1]:
|
|
2188
|
+
for k in [-1,0,1]:
|
|
2189
|
+
dister = np.linalg.norm(pos1-(pos2+np.array([i,k])*box_size))
|
|
2190
|
+
if(dister< min_dist):
|
|
2191
|
+
min_dist = dister
|
|
2192
|
+
part_copy[0] = i
|
|
2193
|
+
part_copy[1] = k
|
|
2194
|
+
|
|
2195
|
+
return min_dist,part_copy
|
|
2196
|
+
|
|
2197
|
+
#a version of the above for use in jitted parts
|
|
2198
|
+
@jax.jit
|
|
2199
|
+
def get_closest_pos_jax(pos1,pos2,box_size):
|
|
2200
|
+
min_dist = 100000.0
|
|
2201
|
+
part_copy = jnp.array([0,0])
|
|
2202
|
+
def loop1(carry,ind1):
|
|
2203
|
+
def loop2(carry,ind2):
|
|
2204
|
+
part_copy = carry[0]
|
|
2205
|
+
min_dist = carry[1]
|
|
2206
|
+
dister = jnp.linalg.norm(pos1-(pos2+jnp.array([ind1,ind2])*box_size))
|
|
2207
|
+
def leq(part_copy,min_dist):
|
|
2208
|
+
part_copy = jnp.array([ind1,ind2])
|
|
2209
|
+
min_dist= dister
|
|
2210
|
+
return part_copy,min_dist
|
|
2211
|
+
def geq(part_copy,min_dist):
|
|
2212
|
+
return part_copy,min_dist
|
|
2213
|
+
part_copy,min_dist = jax.lax.cond(dister<min_dist,leq,geq,part_copy,min_dist)
|
|
2214
|
+
return (part_copy,min_dist),ind2
|
|
2215
|
+
carry,_ =jax.lax.scan(loop2,carry,jnp.array([-1,0,1]))
|
|
2216
|
+
return carry,ind1
|
|
2217
|
+
carry,_ = jax.lax.scan(loop1,(part_copy,min_dist),jnp.array([-1,0,1]))
|
|
2218
|
+
return carry[1],carry[0]
|
|
2219
|
+
|
|
2220
|
+
#function that constrains values to cell
|
|
2221
|
+
def enforce_pbc2(ppos,box_size):
|
|
2222
|
+
box = [0,0,box_size[0],box_size[1]]
|
|
2223
|
+
for p in range(ppos.shape[0]):
|
|
2224
|
+
if(ppos[p,0]-box[0] < 0):
|
|
2225
|
+
ppos[p,0] += box[2]
|
|
2226
|
+
if(ppos[p,1]-box[1] < 0):
|
|
2227
|
+
ppos[p,1] += box[3]
|
|
2228
|
+
ppos[p,0] = np.fmod(ppos[p,0]-box[0],box[2])+box[0]
|
|
2229
|
+
ppos[p,1] = np.fmod(ppos[p,1]-box[1],box[3])+box[1]
|
|
2230
|
+
return ppos
|
|
2231
|
+
|
|
2232
|
+
#a jitted version of the above
|
|
2233
|
+
@jax.jit
|
|
2234
|
+
def enforce_pbc_jax(ppos,box_size):
|
|
2235
|
+
box = jnp.array([box_size[0],box_size[1]])
|
|
2236
|
+
def pos_loop(ppos,ind):
|
|
2237
|
+
def lzero1(val):
|
|
2238
|
+
return val+box[0]
|
|
2239
|
+
def gzero(val):
|
|
2240
|
+
return val
|
|
2241
|
+
def lzero2(val):
|
|
2242
|
+
return val+box[1]
|
|
2243
|
+
ppos = ppos.at[ind,0].set(jax.lax.cond(ppos[ind,0]<0,lzero1,gzero,ppos[ind,0]))
|
|
2244
|
+
ppos = ppos.at[ind,1].set(jax.lax.cond(ppos[ind,1]<0,lzero2,gzero,ppos[ind,1]))
|
|
2245
|
+
ppos = ppos.at[ind,0].set(jnp.fmod(ppos[ind,0],box[0]))
|
|
2246
|
+
ppos = ppos.at[ind,1].set(jnp.fmod(ppos[ind,1],box[1]))
|
|
2247
|
+
return ppos,ind
|
|
2248
|
+
ppos,_ = jax.lax.scan(pos_loop,ppos,jnp.arange(ppos.shape[0]))
|
|
2249
|
+
return ppos
|
|
2250
|
+
|
|
2251
|
+
#calculation of the acceleration given position and bonds
|
|
2252
|
+
@jax.jit
|
|
2253
|
+
def calc_acc_jax(ppos,bonds,box_size):
|
|
2254
|
+
pacc = jnp.zeros_like(ppos)
|
|
2255
|
+
def bond_loop(pacc,ind):
|
|
2256
|
+
bind1 = jnp.array(bonds[ind,0],dtype=int)
|
|
2257
|
+
bind2 = jnp.array(bonds[ind,1],dtype=int)
|
|
2258
|
+
pa = ppos[bind1]
|
|
2259
|
+
pb = ppos[bind2]
|
|
2260
|
+
min_dist,part_copy = get_closest_pos_jax(pa,pb,box_size)
|
|
2261
|
+
err_dist = bonds[ind,2]-min_dist
|
|
2262
|
+
direc = (pa-(pb+part_copy*box_size))/min_dist
|
|
2263
|
+
force = err_dist*direc
|
|
2264
|
+
pacc = pacc.at[bind1].set(pacc[bind1]+force)
|
|
2265
|
+
pacc = pacc.at[bind2].set(pacc[bind2]-force)
|
|
2266
|
+
return pacc,ind
|
|
2267
|
+
pacc,_ = jax.lax.scan(bond_loop,pacc,jnp.arange(bonds.shape[0]))
|
|
2268
|
+
return pacc
|
|
2269
|
+
|
|
2270
|
+
#some minor protein repulsion to avoid major clashes
|
|
2271
|
+
@jax.jit
|
|
2272
|
+
def prot_repul_jax(all_p_pad,ppos,plys,all_p_lens):
|
|
2273
|
+
pacc = jnp.zeros_like(ppos)
|
|
2274
|
+
ls = jnp.zeros(all_p_lens.shape[0])
|
|
2275
|
+
def loop1(ls,ind):
|
|
2276
|
+
ls = ls.at[ind].set(jnp.sum(all_p_pad[ind,:,2])/all_p_lens[ind])
|
|
2277
|
+
return ls,ind
|
|
2278
|
+
ls,_ = jax.lax.scan(loop1,ls,jnp.arange(all_p_lens.shape[0]))
|
|
2279
|
+
|
|
2280
|
+
def loop2(pacc,ind1):
|
|
2281
|
+
def loop3(layer,ind2):
|
|
2282
|
+
def close(layer):
|
|
2283
|
+
layer = ind2
|
|
2284
|
+
return layer
|
|
2285
|
+
def far(layer):
|
|
2286
|
+
return layer
|
|
2287
|
+
layer = jax.lax.cond(jnp.abs(plys[ind1]-ls[ind2]) < 1, close,far,layer)
|
|
2288
|
+
return layer,ind2
|
|
2289
|
+
layer,_ = jax.lax.scan(loop3,0,jnp.arange(ls.shape[0]))
|
|
2290
|
+
|
|
2291
|
+
def loop4(pacc,ind2):
|
|
2292
|
+
direc = ppos[ind1]-all_p_pad[layer,ind2,:2]*50
|
|
2293
|
+
dirlen = jnp.linalg.norm(direc)
|
|
2294
|
+
direc /= dirlen
|
|
2295
|
+
def cutoff():
|
|
2296
|
+
return 0.0
|
|
2297
|
+
def ncutoff():
|
|
2298
|
+
return 170.0
|
|
2299
|
+
force = jax.lax.cond(jnp.logical_or(dirlen > 70,ind2>all_p_lens[layer]), cutoff,ncutoff)
|
|
2300
|
+
pacc = pacc.at[ind1].set(pacc[ind1]+force*direc/dirlen)
|
|
2301
|
+
return pacc,ind2
|
|
2302
|
+
pacc,_ = jax.lax.scan(loop4,pacc,jnp.arange(all_p_pad.shape[1]))
|
|
2303
|
+
return pacc,ind1
|
|
2304
|
+
pacc,_ = jax.lax.scan(loop2,pacc,jnp.arange(ppos.shape[0]))
|
|
2305
|
+
|
|
2306
|
+
return pacc
|
|
2307
|
+
|
|
2308
|
+
#core update function
|
|
2309
|
+
@partial(jax.jit,static_argnums=9)
|
|
2310
|
+
def update_pos_jax(ppos,pvel,pacc,bonds,dt,box_size,plys,all_p_pad,all_p_lens,ngly):
|
|
2311
|
+
pacc = calc_acc_jax(ppos,bonds,box_size)+prot_repul_jax(all_p_pad,ppos,plys,all_p_lens)
|
|
2312
|
+
pvel += pacc*dt+(-0.9*pvel*dt)
|
|
2313
|
+
ppos += pvel*dt
|
|
2314
|
+
ppos = enforce_pbc_jax(ppos,box_size)
|
|
2315
|
+
return ppos,pvel,pacc
|
|
2316
|
+
|
|
2317
|
+
#getting the total contraction/extention force over each bond
|
|
2318
|
+
@jax.jit
|
|
2319
|
+
def get_boxforce_jax(bonds,ppos,box_size):
|
|
2320
|
+
total_force = jnp.zeros(2)
|
|
2321
|
+
|
|
2322
|
+
def bfor_loop(total_force,ind):
|
|
2323
|
+
bind1 = jnp.array(bonds[ind,0],dtype=int)
|
|
2324
|
+
bind2 = jnp.array(bonds[ind,1],dtype=int)
|
|
2325
|
+
pa = ppos[bind1]
|
|
2326
|
+
pb = ppos[bind2]
|
|
2327
|
+
min_dist,part_copy = get_closest_pos_jax(pa,pb,box_size)
|
|
2328
|
+
|
|
2329
|
+
err_dist = bonds[ind,2]-min_dist
|
|
2330
|
+
direc = (pa-(pb+part_copy*box_size))/min_dist
|
|
2331
|
+
|
|
2332
|
+
force = err_dist*jnp.abs(direc)
|
|
2333
|
+
total_force += force
|
|
2334
|
+
return total_force,ind
|
|
2335
|
+
total_force,_ = jax.lax.scan(bfor_loop,total_force,jnp.arange(bonds.shape[0]))
|
|
2336
|
+
return total_force
|
|
2337
|
+
|
|
2338
|
+
|
|
2339
|
+
#resecaling coordinates when the box size changes
|
|
2340
|
+
@jax.jit
|
|
2341
|
+
def rescale_to_new_box_jax(ppos,old_boxsize,new_boxsize):
|
|
2342
|
+
def nbloop(ppos,ind):
|
|
2343
|
+
ppos = ppos.at[ind,0].set(((ppos[ind,0])/old_boxsize[0])*new_boxsize[0])
|
|
2344
|
+
ppos = ppos.at[ind,1].set(((ppos[ind,1])/old_boxsize[1])*new_boxsize[1])
|
|
2345
|
+
return ppos,ind
|
|
2346
|
+
ppos,_ = jax.lax.scan(nbloop,ppos,jnp.arange(ppos.shape[0]))
|
|
2347
|
+
return ppos
|
|
2348
|
+
|
|
2349
|
+
|
|
2350
|
+
#This is a large function that uses a basic physics model to relax the PG layer such that tension is 0 and there are no clashed with the protein
|
|
2351
|
+
def relax_pg(gposes,box_size,tol,all_p):
|
|
2352
|
+
nly = gposes.shape[0]
|
|
2353
|
+
gposes_temp = gposes.reshape((int(gposes.size/14),14))
|
|
2354
|
+
|
|
2355
|
+
particles_pos = []
|
|
2356
|
+
particle_layer = []
|
|
2357
|
+
bonds = []
|
|
2358
|
+
gly_lens = 1.0*50
|
|
2359
|
+
spep_lens = 1.5*50
|
|
2360
|
+
upep_lens = 1.2*50
|
|
2361
|
+
tupep_lens = 0.2*50
|
|
2362
|
+
|
|
2363
|
+
bond_next = False
|
|
2364
|
+
prev_x = 0
|
|
2365
|
+
prev_z = -1
|
|
2366
|
+
chx = 0
|
|
2367
|
+
pind_chx = 0
|
|
2368
|
+
for ind,pgpos in enumerate(gposes_temp):
|
|
2369
|
+
if pgpos[5] == 1:
|
|
2370
|
+
if pgpos[4] == 0:
|
|
2371
|
+
if bond_next and pgpos[0] == prev_x and pgpos[2] == prev_z:
|
|
2372
|
+
bonds.append([len(particles_pos),len(particles_pos)-1,gly_lens])
|
|
2373
|
+
if pgpos[0] != prev_x:
|
|
2374
|
+
a = gposes_temp[-1]
|
|
2375
|
+
b = gposes_temp[chx]
|
|
2376
|
+
if(a[5] == 1 and b[5] == 1):
|
|
2377
|
+
bonds.append([pind_chx,len(particles_pos)-1,gly_lens])
|
|
2378
|
+
chx = ind
|
|
2379
|
+
pind_chx = len(particles_pos)
|
|
2380
|
+
inder = np.unravel_index(ind,(gposes.shape[0],gposes.shape[1],gposes.shape[2]))
|
|
2381
|
+
gposes[inder[0],inder[1],inder[2],12] = len(particles_pos)
|
|
2382
|
+
particles_pos.append(pgpos[:2]*50)
|
|
2383
|
+
particle_layer.append(pgpos[2])
|
|
2384
|
+
bond_next = True
|
|
2385
|
+
prev_x = pgpos[0]
|
|
2386
|
+
prev_z = pgpos[2]
|
|
2387
|
+
else:
|
|
2388
|
+
bond_next = False
|
|
2389
|
+
|
|
2390
|
+
ngly = len(particles_pos)
|
|
2391
|
+
|
|
2392
|
+
a = gposes_temp[np.logical_and(gposes_temp[:,5] == 1,gposes_temp[:,4] == 0)][-1]
|
|
2393
|
+
b = gposes_temp[chx]
|
|
2394
|
+
if(a[5] == 1 and b[5] == 1):
|
|
2395
|
+
bonds.append([pind_chx,len(particles_pos)-1,gly_lens])
|
|
2396
|
+
|
|
2397
|
+
groups = count_all_olig_list(gposes)
|
|
2398
|
+
|
|
2399
|
+
nover_groups = []
|
|
2400
|
+
replace_ind = 0
|
|
2401
|
+
for xi,i in enumerate(groups):
|
|
2402
|
+
replace = False
|
|
2403
|
+
add = True
|
|
2404
|
+
for xk,k in enumerate(nover_groups):
|
|
2405
|
+
if(set(i) >= set(k)):
|
|
2406
|
+
replace = True
|
|
2407
|
+
replace_ind = xk
|
|
2408
|
+
add = False
|
|
2409
|
+
break
|
|
2410
|
+
if(set(i) <= set(k)):
|
|
2411
|
+
add = False
|
|
2412
|
+
break
|
|
2413
|
+
if add:
|
|
2414
|
+
nover_groups.append(i)
|
|
2415
|
+
if replace:
|
|
2416
|
+
nover_groups[replace_ind] = i
|
|
2417
|
+
|
|
2418
|
+
for i in nover_groups:
|
|
2419
|
+
if(len(i) == 2):
|
|
2420
|
+
_,part_copy = get_closest_pos(particles_pos[i[0]],particles_pos[i[1]],box_size)
|
|
2421
|
+
mean_part = (particles_pos[i[0]]+particles_pos[i[1]]+part_copy*box_size)/2.0
|
|
2422
|
+
bonds.append([len(particles_pos),i[0],spep_lens])
|
|
2423
|
+
bonds.append([len(particles_pos),i[1],upep_lens])
|
|
2424
|
+
particles_pos.append(mean_part)
|
|
2425
|
+
particle_layer.append(particle_layer[i[0]])
|
|
2426
|
+
if(len(i) > 2):
|
|
2427
|
+
part_in_group = []
|
|
2428
|
+
for k in i:
|
|
2429
|
+
part_in_group.append(particles_pos[k])
|
|
2430
|
+
part_in_group = np.array(part_in_group)
|
|
2431
|
+
ind_in_group = np.array(i)
|
|
2432
|
+
side1 = part_in_group[part_in_group[:,0] == part_in_group[0,0]]
|
|
2433
|
+
side2 = part_in_group[part_in_group[:,0] != part_in_group[0,0]]
|
|
2434
|
+
iside1 = ind_in_group[part_in_group[:,0] == part_in_group[0,0]]
|
|
2435
|
+
iside2 = ind_in_group[part_in_group[:,0] != part_in_group[0,0]]
|
|
2436
|
+
sind1 = np.argsort(side1[:,1])
|
|
2437
|
+
sind2 = np.argsort(side2[:,1])
|
|
2438
|
+
side1 = side1[sind1]
|
|
2439
|
+
side2 = side2[sind2]
|
|
2440
|
+
iside1 = iside1[sind1]
|
|
2441
|
+
iside2 = iside2[sind2]
|
|
2442
|
+
inter_group = np.empty((side1.shape[0] + side2.shape[0],2), dtype=side1.dtype)
|
|
2443
|
+
ind_inter_group = np.empty((iside1.size + iside2.size,), dtype=iside1.dtype)
|
|
2444
|
+
if(side1.size > side2.size):
|
|
2445
|
+
inter_group[0::2,:] = side1
|
|
2446
|
+
inter_group[1::2,:] = side2
|
|
2447
|
+
ind_inter_group[0::2] = iside1
|
|
2448
|
+
ind_inter_group[1::2] = iside2
|
|
2449
|
+
else:
|
|
2450
|
+
inter_group[0::2,:] = side2
|
|
2451
|
+
inter_group[1::2,:] = side1
|
|
2452
|
+
ind_inter_group[0::2] = iside2
|
|
2453
|
+
ind_inter_group[1::2] = iside1
|
|
2454
|
+
for k in range(len(i)-1):
|
|
2455
|
+
if(k != 0):
|
|
2456
|
+
bonds.append([len(particles_pos),ind_inter_group[k],upep_lens-tupep_lens])
|
|
2457
|
+
bonds.append([len(particles_pos),len(particles_pos)-1,tupep_lens])
|
|
2458
|
+
else:
|
|
2459
|
+
bonds.append([len(particles_pos),ind_inter_group[k],upep_lens])
|
|
2460
|
+
_,part_copy = get_closest_pos(inter_group[k],inter_group[k+1],box_size)
|
|
2461
|
+
mean_part = (inter_group[k]+inter_group[k+1]+part_copy*box_size)/2.0
|
|
2462
|
+
particles_pos.append(mean_part)
|
|
2463
|
+
particle_layer.append(particle_layer[ind_inter_group[k]])
|
|
2464
|
+
bonds.append([len(particles_pos)-1,ind_inter_group[-1],spep_lens])
|
|
2465
|
+
|
|
2466
|
+
ppos = jnp.array(particles_pos)
|
|
2467
|
+
plys = jnp.array(particle_layer)
|
|
2468
|
+
pvel = jnp.zeros_like(ppos)
|
|
2469
|
+
pacc = jnp.zeros_like(ppos)
|
|
2470
|
+
|
|
2471
|
+
box_size = jnp.array(box_size)
|
|
2472
|
+
bonds = jnp.array(bonds)
|
|
2473
|
+
|
|
2474
|
+
|
|
2475
|
+
ppos = enforce_pbc_jax(ppos,box_size)
|
|
2476
|
+
box_vel = jnp.zeros(2)
|
|
2477
|
+
box_dt = 0.2
|
|
2478
|
+
count = 0
|
|
2479
|
+
tforce_add = jnp.zeros(2)
|
|
2480
|
+
|
|
2481
|
+
tforce = get_boxforce_jax(bonds,ppos,box_size)/nly
|
|
2482
|
+
tcheck = tforce.copy()
|
|
2483
|
+
|
|
2484
|
+
all_p_lens = []
|
|
2485
|
+
max_len = 0
|
|
2486
|
+
for ap in all_p:
|
|
2487
|
+
if(ap.shape[0] > max_len):
|
|
2488
|
+
max_len = ap.shape[0]
|
|
2489
|
+
all_p_lens.append(ap.shape[0])
|
|
2490
|
+
all_p_lens = np.array(all_p_lens)
|
|
2491
|
+
for ap in range(all_p_lens.shape[0]):
|
|
2492
|
+
all_p[ap] = np.pad(all_p[ap],((0,max_len-all_p[ap].shape[0]),(0,0)),"constant",constant_values=((0,0),(0,0)))
|
|
2493
|
+
all_p_pad = jnp.array(all_p)
|
|
2494
|
+
all_p_lens = jnp.array(all_p_lens,dtype=int)
|
|
2495
|
+
if all_p_pad.shape[1] == 0:
|
|
2496
|
+
all_p_pad = jnp.zeros((all_p_pad.shape[0],1,3))
|
|
2497
|
+
|
|
2498
|
+
while np.linalg.norm(tcheck) > tol:
|
|
2499
|
+
try:
|
|
2500
|
+
count += 1
|
|
2501
|
+
ppos,pvel,pacc = update_pos_jax(ppos,pvel,pacc,bonds,0.3,box_size,plys,all_p_pad,all_p_lens,ngly)
|
|
2502
|
+
tforce = get_boxforce_jax(bonds,ppos,box_size)/nly
|
|
2503
|
+
old_box_size = box_size.copy()
|
|
2504
|
+
if(count % 40 == 0):
|
|
2505
|
+
#sc += 10
|
|
2506
|
+
box_vel += (tforce_add-box_vel*0.5)*box_dt
|
|
2507
|
+
box_size += (tforce_add)*box_dt
|
|
2508
|
+
ppos = rescale_to_new_box_jax(ppos,old_box_size,box_size)
|
|
2509
|
+
tforce_add = jnp.zeros(2)
|
|
2510
|
+
tcheck = tforce.copy()
|
|
2511
|
+
else:
|
|
2512
|
+
tforce_add = tforce
|
|
2513
|
+
except KeyboardInterrupt:
|
|
2514
|
+
break
|
|
2515
|
+
|
|
2516
|
+
ppos = np.array(ppos)
|
|
2517
|
+
box_size = np.array(box_size)
|
|
2518
|
+
|
|
2519
|
+
cind = 0
|
|
2520
|
+
for ind,pgpos in enumerate(gposes_temp):
|
|
2521
|
+
if pgpos[5] == 1:
|
|
2522
|
+
if pgpos[4] == 0:
|
|
2523
|
+
inder = np.unravel_index(ind,(gposes.shape[0],gposes.shape[1],gposes.shape[2]))
|
|
2524
|
+
gposes[inder[0],inder[1],inder[2],:2] = ppos[cind]
|
|
2525
|
+
cind += 1
|
|
2526
|
+
|
|
2527
|
+
for ly in gposes:
|
|
2528
|
+
for line in ly:
|
|
2529
|
+
for ind,pos in enumerate(line):
|
|
2530
|
+
if pos[5] == 1:
|
|
2531
|
+
if pos[4] == 1:
|
|
2532
|
+
ll = line.shape[0]
|
|
2533
|
+
if line[(ind+1)%ll][5] == 1:
|
|
2534
|
+
if line[(ind-1)%ll][5] == 1:
|
|
2535
|
+
_,pcpy = get_closest_pos(line[(ind+1)%ll][:2],line[(ind-1)%ll][:2],box_size)
|
|
2536
|
+
line[ind][:2] = enforce_pbc2(np.array([(line[(ind+1)%ll][:2]+line[(ind-1)%ll][:2]+pcpy*box_size)/2]),box_size)[0]
|
|
2537
|
+
else:
|
|
2538
|
+
_,pcpy = get_closest_pos(line[(ind+1)%ll][:2],line[(ind+3)%ll][:2],box_size)
|
|
2539
|
+
direc = line[(ind+1)%ll][:2]-(line[(ind+3)%ll][:2]+pcpy*box_size)
|
|
2540
|
+
direc /= np.linalg.norm(direc)
|
|
2541
|
+
direc = np.array([0,-1])
|
|
2542
|
+
line[ind][:2]=enforce_pbc2(np.array([50*0.5*direc+line[(ind+1)%ll][:2]]),box_size)[0]
|
|
2543
|
+
|
|
2544
|
+
gposes[:,:,:,:2] /= 50
|
|
2545
|
+
return box_size,gposes
|
|
2546
|
+
|
|
2547
|
+
|
|
2548
|
+
#This function uses a flood fill algorithm to identifiy the inside of a protein. This works better than the basic method used in ring.
|
|
2549
|
+
def flood_fill(grid,add_in):
|
|
2550
|
+
to_test = [[0,0]]
|
|
2551
|
+
done = []
|
|
2552
|
+
flagged = np.zeros_like(grid)
|
|
2553
|
+
while len(to_test) > 0:
|
|
2554
|
+
ct = to_test[0]
|
|
2555
|
+
if add_in:
|
|
2556
|
+
flagged[ct[0],ct[1]] = 1
|
|
2557
|
+
if grid[ct[0],ct[1]] == 0:
|
|
2558
|
+
flagged[ct[0],ct[1]] = 1
|
|
2559
|
+
poss_tests = [[ct[0]-1,ct[1]],[ct[0]+1,ct[1]],[ct[0],ct[1]+1],[ct[0],ct[1]-1]]
|
|
2560
|
+
for i in poss_tests:
|
|
2561
|
+
if i[0] >= 0 and i[1] >= 0 and i[0] < grid.shape[0] and i[1] < grid.shape[1]:
|
|
2562
|
+
already_done = False
|
|
2563
|
+
for d in done:
|
|
2564
|
+
if d[0] == i[0] and d[1] == i[1]:
|
|
2565
|
+
already_done = True
|
|
2566
|
+
break
|
|
2567
|
+
for d in to_test:
|
|
2568
|
+
if d[0] == i[0] and d[1] == i[1]:
|
|
2569
|
+
already_done = True
|
|
2570
|
+
break
|
|
2571
|
+
if not already_done:
|
|
2572
|
+
to_test.append(i)
|
|
2573
|
+
done.append(to_test[0])
|
|
2574
|
+
del to_test[0]
|
|
2575
|
+
return flagged
|
|
2576
|
+
|
|
2577
|
+
@jax.jit
|
|
2578
|
+
def place_bead(cen,rad,direc,SpGrid,points,tol):
|
|
2579
|
+
start_place = True
|
|
2580
|
+
def loop2(start_place,ind2):
|
|
2581
|
+
def placed(start_place):
|
|
2582
|
+
return start_place
|
|
2583
|
+
def nplaced(start_place):
|
|
2584
|
+
start_place = False
|
|
2585
|
+
return start_place
|
|
2586
|
+
start_place = jax.lax.cond(jnp.linalg.norm(cen-points[ind2])<tol,nplaced,placed,start_place)
|
|
2587
|
+
return start_place,ind2
|
|
2588
|
+
start_place,_ = jax.lax.scan(loop2,start_place,jnp.arange(points.shape[0]))
|
|
2589
|
+
def ncoll():
|
|
2590
|
+
upp = jnp.array([0,0,1])
|
|
2591
|
+
direc2 = direc+1e-4*jnp.linalg.norm(upp+direc)
|
|
2592
|
+
direc2 /= jnp.linalg.norm(direc2)
|
|
2593
|
+
angl = jnp.dot(-direc2,upp)
|
|
2594
|
+
|
|
2595
|
+
|
|
2596
|
+
v = jnp.cross(upp,-direc2)
|
|
2597
|
+
vmat = jnp.array([[0,-v[2],v[1]],[v[2],0,-v[0]],[-v[1],v[0],0]])
|
|
2598
|
+
rot_mat = jnp.eye(3)+vmat+jnp.dot(vmat,vmat)*1/(1+angl)
|
|
2599
|
+
|
|
2600
|
+
newSpGrid = jnp.dot(rot_mat,SpGrid.T).T
|
|
2601
|
+
newSpGrid = newSpGrid*rad+cen
|
|
2602
|
+
can_place = True
|
|
2603
|
+
stop = False
|
|
2604
|
+
new_pos = jnp.zeros(3,dtype=float)
|
|
2605
|
+
def loop1(carry,ind1):
|
|
2606
|
+
can_place = carry[1]
|
|
2607
|
+
new_pos = carry[0]
|
|
2608
|
+
stop = carry[2]
|
|
2609
|
+
def stopped(can_place,new_pos,stop):
|
|
2610
|
+
return can_place,new_pos,stop
|
|
2611
|
+
def nstopped(can_place,new_pos,stop):
|
|
2612
|
+
can_place = True
|
|
2613
|
+
def loop2(can_place,ind2):
|
|
2614
|
+
def placed(can_place):
|
|
2615
|
+
return can_place
|
|
2616
|
+
def nplaced(can_place):
|
|
2617
|
+
can_place = False
|
|
2618
|
+
return can_place
|
|
2619
|
+
can_place = jax.lax.cond(jnp.linalg.norm(newSpGrid[ind1]-points[ind2])<tol,nplaced,placed,can_place)
|
|
2620
|
+
return can_place,ind2
|
|
2621
|
+
can_place,_ = jax.lax.scan(loop2,can_place,jnp.arange(points.shape[0]))
|
|
2622
|
+
def cplace(new_pos,stop):
|
|
2623
|
+
new_pos = newSpGrid[ind1]
|
|
2624
|
+
stop = True
|
|
2625
|
+
return new_pos,stop
|
|
2626
|
+
def ncplace(new_pos,stop):
|
|
2627
|
+
return new_pos,stop
|
|
2628
|
+
new_pos,stop = jax.lax.cond(can_place,cplace,ncplace,new_pos,stop)
|
|
2629
|
+
return can_place,new_pos,stop
|
|
2630
|
+
can_place,new_pos,stop = jax.lax.cond(stop,stopped,nstopped,can_place,new_pos,stop)
|
|
2631
|
+
return (new_pos,can_place,stop),ind1
|
|
2632
|
+
carry,_=jax.lax.scan(loop1,(new_pos,can_place,stop),jnp.arange(newSpGrid.shape[0]))
|
|
2633
|
+
new_pos = carry[0]
|
|
2634
|
+
can_place = carry[1]
|
|
2635
|
+
return new_pos,can_place
|
|
2636
|
+
def coll():
|
|
2637
|
+
return jnp.zeros(3),False
|
|
2638
|
+
new_pos,can_place = jax.lax.cond(start_place,ncoll,coll)
|
|
2639
|
+
return new_pos,can_place
|
|
2640
|
+
|
|
2641
|
+
tm = []
|
|
2642
|
+
lipL = []
|
|
2643
|
+
lipU = []
|
|
2644
|
+
lipL_loc = []
|
|
2645
|
+
lipU_loc = []
|
|
2646
|
+
lipLO = []
|
|
2647
|
+
lipUO = []
|
|
2648
|
+
solv = []
|
|
2649
|
+
pos_ions = [[],[],[]]
|
|
2650
|
+
neg_ions = [[],[],[]]
|
|
2651
|
+
|
|
2652
|
+
# HII edit - lipid definition, for extra lipid definitaions
|
|
2653
|
+
usrmols = []
|
|
2654
|
+
usrheads = []
|
|
2655
|
+
usrlinks = []
|
|
2656
|
+
usrtails = []
|
|
2657
|
+
usrLipHeadMapp = { # Define supported lipid head beads. One letter name mapped to atom name
|
|
2658
|
+
"C": ('NC3'), # NC3 = Choline
|
|
2659
|
+
"E": ('NH3'), # NH3 = Ethanolamine
|
|
2660
|
+
"G": ('GL0'), # GL0 = Glycerol
|
|
2661
|
+
"S": ('CNO'), # CNO = Serine
|
|
2662
|
+
"P": ('PO4'), # PO4 = Phosphate
|
|
2663
|
+
"O": ('PO4') # PO4 = Phosphate acid
|
|
2664
|
+
}
|
|
2665
|
+
usrIndexToLetter = "A B C D E F G H I J K L M N".split() # For naming lipid tail beads
|
|
2666
|
+
|
|
2667
|
+
# Description
|
|
2668
|
+
desc = ""
|
|
2669
|
+
|
|
2670
|
+
# Option list
|
|
2671
|
+
options = [
|
|
2672
|
+
# option type number default description
|
|
2673
|
+
# HII edit - lipid definition (last options are for additional lipid specification)
|
|
2674
|
+
"""
|
|
2675
|
+
Input/output related options
|
|
2676
|
+
""",
|
|
2677
|
+
("-f", Option(tm.append, 1, None, "Input GRO or PDB file 1: Protein")),
|
|
2678
|
+
("-o", Option(str, 1, None, "Output GRO file: Membrane with Protein")),
|
|
2679
|
+
("-o_f", Option(str, 1, None, "Folder for additional files (Default: InsaneData)")),
|
|
2680
|
+
("-p", Option(str, 1, None, "Optional rudimentary topology file")),
|
|
2681
|
+
("-ct", Option(str, 1, None, "This will create a template of the membrane only.")),
|
|
2682
|
+
("-in_t", Option(str, 1, None, "Input template for placement of multiple proteins.")),
|
|
2683
|
+
("-fs", Option(str, 1, None, "Input text file with multiple proteins")),
|
|
2684
|
+
"""
|
|
2685
|
+
Options related to system size. It is reccomended to use -x, -y, -z only.
|
|
2686
|
+
Many options that were available here have been removed and will be readded
|
|
2687
|
+
at a later date.
|
|
2688
|
+
""",
|
|
2689
|
+
("-d", Option(float, 1, 0, "Distance between periodic images (nm)")),
|
|
2690
|
+
("-dz", Option(float, 1, 0, "Z distance between periodic images (nm)")),
|
|
2691
|
+
("-x", Option(vector, 1, 0, "X dimension or first lattice vector of system (nm)")),
|
|
2692
|
+
("-y", Option(vector, 1, 0, "Y dimension or first lattice vector of system (nm)")),
|
|
2693
|
+
("-z", Option(vector, 1, 0, "Z dimension or first lattice vector of system (nm)")),
|
|
2694
|
+
("-box", Option(readBox, 1, None, "Box in GRO (3 or 9 floats) or PDB (6 floats) format, comma separated")),
|
|
2695
|
+
("-n", Option(str, 1, None, "Index file --- TO BE IMPLEMENTED")),
|
|
2696
|
+
"""
|
|
2697
|
+
Membrane/lipid related options.
|
|
2698
|
+
The options -l and -u can be given multiple times. Option -u can be
|
|
2699
|
+
used to set the lipid type and abundance for the upper leaflet. Option
|
|
2700
|
+
-l sets the type and abundance for the lower leaflet if option -u is
|
|
2701
|
+
also given, or for both leaflets if option -u is not given. -lo and -uo
|
|
2702
|
+
behave as -l and -u except -l can set abundance for -lo and -uo is these
|
|
2703
|
+
are not specified. Curvature can be specified using -curv.
|
|
2704
|
+
""",
|
|
2705
|
+
("-l", Option(lipL.append, 1, None, "Lipid type and relative abundance (NAME[:#])")),
|
|
2706
|
+
("-u", Option(lipU.append, 1, None, "Lipid type and relative abundance (NAME[:#])")),
|
|
2707
|
+
("-lo", Option(lipLO.append, 1, None, "Lipid type and relative abundance (For double membrane definitions) (NAME[:#])")),
|
|
2708
|
+
("-uo", Option(lipUO.append, 1, None, "Lipid type and relative abundance (For double membrane definitions) (NAME[:#])")),
|
|
2709
|
+
("-a", Option(float, 1, 0.60, "Area per lipid (nm*nm)")),
|
|
2710
|
+
("-au", Option(float, 1, None, "Area per lipid (nm*nm) for upper layer")),
|
|
2711
|
+
("-ao", Option(float, 1, None, "Area per lipid (nm*nm) for outer membrane")),
|
|
2712
|
+
("-auo", Option(float, 1, None, "Area per lipid (nm*nm) for outer membrane upper layer")),
|
|
2713
|
+
("-asym", Option(int, 1, None, "Membrane asymmetry (number of lipids)")),
|
|
2714
|
+
("-rand", Option(float, 1, 0.1, "Random kick size (maximum atom displacement)")),
|
|
2715
|
+
("-bd", Option(float, 1, 0.3, "Bead distance unit for scaling z-coordinates (nm)")),
|
|
2716
|
+
("-ps", Option(float, 1, 0, "Specifies the distance (nm) between inner and outer membrane, when set to 0 only a single membrane is built")),
|
|
2717
|
+
("-curv", Option(str, 1, "0,0,1", "Curvature of the membrane, consists of 3 comma separated values. The curvature at the middle the curvature as it relaxes back to planar and the direction of the curvature.")),
|
|
2718
|
+
("-curv_o", Option(str, 1, "0,0,1", "Curvature of the outer membrane, see -curv")),
|
|
2719
|
+
("-curv_ext", Option(float, 1, 3, "Extent of curved region in the absence of a protein.")),
|
|
2720
|
+
#("-pore", Option(bool, 0, None, "Create a pore, with inner radius equal to -curv_ext and length equal to -ps")),
|
|
2721
|
+
("-loc", Option(str, 1, None, "Currently WIP do not use. Input .npz for localisation data to bias lipid arangment.")),
|
|
2722
|
+
("-l_loc", Option(lipL_loc.append, 1, None, "Currently WIP do not use. Lipid type for localisation")),
|
|
2723
|
+
("-u_loc", Option(lipU_loc.append, 1, None, "Currently WIP do not use. Lipid type for localisation")),
|
|
2724
|
+
("-micelle", Option(bool, 0, None, "Builds a micelle around a protein instead of a bilayer")),
|
|
2725
|
+
("-radius", Option(float, 1, -1, "Radius of membrane outer disk. This is by default the whole cell")),
|
|
2726
|
+
("-no_lipids", Option(int, 1, -1, "Number of lipids that make up a micelle, this will override area per lipid. Only for use with -micelle")),
|
|
2727
|
+
("-def", Option(str, 1, None, "Input folder containing deformation data from MemPrOD, This cannot be used with -ps or -curv.")),
|
|
2728
|
+
"""
|
|
2729
|
+
Peptidoglycan layer related options.
|
|
2730
|
+
""",
|
|
2731
|
+
|
|
2732
|
+
("-pgl", Option(int, 1, 0, "Number of PG layers to place at -pgl_z.")),
|
|
2733
|
+
("-pgl_z", Option(float, 1, 0, "Z position of PG layer relative to center of periplasmic space.")),
|
|
2734
|
+
("-cper", Option(float, 1, 0.4, "Percentage of crosslinks.")),
|
|
2735
|
+
("-lper", Option(float, 1, 0.1, "Percentage of crosslinks that are between layers.")),
|
|
2736
|
+
("-per33", Option(float, 1, 0.03, "Percentage of 3-3 crosslinks, all other crosslinks will be 3-4.")),
|
|
2737
|
+
("-oper", Option(float, 1, 1, "Percentage chance of a monomer linking with a oligomer. (Actual change of link is cper*oper)")),
|
|
2738
|
+
("-gdist", Option(str, 1, "0.75,4,8.9,0.25,10,45", "Distribution of glycan strand lengths. Format as weight 1,standard deviation 1,mean 1,weight 2..., were each triple describes a gaussian. The sum of these forms the distribution.")),
|
|
2739
|
+
"""
|
|
2740
|
+
Protein related options. -fudge gives the exclusion radius around the protein.
|
|
2741
|
+
""",
|
|
2742
|
+
("-center", Option(bool, 0, None, "Center the protein on z")),
|
|
2743
|
+
("-rotate", Option(str, 1, None, "Rotate protein (random|princ|angle(float))")),
|
|
2744
|
+
("-fudge", Option(float, 1, 0.3, "Fudge factor for allowing lipid-protein overlap. Recommended value when using -def is 0.15")),
|
|
2745
|
+
("-ring", Option(bool, 0, None, "Put lipids inside the protein")),
|
|
2746
|
+
("-dm", Option(float, 1, None, "Shift protein with respect to membrane")),
|
|
2747
|
+
"""
|
|
2748
|
+
Solvent related options.
|
|
2749
|
+
""",
|
|
2750
|
+
("-sol", Option(solv.append, 1, None, "Solvent type and relative abundance (NAME[:#])")),
|
|
2751
|
+
("-sold", Option(float, 1, 0.5, "Solvent diameter")),
|
|
2752
|
+
("-solr", Option(float, 1, 0.1, "Solvent random kick")),
|
|
2753
|
+
("-excl", Option(float, 1, 1.5, "Exclusion range (nm) for solvent addition relative to membrane center")),
|
|
2754
|
+
("-anti_freeze", Option(float, 1, 0.2, "Rate at which to remove solvent to avoid freezing due to hexagonal lattice.")),
|
|
2755
|
+
"""
|
|
2756
|
+
Charge related options.
|
|
2757
|
+
""",
|
|
2758
|
+
("-posi_c0", Option(pos_ions[0].append, 1, None, "Positive ion type and relative abundance (NAME[:#]) in compartment 0")),
|
|
2759
|
+
("-negi_c0", Option(neg_ions[0].append, 1, None, "Negative ion type and relative abundance (NAME[:#]) in compartment 0")),
|
|
2760
|
+
("-posi_c1", Option(pos_ions[1].append, 1, None, "Positive ion type and relative abundance (NAME[:#]) in compartment 1")),
|
|
2761
|
+
("-negi_c1", Option(neg_ions[1].append, 1, None, "Negative ion type and relative abundance (NAME[:#]) in compartment 1")),
|
|
2762
|
+
("-posi_c2", Option(pos_ions[2].append, 1, None, "Positive ion type and relative abundance (NAME[:#]) in compartment 2")),
|
|
2763
|
+
("-negi_c2", Option(neg_ions[2].append, 1, None, "Negative ion type and relative abundance (NAME[:#]) in compartment 2")),
|
|
2764
|
+
("-ion_conc", Option(str, 1, "0.15,0.15,0.15", "Concentration of ions in each compartment")),
|
|
2765
|
+
("-charge", Option(str, 1, "auto", "Charge of system. Set to auto to infer from residue names")),
|
|
2766
|
+
("-charge_ratio", Option(str, 1, None, "Ratios of charge in each compartment")),
|
|
2767
|
+
("-zpbc", Option(bool, 0, None, "Toggles if water compartments are determined with pbc in the Z axis.")),
|
|
2768
|
+
"""
|
|
2769
|
+
Define additional lipid types (same format as in lipid-martini-itp-v01.py)
|
|
2770
|
+
""",
|
|
2771
|
+
("-alname", Option(usrmols.append, 1, None, "Additional lipid name, x4 letter")),
|
|
2772
|
+
("-alhead", Option(usrheads.append, 1, None, "Additional lipid head specification string")),
|
|
2773
|
+
("-allink", Option(usrlinks.append, 1, None, "Additional lipid linker specification string")),
|
|
2774
|
+
("-altail", Option(usrtails.append, 1, None, "Additional lipid tail specification string")),
|
|
2775
|
+
]
|
|
2776
|
+
|
|
2777
|
+
args = sys.argv[1:]
|
|
2778
|
+
|
|
2779
|
+
if '-h' in args or '--help' in args:
|
|
2780
|
+
print("\n",__file__)
|
|
2781
|
+
print(desc or "\nSomeone ought to write a description for this script...\n")
|
|
2782
|
+
for thing in options:
|
|
2783
|
+
print(type(thing) != str and "%10s %s"%(thing[0],thing[1].description) or thing)
|
|
2784
|
+
print("")
|
|
2785
|
+
sys.exit()
|
|
2786
|
+
|
|
2787
|
+
|
|
2788
|
+
# Convert the option list to a dictionary, discarding all comments
|
|
2789
|
+
options = dict([i for i in options if not type(i) == str])
|
|
2790
|
+
|
|
2791
|
+
|
|
2792
|
+
|
|
2793
|
+
# Process the command line
|
|
2794
|
+
while args:
|
|
2795
|
+
ar = args.pop(0)
|
|
2796
|
+
options[ar].setvalue([args.pop(0) for i in range(options[ar].num)])
|
|
2797
|
+
|
|
2798
|
+
|
|
2799
|
+
|
|
2800
|
+
absoluteNumbers = not options["-d"]
|
|
2801
|
+
|
|
2802
|
+
|
|
2803
|
+
out_folder = options["-o_f"].value
|
|
2804
|
+
if not out_folder:
|
|
2805
|
+
out_folder = "InsaneData/"
|
|
2806
|
+
|
|
2807
|
+
if out_folder[-1] != "/":
|
|
2808
|
+
out_folder += "/"
|
|
2809
|
+
if(not os.path.exists(out_folder)):
|
|
2810
|
+
os.mkdir(out_folder)
|
|
2811
|
+
|
|
2812
|
+
SpGrid = jnp.array(SphereGridAng(20,np.pi/2))
|
|
2813
|
+
#print(SpGrid)
|
|
2814
|
+
|
|
2815
|
+
memdata = options["-def"].value
|
|
2816
|
+
if memdata:
|
|
2817
|
+
mdata = np.load(memdata+"Membrane_pos.npz")
|
|
2818
|
+
membrane_pos = mdata["arr_0"]
|
|
2819
|
+
mdata2 = np.load(memdata+"Rotation_matrix.npz")
|
|
2820
|
+
rot_mat_def = mdata2["arr_0"]
|
|
2821
|
+
mdata5 = np.load(memdata+"Z_change.npz")
|
|
2822
|
+
z_change = mdata5["arr_0"]
|
|
2823
|
+
mdata3 = np.load(memdata+"Xlin.npz")
|
|
2824
|
+
xlin_def = mdata3["arr_0"]
|
|
2825
|
+
mdata4 = np.load(memdata+"Ylin.npz")
|
|
2826
|
+
ylin_def = mdata4["arr_0"]
|
|
2827
|
+
else:
|
|
2828
|
+
membrane_pos = 0
|
|
2829
|
+
rot_mat_def = np.eye(3)
|
|
2830
|
+
xlin_def = 0
|
|
2831
|
+
ylin_def = 0
|
|
2832
|
+
z_change = 0
|
|
2833
|
+
|
|
2834
|
+
|
|
2835
|
+
|
|
2836
|
+
# HII edit - lipid definition
|
|
2837
|
+
# Add specified lipid definition to insane lipid library
|
|
2838
|
+
for name, head, link, tail in list(zip(usrmols,usrheads,usrlinks,usrtails)):
|
|
2839
|
+
moltype = "usr_"+name
|
|
2840
|
+
lipidsx[moltype] = []
|
|
2841
|
+
lipidsy[moltype] = []
|
|
2842
|
+
lipidsz[moltype] = []
|
|
2843
|
+
headArray = (head).split()
|
|
2844
|
+
linkArray = (link).split()
|
|
2845
|
+
tailsArray = (tail).split()
|
|
2846
|
+
lipidDefString = ""
|
|
2847
|
+
|
|
2848
|
+
if len(tailsArray) != len(linkArray):
|
|
2849
|
+
print("Error, Number of tails has to equal number of linkers")
|
|
2850
|
+
sys.exit()
|
|
2851
|
+
|
|
2852
|
+
# Find longest tail
|
|
2853
|
+
maxTail = 0
|
|
2854
|
+
for cTail in tailsArray:
|
|
2855
|
+
if len(cTail) > maxTail:
|
|
2856
|
+
maxTail = len(cTail)
|
|
2857
|
+
cBeadZ = maxTail + len(headArray) # longest tail + linker (always x1) + lengths of all heads - 1 (as it starts on 0)
|
|
2858
|
+
|
|
2859
|
+
# Add head beads
|
|
2860
|
+
for cHead in headArray:
|
|
2861
|
+
lipidsx[moltype].append(0)
|
|
2862
|
+
lipidsy[moltype].append(0)
|
|
2863
|
+
lipidsz[moltype].append(cBeadZ)
|
|
2864
|
+
cBeadZ -= 1
|
|
2865
|
+
lipidDefString += usrLipHeadMapp[cHead] + " "
|
|
2866
|
+
|
|
2867
|
+
# Add linkers
|
|
2868
|
+
for i,cLinker in enumerate(linkArray):
|
|
2869
|
+
lipidsx[moltype].append(max(i-0.5,0))
|
|
2870
|
+
lipidsy[moltype].append(0)
|
|
2871
|
+
lipidsz[moltype].append(cBeadZ)
|
|
2872
|
+
if cLinker == 'G':
|
|
2873
|
+
lipidDefString += "GL" + str(i+1) + " "
|
|
2874
|
+
elif cLinker == 'A':
|
|
2875
|
+
lipidDefString += "AM" + str(i+1) + " "
|
|
2876
|
+
else:
|
|
2877
|
+
print("Error, linker type not supported")
|
|
2878
|
+
sys.exit()
|
|
2879
|
+
|
|
2880
|
+
# Add tails
|
|
2881
|
+
for i,cTail in enumerate(tailsArray):
|
|
2882
|
+
cBeadZ = maxTail - 1
|
|
2883
|
+
|
|
2884
|
+
for j,cTailBead in enumerate(cTail):
|
|
2885
|
+
lipidsx[moltype].append(i)
|
|
2886
|
+
lipidsy[moltype].append(0)
|
|
2887
|
+
lipidsz[moltype].append(cBeadZ)
|
|
2888
|
+
cBeadZ -= 1
|
|
2889
|
+
lipidDefString += cTailBead + str(j+1) + usrIndexToLetter[i] + " "
|
|
2890
|
+
|
|
2891
|
+
lipidsa[name] = (moltype,lipidDefString)
|
|
2892
|
+
# End user lipid definition
|
|
2893
|
+
|
|
2894
|
+
|
|
2895
|
+
# HII edit - lipid definition, had to move this one below the user lipid definitions to scale them to.
|
|
2896
|
+
# First all X/Y coordinates of templates are centered and scaled (magic numbers!)
|
|
2897
|
+
for i in lipidsx.keys():
|
|
2898
|
+
cx = (min(lipidsx[i])+max(lipidsx[i]))/2
|
|
2899
|
+
lipidsx[i] = [0.25*(j-cx) for j in lipidsx[i]]
|
|
2900
|
+
cy = (min(lipidsy[i])+max(lipidsy[i]))/2
|
|
2901
|
+
lipidsy[i] = [0.25*(j-cy) for j in lipidsy[i]]
|
|
2902
|
+
|
|
2903
|
+
|
|
2904
|
+
# Periodic boundary conditions
|
|
2905
|
+
|
|
2906
|
+
# option -box overrides everything
|
|
2907
|
+
if options["-box"].value:
|
|
2908
|
+
options["-x"].value = options["-box"].value[:3]
|
|
2909
|
+
options["-y"].value = options["-box"].value[3:6]
|
|
2910
|
+
options["-z"].value = options["-box"].value[6:]
|
|
2911
|
+
|
|
2912
|
+
|
|
2913
|
+
mem_outer_red = options["-radius"].value
|
|
2914
|
+
|
|
2915
|
+
Num_PGL = options["-pgl"].value
|
|
2916
|
+
Pos_PGL = options["-pgl_z"].value
|
|
2917
|
+
cper = options["-cper"].value
|
|
2918
|
+
lper = options["-lper"].value
|
|
2919
|
+
per33 = options["-per33"].value
|
|
2920
|
+
oper = options["-oper"].value
|
|
2921
|
+
gdist_str = options["-gdist"].value
|
|
2922
|
+
|
|
2923
|
+
gdist = gdist_str.split(",")
|
|
2924
|
+
gdist = np.array(gdist,dtype=float)
|
|
2925
|
+
gdist = gdist.reshape(int(gdist.size/3),3)
|
|
2926
|
+
|
|
2927
|
+
|
|
2928
|
+
|
|
2929
|
+
anti_freeze = options["-anti_freeze"].value
|
|
2930
|
+
|
|
2931
|
+
is_micelle = options["-micelle"].value
|
|
2932
|
+
|
|
2933
|
+
if(is_micelle is not None):
|
|
2934
|
+
is_micelle = True
|
|
2935
|
+
else:
|
|
2936
|
+
is_micelle = False
|
|
2937
|
+
|
|
2938
|
+
|
|
2939
|
+
# options -x, -y, -z take precedence over automatic determination
|
|
2940
|
+
pbcSetX = 0
|
|
2941
|
+
if type(options["-x"].value) in (list,tuple):
|
|
2942
|
+
pbcSetX = options["-x"].value
|
|
2943
|
+
elif options["-x"].value:
|
|
2944
|
+
pbcSetX = [options["-x"].value,0,0]
|
|
2945
|
+
|
|
2946
|
+
pbcSetY = 0
|
|
2947
|
+
if type(options["-y"].value) in (list,tuple):
|
|
2948
|
+
pbcSetY = options["-y"].value
|
|
2949
|
+
elif options["-y"].value:
|
|
2950
|
+
pbcSetY = [0,options["-y"].value,0]
|
|
2951
|
+
|
|
2952
|
+
pbcSetZ = 0
|
|
2953
|
+
if type(options["-z"].value) in (list,tuple):
|
|
2954
|
+
pbcSetZ = options["-z"].value
|
|
2955
|
+
elif options["-z"].value:
|
|
2956
|
+
pbcSetZ = [0,0,options["-z"].value]
|
|
2957
|
+
|
|
2958
|
+
|
|
2959
|
+
|
|
2960
|
+
|
|
2961
|
+
################
|
|
2962
|
+
## I. PROTEIN ##
|
|
2963
|
+
################
|
|
2964
|
+
|
|
2965
|
+
|
|
2966
|
+
protein = Structure()
|
|
2967
|
+
protein_lip = Structure()
|
|
2968
|
+
prot = []
|
|
2969
|
+
xshifts = [0] # Shift in x direction per protein
|
|
2970
|
+
|
|
2971
|
+
#Reading and processing inputs
|
|
2972
|
+
|
|
2973
|
+
double_mem = False
|
|
2974
|
+
if(options["-ps"].value > 1e-5):
|
|
2975
|
+
double_mem = True
|
|
2976
|
+
using_temp = False
|
|
2977
|
+
if(options["-fs"].value is not None):
|
|
2978
|
+
using_temp = True
|
|
2979
|
+
|
|
2980
|
+
zpbc = False
|
|
2981
|
+
if(options["-zpbc"].value is not None):
|
|
2982
|
+
zpbc = True
|
|
2983
|
+
|
|
2984
|
+
|
|
2985
|
+
#add_pore = options["-pore"].value
|
|
2986
|
+
#if(add_pore is not None):
|
|
2987
|
+
# add_pore = True
|
|
2988
|
+
#else:
|
|
2989
|
+
# add_pore = False
|
|
2990
|
+
add_pore = False
|
|
2991
|
+
|
|
2992
|
+
zdist = float(options["-ps"].value)
|
|
2993
|
+
|
|
2994
|
+
curv_vals = options["-curv"].value.split(",")
|
|
2995
|
+
curvo_vals = options["-curv_o"].value.split(",")
|
|
2996
|
+
|
|
2997
|
+
|
|
2998
|
+
curv_vals_np = np.zeros(3)
|
|
2999
|
+
curv_vals_np[2] += 1
|
|
3000
|
+
|
|
3001
|
+
if(len(curv_vals) == 1):
|
|
3002
|
+
curv_vals_np[0] = float(curv_vals[0])
|
|
3003
|
+
curv_vals_np[1] = float(curv_vals[0])
|
|
3004
|
+
elif(len(curv_vals) == 2):
|
|
3005
|
+
curv_vals_np[0] = float(curv_vals[0])
|
|
3006
|
+
curv_vals_np[1] = float(curv_vals[1])
|
|
3007
|
+
elif(len(curv_vals) == 3):
|
|
3008
|
+
curv_vals_np[0] = float(curv_vals[0])
|
|
3009
|
+
curv_vals_np[1] = float(curv_vals[1])
|
|
3010
|
+
curv_vals_np[2] = float(curv_vals[2])
|
|
3011
|
+
|
|
3012
|
+
curvo_vals_np = np.zeros(3)
|
|
3013
|
+
curvo_vals_np[2] += 1
|
|
3014
|
+
|
|
3015
|
+
if(len(curvo_vals) == 1):
|
|
3016
|
+
curvo_vals_np[0] = float(curvo_vals[0])
|
|
3017
|
+
curvo_vals_np[1] = float(curvo_vals[0])
|
|
3018
|
+
elif(len(curvo_vals) == 2):
|
|
3019
|
+
curvo_vals_np[0] = float(curvo_vals[0])
|
|
3020
|
+
curvo_vals_np[1] = float(curvo_vals[1])
|
|
3021
|
+
elif(len(curvo_vals) == 3):
|
|
3022
|
+
curvo_vals_np[0] = float(curvo_vals[0])
|
|
3023
|
+
curvo_vals_np[1] = float(curvo_vals[1])
|
|
3024
|
+
curvo_vals_np[2] = float(curvo_vals[2])
|
|
3025
|
+
|
|
3026
|
+
|
|
3027
|
+
|
|
3028
|
+
|
|
3029
|
+
rcurvs_mid = np.array([curv_vals_np[1],curvo_vals_np[1]])
|
|
3030
|
+
curvs_mid = np.array([curv_vals_np[0],curvo_vals_np[0]])
|
|
3031
|
+
|
|
3032
|
+
if(add_pore):
|
|
3033
|
+
if(rcurvs_mid[0] < 1e-5):
|
|
3034
|
+
print("WARNING: Return curvature (inner) cannot be 0 setting to 0.1")
|
|
3035
|
+
rcurvs_mid[0] = 0.1
|
|
3036
|
+
if(rcurvs_mid[1] < 1e-5):
|
|
3037
|
+
print("WARNING: Return curvature (outer) cannot be 0 setting to 0.1")
|
|
3038
|
+
rcurvs_mid[1] = 0.1
|
|
3039
|
+
|
|
3040
|
+
if(add_pore):
|
|
3041
|
+
cdirs = [1,-1]
|
|
3042
|
+
else:
|
|
3043
|
+
cdirs = [float(curv_vals[2]),float(curvo_vals[2])]
|
|
3044
|
+
|
|
3045
|
+
if(curvs_mid[0] < 1e-5):
|
|
3046
|
+
ncurves = np.zeros(2)
|
|
3047
|
+
else:
|
|
3048
|
+
ncurves = np.array([1/((1/curvs_mid[0])+2),1/((1/curvs_mid[0])-2)])
|
|
3049
|
+
|
|
3050
|
+
if(curvs_mid[1] < 1e-5):
|
|
3051
|
+
ncurves_o = np.zeros(2)
|
|
3052
|
+
else:
|
|
3053
|
+
ncurves_o = np.array([1/((1/curvs_mid[1])+2),1/((1/curvs_mid[1])-2)])
|
|
3054
|
+
|
|
3055
|
+
curv_up = np.array([ncurves[0],ncurves_o[0]])
|
|
3056
|
+
curv_lo = np.array([ncurves[1],ncurves_o[1]])
|
|
3057
|
+
|
|
3058
|
+
if(rcurvs_mid[0] < 1e-5):
|
|
3059
|
+
nrcurves = np.zeros(2)
|
|
3060
|
+
else:
|
|
3061
|
+
nrcurves = np.array([1/((1/rcurvs_mid[0])+2),1/((1/rcurvs_mid[0])-2)])
|
|
3062
|
+
|
|
3063
|
+
if(rcurvs_mid[1] < 1e-5):
|
|
3064
|
+
nrcurves_o = np.zeros(2)
|
|
3065
|
+
else:
|
|
3066
|
+
nrcurves_o = np.array([1/((1/rcurvs_mid[1])+2),1/((1/rcurvs_mid[1])-2)])
|
|
3067
|
+
|
|
3068
|
+
rcurv_up = np.array([nrcurves[1],nrcurves_o[1]])
|
|
3069
|
+
rcurv_lo = np.array([nrcurves[0],nrcurves_o[0]])
|
|
3070
|
+
|
|
3071
|
+
|
|
3072
|
+
extent= float(options["-curv_ext"].value)
|
|
3073
|
+
if(add_pore):
|
|
3074
|
+
for i in range(2):
|
|
3075
|
+
curvs_mid[i] = 1/extent
|
|
3076
|
+
|
|
3077
|
+
prot_dirs = []
|
|
3078
|
+
prot_rings = []
|
|
3079
|
+
|
|
3080
|
+
|
|
3081
|
+
|
|
3082
|
+
|
|
3083
|
+
if not tm or options["-ct"].value != None or using_temp:
|
|
3084
|
+
|
|
3085
|
+
ang_exts = np.array([np.arcsin(curvs_mid[0]*extent),np.arcsin(curvs_mid[1]*extent)])
|
|
3086
|
+
resi = 0
|
|
3087
|
+
bsize,bheight = get_box_size(curvs_mid[0],rcurvs_mid[0],ang_exts[0],add_pore)
|
|
3088
|
+
|
|
3089
|
+
|
|
3090
|
+
if(pbcSetX[0] < bsize*2+2):
|
|
3091
|
+
pbcSetX[0] = bsize*2+2
|
|
3092
|
+
if(pbcSetY[1] < bsize*2+2):
|
|
3093
|
+
pbcSetY[1] = bsize*2+2
|
|
3094
|
+
|
|
3095
|
+
pbcx = pbcSetX and pbcSetX[0]
|
|
3096
|
+
pbcy = pbcSetY and pbcSetY[1]
|
|
3097
|
+
pbcz = pbcSetZ and pbcSetZ[2]
|
|
3098
|
+
|
|
3099
|
+
## B. PROTEIN ---
|
|
3100
|
+
#for writing a template for muliple protein placments
|
|
3101
|
+
if(options["-ct"].value != None):
|
|
3102
|
+
print("Writing template file...")
|
|
3103
|
+
new_file = open(options["-ct"].value,"w")
|
|
3104
|
+
count = 0
|
|
3105
|
+
trufal = [True,False]
|
|
3106
|
+
ang_exts = np.array([np.arcsin(curvs_mid[0]*extent),np.arcsin(curvs_mid[1]*extent)])
|
|
3107
|
+
for i in range(2):
|
|
3108
|
+
if(i == 0 or double_mem):
|
|
3109
|
+
if(add_pore):
|
|
3110
|
+
inner_leng = zdist-(1/rcurvs_mid[i])
|
|
3111
|
+
else:
|
|
3112
|
+
inner_leng = 0
|
|
3113
|
+
temp_points,direcs = create_leaflet(4,pbcx/2,pbcy/2,curvs_mid[i],rcurvs_mid[i],ang_exts[i],add_pore,inner_leng,trufal[i],mem_outer_red)
|
|
3114
|
+
if(cdirs[i] > 0):
|
|
3115
|
+
temp_points[:,2] = -temp_points[:,2]
|
|
3116
|
+
direcs[:,2] = -direcs[:,2]
|
|
3117
|
+
|
|
3118
|
+
temp_points =(temp_points+np.array([pbcx/2,pbcy/2,zdist*(2*i-1)]))*10
|
|
3119
|
+
for gp in temp_points:
|
|
3120
|
+
count += 1
|
|
3121
|
+
count_str = (6-len(str(count)))*" "+str(count)
|
|
3122
|
+
c = "ATOM "+count_str+" BB DUM 1 0.000 0.000 15.000 1.00 0.00"
|
|
3123
|
+
xp = np.format_float_positional(gp[0],precision=3)
|
|
3124
|
+
yp = np.format_float_positional(gp[1],precision=3)
|
|
3125
|
+
zp = np.format_float_positional(gp[2],precision=3)
|
|
3126
|
+
xp += "0"*(3-len((xp.split(".")[1])))
|
|
3127
|
+
yp += "0"*(3-len((yp.split(".")[1])))
|
|
3128
|
+
zp += "0"*(3-len((zp.split(".")[1])))
|
|
3129
|
+
new_c = c[:30]+(" "*(8-len(xp)))+xp+(" "*(8-len(yp)))+yp+(" "*(8-len(zp))) +zp+c[54:]+"\n"
|
|
3130
|
+
new_file.write(new_c)
|
|
3131
|
+
|
|
3132
|
+
new_file.close()
|
|
3133
|
+
info_fn = options["-ct"].value.split(".")[0]+".txt"
|
|
3134
|
+
info_file = open(info_fn,"w")
|
|
3135
|
+
info_file.write("Curvature values:"+options["-curv"].value+"\n")
|
|
3136
|
+
info_file.write("Outer curvature values:"+options["-curv_o"].value+"\n")
|
|
3137
|
+
info_file.write("Pore:"+str(add_pore)+"\n")
|
|
3138
|
+
info_file.write("X Y Z:"+str(options["-x"].value)+","+str(options["-y"].value)+","+str(options["-z"].value)+"\n")
|
|
3139
|
+
info_file.write("Box:"+str(options["-box"].value))
|
|
3140
|
+
info_file.close()
|
|
3141
|
+
print("Done!")
|
|
3142
|
+
exit()
|
|
3143
|
+
|
|
3144
|
+
|
|
3145
|
+
|
|
3146
|
+
if(using_temp):
|
|
3147
|
+
print("Extracting data from template...")
|
|
3148
|
+
#WHen a template is present it used to build membrane
|
|
3149
|
+
in_prots = options["-fs"].value
|
|
3150
|
+
prot_file = open(in_prots,"r")
|
|
3151
|
+
lines = prot_file.read().split("\n")
|
|
3152
|
+
prot_file.close()
|
|
3153
|
+
|
|
3154
|
+
|
|
3155
|
+
|
|
3156
|
+
temp_file = open(options["-in_t"].value,"r")
|
|
3157
|
+
temp_lines = temp_file.read().split("\n")
|
|
3158
|
+
temp_file.close()
|
|
3159
|
+
poses = np.zeros((len(lines),3))
|
|
3160
|
+
for tl in temp_lines:
|
|
3161
|
+
stl = tl.split()
|
|
3162
|
+
if(len(stl)>2):
|
|
3163
|
+
prot_no = int(float(stl[-2]))-1
|
|
3164
|
+
if(prot_no> -1):
|
|
3165
|
+
zpos = float(tl[46:54])
|
|
3166
|
+
ypos = float(tl[38:46])
|
|
3167
|
+
xpos = float(tl[30:38])
|
|
3168
|
+
poses[prot_no] = np.array([xpos,ypos,zpos])/10
|
|
3169
|
+
for pr in lines:
|
|
3170
|
+
pr_list = pr.split()
|
|
3171
|
+
prot = pr_list[0]
|
|
3172
|
+
direction = float(pr_list[1])
|
|
3173
|
+
rings = int(pr_list[2])
|
|
3174
|
+
if(rings == 0):
|
|
3175
|
+
rings = False
|
|
3176
|
+
else:
|
|
3177
|
+
rings = True
|
|
3178
|
+
tm.append(prot)
|
|
3179
|
+
prot_dirs.append(direction)
|
|
3180
|
+
prot_rings.append(rings)
|
|
3181
|
+
tm_lip = [ Structure(i) for i in tm ]
|
|
3182
|
+
tm = [ Structure(i) for i in tm ]
|
|
3183
|
+
|
|
3184
|
+
def accessable(grid):
|
|
3185
|
+
ngrid = jnp.zeros_like(grid)
|
|
3186
|
+
def aloop1(ngrid,ind1):
|
|
3187
|
+
def aloop2(ngrid,ind2):
|
|
3188
|
+
t1 = jnp.sum(jnp.array([grid[ind1,ind2],grid[ind1-1,ind2],grid[ind1-1,ind2-1],grid[ind1,ind2-1]]))
|
|
3189
|
+
t2 = jnp.sum(jnp.array([grid[ind1,ind2],grid[ind1+1,ind2],grid[ind1+1,ind2-1],grid[ind1,ind2-1]]))
|
|
3190
|
+
t3 = jnp.sum(jnp.array([grid[ind1,ind2],grid[ind1-1,ind2],grid[ind1-1,ind2+1],grid[ind1,ind2+1]]))
|
|
3191
|
+
t4 = jnp.sum(jnp.array([grid[ind1,ind2],grid[ind1+1,ind2],grid[ind1+1,ind2+1],grid[ind1,ind2+1]]))
|
|
3192
|
+
def good(ngrid):
|
|
3193
|
+
ngrid = ngrid.at[ind1,ind2].set(1)
|
|
3194
|
+
return ngrid
|
|
3195
|
+
def bad(ngrid):
|
|
3196
|
+
return ngrid
|
|
3197
|
+
ngrid = jax.lax.cond(jnp.logical_or(jnp.logical_or(t1==4,t2==4),jnp.logical_or(t3==4,t4==4)),good,bad,ngrid)
|
|
3198
|
+
return ngrid,ind2
|
|
3199
|
+
ngrid,_= jax.lax.scan(aloop2,ngrid,jnp.arange(ngrid.shape[1]))
|
|
3200
|
+
return ngrid,ind1
|
|
3201
|
+
ngrid,_ = jax.lax.scan(aloop1,ngrid,jnp.arange(ngrid.shape[0]))
|
|
3202
|
+
return ngrid
|
|
3203
|
+
|
|
3204
|
+
if(using_temp or tm):
|
|
3205
|
+
if(not using_temp):
|
|
3206
|
+
#when not using a template
|
|
3207
|
+
tm_lip = [ Structure(i) for i in tm ]
|
|
3208
|
+
tm = [ Structure(i) for i in tm ]
|
|
3209
|
+
|
|
3210
|
+
|
|
3211
|
+
|
|
3212
|
+
xmax = np.max(np.array(tm[0].coord)[:,0])
|
|
3213
|
+
ymax = np.max(np.array(tm[0].coord)[:,1])
|
|
3214
|
+
xmin = np.min(np.array(tm[0].coord)[:,0])
|
|
3215
|
+
ymin = np.min(np.array(tm[0].coord)[:,1])
|
|
3216
|
+
xrang = xmax-xmin
|
|
3217
|
+
yrang = ymax-ymin
|
|
3218
|
+
|
|
3219
|
+
rang = np.max([xrang,yrang])/2
|
|
3220
|
+
extent = rang
|
|
3221
|
+
ang_exts = np.array([np.arcsin(curvs_mid[0]*extent),np.arcsin(curvs_mid[1]*extent)])
|
|
3222
|
+
|
|
3223
|
+
bsize,bheight = get_box_size(curvs_mid[0],rcurvs_mid[0],ang_exts[0],add_pore)
|
|
3224
|
+
if(pbcSetX[0] < bsize*2+2):
|
|
3225
|
+
pbcSetX[0] = bsize*2+2
|
|
3226
|
+
if(pbcSetY[1] < bsize*2+2):
|
|
3227
|
+
pbcSetY[1] = bsize*2+2
|
|
3228
|
+
if(pbcSetZ[2] < bheight*2+10):
|
|
3229
|
+
pbcSetZ[2] = bheight*2+10
|
|
3230
|
+
|
|
3231
|
+
|
|
3232
|
+
pbcx = pbcSetX and pbcSetX[0]
|
|
3233
|
+
pbcy = pbcSetY and pbcSetY[1]
|
|
3234
|
+
pbcz = pbcSetZ and pbcSetZ[2]
|
|
3235
|
+
|
|
3236
|
+
|
|
3237
|
+
poses = np.zeros((1,3))
|
|
3238
|
+
prot_dirs.append(1)
|
|
3239
|
+
if(options["-ring"].value != None):
|
|
3240
|
+
rings = True
|
|
3241
|
+
else:
|
|
3242
|
+
rings = False
|
|
3243
|
+
prot_rings.append(rings)
|
|
3244
|
+
|
|
3245
|
+
poses[0][0] = pbcx/2
|
|
3246
|
+
poses[0][1] = pbcy/2
|
|
3247
|
+
|
|
3248
|
+
print("Building protein(s)...")
|
|
3249
|
+
for pind,prot in enumerate(tm):
|
|
3250
|
+
|
|
3251
|
+
prot_lip = tm_lip[pind]
|
|
3252
|
+
## a. NO MEMBRANE --
|
|
3253
|
+
if not lipL:
|
|
3254
|
+
pass
|
|
3255
|
+
## b. PROTEIN AND MEMBRANE --
|
|
3256
|
+
else:
|
|
3257
|
+
|
|
3258
|
+
# Have to build a membrane around the protein.
|
|
3259
|
+
# So first put the protein in properly.
|
|
3260
|
+
|
|
3261
|
+
|
|
3262
|
+
# Center the protein and store the shift
|
|
3263
|
+
shift = prot.center((0,0,0))
|
|
3264
|
+
shift_lip = prot_lip.center((0,0,0))
|
|
3265
|
+
|
|
3266
|
+
## 5. Determine the minimum and maximum x and y of the protein
|
|
3267
|
+
pmin, pmax = prot.fun(min), prot.fun(max)
|
|
3268
|
+
prng = (pmax[0]-pmin[0],pmax[1]-pmin[1],pmax[2]-pmin[2])
|
|
3269
|
+
center = (0.5*(pmin[0]+pmax[0]),0.5*(pmin[1]+pmax[1]))
|
|
3270
|
+
|
|
3271
|
+
|
|
3272
|
+
pbcz += options["-dz"].value or options["-d"].value or 0
|
|
3273
|
+
|
|
3274
|
+
|
|
3275
|
+
## 2. Shift of protein relative to the membrane center
|
|
3276
|
+
zshift = 0
|
|
3277
|
+
if not options["-center"].value:
|
|
3278
|
+
zshift = -shift[2]
|
|
3279
|
+
if options["-dm"].value:
|
|
3280
|
+
if options["-dm"].value < 0:
|
|
3281
|
+
zshift += options["-dm"].value # - max(list(zip(*prot.coord))[2])
|
|
3282
|
+
else:
|
|
3283
|
+
zshift += options["-dm"].value # - min(list(zip(*prot.coord))[2])
|
|
3284
|
+
|
|
3285
|
+
|
|
3286
|
+
if(poses[pind][2] < 0):
|
|
3287
|
+
mind = 0
|
|
3288
|
+
else:
|
|
3289
|
+
mind = 1
|
|
3290
|
+
if(add_pore):
|
|
3291
|
+
inner_leng = zdist-(1/rcurvs_mid[mind])
|
|
3292
|
+
else:
|
|
3293
|
+
inner_leng = 0
|
|
3294
|
+
fun_pos,normal = leaflet_function(poses[pind][0]-pbcx/2,poses[pind][1]-pbcy/2,curvs_mid[mind],rcurvs_mid[mind],ang_exts[mind],add_pore,inner_leng)
|
|
3295
|
+
if(cdirs[mind] > 0):
|
|
3296
|
+
fun_pos = -fun_pos
|
|
3297
|
+
normal[2] = -normal[2]
|
|
3298
|
+
|
|
3299
|
+
downn = np.array([0,0,-1*prot_dirs[pind]])
|
|
3300
|
+
angl = np.dot(normal,downn)
|
|
3301
|
+
if(angl < -1+1e-5):
|
|
3302
|
+
downn = np.array([0,1e-4,-1*prot_dirs[pind]])
|
|
3303
|
+
downn = downn/np.linalg.norm(downn)
|
|
3304
|
+
angl = np.dot(normal,downn)
|
|
3305
|
+
|
|
3306
|
+
v = np.cross(downn,normal)
|
|
3307
|
+
vmat = np.array([[0,-v[2],v[1]],[v[2],0,-v[0]],[-v[1],v[0],0]])
|
|
3308
|
+
rot_mat = np.eye(3)+vmat+np.dot(vmat,vmat)*1/(1+angl)
|
|
3309
|
+
|
|
3310
|
+
prot += [0,0,zshift]
|
|
3311
|
+
prot_lip.coord = list(np.array(prot_lip.coord)+[0,0,zshift])
|
|
3312
|
+
|
|
3313
|
+
if(not prot_rings[pind]):
|
|
3314
|
+
for dmi in range(2):
|
|
3315
|
+
if(dmi == 0 or (not using_temp and zdist > 1e-5)):
|
|
3316
|
+
if(not using_temp and zdist > 1e-5):
|
|
3317
|
+
ztestpos = zdist*(2*dmi-1)
|
|
3318
|
+
else:
|
|
3319
|
+
ztestpos = 0
|
|
3320
|
+
|
|
3321
|
+
|
|
3322
|
+
for zt in np.linspace(ztestpos-4,ztestpos+4,25):
|
|
3323
|
+
in_mem = get_box_slice(np.array(prot.coord),[0,0,zt],[100,100,0.5])
|
|
3324
|
+
if in_mem.size > 0:
|
|
3325
|
+
xmin = np.min(in_mem[:,0])
|
|
3326
|
+
xmax = np.max(in_mem[:,0])
|
|
3327
|
+
ymin = np.min(in_mem[:,1])
|
|
3328
|
+
ymax = np.max(in_mem[:,1])
|
|
3329
|
+
xext = xmax-xmin
|
|
3330
|
+
yext = ymax-ymin
|
|
3331
|
+
|
|
3332
|
+
gridd = np.zeros((20,20))
|
|
3333
|
+
|
|
3334
|
+
xxs = np.linspace(xmin-1,xmax+1,20)
|
|
3335
|
+
yys = np.linspace(ymin-1,ymax+1,20)
|
|
3336
|
+
dx = xxs[1]-xxs[0]
|
|
3337
|
+
dy = yys[1]-yys[0]
|
|
3338
|
+
for im in in_mem:
|
|
3339
|
+
gridx,gridy = put_into_grid(im[:2],[xext+4,yext+4],[20,20],[xmin-2,ymin-2])
|
|
3340
|
+
gridd[gridx,gridy] =1
|
|
3341
|
+
|
|
3342
|
+
gridd = 1-np.array(accessable(1-jnp.array(gridd)))
|
|
3343
|
+
gridd = 1-flood_fill(gridd,True)
|
|
3344
|
+
gridd = 1-flood_fill(gridd,True)
|
|
3345
|
+
|
|
3346
|
+
rad = np.sqrt(dx*dx+dy*dy)/3
|
|
3347
|
+
packer= DiskGridFib(10,rad)
|
|
3348
|
+
for xi in range(20):
|
|
3349
|
+
for yi in range(20):
|
|
3350
|
+
if gridd[xi,yi] == 1:
|
|
3351
|
+
for pi in range(10):
|
|
3352
|
+
new_coord = np.array([xxs[xi],yys[yi],zt])+packer[pi]
|
|
3353
|
+
prot_lip.coord.extend([new_coord])
|
|
3354
|
+
|
|
3355
|
+
prot.coord = np.dot(rot_mat,np.array(prot.coord).T).T
|
|
3356
|
+
prot_lip.coord = np.dot(rot_mat,np.array(prot_lip.coord).T).T
|
|
3357
|
+
prot += poses[pind]
|
|
3358
|
+
prot_lip.coord = list(np.array(prot_lip.coord)+poses[pind])
|
|
3359
|
+
|
|
3360
|
+
|
|
3361
|
+
# And we collect the atoms
|
|
3362
|
+
protein.atoms.extend(prot.atoms)
|
|
3363
|
+
protein.coord.extend(np.array([0,0,-z_change/10])+(np.dot(rot_mat_def,(np.array(prot.coord)-poses[0]).T).T)+poses[0])
|
|
3364
|
+
|
|
3365
|
+
|
|
3366
|
+
protein_lip.atoms.extend(prot_lip.atoms)
|
|
3367
|
+
protein_lip.coord.extend(np.array([0,0,-z_change/10])+(np.dot(rot_mat_def,(np.array(prot_lip.coord)-poses[0]).T).T)+poses[0])
|
|
3368
|
+
|
|
3369
|
+
|
|
3370
|
+
prot_up,prot_lo,prot_up_a,prot_up_b,prot_lo_a,prot_lo_b = [],[],[],[],[],[]
|
|
3371
|
+
|
|
3372
|
+
|
|
3373
|
+
# Current residue ID is set to that of the last atom
|
|
3374
|
+
resi = protein.atoms[-1][2]
|
|
3375
|
+
|
|
3376
|
+
atid = len(protein)+1
|
|
3377
|
+
molecules = []
|
|
3378
|
+
|
|
3379
|
+
# The box dimensions are now (likely) set.
|
|
3380
|
+
# If a protein was given, it is positioned in the center of the
|
|
3381
|
+
# rectangular brick.
|
|
3382
|
+
|
|
3383
|
+
|
|
3384
|
+
# Override lattice vectors if they were set explicitly
|
|
3385
|
+
box = [[0,0,0],[0,0,0],[0,0,0]]
|
|
3386
|
+
box[0] = pbcSetX
|
|
3387
|
+
box[1] = pbcSetY
|
|
3388
|
+
box[2] = pbcSetZ
|
|
3389
|
+
|
|
3390
|
+
grobox = (box[0][0],box[1][1],box[2][2],
|
|
3391
|
+
box[0][1],box[0][2],box[1][0],
|
|
3392
|
+
box[1][2],box[2][0],box[2][1])
|
|
3393
|
+
|
|
3394
|
+
pbcx, pbcy, pbcz = box[0][0], box[1][1], box[2][2]
|
|
3395
|
+
|
|
3396
|
+
|
|
3397
|
+
|
|
3398
|
+
rx, ry, rz = pbcx+1e-8, pbcy+1e-8, pbcz+1e-8
|
|
3399
|
+
|
|
3400
|
+
print("Done")
|
|
3401
|
+
|
|
3402
|
+
#PG layer
|
|
3403
|
+
|
|
3404
|
+
PGL = Structure()
|
|
3405
|
+
if(Num_PGL > 0):
|
|
3406
|
+
print("Begining to build PG layer...")
|
|
3407
|
+
spaceing = 2.5
|
|
3408
|
+
z_poses = np.linspace(-spaceing*(Num_PGL-1)/2,spaceing*(Num_PGL-1)/2,Num_PGL)
|
|
3409
|
+
exprot = float(options["-fudge"].value)
|
|
3410
|
+
prev_str = ["[ atoms ]\n","[ bonds ]\n","[ constraints ]\n","[ angles ]\n","[ dihedrals ]\n"]
|
|
3411
|
+
prev_nos = [1,0]
|
|
3412
|
+
print("Creating glycan strands...")
|
|
3413
|
+
Gposes,pc_zslice = Create_Glycan_strands2(Num_PGL,pbcy,pbcx,z_poses,0,0,np.array(protein.coord),gdist)
|
|
3414
|
+
print("Cross-linking...")
|
|
3415
|
+
Gposes = cross_link(Gposes,pbcy,cper,per33,lper,oper)
|
|
3416
|
+
print("Counting resulting oligomers...")
|
|
3417
|
+
olig_lens = count_all_olig(Gposes)
|
|
3418
|
+
total_clink = olig_lens.shape[0]
|
|
3419
|
+
mono = olig_lens[olig_lens == 1].shape[0]/total_clink
|
|
3420
|
+
dimer = olig_lens[olig_lens == 2].shape[0]/total_clink
|
|
3421
|
+
olig_plus = olig_lens[olig_lens > 2].shape[0]/total_clink
|
|
3422
|
+
print("Momomer:",mono)
|
|
3423
|
+
print("Dimer:",dimer)
|
|
3424
|
+
print("Higher oligomer:",olig_plus)
|
|
3425
|
+
print("Writing ITP for PG layer...")
|
|
3426
|
+
prev_str,prev_nos = write_PGL_itp(Gposes,"NAM.itp","NAG.itp","SNPEP.itp","UNPEP.itp","UUNPEP.itp",prev_str,prev_nos)
|
|
3427
|
+
print("Relaxing the PG layer (This will change the cell size slightly)...")
|
|
3428
|
+
box_size,Gposes = relax_pg(Gposes,np.array([pbcx*50,pbcy*50]),5,pc_zslice)
|
|
3429
|
+
box[0] = [box_size[0]/50,0,0]
|
|
3430
|
+
box[1] = [0,box_size[1]/50,0]
|
|
3431
|
+
#box[2] = pbcSetZ
|
|
3432
|
+
|
|
3433
|
+
grobox = (box[0][0],box[1][1],box[2][2],
|
|
3434
|
+
box[0][1],box[0][2],box[1][0],
|
|
3435
|
+
box[1][2],box[2][0],box[2][1])
|
|
3436
|
+
|
|
3437
|
+
pbcx, pbcy, pbcz = box[0][0], box[1][1], box[2][2]
|
|
3438
|
+
|
|
3439
|
+
|
|
3440
|
+
|
|
3441
|
+
rx, ry, rz = pbcx+1e-8, pbcy+1e-8, pbcz+1e-8
|
|
3442
|
+
|
|
3443
|
+
|
|
3444
|
+
|
|
3445
|
+
|
|
3446
|
+
|
|
3447
|
+
|
|
3448
|
+
|
|
3449
|
+
|
|
3450
|
+
Gposes,Gshape = lines_to_coords(Gposes)
|
|
3451
|
+
|
|
3452
|
+
No_Nag = Gposes[Gposes[:,4] == 0].shape[0]
|
|
3453
|
+
No_Nam = Gposes[Gposes[:,4] == 1].shape[0]
|
|
3454
|
+
|
|
3455
|
+
PG_Glycan = ["NAG:"+str(No_Nag),"NAM:"+str(No_Nam)]
|
|
3456
|
+
|
|
3457
|
+
|
|
3458
|
+
Gly_new, numG = list(zip(*[ parse_mol(i) for i in PG_Glycan ]))
|
|
3459
|
+
totG = float(sum(numG))
|
|
3460
|
+
num_g = [int(len(Gposes)*i/totG) for i in numG]
|
|
3461
|
+
|
|
3462
|
+
Gly = [l for i,l in list(zip(num_g,Gly_new)) for j in range(i)]
|
|
3463
|
+
|
|
3464
|
+
|
|
3465
|
+
Gly_s = (list(zip(Gly,Gposes)))
|
|
3466
|
+
print("Building the PG layer...")
|
|
3467
|
+
glycans = ["NAM","NAG"]
|
|
3468
|
+
#Placing templates of components at each point defined
|
|
3469
|
+
for pos in Gposes:
|
|
3470
|
+
glycan = glycans[int(pos[4])]
|
|
3471
|
+
if(pos[5] > 0):
|
|
3472
|
+
resi += 1
|
|
3473
|
+
atoms = list(zip(lipidsa[glycan][1].split(),lipidsx[lipidsa[glycan][0]],lipidsy[lipidsa[glycan][0]],lipidsz[lipidsa[glycan][0]]))
|
|
3474
|
+
at,ax,ay,az = list(zip(*[i for i in atoms if i[0] != "-"]))
|
|
3475
|
+
az = [ i+pos[2] for i in az ]
|
|
3476
|
+
xx = list(zip( ax,ay ))
|
|
3477
|
+
nx = [pos[3]*i+pos[0] for i in ax]
|
|
3478
|
+
ny = [j+pos[1] for j in ay]
|
|
3479
|
+
for i in range(len(at)):
|
|
3480
|
+
atom = "%5d%-5s%5s%5d"%(resi,glycan,at[i],atid)
|
|
3481
|
+
PGL.coord.append((nx[i],ny[i],az[i]))
|
|
3482
|
+
PGL.atoms.append((at[i],glycan,resi,0,0,0))
|
|
3483
|
+
atid += 1
|
|
3484
|
+
|
|
3485
|
+
|
|
3486
|
+
atoms_nam = list(zip(lipidsa["NAM"][1].split(),lipidsx[lipidsa["NAM"][0]],lipidsy[lipidsa["NAM"][0]],lipidsz[lipidsa["NAM"][0]]))
|
|
3487
|
+
atn,axn,ayn,azn = list(zip(*[i for i in atoms_nam if i[0] != "-"]))
|
|
3488
|
+
nam_temp = np.array([axn[-1],ayn[-1],azn[-1]])
|
|
3489
|
+
for pos in Gposes:
|
|
3490
|
+
glycan = glycans[int(pos[4])]
|
|
3491
|
+
b1_pos = pos[:3]+np.array([pos[3],1,1])*nam_temp
|
|
3492
|
+
if(pos[13] == 1):
|
|
3493
|
+
atm = "UUPEP"
|
|
3494
|
+
atm = "UUPEP"
|
|
3495
|
+
else:
|
|
3496
|
+
if(pos[6] != -1 or pos[13] ==2):
|
|
3497
|
+
atm = "UPEP"
|
|
3498
|
+
else:
|
|
3499
|
+
atm = "SPEP"
|
|
3500
|
+
if(pos[5] > 0 and glycan == "NAM"):
|
|
3501
|
+
resi += 1
|
|
3502
|
+
atoms = list(zip(lipidsa[atm][1].split(),lipidsx[lipidsa[atm][0]],lipidsy[lipidsa[atm][0]],lipidsz[lipidsa[atm][0]]))
|
|
3503
|
+
if(pos[6] > -0.5 and pos[9] > -0.5):
|
|
3504
|
+
lind1 = int(pos[6])
|
|
3505
|
+
bind1 = int(pos[7])
|
|
3506
|
+
lyind1 = int(pos[8])
|
|
3507
|
+
lind2 = int(pos[9])
|
|
3508
|
+
bind2 = int(pos[10])
|
|
3509
|
+
lyind2 = int(pos[11])
|
|
3510
|
+
b2_posA = Gposes[lyind1*Gshape[1]*Gshape[2]+lind1*Gshape[2]+bind1][:3]
|
|
3511
|
+
b2_posB = Gposes[lyind2*Gshape[1]*Gshape[2]+lind2*Gshape[2]+bind2][:3]
|
|
3512
|
+
b2_posB = b2_posB-b2_posA+np.array([pbcx/2,pbcy/2,0])
|
|
3513
|
+
while(b2_posB[0]<0):
|
|
3514
|
+
b2_posB[0] += pbcx
|
|
3515
|
+
while(b2_posB[0]>=pbcx):
|
|
3516
|
+
b2_posB[0] -= pbcx
|
|
3517
|
+
while(b2_posB[1]<0):
|
|
3518
|
+
b2_posB[1] += pbcy
|
|
3519
|
+
while(b2_posB[1]>=pbcy):
|
|
3520
|
+
b2_posB[1] -= pbcy
|
|
3521
|
+
b2_pos = (b2_posB+np.array([pbcx/2,pbcy/2,0]))/2+b2_posA-np.array([pbcx/2,pbcy/2,0])
|
|
3522
|
+
elif(pos[6] > -0.5):
|
|
3523
|
+
lind1 = int(pos[6])
|
|
3524
|
+
bind1 = int(pos[7])
|
|
3525
|
+
lyind1 = int(pos[8])
|
|
3526
|
+
b2_pos = Gposes[lyind1*Gshape[1]*Gshape[2]+lind1*Gshape[2]+bind1][:3]
|
|
3527
|
+
elif(pos[9] > -0.5):
|
|
3528
|
+
lind1 = int(pos[9])
|
|
3529
|
+
bind1 = int(pos[10])
|
|
3530
|
+
lyind1 = int(pos[11])
|
|
3531
|
+
b2_pos = Gposes[lyind1*Gshape[1]*Gshape[2]+lind1*Gshape[2]+bind1][:3]
|
|
3532
|
+
else:
|
|
3533
|
+
b2_pos = b1_pos-np.array([pos[3],0,0])*2.5
|
|
3534
|
+
|
|
3535
|
+
|
|
3536
|
+
pbcb2= b2_pos-b1_pos+np.array([pbcx/2,pbcy/2,0])
|
|
3537
|
+
while(pbcb2[0]<0):
|
|
3538
|
+
pbcb2[0] += pbcx
|
|
3539
|
+
while(pbcb2[0]>=pbcx):
|
|
3540
|
+
pbcb2[0] -= pbcx
|
|
3541
|
+
while(pbcb2[1]<0):
|
|
3542
|
+
pbcb2[1] += pbcy
|
|
3543
|
+
while(pbcb2[1]>=pbcy):
|
|
3544
|
+
pbcb2[1] -= pbcy
|
|
3545
|
+
leng = np.linalg.norm(pbcb2-np.array([pbcx/2,pbcy/2,0]))-0.64
|
|
3546
|
+
if(leng < 1.5):
|
|
3547
|
+
leng = 1.5 #changed this maybe change back idk
|
|
3548
|
+
|
|
3549
|
+
v2 = pbcb2-np.array([pbcx/2,pbcy/2,0])
|
|
3550
|
+
v2 = v2/np.linalg.norm(v2)
|
|
3551
|
+
v1 = [-1,0,0]
|
|
3552
|
+
vcross = np.cross(v1,v2)
|
|
3553
|
+
vmat = np.array([[0,-vcross[2],vcross[1]],[vcross[2],0,-vcross[0]],[-vcross[1],vcross[0],0]])
|
|
3554
|
+
asin = np.linalg.norm(vcross)
|
|
3555
|
+
acos = np.dot(v1,v2)
|
|
3556
|
+
if(np.abs(1+acos) < 1e-6):
|
|
3557
|
+
rot_mat = np.array([[-1,0,0],[0,1,0],[0,0,1]])
|
|
3558
|
+
else:
|
|
3559
|
+
rot_mat = np.eye(3)+vmat+np.dot(vmat,vmat)*(1/(1+acos))
|
|
3560
|
+
|
|
3561
|
+
|
|
3562
|
+
|
|
3563
|
+
npos = (np.array([pbcx/2,pbcy/2,0])+pbcb2)/2+b1_pos-np.array([pbcx/2,pbcy/2,0])
|
|
3564
|
+
|
|
3565
|
+
dil = leng/2.03
|
|
3566
|
+
|
|
3567
|
+
|
|
3568
|
+
|
|
3569
|
+
at,ax,ay,az = list(zip(*[i for i in atoms if i[0] != "-"]))
|
|
3570
|
+
xx = list(zip( ax,ay,az ))
|
|
3571
|
+
nx = [rot_mat[0,0]*i*dil+rot_mat[0,1]*j+rot_mat[0,2]*k+npos[0] for i,j,k in xx]
|
|
3572
|
+
ny = [rot_mat[1,0]*i*dil+rot_mat[1,1]*j+rot_mat[1,2]*k+npos[1] for i,j,k in xx]
|
|
3573
|
+
nz = [rot_mat[2,0]*i*dil+rot_mat[2,1]*j+rot_mat[2,2]*k+npos[2] for i,j,k in xx]
|
|
3574
|
+
for i in range(len(at)):
|
|
3575
|
+
atom = "%5d%-5s%5s%5d"%(resi,glycan,at[i],atid)
|
|
3576
|
+
PGL.coord.append((nx[i],ny[i],nz[i]))
|
|
3577
|
+
PGL.atoms.append((at[i],atm,resi,0,0,0))
|
|
3578
|
+
atid += 1
|
|
3579
|
+
|
|
3580
|
+
|
|
3581
|
+
|
|
3582
|
+
molecules.extend(list(zip(["PGL"],[1])))
|
|
3583
|
+
write_all_itp(prev_str,out_folder)
|
|
3584
|
+
print("Done")
|
|
3585
|
+
|
|
3586
|
+
|
|
3587
|
+
#################
|
|
3588
|
+
## 2. MEMBRANE ##
|
|
3589
|
+
#################
|
|
3590
|
+
|
|
3591
|
+
membrane = Structure()
|
|
3592
|
+
mi_rad = 0
|
|
3593
|
+
if lipL:
|
|
3594
|
+
print("Begining to build lipid bilayer(s)...")
|
|
3595
|
+
#reading inputs
|
|
3596
|
+
area_l = float(options["-a"].value)
|
|
3597
|
+
if(not options["-au"].value is None):
|
|
3598
|
+
area_u = float(options["-au"].value)
|
|
3599
|
+
else:
|
|
3600
|
+
area_u = float(options["-a"].value)
|
|
3601
|
+
|
|
3602
|
+
if(not options["-ao"].value is None):
|
|
3603
|
+
area_lo = float(options["-ao"].value)
|
|
3604
|
+
else:
|
|
3605
|
+
area_lo = float(options["-a"].value)
|
|
3606
|
+
|
|
3607
|
+
|
|
3608
|
+
if(not options["-auo"].value is None):
|
|
3609
|
+
area_uo = float(options["-auo"].value)
|
|
3610
|
+
else:
|
|
3611
|
+
if(not options["-ao"].value is None):
|
|
3612
|
+
area_uo = float(options["-ao"].value)
|
|
3613
|
+
else:
|
|
3614
|
+
area_uo = float(options["-a"].value)
|
|
3615
|
+
|
|
3616
|
+
density_l = [np.pi/2*np.sqrt(1/area_l),np.pi/2*np.sqrt(1/area_lo)]
|
|
3617
|
+
density_u = [np.pi/2*np.sqrt(1/area_u),np.pi/2*np.sqrt(1/area_uo)]
|
|
3618
|
+
area_ls = [area_l,area_lo]
|
|
3619
|
+
|
|
3620
|
+
|
|
3621
|
+
|
|
3622
|
+
|
|
3623
|
+
up_grids = []
|
|
3624
|
+
lo_grids = []
|
|
3625
|
+
direcss = []
|
|
3626
|
+
direcs2s = []
|
|
3627
|
+
|
|
3628
|
+
lipU = lipU or lipL
|
|
3629
|
+
trufal = [True,False]
|
|
3630
|
+
#building membrae grid points and normals based on inputs
|
|
3631
|
+
print("Creating leaflet shape...")
|
|
3632
|
+
for i in range(2):
|
|
3633
|
+
if(options["-ps"].value > 1e-5 or i == 0):
|
|
3634
|
+
if(add_pore):
|
|
3635
|
+
inner_leng = zdist-(1/rcurvs_mid[i])
|
|
3636
|
+
curv_up[i] = 1/(extent+2)
|
|
3637
|
+
curv_lo[i] = 1/(extent-2)
|
|
3638
|
+
else:
|
|
3639
|
+
inner_leng = 0
|
|
3640
|
+
if(is_micelle):
|
|
3641
|
+
prot_points = np.array(protein.coord)
|
|
3642
|
+
prot_points = prot_points[np.logical_and(prot_points[:,2]+zdist*(i*2-1) < 2,prot_points[:,2]+zdist*(i*2-1) > -2)]
|
|
3643
|
+
prot_points = prot_points[:,:2]
|
|
3644
|
+
prot_points = prot_points[::2]
|
|
3645
|
+
prot_points = jnp.array(prot_points)
|
|
3646
|
+
|
|
3647
|
+
|
|
3648
|
+
ret_val,grid_vals = gaussian_grid(prot_points,-pbcx/2,-pbcx/2,pbcx/2,pbcx/2,300,300)
|
|
3649
|
+
av_liplen = get_avlip_len(lipU)
|
|
3650
|
+
up_grid,direcs,mi_rad = build_micelle(area_ls[i],prot_points,ret_val,grid_vals,8,pbcx,pbcy,av_liplen)
|
|
3651
|
+
if(options["-no_lipids"].value != -1):
|
|
3652
|
+
no_lips = int(options["-no_lipids"].value)
|
|
3653
|
+
acc_lips = len(direcs)
|
|
3654
|
+
new_area = area_ls[i]*acc_lips/no_lips
|
|
3655
|
+
up_grid,direcs,mi_rad = build_micelle(new_area,prot_points,ret_val,grid_vals,8,pbcx,pbcy,av_liplen)
|
|
3656
|
+
|
|
3657
|
+
#up_grid,direcs,mi_rad = build_micelle(area_ls[i],prot_points,ret_val,grid_vals,8,pbcx,pbcy)
|
|
3658
|
+
|
|
3659
|
+
|
|
3660
|
+
lo_grid = np.zeros((0,3))
|
|
3661
|
+
direcs2 = np.zeros((0,3))
|
|
3662
|
+
else:
|
|
3663
|
+
up_grid,direcs = create_leaflet(density_u[i],pbcx/2,pbcy/2,curv_up[i],rcurv_up[i],ang_exts[i],add_pore,inner_leng,trufal[i],mem_outer_red)
|
|
3664
|
+
lo_grid,direcs2 = create_leaflet(density_l[i],pbcx/2,pbcy/2,curv_lo[i],rcurv_lo[i],ang_exts[i],add_pore,inner_leng,trufal[i],mem_outer_red)
|
|
3665
|
+
up_grid[:,2] = -up_grid[:,2]+2
|
|
3666
|
+
lo_grid[:,2] = -lo_grid[:,2]-2
|
|
3667
|
+
|
|
3668
|
+
|
|
3669
|
+
if(cdirs[i] < 0):
|
|
3670
|
+
temp = up_grid
|
|
3671
|
+
up_grid = lo_grid
|
|
3672
|
+
lo_grid= temp
|
|
3673
|
+
|
|
3674
|
+
dtemp = -direcs
|
|
3675
|
+
direcs = -direcs2
|
|
3676
|
+
direcs2= dtemp
|
|
3677
|
+
|
|
3678
|
+
up_grid[:,2] = -up_grid[:,2]
|
|
3679
|
+
lo_grid[:,2] = -lo_grid[:,2]
|
|
3680
|
+
direcs[:,2] = -direcs[:,2]
|
|
3681
|
+
direcs2[:,2] = -direcs2[:,2]
|
|
3682
|
+
if(not is_micelle):
|
|
3683
|
+
up_grid = up_grid+np.array([pbcx/2,pbcy/2,0])
|
|
3684
|
+
lo_grid = lo_grid+np.array([pbcx/2,pbcy/2,0])
|
|
3685
|
+
else:
|
|
3686
|
+
up_grid = np.zeros((0,3))
|
|
3687
|
+
direcs = np.zeros((0,3))
|
|
3688
|
+
lo_grid = np.zeros((0,3))
|
|
3689
|
+
direcs2 = np.zeros((0,3))
|
|
3690
|
+
|
|
3691
|
+
up_grids.append(up_grid)
|
|
3692
|
+
lo_grids.append(lo_grid)
|
|
3693
|
+
direcss.append(direcs)
|
|
3694
|
+
direcs2s.append(direcs2)
|
|
3695
|
+
|
|
3696
|
+
upper, lower = [], []
|
|
3697
|
+
random.seed()
|
|
3698
|
+
|
|
3699
|
+
|
|
3700
|
+
#lipU = lipU or lipL
|
|
3701
|
+
lipU_loc = lipU_loc or lipL_loc
|
|
3702
|
+
lipLO = lipLO or lipL
|
|
3703
|
+
lipUO = lipUO or lipLO
|
|
3704
|
+
lipUs = [lipU,lipUO]
|
|
3705
|
+
lipLs = [lipL,lipLO]
|
|
3706
|
+
|
|
3707
|
+
av_liplenU = get_avlip_len(lipU)
|
|
3708
|
+
av_liplenUO = get_avlip_len(lipUO)
|
|
3709
|
+
av_liplenL = get_avlip_len(lipL)
|
|
3710
|
+
av_liplenLO = get_avlip_len(lipLO)
|
|
3711
|
+
|
|
3712
|
+
#removing lipids within -fudge of protein
|
|
3713
|
+
prot_coords = np.array(protein_lip.coord)
|
|
3714
|
+
#write_point(prot_coords*10,"Protein_filled.pdb")
|
|
3715
|
+
|
|
3716
|
+
tailsU = np.linspace(0,av_liplenU*1.5,50)
|
|
3717
|
+
tailsUO = np.linspace(0,av_liplenUO*1.5,50)
|
|
3718
|
+
tailsL = np.linspace(0,av_liplenL*1.5,50)
|
|
3719
|
+
tailsLO = np.linspace(0,av_liplenLO*1.5,50)
|
|
3720
|
+
tailsUs = [tailsU,tailsUO]
|
|
3721
|
+
tailsLs = [tailsL,tailsLO]
|
|
3722
|
+
|
|
3723
|
+
exprot = float(options["-fudge"].value)
|
|
3724
|
+
zdist = float(options["-ps"].value)
|
|
3725
|
+
print("Calculating lipid positions...")
|
|
3726
|
+
|
|
3727
|
+
for gi in range(2):
|
|
3728
|
+
test_pts = DiskGridFib(20,np.sqrt(area_ls[gi])/1.5)
|
|
3729
|
+
total_up_lips = up_grids[gi].shape[0]
|
|
3730
|
+
total_lo_lips = lo_grids[gi].shape[0]
|
|
3731
|
+
if(options["-ps"].value > 1e-5 or gi == 0):
|
|
3732
|
+
upper_tmp, lower_tmp = [], []
|
|
3733
|
+
for i in range(total_up_lips):
|
|
3734
|
+
zdef = 0
|
|
3735
|
+
mtdef = 1.0
|
|
3736
|
+
|
|
3737
|
+
direc = np.array([direcss[gi][i][0],direcss[gi][i][1],direcss[gi][i][2]])
|
|
3738
|
+
coll = False
|
|
3739
|
+
for si in test_pts:
|
|
3740
|
+
if memdata:
|
|
3741
|
+
xtest = (up_grids[gi][i][0]+si[0]-pbcx/2)*10
|
|
3742
|
+
ytest = (up_grids[gi][i][1]+si[1]-pbcy/2)*10
|
|
3743
|
+
xind = int(((xtest-xlin_def[0])/(xlin_def[-1]-xlin_def[0]))*xlin_def.shape[0])
|
|
3744
|
+
yind = int(((ytest-ylin_def[0])/(ylin_def[-1]-ylin_def[0]))*ylin_def.shape[0])
|
|
3745
|
+
if xind < 0 or yind < 0 or xind >= xlin_def.shape[0] or yind >= ylin_def.shape[0]:
|
|
3746
|
+
zdef = 0
|
|
3747
|
+
else:
|
|
3748
|
+
defor = membrane_pos[xind,yind]/10.0
|
|
3749
|
+
zdef = defor[0]
|
|
3750
|
+
mtdef = (10*defor[1]/membrane_pos[0,0,1])
|
|
3751
|
+
poser = np.array([up_grids[gi][i][0],up_grids[gi][i][1],mtdef*up_grids[gi][i][2]+zdist*(gi*2-1)+zdef])
|
|
3752
|
+
coll = False
|
|
3753
|
+
path = [poser+si]
|
|
3754
|
+
for it,dr in enumerate(tailsUs[gi]):
|
|
3755
|
+
#prot_slice = get_box_slice(prot_coords,poser-dr*direc*mtdef,[exprot,exprot,exprot])
|
|
3756
|
+
if tm:
|
|
3757
|
+
prot_sliceb = get_box_slice(prot_coords,path[-1],[exprot,exprot,exprot])
|
|
3758
|
+
else:
|
|
3759
|
+
prot_sliceb = jnp.empty((0,3))
|
|
3760
|
+
if not prot_sliceb.size == 0:
|
|
3761
|
+
path_bead,can_place = place_bead(jnp.array(path[-1]),tailsUs[gi][1],jnp.array(direc),SpGrid,jnp.array(prot_sliceb),exprot)
|
|
3762
|
+
else:
|
|
3763
|
+
path_bead = path[-1]-direc*tailsUs[gi][1]
|
|
3764
|
+
can_place =True
|
|
3765
|
+
path.append(np.array(path_bead))
|
|
3766
|
+
if(not can_place):
|
|
3767
|
+
coll = True
|
|
3768
|
+
break
|
|
3769
|
+
if not coll:
|
|
3770
|
+
for _ in range(10):
|
|
3771
|
+
path_bead = path[-1]-direc*tailsUs[gi][1]
|
|
3772
|
+
path.append(np.array(path_bead))
|
|
3773
|
+
path_top = [poser+si+direc*tailsUs[gi][1]]
|
|
3774
|
+
for _ in range(50):
|
|
3775
|
+
path_top.append(path_top[-1]+direc*tailsUs[gi][1])
|
|
3776
|
+
for i in range(49):
|
|
3777
|
+
path.append(path_top[-i-1])
|
|
3778
|
+
break
|
|
3779
|
+
if(not coll):
|
|
3780
|
+
upper_tmp.append((random.random(),up_grids[gi][i][0],up_grids[gi][i][1],up_grids[gi][i][2],direcss[gi][i][0],direcss[gi][i][1],direcss[gi][i][2],path))
|
|
3781
|
+
upper.append((random.random(),up_grids[gi][i][0],up_grids[gi][i][1],up_grids[gi][i][2],direcss[gi][i][0],direcss[gi][i][1],direcss[gi][i][2],path))
|
|
3782
|
+
for i in range(total_lo_lips):
|
|
3783
|
+
zdef = 0
|
|
3784
|
+
mtdef = 1.0
|
|
3785
|
+
direc = np.array([direcs2s[gi][i][0],direcs2s[gi][i][1],direcs2s[gi][i][2]])
|
|
3786
|
+
coll = False
|
|
3787
|
+
for si in test_pts:
|
|
3788
|
+
if memdata:
|
|
3789
|
+
xtest = (lo_grids[gi][i][0]+si[0]-pbcx/2)*10
|
|
3790
|
+
ytest = (lo_grids[gi][i][1]+si[1]-pbcy/2)*10
|
|
3791
|
+
xind = int(((xtest-xlin_def[0])/(xlin_def[-1]-xlin_def[0]))*xlin_def.shape[0])
|
|
3792
|
+
yind = int(((ytest-ylin_def[0])/(ylin_def[-1]-ylin_def[0]))*ylin_def.shape[0])
|
|
3793
|
+
if xind < 0 or yind < 0 or xind >= xlin_def.shape[0] or yind >= ylin_def.shape[0]:
|
|
3794
|
+
zdef = 0
|
|
3795
|
+
else:
|
|
3796
|
+
defor = membrane_pos[xind,yind]/10.0
|
|
3797
|
+
zdef = defor[0]
|
|
3798
|
+
mtdef = (10*defor[1]/membrane_pos[0,0,1])
|
|
3799
|
+
poser = np.array([lo_grids[gi][i][0],lo_grids[gi][i][1],mtdef*lo_grids[gi][i][2]+zdist*(gi*2-1)+zdef])
|
|
3800
|
+
|
|
3801
|
+
coll = False
|
|
3802
|
+
path = [poser+si]
|
|
3803
|
+
#if tm:
|
|
3804
|
+
for it,dr in enumerate(tailsLs[gi]):
|
|
3805
|
+
#prot_slice = get_box_slice(prot_coords,poser+dr*direc*mtdef,[exprot,exprot,exprot])
|
|
3806
|
+
if tm:
|
|
3807
|
+
prot_sliceb = get_box_slice(prot_coords,path[-1],[exprot,exprot,exprot])
|
|
3808
|
+
else:
|
|
3809
|
+
prot_sliceb = jnp.empty((0,3))
|
|
3810
|
+
if not prot_sliceb.size == 0:
|
|
3811
|
+
path_bead,can_place = place_bead(jnp.array(path[-1]),tailsLs[gi][1],-jnp.array(direc),SpGrid,jnp.array(prot_sliceb),exprot)
|
|
3812
|
+
else:
|
|
3813
|
+
path_bead = path[-1]+direc*tailsLs[gi][1]
|
|
3814
|
+
can_place =True
|
|
3815
|
+
path.append(np.array(path_bead))
|
|
3816
|
+
if(not can_place):
|
|
3817
|
+
coll = True
|
|
3818
|
+
break
|
|
3819
|
+
if not coll:
|
|
3820
|
+
for _ in range(10):
|
|
3821
|
+
path_bead = path[-1]+direc*tailsLs[gi][1]
|
|
3822
|
+
path.append(np.array(path_bead))
|
|
3823
|
+
path_top = [poser+si+direc*tailsUs[gi][1]]
|
|
3824
|
+
for _ in range(50):
|
|
3825
|
+
path_top.append(path_top[-1]+direc*tailsUs[gi][1])
|
|
3826
|
+
for i in range(49):
|
|
3827
|
+
path.append(path_top[-i-1])
|
|
3828
|
+
break
|
|
3829
|
+
|
|
3830
|
+
if(not coll):
|
|
3831
|
+
|
|
3832
|
+
lower_tmp.append((random.random(),lo_grids[gi][i][0],lo_grids[gi][i][1],lo_grids[gi][i][2],direcs2s[gi][i][0],direcs2s[gi][i][1],direcs2s[gi][i][2],path))
|
|
3833
|
+
lower.append((random.random(),lo_grids[gi][i][0],lo_grids[gi][i][1],lo_grids[gi][i][2],direcs2s[gi][i][0],direcs2s[gi][i][1],direcs2s[gi][i][2],path))
|
|
3834
|
+
|
|
3835
|
+
|
|
3836
|
+
# Sort on the random number
|
|
3837
|
+
upper_tmp.sort()
|
|
3838
|
+
lower_tmp.sort()
|
|
3839
|
+
|
|
3840
|
+
|
|
3841
|
+
|
|
3842
|
+
|
|
3843
|
+
# Extract coordinates, taking asymmetry in account
|
|
3844
|
+
asym = options["-asym"].value or 0
|
|
3845
|
+
upper_tmp = [i[1:] for i in upper_tmp[max(0, asym):]]
|
|
3846
|
+
lower_tmp = [i[1:] for i in lower_tmp[max(0,-asym):]]
|
|
3847
|
+
print("; %d lipids in upper leaflet, %d lipids in lower leaflet"%(len(upper_tmp),len(lower_tmp)),file=sys.stderr )
|
|
3848
|
+
|
|
3849
|
+
# Types of lipids, relative numbers, fractions and numbers
|
|
3850
|
+
|
|
3851
|
+
# Upper leaflet (+1)
|
|
3852
|
+
lipU_new, numU = list(zip(*[ parse_mol(i) for i in lipUs[gi] ]))
|
|
3853
|
+
totU = float(sum(numU))
|
|
3854
|
+
num_up = [int(len(upper_tmp)*i/totU) for i in numU]
|
|
3855
|
+
|
|
3856
|
+
lip_up = [l for i,l in list(zip(num_up,lipU_new)) for j in range(i)]
|
|
3857
|
+
|
|
3858
|
+
leaf_up = ( 1,list(zip(lip_up,upper_tmp)))
|
|
3859
|
+
|
|
3860
|
+
# Lower leaflet (-1)
|
|
3861
|
+
lipL_new, numL = list(zip(*[ parse_mol(i) for i in lipLs[gi] ]))
|
|
3862
|
+
totL = float(sum(numL))
|
|
3863
|
+
num_lo = [int(len(lower_tmp)*i/totL) for i in numL]
|
|
3864
|
+
lip_lo = [l for i,l in list(zip(num_lo,lipL_new)) for j in range(i)]
|
|
3865
|
+
|
|
3866
|
+
#lower_tmp = LocBias(lower_tmp,num_lo,lipL_new,10000,lipL_loc,loc_grid[0])
|
|
3867
|
+
leaf_lo = (-1,list(zip(lip_lo,lower_tmp)))
|
|
3868
|
+
if(gi == 0):
|
|
3869
|
+
molecules += list(zip(lipU_new,num_up)) + list(zip(lipL_new,num_lo))
|
|
3870
|
+
else:
|
|
3871
|
+
molecules += list(zip(lipU_new,num_up)) + list(zip(lipL_new,num_lo))
|
|
3872
|
+
|
|
3873
|
+
kick = options["-rand"].value
|
|
3874
|
+
|
|
3875
|
+
|
|
3876
|
+
print("Building membrane(s)...")
|
|
3877
|
+
# Build the membrane
|
|
3878
|
+
for leaflet,leaf_lip in [leaf_up,leaf_lo]:
|
|
3879
|
+
for lipid, pos_dir in leaf_lip:
|
|
3880
|
+
pos = pos_dir[:3]
|
|
3881
|
+
dirs = pos_dir[3:6]
|
|
3882
|
+
path = np.array(pos_dir[-1])-pos
|
|
3883
|
+
#print(path[0])
|
|
3884
|
+
#print(pos)
|
|
3885
|
+
# Increase the residue number by one
|
|
3886
|
+
resi += 1
|
|
3887
|
+
# Set the random rotation for this lipid
|
|
3888
|
+
rangle = 2*random.random()*math.pi
|
|
3889
|
+
rcos = math.cos(rangle)
|
|
3890
|
+
rsin = math.sin(rangle)
|
|
3891
|
+
# Fetch the atom list with x,y,z coordinates
|
|
3892
|
+
atoms = list(zip(lipidsa[lipid][1].split(),lipidsx[lipidsa[lipid][0]],lipidsy[lipidsa[lipid][0]],lipidsz[lipidsa[lipid][0]]))
|
|
3893
|
+
# Only keep atoms appropriate for the lipid
|
|
3894
|
+
at,ax,ay,az = list(zip(*[i for i in atoms if i[0] != "-"]))
|
|
3895
|
+
# The z-coordinates are spaced at 0.3 nm,
|
|
3896
|
+
# starting with the first bead at 0.15 nm
|
|
3897
|
+
#+leaflet*(0.5+(i-min(az)))*options["-bd"].value
|
|
3898
|
+
|
|
3899
|
+
xx = list(zip( ax,ay ))
|
|
3900
|
+
nx = [rcos*i-rsin*j+random.random()*kick for i,j in xx]
|
|
3901
|
+
ny = [rsin*i+rcos*j+random.random()*kick for i,j in xx]
|
|
3902
|
+
|
|
3903
|
+
az = np.array([ leaflet*-2+pos[2]+leaflet*(0.5+(i-min(az)))*options["-bd"].value for i in az ])
|
|
3904
|
+
if leaflet == 1:
|
|
3905
|
+
vgrid = tailsUs[gi]
|
|
3906
|
+
else:
|
|
3907
|
+
vgrid = tailsLs[gi]
|
|
3908
|
+
new_poses = []
|
|
3909
|
+
for ai in range(az.shape[0]):
|
|
3910
|
+
vi = 0
|
|
3911
|
+
indv = -leaflet*((az[ai]-pos[2])/vgrid[-1])*len(vgrid)
|
|
3912
|
+
indv_f = np.floor(indv)
|
|
3913
|
+
indv_c = np.ceil(indv)
|
|
3914
|
+
indv_p = indv_c-indv
|
|
3915
|
+
pf = path[int(indv_f)]
|
|
3916
|
+
pc = path[int(indv_c)]
|
|
3917
|
+
|
|
3918
|
+
sdirec = pf-pc
|
|
3919
|
+
sdirec /= np.linalg.norm(sdirec)
|
|
3920
|
+
|
|
3921
|
+
upp = np.array([0,0,1])
|
|
3922
|
+
sdirec2 = sdirec+1e-4*np.linalg.norm(upp+sdirec)
|
|
3923
|
+
sdirec2 /= np.linalg.norm(sdirec2)
|
|
3924
|
+
angl = np.dot(-sdirec2,upp)
|
|
3925
|
+
|
|
3926
|
+
|
|
3927
|
+
v = np.cross(-sdirec2,upp)
|
|
3928
|
+
vmat = np.array([[0,-v[2],v[1]],[v[2],0,-v[0]],[-v[1],v[0],0]])
|
|
3929
|
+
rot_mat = np.eye(3)+vmat+np.dot(vmat,vmat)*1/(1+angl)
|
|
3930
|
+
|
|
3931
|
+
xdir = np.dot(np.array([1,0,0]),rot_mat)
|
|
3932
|
+
ydir = np.dot(np.array([0,1,0]),rot_mat)
|
|
3933
|
+
|
|
3934
|
+
if np.linalg.norm(xdir)<0.9:
|
|
3935
|
+
print(np.linalg.norm(xdir))
|
|
3936
|
+
|
|
3937
|
+
new_pos = pf*(1-indv_p)+pc*indv_p+pos[:3]+nx[ai]*xdir+ny[ai]*ydir
|
|
3938
|
+
new_poses.append(new_pos)
|
|
3939
|
+
|
|
3940
|
+
|
|
3941
|
+
for i in range(len(at)):
|
|
3942
|
+
atom = "%5d%-5s%5s%5d"%(resi,lipid,at[i],atid)
|
|
3943
|
+
membrane.coord.append((new_poses[i][0],new_poses[i][1],new_poses[i][2]))
|
|
3944
|
+
|
|
3945
|
+
membrane.atoms.append((at[i],lipid,resi,0,0,0))
|
|
3946
|
+
atid += 1
|
|
3947
|
+
|
|
3948
|
+
|
|
3949
|
+
|
|
3950
|
+
# Now move everything to the center of the box before adding solvent
|
|
3951
|
+
mz = pbcz/2
|
|
3952
|
+
z = [ i[2] for i in protein.coord+membrane.coord ]
|
|
3953
|
+
adj = -(max(z)+min(z))/2
|
|
3954
|
+
mz += adj
|
|
3955
|
+
protein += (0,0,mz)
|
|
3956
|
+
membrane += (0,0,mz)
|
|
3957
|
+
print("Done")
|
|
3958
|
+
else:
|
|
3959
|
+
mz=0
|
|
3960
|
+
adj = 0
|
|
3961
|
+
|
|
3962
|
+
if(Num_PGL > 0):
|
|
3963
|
+
PGL += (0,0,adj)
|
|
3964
|
+
|
|
3965
|
+
|
|
3966
|
+
|
|
3967
|
+
################
|
|
3968
|
+
## 3. SOLVENT ##
|
|
3969
|
+
################
|
|
3970
|
+
|
|
3971
|
+
# Charge of the system so far
|
|
3972
|
+
|
|
3973
|
+
|
|
3974
|
+
charge,pcharge,mcharge,pgcharge = get_charge(0,pbcz)
|
|
3975
|
+
|
|
3976
|
+
plen, mlen, slen = 0, 0, 0
|
|
3977
|
+
plen = protein and len(protein) or 0
|
|
3978
|
+
|
|
3979
|
+
print("; NDX Protein %d %d" % (1, protein and plen or 0),file=sys.stderr)
|
|
3980
|
+
print("; Charge of protein: %f" % pcharge,file=sys.stderr)
|
|
3981
|
+
|
|
3982
|
+
mlen = membrane and len(membrane) or 0
|
|
3983
|
+
|
|
3984
|
+
pglen = PGL and len(PGL) or 0
|
|
3985
|
+
|
|
3986
|
+
print("; NDX Membrane %d %d" % (1+plen, membrane and plen+mlen or 0),file=sys.stderr)
|
|
3987
|
+
print("; Charge of membrane: %f" % mcharge,file=sys.stderr)
|
|
3988
|
+
|
|
3989
|
+
print("; NDX PG Layer %d %d" % (1+mlen+plen, PGL and plen+mlen+pglen or 0),file=sys.stderr)
|
|
3990
|
+
print("; Charge of PG Layer: %f" % pgcharge,file=sys.stderr)
|
|
3991
|
+
|
|
3992
|
+
print("; Total charge: %f" % charge,file=sys.stderr)
|
|
3993
|
+
|
|
3994
|
+
|
|
3995
|
+
def _point(y,phi):
|
|
3996
|
+
r = math.sqrt(1-y*y)
|
|
3997
|
+
return math.cos(phi)*r, y, math.sin(phi)*r
|
|
3998
|
+
|
|
3999
|
+
|
|
4000
|
+
def pointsOnSphere(n):
|
|
4001
|
+
return [_point((2.*k+1)/n-1,k*2.3999632297286531) for k in range(n)]
|
|
4002
|
+
|
|
4003
|
+
if solv:
|
|
4004
|
+
print("Adding solvent...")
|
|
4005
|
+
|
|
4006
|
+
# Set up a grid
|
|
4007
|
+
d = 1/(options["-sold"].value*np.sqrt(3)/2)
|
|
4008
|
+
da = 1/options["-sold"].value
|
|
4009
|
+
|
|
4010
|
+
nx,ny,nz = int(1+da*pbcx),int(1+d*pbcy),int(1+d*pbcz)
|
|
4011
|
+
|
|
4012
|
+
dx,dy,dz = pbcx/nx,pbcy/ny,pbcz/nz
|
|
4013
|
+
zdist = options["-ps"].value
|
|
4014
|
+
inner_lengs = [zdist,zdist]
|
|
4015
|
+
|
|
4016
|
+
|
|
4017
|
+
dzdist = int(zdist/dz)+1
|
|
4018
|
+
|
|
4019
|
+
excl,hz = int(nz*options["-excl"].value/pbcz), int(0.5*nz)
|
|
4020
|
+
|
|
4021
|
+
zshift = 0
|
|
4022
|
+
if membrane:
|
|
4023
|
+
if(options["-ps"].value > 1e-5):
|
|
4024
|
+
memz = [i[2] for i in membrane.coord]
|
|
4025
|
+
midz = (max(memz)+min(memz))/2
|
|
4026
|
+
memz_upp = [i[2] for i in membrane.coord if i[2]>midz]
|
|
4027
|
+
midz_upp = (max(memz_upp)+min(memz_upp))/2
|
|
4028
|
+
memz_low = [i[2] for i in membrane.coord if i[2]<=midz]
|
|
4029
|
+
midz_low = (max(memz_low)+min(memz_low))/2
|
|
4030
|
+
midz = (midz_upp+midz_low)/2
|
|
4031
|
+
excl -= 1
|
|
4032
|
+
else:
|
|
4033
|
+
memz = [i[2] for i in membrane.coord]
|
|
4034
|
+
midz = (max(memz)+min(memz))/2
|
|
4035
|
+
hz = int(nz*midz/pbcz) # Grid layer in which the membrane is located
|
|
4036
|
+
zshift = (hz+0.5)*nz - midz # Shift of membrane middle to center of grid layer
|
|
4037
|
+
# Initialize a grid of solvent, spanning the whole cell
|
|
4038
|
+
# Exclude all cells within specified distance from membrane center
|
|
4039
|
+
mem_size = 1.9
|
|
4040
|
+
if(lipL):
|
|
4041
|
+
print("Excluding solvent from membrane(s)...")
|
|
4042
|
+
if(options["-ps"].value > 1e-5):
|
|
4043
|
+
grids = []
|
|
4044
|
+
for gk in range(2):
|
|
4045
|
+
|
|
4046
|
+
if(cdirs[gk] < 0):
|
|
4047
|
+
grid = [[[(pbcz*(i+0.5))/nz <= -leaflet_function((pbcx*k)/nx-pbcx/2+((i+j)%2)*0.5*dx,(pbcy*j)/ny-pbcy/2+(i%2)*0.5*dy,curv_up[gk],rcurv_up[gk],ang_exts[gk],add_pore,inner_lengs[gk]-2)[0]-mem_size+mz+zdist*(2*gk-1) or (pbcz*(i+0.5))/nz >= -leaflet_function((pbcx*k)/nx-pbcx/2+((i+j)%2)*0.5*dx,(pbcy*j)/ny-pbcy/2+(i%2)*0.5*dy,curv_lo[gk],rcurv_lo[gk],ang_exts[gk],add_pore,inner_lengs[gk]+2)[0]+mem_size+mz+zdist*(2*gk-1) for i in range(nz)] for j in range(ny)] for k in range(nx)]
|
|
4048
|
+
else:
|
|
4049
|
+
grid = [[[(pbcz*(i+0.5))/nz >= leaflet_function((pbcx*k)/nx-pbcx/2+((i+j)%2)*0.5*dx,(pbcy*j)/ny-pbcy/2+(i%2)*0.5*dy,curv_up[gk],rcurv_up[gk],ang_exts[gk],add_pore,inner_lengs[gk]-2)[0]+mem_size+mz+zdist*(2*gk-1) or (pbcz*(i+0.5))/nz <= leaflet_function((pbcx*k)/nx-pbcx/2+((i+j)%2)*0.5*dx,(pbcy*j)/ny-pbcy/2+(i%2)*0.5*dy,curv_lo[gk],rcurv_lo[gk],ang_exts[gk],add_pore,inner_lengs[gk]+2)[0]-mem_size+mz+zdist*(2*gk-1) for i in range(nz)] for j in range(ny)] for k in range(nx)]
|
|
4050
|
+
grids.append(grid)
|
|
4051
|
+
grids = np.array(grids)
|
|
4052
|
+
grid = grids[0]*grids[1]
|
|
4053
|
+
|
|
4054
|
+
else:
|
|
4055
|
+
if is_micelle:
|
|
4056
|
+
rad = mi_rad
|
|
4057
|
+
else:
|
|
4058
|
+
if mem_outer_red>0:
|
|
4059
|
+
rad = mem_outer_red
|
|
4060
|
+
else:
|
|
4061
|
+
rad = 1000
|
|
4062
|
+
if(cdirs[0] < 0):
|
|
4063
|
+
grid = [[[((pbcx*k)/nx-pbcx/2)*((pbcx*k)/nx-pbcx/2)+((pbcy*j)/ny-pbcy/2)*((pbcy*j)/ny-pbcy/2) > rad*rad or (pbcz*(i+0.5))/nz <= -leaflet_function((pbcx*k)/nx-pbcx/2+((i+j)%2)*0.5*dx,(pbcy*j)/ny-pbcy/2+(i%2)*0.5*dy,curv_up[0],rcurv_up[0],ang_exts[0],add_pore,inner_lengs[0])[0]-mem_size+mz or (pbcz*(i+0.5))/nz >= -leaflet_function((pbcx*k)/nx-pbcx/2+((i+j)%2)*0.5*dx,(pbcy*j)/ny-pbcy/2+(i%2)*0.5*dy,curv_lo[0],rcurv_lo[0],ang_exts[0],add_pore,inner_lengs[0])[0]+mem_size+mz for i in range(nz)] for j in range(ny)] for k in range(nx)]
|
|
4064
|
+
else:
|
|
4065
|
+
grid = [[[((pbcx*k)/nx-pbcx/2)*((pbcx*k)/nx-pbcx/2)+((pbcy*j)/ny-pbcy/2)*((pbcy*j)/ny-pbcy/2) > rad*rad or (pbcz*(i+0.5))/nz >= leaflet_function((pbcx*k)/nx-pbcx/2+((i+j)%2)*0.5*dx,(pbcy*j)/ny-pbcy/2+(i%2)*0.5*dy,curv_up[0],rcurv_up[0],ang_exts[0],add_pore,inner_lengs[0])[0]+mem_size+mz or (pbcz*(i+0.5))/nz <= leaflet_function((pbcx*k)/nx-pbcx/2+((i+j)%2)*0.5*dx,(pbcy*j)/ny-pbcy/2+(i%2)*0.5*dy,curv_lo[0],rcurv_lo[0],ang_exts[0],add_pore,inner_lengs[0])[0]-mem_size+mz for i in range(nz)] for j in range(ny)] for k in range(nx)]
|
|
4066
|
+
else:
|
|
4067
|
+
grid = [[[True for i in range(nz)] for j in range(ny)] for k in range(nx)]
|
|
4068
|
+
|
|
4069
|
+
|
|
4070
|
+
if len(protein.coord) > 0:
|
|
4071
|
+
print("Filling the inside of protein(s) with solvent...")
|
|
4072
|
+
|
|
4073
|
+
grid = np.array(grid)
|
|
4074
|
+
pc = np.array(protein.coord)
|
|
4075
|
+
maxz = np.max(pc[:,2])
|
|
4076
|
+
minz = np.min(pc[:,2])
|
|
4077
|
+
|
|
4078
|
+
max_iz = int((maxz/pbcz)*nz)
|
|
4079
|
+
min_iz = int((minz/pbcz)*nz)
|
|
4080
|
+
#print(max_iz,min_iz)
|
|
4081
|
+
|
|
4082
|
+
for zl in range(min_iz,max_iz):
|
|
4083
|
+
#print(zl)
|
|
4084
|
+
acc_z = (zl/nz)*pbcz
|
|
4085
|
+
lzrange = acc_z-dz
|
|
4086
|
+
uzrange = acc_z+dz
|
|
4087
|
+
zpslice = pc[np.logical_and(pc[:,2] > lzrange,pc[:,2] < uzrange)]
|
|
4088
|
+
water_layer = np.zeros((nx,ny))
|
|
4089
|
+
for pos in zpslice[:,:2]:
|
|
4090
|
+
px = int((pos[0]/pbcx)*nx)
|
|
4091
|
+
py = int((pos[1]/pbcy)*ny)
|
|
4092
|
+
water_layer[px,py] = 1
|
|
4093
|
+
|
|
4094
|
+
filled_water = flood_fill(water_layer,False)+water_layer
|
|
4095
|
+
|
|
4096
|
+
grid[:,:,zl][filled_water[:,:] == 0] = True
|
|
4097
|
+
print("Removing solvent in cells occupied by other structures...")
|
|
4098
|
+
# Flag all cells occupied by protein or membrane
|
|
4099
|
+
for p,q,r in protein.coord+membrane.coord+PGL.coord:
|
|
4100
|
+
for s,t,u in pointsOnSphere(20):
|
|
4101
|
+
x,y,z = p+0.1*s,q+0.1*t,r+0.1*u
|
|
4102
|
+
|
|
4103
|
+
if z >= pbcz:
|
|
4104
|
+
x -= box[2][0]
|
|
4105
|
+
y -= box[2][1]
|
|
4106
|
+
z -= box[2][2]
|
|
4107
|
+
if z < 0:
|
|
4108
|
+
x += box[2][0]
|
|
4109
|
+
y += box[2][1]
|
|
4110
|
+
z += box[2][2]
|
|
4111
|
+
if y >= pbcy:
|
|
4112
|
+
x -= box[1][0]
|
|
4113
|
+
y -= box[1][1]
|
|
4114
|
+
if y < 0:
|
|
4115
|
+
x += box[1][0]
|
|
4116
|
+
y += box[1][1]
|
|
4117
|
+
if x >= pbcx:
|
|
4118
|
+
x -= box[0][0]
|
|
4119
|
+
if x < 0:
|
|
4120
|
+
x += box[0][0]
|
|
4121
|
+
|
|
4122
|
+
|
|
4123
|
+
zgrid = int(nz*z/rz)
|
|
4124
|
+
y = y-(0.5*dy)*(zgrid%2)
|
|
4125
|
+
ygrid = int(ny*y/ry)
|
|
4126
|
+
x = x - (0.5*dx)*((zgrid+ygrid)%2)
|
|
4127
|
+
|
|
4128
|
+
|
|
4129
|
+
grid[int(nx*x/rx)][ygrid][zgrid] = False
|
|
4130
|
+
|
|
4131
|
+
for i in range(nx):
|
|
4132
|
+
for j in range(ny):
|
|
4133
|
+
for k in range(nz):
|
|
4134
|
+
if(random.random() < anti_freeze):
|
|
4135
|
+
grid[i][j][k] = False
|
|
4136
|
+
|
|
4137
|
+
|
|
4138
|
+
# Set the center for each solvent molecule
|
|
4139
|
+
kick = options["-solr"].value
|
|
4140
|
+
grid = [ [R(),(i+0.5+R()*kick)*dx + (0.5*dx)*((j+k)%2),(j+0.5+R()*kick)*dy+(0.5*dy)*(k%2),(k+0.5+R()*kick)*dz]
|
|
4141
|
+
for i in range(nx) for j in range(ny) for k in range(nz) if grid[i][j][k] ]
|
|
4142
|
+
|
|
4143
|
+
|
|
4144
|
+
print("Calculating number of solvent compartments...")
|
|
4145
|
+
comp_nos = np.zeros(3)
|
|
4146
|
+
if(zdist > 1e-5):
|
|
4147
|
+
for gr in grid:
|
|
4148
|
+
lz = leaflet_function(gr[1]-pbcx/2,gr[2]-pbcy/2,curv_up[0],rcurv_up[0],ang_exts[0],add_pore,inner_lengs[0])[0]+mz-zdist
|
|
4149
|
+
uz = -leaflet_function(gr[1]-pbcx/2,gr[2]-pbcy/2,curv_up[1],rcurv_up[1],ang_exts[1],add_pore,inner_lengs[1])[0]+mz+zdist
|
|
4150
|
+
|
|
4151
|
+
if(gr[3] > lz and gr[3] < uz):
|
|
4152
|
+
gr[0] += 1
|
|
4153
|
+
comp_nos[1] += 1
|
|
4154
|
+
elif gr[3] < lz:
|
|
4155
|
+
comp_nos[0] += 1
|
|
4156
|
+
elif gr[3] > uz:
|
|
4157
|
+
if(not (zpbc or add_pore)):
|
|
4158
|
+
gr[0] += 2
|
|
4159
|
+
comp_nos[2] += 1
|
|
4160
|
+
|
|
4161
|
+
else:
|
|
4162
|
+
for gr in grid:
|
|
4163
|
+
lz = cdirs[0]*leaflet_function(gr[1]-pbcx/2,gr[2]-pbcy/2,curv_up[0],rcurv_up[0],ang_exts[0],add_pore,inner_lengs[0])[0]+mz
|
|
4164
|
+
if(gr[3] > lz):
|
|
4165
|
+
if(not (zpbc or add_pore)):
|
|
4166
|
+
gr[0] += 1
|
|
4167
|
+
comp_nos[2] += 1
|
|
4168
|
+
elif gr[3] < lz:
|
|
4169
|
+
comp_nos[0] += 1
|
|
4170
|
+
if(zpbc or add_pore):
|
|
4171
|
+
comp_nos[0] = comp_nos[0]+comp_nos[2]
|
|
4172
|
+
comp_nos[2] = 0
|
|
4173
|
+
|
|
4174
|
+
|
|
4175
|
+
# Sort on the random number
|
|
4176
|
+
grid.sort()
|
|
4177
|
+
|
|
4178
|
+
# 'grid' contains all positions on which a solvent molecule can be placed.
|
|
4179
|
+
# The number of positions is taken as the basis for determining the salt concentration.
|
|
4180
|
+
# This is fine for simple salt solutions, but may not be optimal for complex mixtures
|
|
4181
|
+
# (like when mixing a 1M solution of this with a 1M solution of that
|
|
4182
|
+
|
|
4183
|
+
|
|
4184
|
+
print("Calculating charges per compartment...")
|
|
4185
|
+
|
|
4186
|
+
# First get names and relative numbers for each solvent
|
|
4187
|
+
solnames, solnums = list(zip(*[ parse_mol(i) for i in solv ]))
|
|
4188
|
+
solnames, solnums = list(solnames), list(solnums)
|
|
4189
|
+
totS = float(sum(solnums))
|
|
4190
|
+
|
|
4191
|
+
# Set the number of ions to add
|
|
4192
|
+
nna, ncl = 0, 0
|
|
4193
|
+
charge_rats = np.zeros(3)
|
|
4194
|
+
if options["-charge_ratio"].value:
|
|
4195
|
+
concs = options["-charge_ratio"].value.split(",")
|
|
4196
|
+
# If the concentration is set negative, set the charge to zero
|
|
4197
|
+
countc = 0
|
|
4198
|
+
for c in concs:
|
|
4199
|
+
charge_rats[countc] = float(c)
|
|
4200
|
+
countc += 1
|
|
4201
|
+
|
|
4202
|
+
|
|
4203
|
+
|
|
4204
|
+
|
|
4205
|
+
non_zero = 0
|
|
4206
|
+
for cn in comp_nos:
|
|
4207
|
+
if(cn > 1e-5):
|
|
4208
|
+
non_zero += 1
|
|
4209
|
+
|
|
4210
|
+
|
|
4211
|
+
concentrations = np.zeros(3)
|
|
4212
|
+
if options["-ion_conc"].value:
|
|
4213
|
+
concs = options["-ion_conc"].value.split(",")
|
|
4214
|
+
# If the concentration is set negative, set the charge to zero
|
|
4215
|
+
countc = 0
|
|
4216
|
+
for c in concs:
|
|
4217
|
+
concentrations[countc] = float(c)
|
|
4218
|
+
countc += 1
|
|
4219
|
+
|
|
4220
|
+
nsol = ("SPC" in solnames and 1 or 4)*len(grid)
|
|
4221
|
+
|
|
4222
|
+
# Correct number of grid cells for placement of solvent
|
|
4223
|
+
|
|
4224
|
+
|
|
4225
|
+
if options["-charge"].value != "0":
|
|
4226
|
+
charge = (options["-charge"].value != "auto") and int(options["-charge"].value) or charge
|
|
4227
|
+
else:
|
|
4228
|
+
charge = 0
|
|
4229
|
+
|
|
4230
|
+
ncharges = np.zeros(3,dtype=int)
|
|
4231
|
+
if options["-charge_ratio"].value:
|
|
4232
|
+
charge_rats /= np.sum(charge_rats[:non_zero])
|
|
4233
|
+
ncharges = np.array(charge*charge_rats,dtype=int)
|
|
4234
|
+
else:
|
|
4235
|
+
if(zdist > 1e-5):
|
|
4236
|
+
ncharges[1],_,_,_ = get_charge(mz-zdist,mz+zdist)
|
|
4237
|
+
ncharges[2],_,_,_ = get_charge(mz+zdist,pbcz)
|
|
4238
|
+
ncharges[0],_,_,_ = get_charge(0,mz-zdist)
|
|
4239
|
+
if(zpbc):
|
|
4240
|
+
ncharges[0] = ncharges[0]+ncharges[2]
|
|
4241
|
+
else:
|
|
4242
|
+
if(zpbc):
|
|
4243
|
+
ncharges[0] = charge
|
|
4244
|
+
else:
|
|
4245
|
+
ncharges[2],_,_,_ = get_charge(mz,pbcz)
|
|
4246
|
+
ncharges[0],_,_,_ = get_charge(0,mz)
|
|
4247
|
+
|
|
4248
|
+
|
|
4249
|
+
#dealing with charge of each compartment
|
|
4250
|
+
diff_c = charge-np.sum(ncharges)
|
|
4251
|
+
ncharges[0] += diff_c
|
|
4252
|
+
new_solnames = []
|
|
4253
|
+
new_num_sol = []
|
|
4254
|
+
rcomp_nos = comp_nos/np.sum(comp_nos)
|
|
4255
|
+
|
|
4256
|
+
if(len(pos_ions[1]) == 0):
|
|
4257
|
+
pos_ions[1] = pos_ions[0]
|
|
4258
|
+
if(len(pos_ions[2]) == 0):
|
|
4259
|
+
pos_ions[2] = pos_ions[0]
|
|
4260
|
+
|
|
4261
|
+
if(len(neg_ions[1]) == 0):
|
|
4262
|
+
neg_ions[1] = neg_ions[0]
|
|
4263
|
+
if(len(neg_ions[2]) == 0):
|
|
4264
|
+
neg_ions[2] = neg_ions[0]
|
|
4265
|
+
ion_names = []
|
|
4266
|
+
for pi in pos_ions:
|
|
4267
|
+
for pii in pi:
|
|
4268
|
+
mole = parse_mol(pii)[0]
|
|
4269
|
+
if(mole not in solnames):
|
|
4270
|
+
solnames.append(mole)
|
|
4271
|
+
ion_names.append(mole)
|
|
4272
|
+
for pi in neg_ions:
|
|
4273
|
+
for pii in pi:
|
|
4274
|
+
mole = parse_mol(pii)[0]
|
|
4275
|
+
if(mole not in solnames):
|
|
4276
|
+
solnames.append(mole)
|
|
4277
|
+
ion_names.append(mole)
|
|
4278
|
+
|
|
4279
|
+
for ci,cn in enumerate(comp_nos):
|
|
4280
|
+
added = 0
|
|
4281
|
+
new_nsol = nsol*rcomp_nos[ci]
|
|
4282
|
+
total_ions = int(1+(concentrations[ci]*new_nsol/(27.7+concentrations[ci])))
|
|
4283
|
+
|
|
4284
|
+
cperi = -ncharges[ci]/total_ions
|
|
4285
|
+
|
|
4286
|
+
negi = neg_ions[ci]
|
|
4287
|
+
posi = pos_ions[ci]
|
|
4288
|
+
|
|
4289
|
+
|
|
4290
|
+
total_negc = 0
|
|
4291
|
+
total_posc = 0
|
|
4292
|
+
total_negi = 0
|
|
4293
|
+
total_posi = 0
|
|
4294
|
+
for ni_c in negi:
|
|
4295
|
+
iname, icount = parse_mol(ni_c)
|
|
4296
|
+
total_negc += ion_charges[iname]*icount
|
|
4297
|
+
total_negi += icount
|
|
4298
|
+
|
|
4299
|
+
for pi_c in posi:
|
|
4300
|
+
iname, icount = parse_mol(pi_c)
|
|
4301
|
+
total_posc += ion_charges[iname]*icount
|
|
4302
|
+
total_posi += icount
|
|
4303
|
+
|
|
4304
|
+
|
|
4305
|
+
if(total_negc-(total_negi/total_posi) == 0):
|
|
4306
|
+
A_pos = (cperi-total_negc/total_negi)/(total_posc-total_negc*(total_posi/total_negi))
|
|
4307
|
+
A_neg = (cperi-total_posc*A_pos)/total_negc
|
|
4308
|
+
elif(total_posc-(total_posi/total_negi) == 0):
|
|
4309
|
+
A_neg = (cperi-total_posc/total_posi)/(total_negc-total_posc*(total_negi/total_posi))
|
|
4310
|
+
A_pos = (cperi-total_negc*A_neg)/total_posc
|
|
4311
|
+
else:
|
|
4312
|
+
A_neg = (cperi-total_posc/total_posi)/(total_negc-total_posc*(total_negi/total_posi))
|
|
4313
|
+
A_pos = (cperi-total_negc/total_negi)/(total_posc-total_negc*(total_posi/total_negi))
|
|
4314
|
+
|
|
4315
|
+
if(A_pos < 0):
|
|
4316
|
+
A_pos = 0
|
|
4317
|
+
A_neg = cperi/total_negc
|
|
4318
|
+
if(A_neg < 0):
|
|
4319
|
+
A_neg = 0
|
|
4320
|
+
A_pos = cperi/total_posc
|
|
4321
|
+
|
|
4322
|
+
A_pos = max(0,A_pos)*total_ions
|
|
4323
|
+
A_neg = max(0,A_neg)*total_ions
|
|
4324
|
+
|
|
4325
|
+
negi_dict = {}
|
|
4326
|
+
posi_dict = {}
|
|
4327
|
+
|
|
4328
|
+
for pi_c in ion_names:
|
|
4329
|
+
negi_dict[pi_c]=0
|
|
4330
|
+
posi_dict[pi_c]=0
|
|
4331
|
+
|
|
4332
|
+
for ni_c in negi:
|
|
4333
|
+
iname, icount = parse_mol(ni_c)
|
|
4334
|
+
negi_dict[iname]=icount*A_neg
|
|
4335
|
+
|
|
4336
|
+
total_pic = 0
|
|
4337
|
+
for pi_c in posi:
|
|
4338
|
+
iname, icount = parse_mol(pi_c)
|
|
4339
|
+
posi_dict[iname]=icount*A_pos
|
|
4340
|
+
|
|
4341
|
+
ion_nums = []
|
|
4342
|
+
for inn in ion_names:
|
|
4343
|
+
ion_nums.append(int(posi_dict[inn]+negi_dict[inn]))
|
|
4344
|
+
|
|
4345
|
+
|
|
4346
|
+
|
|
4347
|
+
total_ion_charge = 0
|
|
4348
|
+
for ind,inn in enumerate(ion_names):
|
|
4349
|
+
total_ion_charge += ion_charges[inn]*ion_nums[ind]
|
|
4350
|
+
|
|
4351
|
+
|
|
4352
|
+
cdiff = ncharges[ci]+total_ion_charge
|
|
4353
|
+
|
|
4354
|
+
|
|
4355
|
+
if(cdiff > 0):
|
|
4356
|
+
for ind,inn in enumerate(ion_names):
|
|
4357
|
+
if(ion_charges[inn] == -1):
|
|
4358
|
+
ion_nums[ind] += cdiff
|
|
4359
|
+
break
|
|
4360
|
+
|
|
4361
|
+
elif(cdiff < 0):
|
|
4362
|
+
for ind,inn in enumerate(ion_names):
|
|
4363
|
+
if(ion_charges[inn] == 1):
|
|
4364
|
+
ion_nums[ind] -= cdiff
|
|
4365
|
+
break
|
|
4366
|
+
|
|
4367
|
+
|
|
4368
|
+
ngrid = cn - np.sum(ion_nums)
|
|
4369
|
+
num_sol = [int(ngrid*i/totS) for i in solnums]
|
|
4370
|
+
for inn in ion_nums:
|
|
4371
|
+
num_sol.append(inn)
|
|
4372
|
+
|
|
4373
|
+
|
|
4374
|
+
|
|
4375
|
+
for n,sn in enumerate(solnames):
|
|
4376
|
+
adj_cn = num_sol
|
|
4377
|
+
if(cn > 1e-5):
|
|
4378
|
+
new_solnames.append(sn)
|
|
4379
|
+
new_num_sol.append(num_sol[n])
|
|
4380
|
+
added += num_sol[n]
|
|
4381
|
+
differ = int(cn-added)
|
|
4382
|
+
if(len(new_num_sol)>0):
|
|
4383
|
+
new_num_sol[-len(solnames)]+=differ
|
|
4384
|
+
|
|
4385
|
+
num_sol = []
|
|
4386
|
+
for i in range(len(solnames)):
|
|
4387
|
+
num_sol.append(np.sum(new_num_sol[i::len(solnames)]))
|
|
4388
|
+
print("THIS SHOULD BE ZERO",len(grid)-sum(num_sol))
|
|
4389
|
+
|
|
4390
|
+
|
|
4391
|
+
|
|
4392
|
+
# Names and grid positions for solvent molecules
|
|
4393
|
+
solvent = list(zip([s for i,s in list(zip(new_num_sol,new_solnames)) for j in range(i)],grid))
|
|
4394
|
+
|
|
4395
|
+
solvent_split = []
|
|
4396
|
+
for sni in range(len(solnames)):
|
|
4397
|
+
solvent_split.append([])
|
|
4398
|
+
for si in solvent:
|
|
4399
|
+
if(si[0] in solnames):
|
|
4400
|
+
solvent_split[solnames.index(si[0])].append(si)
|
|
4401
|
+
solvent = []
|
|
4402
|
+
for si in solvent_split:
|
|
4403
|
+
for ssi in si:
|
|
4404
|
+
solvent.append(ssi)
|
|
4405
|
+
|
|
4406
|
+
# Extend the list of molecules (for the topology)
|
|
4407
|
+
molecules.extend(list(zip(solnames,num_sol)))
|
|
4408
|
+
print("Building solvent and ions...")
|
|
4409
|
+
cc = 0
|
|
4410
|
+
# Build the solvent
|
|
4411
|
+
sol = []
|
|
4412
|
+
for resn,(rndm,x,y,z) in solvent:
|
|
4413
|
+
|
|
4414
|
+
cc += 1
|
|
4415
|
+
resi += 1
|
|
4416
|
+
solmol = solventParticles.get(resn)
|
|
4417
|
+
if solmol and len(solmol) > 1:
|
|
4418
|
+
# Random rotation (quaternion)
|
|
4419
|
+
u, v, w = random.random(), 2*math.pi*random.random(), 2*math.pi*random.random()
|
|
4420
|
+
s, t = math.sqrt(1-u), math.sqrt(u)
|
|
4421
|
+
qw, qx, qy, qz = s*math.sin(v), s*math.cos(v), t*math.sin(w), t*math.cos(w)
|
|
4422
|
+
qq = qw*qw-qx*qx-qy*qy-qz*qz
|
|
4423
|
+
for atnm,(px,py,pz) in solmol:
|
|
4424
|
+
qp = 2*(qx*px + qy*py + qz*pz)
|
|
4425
|
+
rx = x + qp*qx + qq*px + qw*(qy*pz-qz*py)
|
|
4426
|
+
ry = y + qp*qy + qq*py + qw*(qz*px-qx*pz)
|
|
4427
|
+
rz = z + qp*qz + qq*pz + qw*(qx*py-qy*px)
|
|
4428
|
+
sol.append(("%5d%-5s%5s%5d"%(resi%1e5,resn,atnm,atid%1e5),(rx,ry,rz)))
|
|
4429
|
+
atid += 1
|
|
4430
|
+
else:
|
|
4431
|
+
sol.append(("%5d%-5s%5s%5d"%(resi%1e5,resn,solmol and solmol[0][0] or resn,atid%1e5),(x,y,z)))
|
|
4432
|
+
atid += 1
|
|
4433
|
+
print("Done")
|
|
4434
|
+
else:
|
|
4435
|
+
solvent, sol = None, []
|
|
4436
|
+
|
|
4437
|
+
print("Writing files...")
|
|
4438
|
+
## Write the output ##
|
|
4439
|
+
slen = solvent and len(sol) or 0
|
|
4440
|
+
|
|
4441
|
+
print("; NDX Solvent %d %d" % (1+plen+mlen+pglen, solvent and plen+mlen+slen+pglen or 0),file=sys.stderr)
|
|
4442
|
+
print("; NDX System %d %d" % (1, plen+mlen+slen+pglen),file=sys.stderr)
|
|
4443
|
+
print("; \"I mean, the good stuff is just INSANE\" --Julia Ormond",file=sys.stderr)
|
|
4444
|
+
|
|
4445
|
+
# Open the output stream
|
|
4446
|
+
oStream = options["-o"] and open(options["-o"].value,"w") or sys.stdout
|
|
4447
|
+
|
|
4448
|
+
# print(the title)
|
|
4449
|
+
if membrane.atoms:
|
|
4450
|
+
title = "INSANE! Membrane UpperLeaflet>"+":".join(lipU)+"="+":".join([str(i) for i in numU])
|
|
4451
|
+
title += " LowerLeaflet>"+":".join(lipL)+"="+":".join([str(i) for i in numL])
|
|
4452
|
+
|
|
4453
|
+
if protein:
|
|
4454
|
+
title = "Protein in " + title
|
|
4455
|
+
else:
|
|
4456
|
+
title = "Insanely solvated protein."
|
|
4457
|
+
|
|
4458
|
+
print(title,file=oStream)
|
|
4459
|
+
|
|
4460
|
+
#print(the number of atoms)
|
|
4461
|
+
print("%5d"%(len(protein)+len(membrane)+len(sol)+len(PGL)),file=oStream)
|
|
4462
|
+
|
|
4463
|
+
|
|
4464
|
+
membrane.atoms,membrane.coord = reorder_atoms(membrane.atoms,membrane.coord)
|
|
4465
|
+
|
|
4466
|
+
new_molecules = []
|
|
4467
|
+
mol_types = []
|
|
4468
|
+
for m in molecules:
|
|
4469
|
+
if(m[0] in mol_types):
|
|
4470
|
+
new_molecules[mol_types.index(m[0])][1] += m[1]
|
|
4471
|
+
else:
|
|
4472
|
+
mol_types.append(m[0])
|
|
4473
|
+
new_molecules.append(list(m))
|
|
4474
|
+
|
|
4475
|
+
|
|
4476
|
+
# print(the atoms)
|
|
4477
|
+
id = 1
|
|
4478
|
+
if protein:
|
|
4479
|
+
for i in range(len(protein)):
|
|
4480
|
+
at,rn,ri = protein.atoms[i][:3]
|
|
4481
|
+
x,y,z = protein.coord[i]
|
|
4482
|
+
oStream.write("%5d%-5s%5s%5d%8.3f%8.3f%8.3f\n"%(ri%1e5,rn,at,id%1e5,x,y,z))
|
|
4483
|
+
id += 1
|
|
4484
|
+
if PGL:
|
|
4485
|
+
for i in range(len(PGL)):
|
|
4486
|
+
at,rn,ri = PGL.atoms[i][:3]
|
|
4487
|
+
x,y,z = PGL.coord[i]
|
|
4488
|
+
x = x%pbcx
|
|
4489
|
+
y = y%pbcy
|
|
4490
|
+
oStream.write("%5d%-5s%5s%5d%8.3f%8.3f%8.3f\n"%(ri%1e5,rn,at,id%1e5,x,y,z))
|
|
4491
|
+
id += 1
|
|
4492
|
+
if membrane:
|
|
4493
|
+
for i in range(len(membrane)):
|
|
4494
|
+
at,rn,ri = membrane.atoms[i][:3]
|
|
4495
|
+
x,y,z = membrane.coord[i]
|
|
4496
|
+
oStream.write("%5d%-5s%5s%5d%8.3f%8.3f%8.3f\n"%(ri%1e5,rn,at,id%1e5,x,y,z))
|
|
4497
|
+
id += 1
|
|
4498
|
+
|
|
4499
|
+
if sol:
|
|
4500
|
+
# print(the solvent)
|
|
4501
|
+
print("\n".join([i[0]+"%8.3f%8.3f%8.3f"%i[1] for i in sol]),file=oStream)
|
|
4502
|
+
|
|
4503
|
+
|
|
4504
|
+
# print(the box)
|
|
4505
|
+
print("%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f\n"%grobox,file=oStream)
|
|
4506
|
+
oStream.close()
|
|
4507
|
+
if options["-p"].value:
|
|
4508
|
+
# Write a rudimentary topology file
|
|
4509
|
+
with open(options["-p"].value,"w") as top:
|
|
4510
|
+
#print('#include "martini_v3.itp"\n',file=top)
|
|
4511
|
+
print('; '+' '.join(sys.argv),file=top)
|
|
4512
|
+
print('#include "martini_v3.0.0.itp"',file=top)
|
|
4513
|
+
print('#include "martini_v3.0.0_ions_v1.itp"',file=top)
|
|
4514
|
+
print('#include "martini_v3.0.0_solvents_v1.itp"',file=top)
|
|
4515
|
+
print('#include "martini_v3.0.0_phospholipids_v1.itp"',file=top)
|
|
4516
|
+
if(PGL):
|
|
4517
|
+
print('#include "PGL.itp"',file=top)
|
|
4518
|
+
|
|
4519
|
+
if protein:
|
|
4520
|
+
print('#include "protein-cg.itp"',file=top)
|
|
4521
|
+
print('[ system ]\n; name\n%s\n\n[ molecules ]\n; name number'%title,file=top)
|
|
4522
|
+
if protein:
|
|
4523
|
+
print("%-10s %5d"%("Protein",1),file=top)
|
|
4524
|
+
print("\n".join("%-10s %7d"%tuple(i) for i in new_molecules),file=top)
|
|
4525
|
+
|
|
4526
|
+
else:
|
|
4527
|
+
print("\n".join("%-10s %7d"%tuple(i) for i in new_molecules),file=sys.stderr)
|
|
4528
|
+
|
|
4529
|
+
print("Done!")
|
|
4530
|
+
|
|
4531
|
+
|
|
4532
|
+
if __name__ == "__main__":
|
|
4533
|
+
main()
|