Unverified Commit b5581e88 authored by peastman's avatar peastman Committed by GitHub
Browse files

Merge pull request #1946 from peastman/patch

Can build arbitrary membranes by supplying a pre-equilibrated patch
parents a2c77a35 6ea84b2e
...@@ -1150,12 +1150,18 @@ class Modeller(object): ...@@ -1150,12 +1150,18 @@ class Modeller(object):
adds whole copies of the pre-equilibrated membrane patch, so the box dimensions will always be adds whole copies of the pre-equilibrated membrane patch, so the box dimensions will always be
integer multiples of the patch size. That may lead to a larger membrane than what you requested. integer multiples of the patch size. That may lead to a larger membrane than what you requested.
This method has built in support for POPC and POPE lipids. You can also build other types of
membranes by providing a pre-equilibrated, solvated membrane patch that can be tiled in the XY
plane to form the membrane.
Parameters Parameters
---------- ----------
forcefield : ForceField forcefield : ForceField
the ForceField to use for determining atomic charges and for relaxing the membrane the ForceField to use for determining atomic charges and for relaxing the membrane
lipidType : string='POPC' lipidType : string or object
the type of lipid to use. Supported values are 'POPC' and 'POPE'. the type of lipid to use. Supported string values are 'POPC' and 'POPE'. For other types
of lipids, provide a PDBFile or PDBxFile object (or any other object with "topology" and
"positions" fields) containing a membrane patch.
membraneCenterZ: distance=0*nanometer membraneCenterZ: distance=0*nanometer
the position along the Z axis of the center of the membrane the position along the Z axis of the center of the membrane
minimumPadding : distance=1*nanometer minimumPadding : distance=1*nanometer
...@@ -1172,10 +1178,12 @@ class Modeller(object): ...@@ -1172,10 +1178,12 @@ class Modeller(object):
neutralize : bool=True neutralize : bool=True
whether to add ions to neutralize the system whether to add ions to neutralize the system
""" """
lipidType = lipidType.upper() if 'topology' in dir(lipidType) and 'positions' in dir(lipidType):
if lipidType not in ('POPC', 'POPE'): patch = lipidType
elif lipidType.upper() in ('POPC', 'POPE'):
patch = PDBFile(os.path.join(os.path.dirname(__file__), 'data', lipidType.upper()+'.pdb'))
else:
raise ValueError('Unsupported lipid type: '+lipidType) raise ValueError('Unsupported lipid type: '+lipidType)
patchPdb = PDBFile(os.path.join(os.path.dirname(__file__), 'data', lipidType+'.pdb'))
if is_quantity(membraneCenterZ): if is_quantity(membraneCenterZ):
membraneCenterZ = membraneCenterZ.value_in_unit(nanometer) membraneCenterZ = membraneCenterZ.value_in_unit(nanometer)
if is_quantity(minimumPadding): if is_quantity(minimumPadding):
...@@ -1189,8 +1197,8 @@ class Modeller(object): ...@@ -1189,8 +1197,8 @@ class Modeller(object):
proteinSize = proteinMaxPos-proteinMinPos proteinSize = proteinMaxPos-proteinMinPos
proteinCenterPos = (proteinMinPos+proteinMaxPos)/2 proteinCenterPos = (proteinMinPos+proteinMaxPos)/2
proteinCenterPos = Vec3(proteinCenterPos[0], proteinCenterPos[1], membraneCenterZ) proteinCenterPos = Vec3(proteinCenterPos[0], proteinCenterPos[1], membraneCenterZ)
patchPos = patchPdb.positions.value_in_unit(nanometer) patchPos = patch.positions.value_in_unit(nanometer)
patchSize = patchPdb.topology.getUnitCellDimensions().value_in_unit(nanometer) patchSize = patch.topology.getUnitCellDimensions().value_in_unit(nanometer)
patchCenterPos = (min(patchPos)+max(patchPos))/2 patchCenterPos = (min(patchPos)+max(patchPos))/2
nx = int(ceil((proteinSize[0]+2*minimumPadding)/patchSize[0])) nx = int(ceil((proteinSize[0]+2*minimumPadding)/patchSize[0]))
ny = int(ceil((proteinSize[1]+2*minimumPadding)/patchSize[1])) ny = int(ceil((proteinSize[1]+2*minimumPadding)/patchSize[1]))
...@@ -1209,7 +1217,7 @@ class Modeller(object): ...@@ -1209,7 +1217,7 @@ class Modeller(object):
# Record the bonds for each residue. # Record the bonds for each residue.
resBonds = defaultdict(list) resBonds = defaultdict(list)
for bond in patchPdb.topology.bonds(): for bond in patch.topology.bonds():
resBonds[bond[0].residue].append(bond) resBonds[bond[0].residue].append(bond)
# Identify which leaf of the membrane each lipid is in. # Identify which leaf of the membrane each lipid is in.
...@@ -1217,7 +1225,7 @@ class Modeller(object): ...@@ -1217,7 +1225,7 @@ class Modeller(object):
numLipidAtoms = 0 numLipidAtoms = 0
resMeanZ = {} resMeanZ = {}
membraneMeanZ = 0.0 membraneMeanZ = 0.0
for res in patchPdb.topology.residues(): for res in patch.topology.residues():
if res.name != 'HOH': if res.name != 'HOH':
numResAtoms = 0 numResAtoms = 0
sumZ = 0.0 sumZ = 0.0
...@@ -1263,7 +1271,7 @@ class Modeller(object): ...@@ -1263,7 +1271,7 @@ class Modeller(object):
for x in range(nx): for x in range(nx):
for y in range(ny): for y in range(ny):
offset = proteinCenterPos - patchCenterPos + Vec3((x-0.5*(nx-1))*patchSize[0], (y-0.5*(ny-1))*patchSize[1], 0) offset = proteinCenterPos - patchCenterPos + Vec3((x-0.5*(nx-1))*patchSize[0], (y-0.5*(ny-1))*patchSize[1], 0)
for res in patchPdb.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 referencePos = proteinPos
......
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