Commit a11b141c by Jaime RGP

Support for additional solvation boxes

parent 1e02b130
...@@ -8,14 +8,21 @@ function validateForm() { ...@@ -8,14 +8,21 @@ function validateForm() {
} }
} }
if (document.getElementById("addWaterCheckbox").checked) { if (document.getElementById("addWaterCheckbox").checked) {
var custombox = document.getElementById("customBoxRadio").checked
var xsize = document.getElementById("boxxfield").value var xsize = document.getElementById("boxxfield").value
var ysize = document.getElementById("boxyfield").value var ysize = document.getElementById("boxyfield").value
var zsize = document.getElementById("boxzfield").value var zsize = document.getElementById("boxzfield").value
var strength = document.getElementById("ionicstrengthfield").value if (custombox && !(xsize > 0 && ysize > 0 && zsize > 0)) {
if (!(xsize > 0 && ysize > 0 && zsize > 0)) {
alert("Box dimensions must be positive numbers.") alert("Box dimensions must be positive numbers.")
return false return false
} }
var geombox = document.getElementById("geometricBoxRadio").checked
var padsize = document.getElementById("geomPadding").value
if (geombox && !(padsize > 0)) {
alert("Box padding must be a positive number.")
return false
}
var strength = document.getElementById("ionicstrengthfield").value
if (!(strength >= 0)) { if (!(strength >= 0)) {
alert("Ionic strength must be a nonnegative number.") alert("Ionic strength must be a nonnegative number.")
return false return false
...@@ -59,15 +66,28 @@ Add a water box surrounding the model? ...@@ -59,15 +66,28 @@ Add a water box surrounding the model?
<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>
<td>Type box dimensions (in nm):</td> <td style="text-align:left"><input id="customBoxRadio" type="radio" name="boxType" value="custom" checked>Custom box dimensions (in nm):</td>
<div id="customBoxDimensions">
<td><input type="text" id="boxxfield" name="boxx" size="8"></td> <td><input type="text" id="boxxfield" name="boxx" size="8"></td>
<td><input type="text" id="boxyfield" name="boxy" size="8"></td> <td><input type="text" id="boxyfield" name="boxy" size="8"></td>
<td><input type="text" id="boxzfield" name="boxz" size="8"></td> <td><input type="text" id="boxzfield" name="boxz" size="8"></td>
</div>
</tr> </tr>
<tr> <tr>
<td>... or set them from padding:</td> <td style="text-align:left"><input id="geometricBoxRadio" type="radio" name="boxType" value="geometry">Geometry with padding (in nm):</td>
<td><input type="text" id="xyzpadding" name="xyzpad" size="8" oninput="applyPaddingToWaterBox(this.value)"></td> <div id="geometricBoxDimensions">
<td colspan="2"><input type="checkbox" id="cubicPaddingCheckBox" name="cubicPaddingCheckBox" checked>Force cubic geometry <span title="All sides are equal to the biggest dimension plus padding" style="border-bottom: 1px dotted black; cursor: help">?</span></td> <td><input type="text" id="geomPadding" name="geomPadding" size="8">
</td>
<td colspan="2">
<select id="geometryDropdown" name="geometryDropdown">
<option value="cube" selected="selected">Cube</option>
<option value="truncatedOctahedron">Truncated octahedron</option>
<option value="rhombicDodecahedron">Rhombic dodecahedron</option>
</select>
<span title="The specified padding will be applied on the largest molecular axis, maintaining selected geometry" style="border-bottom: 1px dotted black; cursor: help">?</span>
</div>
</td>
</tr> </tr>
%s %s
</table> </table>
...@@ -87,7 +107,11 @@ Add a water box surrounding the model? ...@@ -87,7 +107,11 @@ Add a water box surrounding the model?
setCurrentStep(6); setCurrentStep(6);
enableControls(document.getElementById('waterInputs'), false); enableControls(document.getElementById('waterInputs'), 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 pbcxyz = [document.getElementById('boxxfield'), document.getElementById('boxyfield'), document.getElementById('boxzfield')]; var hiddenInput = document.createElement("input");
hiddenInput.setAttribute("type", "hidden");
hiddenInput.setAttribute("name", "maxMolecularAxis");
hiddenInput.setAttribute("value", Math.max.apply(Math, molxyz));
document.getElementById("mainform").appendChild(hiddenInput);
</script> </script>
</body> </body>
<html> <html>
...@@ -1021,15 +1021,17 @@ class PDBFixer(object): ...@@ -1021,15 +1021,17 @@ class PDBFixer(object):
self.topology = modeller.topology self.topology = modeller.topology
self.positions = modeller.positions self.positions = modeller.positions
def addSolvent(self, boxSize=None, padding=None, positiveIon='Na+', negativeIon='Cl-', ionicStrength=0*unit.molar): def addSolvent(self, boxSize=None, padding=None, boxVectors=None, positiveIon='Na+', negativeIon='Cl-', ionicStrength=0*unit.molar):
"""Add a solvent box surrounding the structure. """Add a solvent box surrounding the structure.
Parameters Parameters
---------- ----------
boxSize : simtk.openmm.Vec3, optional, default=None boxSize : simtk.openmm.Vec3, optional, default=None
The size of the box to fill with water. If specified, padding must not be specified. The size of the box to fill with water. If specified, padding and boxVectors must not be specified.
padding : simtk.unit.Quantity compatible with nanometers, optional, default=None padding : simtk.unit.Quantity compatible with nanometers, optional, default=None
Padding around macromolecule for filling box with water. If specified, boxSize must not be specified. Padding around macromolecule for filling box with water. If specified, boxSize and boxVectors must not be specified.
boxVectors : 3-tuple of simtk.openmm.Vec3, optional, default=None
Three vectors specifying the geometry of the box. If specified, padding and boxSize must not be specified.
positiveIon : str, optional, default='Na+' positiveIon : str, optional, default='Na+'
The type of positive ion to add. Allowed values are 'Cs+', 'K+', 'Li+', 'Na+', and 'Rb+'. The type of positive ion to add. Allowed values are 'Cs+', 'K+', 'Li+', 'Na+', and 'Rb+'.
negativeIon : str, optional, default='Cl-' negativeIon : str, optional, default='Cl-'
...@@ -1053,7 +1055,7 @@ class PDBFixer(object): ...@@ -1053,7 +1055,7 @@ class PDBFixer(object):
modeller = app.Modeller(self.topology, self.positions) modeller = app.Modeller(self.topology, self.positions)
forcefield = self._createForceField(self.topology, True) forcefield = self._createForceField(self.topology, True)
modeller.addSolvent(forcefield, padding=padding, boxSize=boxSize, positiveIon=positiveIon, negativeIon=negativeIon, ionicStrength=ionicStrength) modeller.addSolvent(forcefield, padding=padding, boxSize=boxSize, boxVectors=boxVectors, positiveIon=positiveIon, negativeIon=negativeIon, ionicStrength=ionicStrength)
chains = list(modeller.topology.chains()) chains = list(modeller.topology.chains())
if len(chains) == 1: if len(chains) == 1:
chains[0].id = 'A' chains[0].id = 'A'
......
...@@ -3,9 +3,11 @@ from __future__ import absolute_import ...@@ -3,9 +3,11 @@ from __future__ import absolute_import
import webbrowser import webbrowser
import os.path import os.path
import time import time
from math import sqrt
import simtk.openmm.app as app import simtk.openmm.app as app
import simtk.unit as unit import simtk.unit as unit
from simtk.openmm.vec3 import Vec3
from .pdbfixer import PDBFixer, proteinResidues, dnaResidues, rnaResidues, _guessFileFormat from .pdbfixer import PDBFixer, proteinResidues, dnaResidues, rnaResidues, _guessFileFormat
from . import uiserver from . import uiserver
...@@ -111,11 +113,25 @@ def addHydrogensPageCallback(parameters, handler): ...@@ -111,11 +113,25 @@ def addHydrogensPageCallback(parameters, handler):
pH = float(parameters.getfirst('ph')) pH = float(parameters.getfirst('ph'))
fixer.addMissingHydrogens(pH) fixer.addMissingHydrogens(pH)
if 'addwater' in parameters: if 'addwater' in parameters:
boxSize = (float(parameters.getfirst('boxx')), float(parameters.getfirst('boxy')), float(parameters.getfirst('boxz')))*unit.nanometer padding, boxSize, boxVectors = None, None, None
if parameters.getfirst('boxType') == 'geometry':
geompadding = float(parameters.getfirst('geomPadding')) * unit.nanometer
geometry = parameters.getfirst('geometryDropdown')
base_size = float(parameters.getfirst('maxMolecularAxis')) * unit.nanometer
if geometry == 'cube':
padding = geompadding
elif geometry == 'truncatedOctahedron':
vectors = Vec3(1,0,0), Vec3(1/3,2*sqrt(2)/3,0), Vec3(-1/3,1/3,sqrt(6)/3)
boxVectors = [(base_size+geompadding)*v for v in vectors]
elif geometry == 'rhombicDodecahedron':
vectors = Vec3(1,0,0), Vec3(0,1,0), Vec3(0.5,0.5,sqrt(2)/2)
boxVectors = [(base_size+geompadding)*v for v in vectors]
else:
boxSize = (float(parameters.getfirst('boxx')), float(parameters.getfirst('boxy')), float(parameters.getfirst('boxz')))*unit.nanometer
ionicStrength = float(parameters.getfirst('ionicstrength'))*unit.molar ionicStrength = float(parameters.getfirst('ionicstrength'))*unit.molar
positiveIon = parameters.getfirst('positiveion')+'+' positiveIon = parameters.getfirst('positiveion')+'+'
negativeIon = parameters.getfirst('negativeion')+'-' negativeIon = parameters.getfirst('negativeion')+'-'
fixer.addSolvent(boxSize, None, positiveIon, negativeIon, ionicStrength) fixer.addSolvent(boxSize, padding, boxVectors, positiveIon, negativeIon, ionicStrength)
displaySaveFilePage() displaySaveFilePage()
def saveFilePageCallback(parameters, handler): def saveFilePageCallback(parameters, handler):
...@@ -123,7 +139,10 @@ def saveFilePageCallback(parameters, handler): ...@@ -123,7 +139,10 @@ def saveFilePageCallback(parameters, handler):
output = StringIO() output = StringIO()
if fixer.source is not None: if fixer.source is not None:
output.write("REMARK 1 PDBFIXER FROM: %s\n" % fixer.source) output.write("REMARK 1 PDBFIXER FROM: %s\n" % fixer.source)
app.PDBFile.writeFile(fixer.topology, fixer.positions, output, True) try:
app.PDBFile.writeFile(fixer.topology, fixer.positions, output, True)
except AssertionError:
print
handler.sendDownload(output.getvalue(), 'output.pdb') handler.sendDownload(output.getvalue(), 'output.pdb')
else: else:
displayStartPage() displayStartPage()
......
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