Commit 93663581 by John Chodera (MSKCC)

Merge remote-tracking branch 'upstream/master'

parents 94084151 db272571
language: c
env:
matrix:
- CONDA_PY=2.7
- CONDA_PY=3.3
- CONDA_PY=3.4
install:
- sudo apt-get update -qq
- sudo apt-get install -qq python-dev python-pip python-yaml g++ ftp
- sudo pip install conda eventlet
- sudo conda init
- conda config --add channels http://conda.binstar.org/omnia
- conda create --yes --name test nose setuptools numpy biopython pyflakes openmm
- conda create --yes --name test nose setuptools numpy biopython pyflakes openmm-dev
- export PATH="$HOME/envs/test/bin/:$PATH"
script:
......
from pdbfixer import PDBFixer
from __future__ import absolute_import
from .pdbfixer import PDBFixer
......@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of
Biological Structures at Stanford, funded under the NIH Roadmap for
Medical Research, grant U54 GM072970. See https://simtk.org.
Portions copyright (c) 2013-2014 Stanford University and the Authors.
Portions copyright (c) 2013-2015 Stanford University and the Authors.
Authors: Peter Eastman
Contributors:
......@@ -28,6 +28,7 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from __future__ import absolute_import
__author__ = "Peter Eastman"
__version__ = "1.1"
......@@ -207,7 +208,7 @@ class PDBFixer(object):
self.source = url
file = urlopen(url)
# Read contents all at once and split into lines, since urlopen doesn't like it when we read one line at a time over the network.
contents = file.read()
contents = file.read().decode('utf-8')
lines = contents.split('\n')
file.close()
structure = PdbStructure(lines)
......@@ -221,7 +222,6 @@ class PDBFixer(object):
self.pdb = app.PDBFile(structure)
self.topology = self.pdb.topology
self.positions = self.pdb.positions
self.structureChains = list(self.structure.iter_chains())
# Load the templates.
......@@ -462,7 +462,6 @@ class PDBFixer(object):
modeller.delete(allChains[i] for i in chainIndices)
self.topology = modeller.topology
self.positions = modeller.positions
self.structureChains = [self.structureChains[i] for i in range(len(self.structureChains)) if i not in chainIndices]
return
......@@ -481,17 +480,17 @@ class PDBFixer(object):
>>> missing_residues = fixer.missingResidues
"""
chains = [c for c in self.structureChains if any(atom.record_name == 'ATOM' for atom in c.iter_atoms())]
chains = [c for c in self.topology.chains() if len(list(c.residues())) > 0]
chainWithGaps = {}
# Find the sequence of each chain, with gaps for missing residues.
for chain in chains:
minResidue = min(r.number for r in chain.iter_residues())
maxResidue = max(r.number for r in chain.iter_residues())
minResidue = min(int(r.id) for r in chain.residues())
maxResidue = max(int(r.id) for r in chain.residues())
residues = [None]*(maxResidue-minResidue+1)
for r in chain.iter_residues():
residues[r.number-minResidue] = r.get_name()
for r in chain.residues():
residues[int(r.id)-minResidue] = r.name
chainWithGaps[chain] = residues
# Try to find the chain that matches each sequence.
......@@ -500,7 +499,7 @@ class PDBFixer(object):
chainOffset = {}
for sequence in self.structure.sequences:
for chain in chains:
if chain.chain_id != sequence.chain_id:
if chain.id != sequence.chain_id:
continue
if chain in chainSequence:
continue
......@@ -515,15 +514,15 @@ class PDBFixer(object):
# Now build the list of residues to add.
self.missingResidues = {}
for structChain, topChain in zip(self.structureChains, self.topology.chains()):
if structChain in chainSequence:
offset = chainOffset[structChain]
sequence = chainSequence[structChain].residues
gappedSequence = chainWithGaps[structChain]
for chain in self.topology.chains():
if chain in chainSequence:
offset = chainOffset[chain]
sequence = chainSequence[chain].residues
gappedSequence = chainWithGaps[chain]
index = 0
for i in range(len(sequence)):
if i < offset or i >= len(gappedSequence)+offset or gappedSequence[i-offset] is None:
key = (topChain.index, index)
key = (chain.index, index)
if key not in self.missingResidues:
self.missingResidues[key] = []
residueName = sequence[i]
......@@ -556,16 +555,16 @@ class PDBFixer(object):
# Now add ones based on MODRES records.
modres = dict(((m.chain_id, m.number, m.residue_name), m.standard_name) for m in self.structure.modified_residues)
for structChain, topChain in zip(self.structureChains, self.topology.chains()):
for structResidue, topResidue in zip(structChain.iter_residues(), topChain.residues()):
key = (structChain.chain_id, structResidue.number, structResidue.name)
modres = dict(((m.chain_id, str(m.number), m.residue_name), m.standard_name) for m in self.structure.modified_residues)
for chain in self.topology.chains():
for residue in chain.residues():
key = (chain.id, residue.id, residue.name)
if key in modres:
replacement = modres[key]
if replacement == 'DU':
replacement = 'DT'
if replacement in self.templates:
nonstandard[topResidue] = replacement
nonstandard[residue] = replacement
self.nonstandardResidues = [(r, nonstandard[r]) for r in sorted(nonstandard, key=lambda r: r.index)]
def replaceNonstandardResidues(self):
......@@ -1027,8 +1026,7 @@ class PDBFixer(object):
def main():
if len(sys.argv) < 2:
# Display the UI.
import ui
from . import ui
ui.launchUI()
else:
# Run in command line mode.
......
import simtk.openmm.app as app
from simtk.openmm.app.internal.pdbstructure import PdbStructure
import simtk.unit as unit
from pdbfixer import PDBFixer, substitutions, proteinResidues, dnaResidues, rnaResidues
import uiserver
from __future__ import absolute_import
import webbrowser
import os.path
import gzip
import time
from io import BytesIO
import simtk.openmm.app as app
import simtk.unit as unit
from .pdbfixer import PDBFixer, proteinResidues, dnaResidues, rnaResidues
from . import uiserver
try:
from urllib.request import urlopen
from io import StringIO
......@@ -27,7 +29,7 @@ def loadImageFile(name):
if name not in cachedImages:
imagePath = os.path.join(os.path.dirname(__file__), 'images')
file = os.path.join(imagePath, name)
cachedImages[name] = open(file).read()
cachedImages[name] = open(file, 'rb').read()
return cachedImages[name]
def controlsCallback(parameters, handler):
......@@ -53,13 +55,21 @@ def startPageCallback(parameters, handler):
global fixer
if 'type' in parameters:
if parameters.getfirst('type') == 'local':
fixer = PDBFixer(file=parameters['pdbfile'].value.decode().splitlines())
fixer = PDBFixer(pdbfile=parameters['pdbfile'].value.decode().splitlines())
fixer.source = parameters['pdbfile'].filename
else:
id = parameters.getfirst('pdbid')
try:
fixer = PDBFixer(pdbid=id)
except:
handler.sendResponse(header+"Unable to download the PDB file. This may indicate an invalid PDB identifier, or an error in network connectivity."+loadHtmlFile("error.html"))
except Exception as e:
import traceback
print(traceback.format_exc())
handler.sendResponse(
header + "<p>Unable to download the PDB file. " +
"This may indicate an invalid PDB identifier, " +
"or an error in network connectivity.</p>" +
"<p>{}</p>".format(e) +
loadHtmlFile("error.html"))
displayDeleteChainsPage()
def deleteChainsPageCallback(parameters, handler):
......@@ -73,7 +83,7 @@ def addResiduesPageCallback(parameters, handler):
for i, key in enumerate(keys):
if 'add'+str(i) not in parameters:
del fixer.missingResidues[key]
displayMissingAtomsPage()
displayConvertResiduesPage()
def convertResiduesPageCallback(parameters, handler):
for i in range(len(fixer.nonstandardResidues)):
......@@ -134,7 +144,7 @@ def displayDeleteChainsPage():
content = "DNA"
else:
content = ', '.join(set(residues))
table += ' <tr><td>%d</td><td>%d</td><td>%s</td><td><input type="checkbox" name="include%d" checked></td></tr>\n' % (chain.index+1, len(residues), content, i)
table += ' <tr><td>%s</td><td>%d</td><td>%s</td><td><input type="checkbox" name="include%d" checked></td></tr>\n' % (chain.id, len(residues), content, i)
uiserver.setContent(header+loadHtmlFile("removeChains.html") % (numChains, table))
def displayAddResiduesPage():
......@@ -144,14 +154,16 @@ def displayAddResiduesPage():
displayConvertResiduesPage()
return
table = ""
chains = list(fixer.topology.chains())
for i, key in enumerate(sorted(fixer.missingResidues)):
residues = fixer.missingResidues[key]
chain = fixer.structureChains[key[0]]
if key[1] < len(chain.residues):
offset = chain.residues[key[1]].number-len(residues)-1
chain = chains[key[0]]
chainResidues = list(chain.residues())
if key[1] < len(chainResidues):
offset = int(chainResidues[key[1]].id)-len(residues)-1
else:
offset = chain.residues[-1].number
table += ' <tr><td>%d</td><td>%d to %d</td><td>%s</td><td><input type="checkbox" name="add%d" checked></td></tr>\n' % (key[0]+1, offset+1, offset+len(residues), ', '.join(residues), i)
offset = int(chainResidues[-1].id)
table += ' <tr><td>%s</td><td>%d to %d</td><td>%s</td><td><input type="checkbox" name="add%d" checked></td></tr>\n' % (chain.id, offset+1, offset+len(residues), ', '.join(residues), i)
uiserver.setContent(header+loadHtmlFile("addResidues.html") % table)
def displayConvertResiduesPage():
......@@ -160,10 +172,6 @@ def displayConvertResiduesPage():
if len(fixer.nonstandardResidues) == 0:
displayMissingAtomsPage()
return
indexInChain = {}
for structChain, topChain in zip(fixer.structureChains, fixer.topology.chains()):
for structResidue, topResidue in zip(structChain.iter_residues(), topChain.residues()):
indexInChain[topResidue] = structResidue.number
table = ''
nucleotides = ['DA', 'DC', 'DG', 'DT', 'A', 'C', 'G', 'T']
for i in range(len(fixer.nonstandardResidues)):
......@@ -178,7 +186,7 @@ def displayConvertResiduesPage():
if res == replaceWith:
selected = ' selected'
options += '<option value="%s"%s>%s</option>' % (res, selected, res)
table += ' <tr><td>%d</td><td>%s %d</td><td><select name="residue%d">%s</select></td><td><input type="checkbox" name="convert%d" checked></td></tr>\n' % (residue.chain.index+1, residue.name, indexInChain[residue], i, options, i)
table += ' <tr><td>%s</td><td>%s %s</td><td><select name="residue%d">%s</select></td><td><input type="checkbox" name="convert%d" checked></td></tr>\n' % (residue.chain.id, residue.name, residue.id, i, options, i)
uiserver.setContent(header+loadHtmlFile("convertResidues.html") % table)
def displayMissingAtomsPage():
......@@ -190,10 +198,6 @@ def displayMissingAtomsPage():
fixer.addMissingAtoms()
displayAddHydrogensPage()
return
indexInChain = {}
for structChain, topChain in zip(fixer.structureChains, fixer.topology.chains()):
for structResidue, topResidue in zip(structChain.iter_residues(), topChain.residues()):
indexInChain[topResidue] = structResidue.number
table = ""
for residue in allResidues:
atoms = []
......@@ -201,7 +205,7 @@ def displayMissingAtomsPage():
atoms.extend(atom.name for atom in fixer.missingAtoms[residue])
if residue in fixer.missingTerminals:
atoms.extend(atom for atom in fixer.missingTerminals[residue])
table += ' <tr><td>%d</td><td>%s %d</td><td>%s</td></tr>\n' % (residue.chain.index+1, residue.name, indexInChain[residue], ', '.join(atoms))
table += ' <tr><td>%s</td><td>%s %s</td><td>%s</td></tr>\n' % (residue.chain.id, residue.name, residue.id, ', '.join(atoms))
uiserver.setContent(header+loadHtmlFile("addHeavyAtoms.html") % table)
def displayAddHydrogensPage():
......
......@@ -46,7 +46,7 @@ class _Handler(BaseHTTPRequestHandler):
self.send_header("Content-type", type)
self.send_header("Content-length", str(len(response)))
self.end_headers()
if sys.version_info.major > 2:
if sys.version_info.major > 2 and isinstance(response, str):
response = bytes(response, 'UTF-8')
self.wfile.write(response)
......
from __future__ import print_function
import pdbfixer
import simtk.openmm
......@@ -79,7 +80,7 @@ def simulate(pdbcode, pdb_filename):
del context, integrator
print "Simulation completed: potential = %.3f kcal/mol" % potential
print("Simulation completed: potential = %.3f kcal/mol" % potential)
return
......@@ -105,8 +106,8 @@ def test_build_and_simulate():
failures = list()
for pdbcode in pdbcodes_to_build:
print "------------------------------------------------"
print pdbcode
print("------------------------------------------------")
print(pdbcode)
output_pdb_filename = 'output.pdb'
......@@ -152,14 +153,14 @@ def test_build_and_simulate():
except Watchdog:
message = "timed out in stage %s" % stage
print message
print(message)
failures.append((pdbcode, Exception(message)))
except Exception as e:
print "EXCEPTION DURING BUILD"
print("EXCEPTION DURING BUILD")
#import traceback
#print traceback.print_exc()
print str(e)
print(str(e))
failures.append((pdbcode, e))
watchdog.stop()
......@@ -173,14 +174,14 @@ def test_build_and_simulate():
except Watchdog:
message = "timed out in simulation"
print message
print(message)
failures.append((pdbcode, Exception(message)))
except Exception as e:
print "EXCEPTION DURING SIMULATE"
print("EXCEPTION DURING SIMULATE")
#import traceback
#print traceback.print_exc()
print str(e)
print(str(e))
failures.append((pdbcode, e))
watchdog.stop()
......@@ -189,21 +190,21 @@ def test_build_and_simulate():
# Clean up.
os.remove(output_pdb_filename)
print "------------------------------------------------"
print("------------------------------------------------")
if len(failures) != 0:
print ""
print "SUMMARY OF FAILURES:"
print ""
print("")
print("SUMMARY OF FAILURES:")
print("")
for failure in failures:
(pdbcode, exception) = failure
print "%6s : %s" % (pdbcode, str(exception))
print ""
print("%6s : %s" % (pdbcode, str(exception)))
print("")
raise Exception("Build test failed on one or more PDB files.")
else:
print "All tests succeeded."
print("All tests succeeded.")
if __name__ == '__main__':
test_build_and_simulate()
......@@ -9,7 +9,7 @@ def remove_chain_ids_and_verify(pdbid, chain_ids_to_remove, expected_chain_ids_r
# Remove specified chains.
fixer.removeChains(chainIds=chain_ids_to_remove)
# Check to make sure asserted chains remain.
chain_ids_remaining = [c.chain_id for c in fixer.structureChains]
chain_ids_remaining = [c.id for c in fixer.topology.chains()]
assert_items_equal(chain_ids_remaining, expected_chain_ids_remaining)
def test_removechain_ids():
......@@ -25,7 +25,7 @@ def remove_chain_indices_and_verify(pdbid, chain_indices_to_remove, expected_cha
# Remove specified chains.
fixer.removeChains(chainIndices=chain_indices_to_remove)
# Check to make sure asserted chains remain.
chain_ids_remaining = [c.chain_id for c in fixer.structureChains]
chain_ids_remaining = [c.id for c in fixer.topology.chains()]
assert_items_equal(chain_ids_remaining, expected_chain_ids_remaining)
def test_removechain_indices():
......
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