"vscode:/vscode.git/clone" did not exist on "ea4b6872df6de546186be2d2eb97a4fd00a8211a"
Unverified Commit 91c8073e authored by peastman's avatar peastman Committed by GitHub
Browse files

Merge pull request #2072 from peastman/membrane

Improvements to building membranes
parents d03646b5 fcee4150
...@@ -42,6 +42,7 @@ from simtk.openmm import System, Context, NonbondedForce, CustomNonbondedForce, ...@@ -42,6 +42,7 @@ from simtk.openmm import System, Context, NonbondedForce, CustomNonbondedForce,
from simtk.unit import nanometer, molar, elementary_charge, amu, gram, liter, degree, sqrt, acos, is_quantity, dot, norm from simtk.unit import nanometer, molar, elementary_charge, amu, gram, liter, degree, sqrt, acos, is_quantity, dot, norm
import simtk.unit as unit import simtk.unit as unit
from . import element as elem from . import element as elem
import gc
import os import os
import random import random
import xml.etree.ElementTree as etree import xml.etree.ElementTree as etree
...@@ -1255,8 +1256,8 @@ class Modeller(object): ...@@ -1255,8 +1256,8 @@ class Modeller(object):
boxSizeZ = max(boxSizeZ, self.topology.getUnitCellDimensions()[2].value_in_unit(nanometer)+2*minimumPadding) boxSizeZ = max(boxSizeZ, self.topology.getUnitCellDimensions()[2].value_in_unit(nanometer)+2*minimumPadding)
membraneTopology.setUnitCellDimensions((nx*patchSize[0], ny*patchSize[1], boxSizeZ)) membraneTopology.setUnitCellDimensions((nx*patchSize[0], ny*patchSize[1], boxSizeZ))
# Add membrane patches. We exclude any water that is within a cutoff distance of the *actual* protein, # Add membrane patches. We exclude any water that is within a cutoff distance of either the actual or scaled
# and any lipid that is within a cutoff distance of the *scaled* protein. We also keep track of how # protein, and any lipid that is within a cutoff distance of the scaled protein. We also keep track of how
# many lipids have been excluded from each leaf of the membrane, so we can make sure exactly the same # many lipids have been excluded from each leaf of the membrane, so we can make sure exactly the same
# number get removed from each leaf. # number get removed from each leaf.
...@@ -1274,23 +1275,28 @@ class Modeller(object): ...@@ -1274,23 +1275,28 @@ class Modeller(object):
for res in patch.topology.residues(): for res in patch.topology.residues():
resPos = [patchPos[atom.index]+offset for atom in res.atoms()] resPos = [patchPos[atom.index]+offset for atom in res.atoms()]
if res.name == 'HOH': if res.name == 'HOH':
referencePos = proteinPos # Remove waters that are too close to either the original OR scaled protein positions.
cells = proteinCells referencePosLists = [proteinPos, scaledProteinPos]
cellLists = [proteinCells, scaledProteinCells]
else: else:
referencePos = scaledProteinPos # Remove lipids that are too close to the scaled protein positions.
cells = scaledProteinCells referencePosLists = [scaledProteinPos]
cellLists = [scaledProteinCells]
overlap = False overlap = False
nearest = nx*patchSize[0] nearest = nx*patchSize[0]
for index, atom in enumerate(res.atoms()): for cells, referencePos in zip(cellLists, referencePosLists):
pos = resPos[index]
for atom in cells.neighbors(pos):
distance = norm(pos-referencePos[atom])
if distance < overlapCutoff:
overlap = True
break
nearest = min(nearest, distance)
if overlap: if overlap:
break break
for index, atom in enumerate(res.atoms()):
pos = resPos[index]
for atom in cells.neighbors(pos):
distance = norm(pos-referencePos[atom])
if distance < overlapCutoff:
overlap = True
break
nearest = min(nearest, distance)
if overlap:
break
if res.name == 'HOH': if res.name == 'HOH':
if not overlap: if not overlap:
addedWater.append((res, resPos)) addedWater.append((res, resPos))
...@@ -1300,6 +1306,9 @@ class Modeller(object): ...@@ -1300,6 +1306,9 @@ class Modeller(object):
else: else:
addedLipids.append((nearest, res, resPos)) addedLipids.append((nearest, res, resPos))
skipFromLeaf = [max(removedFromLeaf)-removedFromLeaf[i] for i in (0,1)] skipFromLeaf = [max(removedFromLeaf)-removedFromLeaf[i] for i in (0,1)]
del cellLists
del cells
del proteinCells
# Add the lipids. # Add the lipids.
...@@ -1317,6 +1326,8 @@ class Modeller(object): ...@@ -1317,6 +1326,8 @@ class Modeller(object):
membranePos += pos membranePos += pos
for bond in resBonds[residue]: for bond in resBonds[residue]:
membraneTopology.addBond(newAtoms[bond[0]], newAtoms[bond[1]], bond.type, bond.order) membraneTopology.addBond(newAtoms[bond[0]], newAtoms[bond[1]], bond.type, bond.order)
del lipidLeaf
del addedLipids
# Add the solvent. # Add the solvent.
...@@ -1329,6 +1340,10 @@ class Modeller(object): ...@@ -1329,6 +1340,10 @@ class Modeller(object):
membranePos += pos membranePos += pos
for bond in resBonds[residue]: for bond in resBonds[residue]:
membraneTopology.addBond(newAtoms[bond[0]], newAtoms[bond[1]], bond.type, bond.order) membraneTopology.addBond(newAtoms[bond[0]], newAtoms[bond[1]], bond.type, bond.order)
del newAtoms
del addedWater
del resBonds
gc.collect()
# Create a System for the lipids, then add in the protein as stationary particles. # Create a System for the lipids, then add in the protein as stationary particles.
...@@ -1344,11 +1359,15 @@ class Modeller(object): ...@@ -1344,11 +1359,15 @@ class Modeller(object):
nonbonded = f2 nonbonded = f2
for i in range(numProteinParticles): for i in range(numProteinParticles):
f1.addParticle(*f2.getParticleParameters(i)) f1.addParticle(*f2.getParticleParameters(i))
for j in range(i): for j in scaledProteinCells.neighbors(scaledProteinPos[i]):
f1.addException(i+numMembraneParticles, j+numMembraneParticles, 0.0, 1.0, 0.0) if j < i:
f1.addException(i+numMembraneParticles, j+numMembraneParticles, 0.0, 1.0, 0.0)
if nonbonded is None: if nonbonded is None:
raise ValueError('The ForceField does not specify a NonbondedForce') raise ValueError('The ForceField does not specify a NonbondedForce')
mergedPositions = membranePos+scaledProteinPos mergedPositions = membranePos+scaledProteinPos
del membranePos
del scaledProteinCells
gc.collect()
# Run a simulation while slowly scaling up the protein so the membrane can relax. # Run a simulation while slowly scaling up the protein so the membrane can relax.
...@@ -1370,6 +1389,9 @@ class Modeller(object): ...@@ -1370,6 +1389,9 @@ class Modeller(object):
modeller = Modeller(self.topology, self.positions) modeller = Modeller(self.topology, self.positions)
modeller.add(membraneTopology, context.getState(getPositions=True).getPositions()[:numMembraneParticles]) modeller.add(membraneTopology, context.getState(getPositions=True).getPositions()[:numMembraneParticles])
modeller.topology.setPeriodicBoxVectors(membraneTopology.getPeriodicBoxVectors()) modeller.topology.setPeriodicBoxVectors(membraneTopology.getPeriodicBoxVectors())
del context
del system
del integrator
# Depending on the box size, we may need to add more water beyond what was included with the membrane patch. # Depending on the box size, we may need to add more water beyond what was included with the membrane patch.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment