Commit 3f8ea2f5 by peastman

Can build membranes

parent 943fda10
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
</head> </head>
<body> <body>
<h1 style="text-align:center">PDBFixer</h1> <h1 style="text-align:center">PDBFixer</h1>
<div style="text-align:center">Copyright 2013-2015 by Peter Eastman and Stanford University</div> <div style="text-align:center">Copyright 2013-2017 by Peter Eastman and Stanford University</div>
<h1>1. Introduction</h1> <h1>1. Introduction</h1>
...@@ -18,6 +18,7 @@ Protein Data Bank (PDB or PDBx/mmCIF) files often have a number of problems that ...@@ -18,6 +18,7 @@ Protein Data Bank (PDB or PDBx/mmCIF) files often have a number of problems that
<li>The file may include more than what you want to simulate. For example, there may be salts, ligands, or other molecules that were added for experimental purposes. Or the crystallographic unit cell may contain multiple copies of a protein, but you only want to simulate a single copy.</li> <li>The file may include more than what you want to simulate. For example, there may be salts, ligands, or other molecules that were added for experimental purposes. Or the crystallographic unit cell may contain multiple copies of a protein, but you only want to simulate a single copy.</li>
<li>There may be multiple locations listed for some atoms.</li> <li>There may be multiple locations listed for some atoms.</li>
<li>If you want to simulate the structure in explicit solvent, you will need to add a water box surrounding it.</li> <li>If you want to simulate the structure in explicit solvent, you will need to add a water box surrounding it.</li>
<li>For membrane proteins, you may also need to add a lipid membrane.</li>
</ol> </ol>
PDBFixer can fix all of these problems for you in a fully automated way. You simply select a file, tell it which problems to fix, and it does everything else. PDBFixer can fix all of these problems for you in a fully automated way. You simply select a file, tell it which problems to fix, and it does everything else.
...@@ -71,13 +72,14 @@ If the file contains nonstandard residues, this page will allow you to replace t ...@@ -71,13 +72,14 @@ If the file contains nonstandard residues, this page will allow you to replace t
This page lists all heavy atoms that are missing from the file. They will be added automatically. This page lists all heavy atoms that are missing from the file. They will be added automatically.
<h3>Add Hydrogens and Water</h3> <h3>Add Hydrogens, Water, and Membrane</h3>
This page gives you the chance to make other optional changes: This page gives you the chance to make other optional changes:
<ul> <ul>
<li><b>Add Missing Hydrogens</b> If hydrogen atoms are missing from the file, PDBFixer can add them for you. Some residues can exist in multiple protonation states. To select which one to use, you can specify a pH, and the most common form of each residue at that pH will be used.</li> <li><b>Add Missing Hydrogens</b> If hydrogen atoms are missing from the file, PDBFixer can add them for you. Some residues can exist in multiple protonation states. To select which one to use, you can specify a pH, and the most common form of each residue at that pH will be used.</li>
<li><b>Add Water</b> Add a water box surrounding the system. In addition to water, counterions will be added to neutalize the system. You also may choose to add more ions based on a desired total ionic strength. Select the ionic strength and the types of ions to use. <li><b>Add Water</b> Add a water box surrounding the system. In addition to water, counterions will be added to neutalize the system. You also may choose to add more ions based on a desired total ionic strength. Select the ionic strength and the types of ions to use.</li>
<li><b>Add Membrane</b> Add a lipid membrane. POPC and POPE lipids are supported.</li>
</ul> </ul>
<h3>Save File</h3> <h3>Save File</h3>
...@@ -212,6 +214,16 @@ If you want to add a water box, call <tt>addSolvent()</tt>. This method has sev ...@@ -212,6 +214,16 @@ If you want to add a water box, call <tt>addSolvent()</tt>. This method has sev
<p> <p>
<tt>fixer.addSolvent(Vec3(5, 5, 5)*nanometer, positiveIon='K+', ionicStrength=0.1*molar)</tt> <tt>fixer.addSolvent(Vec3(5, 5, 5)*nanometer, positiveIon='K+', ionicStrength=0.1*molar)</tt>
<h3>Add Membrane</h3>
If you want to add a lipid membrane, call <tt>addMembrane()</tt>. This method also adds water, so you should not also call <tt>addSolvent()</tt> when using it. There are several optional arguments. The full definition is
<p>
<tt>addMembrane(self, lipidType='POPC', membraneCenterZ=0*nanometer, minimumPadding=1*nanometer, positiveIon='Na+', negativeIon='Cl-', ionicStrength=0*molar)</tt>
<p>
<tt>lipidType</tt> should be either <tt>'POPC'</tt> or <tt>'POPE'</tt>. <tt>membraneCenterZ</tt> is the position along the Z axis at which the center of the membrane will be located. <tt>minimumPadding</tt> is the minimum acceptable distance between the protein and the edges of the periodic box. All other arguments are the same as for <tt>addSolvent()</tt>. For example, the following line adds a POPE membrane centered at Z=0 with at least 1 nm of padding on all sides:
<p>
<tt>fixer.addMembrane('POPE')</tt>
<h3>Examples</h3> <h3>Examples</h3>
Here is a complete example that ties this together. It adds all missing atoms including heavy atoms, missing residues, and hydrogens. It replaces all nonstandard residues by their standard equivalents then deletes all remaining heterogens except water. Finally, it fills in all gaps with water; that is, it adds a water box whose dimensions match the crystallographic unit cell. It saves the result to a file called output.pdb. Here is a complete example that ties this together. It adds all missing atoms including heavy atoms, missing residues, and hydrogens. It replaces all nonstandard residues by their standard equivalents then deletes all remaining heterogens except water. Finally, it fills in all gaps with water; that is, it adds a water box whose dimensions match the crystallographic unit cell. It saves the result to a file called output.pdb.
......
...@@ -18,8 +18,20 @@ function validateForm() { ...@@ -18,8 +18,20 @@ function validateForm() {
} }
var geombox = document.getElementById("geometricBoxRadio").checked var geombox = document.getElementById("geometricBoxRadio").checked
var padsize = document.getElementById("geomPadding").value var padsize = document.getElementById("geomPadding").value
if (geombox && !(padsize > 0)) { if (geombox && padsize < 0) {
alert("Box padding must be a positive number.") alert("Box padding cannot be negative.")
return false
}
var strength = document.getElementById("ionicstrengthfield").value
if (!(strength >= 0)) {
alert("Ionic strength must be a nonnegative number.")
return false
}
}
if (document.getElementById("addMembraneCheckbox").checked) {
var padsize = document.getElementById("membranePadding").value
if (padsize < 0) {
alert("Box padding cannot be negative.")
return false return false
} }
var strength = document.getElementById("ionicstrengthfield").value var strength = document.getElementById("ionicstrengthfield").value
...@@ -45,6 +57,20 @@ function applyPaddingToWaterBox(padding) { ...@@ -45,6 +57,20 @@ function applyPaddingToWaterBox(padding) {
} }
} }
} }
function waterBoxChanged() {
checked = document.getElementById('addWaterCheckbox').checked;
document.getElementById('addMembraneCheckbox').checked = false;
enableControls(document.getElementById('waterInputs'), checked);
enableControls(document.getElementById('ionInputs'), checked);
enableControls(document.getElementById('membraneInputs'), false);
}
function membraneBoxChanged() {
checked = document.getElementById('addMembraneCheckbox').checked;
document.getElementById('addWaterCheckbox').checked = false;
enableControls(document.getElementById('membraneInputs'), checked);
enableControls(document.getElementById('ionInputs'), checked);
enableControls(document.getElementById('waterInputs'), false);
}
</script> </script>
<style> <style>
a.tooltip { a.tooltip {
...@@ -90,10 +116,10 @@ a.tooltip:hover:before { ...@@ -90,10 +116,10 @@ a.tooltip:hover:before {
Add missing hydrogen atoms? Add missing hydrogen atoms?
<p> <p>
<input type="checkbox" id="addHydrogensCheckbox" name="addhydrogens" onchange="document.getElementById('phfield').disabled=!document.getElementById('addHydrogensCheckbox').checked" checked> Add hydrogens appropriate for pH <input type="text" id="phfield" name="ph" value="7.0" size="5"> <input type="checkbox" id="addHydrogensCheckbox" name="addhydrogens" onchange="document.getElementById('phfield').disabled=!document.getElementById('addHydrogensCheckbox').checked" checked> Add hydrogens appropriate for pH <input type="text" id="phfield" name="ph" value="7.0" size="5">
<h1>Add Water</h1> <h1>Add Water/Membrane</h1>
Add a water box surrounding the model? Add a water box or membrane surrounding the model?
<p> <p>
<input type="checkbox" id="addWaterCheckbox" name="addwater" onchange="enableControls(document.getElementById('waterInputs'), document.getElementById('addWaterCheckbox').checked)"> Add water <input type="checkbox" id="addWaterCheckbox" name="addwater" onchange="waterBoxChanged()"> Add water box
<div id="waterInputs" style="margin-left:50px"> <div id="waterInputs" style="margin-left:50px">
<table style="text-align:right"> <table style="text-align:right">
<tr> <tr>
...@@ -122,6 +148,22 @@ Add a water box surrounding the model? ...@@ -122,6 +148,22 @@ Add a water box surrounding the model?
</tr> </tr>
%s %s
</table> </table>
</div>
<p>
<input type="checkbox" id="addMembraneCheckbox" name="addmembrane" onchange="membraneBoxChanged()"> Add membrane and water
<div id="membraneInputs" style="margin-left:50px">
The membrane will lie in the XY plane and be centered at Z=0. Make sure the protein is properly oriented and positioned.
When possible, it is easiest to use a PDB file from <a href="http://opm.phar.umich.edu/">OPM</a> since they are already properly positioned.
<p>
Lipid type:
<select id="lipidType" name="lipidType">
<option value="POPC" selected="selected">POPC</option>
<option value="POPE">POPE</option>
</select>
<p>
Minimum padding around protein: <input type="text" id="membranePadding" name="membranePadding" value="1.0" size="5"> (nm)
</div>
<div id="ionInputs">
<p> <p>
Ions will be added to neutralize the model. You can optionally add more ions based on a desired bulk ionic strength. Ions will be added to neutralize the model. You can optionally add more ions based on a desired bulk ionic strength.
<p> <p>
...@@ -137,6 +179,8 @@ Add a water box surrounding the model? ...@@ -137,6 +179,8 @@ Add a water box surrounding the model?
<script> <script>
setCurrentStep(6); setCurrentStep(6);
enableControls(document.getElementById('waterInputs'), false); enableControls(document.getElementById('waterInputs'), false);
enableControls(document.getElementById('membraneInputs'), false);
enableControls(document.getElementById('ionInputs'), false);
var molxyz = [].slice.call(document.getElementById('boxContainingAllAtoms').getElementsByTagName('td')).splice(1,3).map(function(td){ return parseFloat(td.textContent)}); var molxyz = [].slice.call(document.getElementById('boxContainingAllAtoms').getElementsByTagName('td')).splice(1,3).map(function(td){ return parseFloat(td.textContent)});
var hiddenInput = document.createElement("input"); var hiddenInput = document.createElement("input");
hiddenInput.setAttribute("type", "hidden"); hiddenInput.setAttribute("type", "hidden");
......
...@@ -1063,11 +1063,43 @@ class PDBFixer(object): ...@@ -1063,11 +1063,43 @@ class PDBFixer(object):
self.topology = modeller.topology self.topology = modeller.topology
self.positions = modeller.positions self.positions = modeller.positions
def addMembrane(self, lipidType='POPC', membraneCenterZ=0*unit.nanometer, minimumPadding=1*unit.nanometer, positiveIon='Na+', negativeIon='Cl-', ionicStrength=0*unit.molar):
"""Add a lipid membrane to the structure.
This method adds both lipids and water, so you should call either addSolvent() or addMembrane(),
but not both. See Modeller.addMembrane() for more details.
Parameters
----------
lipidType : string='POPC'
the type of lipid to use. Supported values are 'POPC' and 'POPE'.
membraneCenterZ: distance=0*nanometer
the position along the Z axis of the center of the membrane
minimumPadding : distance=1*nanometer
the padding distance to use
positiveIon : str, optional, default='Na+'
The type of positive ion to add. Allowed values are 'Cs+', 'K+', 'Li+', 'Na+', and 'Rb+'.
negativeIon : str, optional, default='Cl-'
The type of negative ion to add. Allowed values are 'Cl-', 'Br-', 'F-', and 'I-'.
ionicStrength : simtk.unit.Quantity with units compatible with molar, optional, default=0*molar
The total concentration of ions (both positive and negative) to add. This does not include ions that are added to neutralize the system.
"""
modeller = app.Modeller(self.topology, self.positions)
forcefield = self._createForceField(self.topology, True)
modeller.addMembrane(forcefield, lipidType=lipidType, minimumPadding=minimumPadding, positiveIon=positiveIon, negativeIon=negativeIon, ionicStrength=ionicStrength)
chains = list(modeller.topology.chains())
if len(chains) == 1:
chains[0].id = 'A'
else:
chains[-1].id = chr(ord(chains[-2].id)+1)
self.topology = modeller.topology
self.positions = modeller.positions
def _createForceField(self, newTopology, water): def _createForceField(self, newTopology, water):
"""Create a force field to use for optimizing the positions of newly added atoms.""" """Create a force field to use for optimizing the positions of newly added atoms."""
if water: if water:
forcefield = app.ForceField('amber10.xml', 'tip3p.xml') forcefield = app.ForceField('amber14-all.xml', 'amber14/tip3p.xml')
nonbonded = [f for f in forcefield._forces if isinstance(f, NonbondedGenerator)][0] nonbonded = [f for f in forcefield._forces if isinstance(f, NonbondedGenerator)][0]
radii = {'H':0.198, 'Li':0.203, 'C':0.340, 'N':0.325, 'O':0.299, 'F':0.312, 'Na':0.333, 'Mg':0.141, radii = {'H':0.198, 'Li':0.203, 'C':0.340, 'N':0.325, 'O':0.299, 'F':0.312, 'Na':0.333, 'Mg':0.141,
'P':0.374, 'S':0.356, 'Cl':0.347, 'K':0.474, 'Br':0.396, 'Rb':0.527, 'I':0.419, 'Cs':0.605} 'P':0.374, 'S':0.356, 'Cl':0.347, 'K':0.474, 'Br':0.396, 'Rb':0.527, 'I':0.419, 'Cs':0.605}
......
...@@ -128,6 +128,13 @@ def addHydrogensPageCallback(parameters, handler): ...@@ -128,6 +128,13 @@ def addHydrogensPageCallback(parameters, handler):
positiveIon = parameters.getfirst('positiveion')+'+' positiveIon = parameters.getfirst('positiveion')+'+'
negativeIon = parameters.getfirst('negativeion')+'-' negativeIon = parameters.getfirst('negativeion')+'-'
fixer.addSolvent(boxSize, padding, boxVectors, positiveIon, negativeIon, ionicStrength) fixer.addSolvent(boxSize, padding, boxVectors, positiveIon, negativeIon, ionicStrength)
if 'addmembrane' in parameters:
lipidType = parameters.getfirst('lipidType')
padding = float(parameters.getfirst('membranePadding'))*unit.nanometer
ionicStrength = float(parameters.getfirst('ionicstrength'))*unit.molar
positiveIon = parameters.getfirst('positiveion')+'+'
negativeIon = parameters.getfirst('negativeion')+'-'
fixer.addMembrane(lipidType, 0*unit.nanometer, padding, positiveIon, negativeIon, ionicStrength)
displaySaveFilePage() displaySaveFilePage()
def saveFilePageCallback(parameters, handler): def saveFilePageCallback(parameters, handler):
......
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