Commit 66d31f0a by peastman

Merge pull request #96 from jchodera/master

Added --pdbid, --url, and --verbose flags.
parents 97c882cd 326babc5
......@@ -98,6 +98,8 @@ When run with no arguments, it launches the user interface. If any arguments ar
Options:
-h, --help show this help message and exit
--pdbid=PDBID PDB id to retrieve from RCSB [default: None]
--url=URL URL to retrieve PDB from [default: None]
--output=FILENAME output pdb file [default: output.pdb]
--add-atoms=ATOMS which missing atoms to add: all, heavy, hydrogen, or
none [default: all]
......
[![Build Status](https://travis-ci.org/pandegroup/pdbfixer.svg)](https://travis-ci.org/pandegroup/pdbfixer)
[![Build Status](https://travis-ci.org/pandegroup/pdbfixer.svg?branch=master)](https://travis-ci.org/pandegroup/pdbfixer)
PDBFixer
========
......
......@@ -2,6 +2,10 @@ package:
name: pdbfixer-dev
version: dev
build:
entry_points:
- pdbfixer = pdbfixer.pdbfixer:main
requirements:
build:
- python
......@@ -18,6 +22,9 @@ test:
requires:
- nose
imports:
- pdbfixer
commands:
- nosetests pdbfixer --nocapture --verbosity=2 --with-doctest
......
......@@ -1036,6 +1036,8 @@ def main():
from optparse import OptionParser
parser = OptionParser(usage="Usage: %prog\n %prog [options] filename\n\nWhen run with no arguments, it launches the user interface. If any arguments are specified, it runs in command line mode.")
parser.add_option('--pdbid', default=None, dest='pdbid', metavar='PDBID', help='PDB id to retrieve from RCSB [default: None]')
parser.add_option('--url', default=None, dest='url', metavar='URL', help='URL to retrieve PDB from [default: None]')
parser.add_option('--output', default='output.pdb', dest='output', metavar='FILENAME', help='output pdb file [default: output.pdb]')
parser.add_option('--add-atoms', default='all', dest='atoms', choices=('all', 'heavy', 'hydrogen', 'none'), help='which missing atoms to add: all, heavy, hydrogen, or none [default: all]')
parser.add_option('--keep-heterogens', default='all', dest='heterogens', choices=('all', 'water', 'none'), metavar='OPTION', help='which heterogens to keep: all, water, or none [default: all]')
......@@ -1046,37 +1048,54 @@ def main():
parser.add_option('--positive-ion', default='Na+', dest='positiveIon', choices=('Cs+', 'K+', 'Li+', 'Na+', 'Rb+'), metavar='ION', help='positive ion to include in the water box: Cs+, K+, Li+, Na+, or Rb+ [default: Na+]')
parser.add_option('--negative-ion', default='Cl-', dest='negativeIon', choices=('Cl-', 'Br-', 'F-', 'I-'), metavar='ION', help='negative ion to include in the water box: Cl-, Br-, F-, or I- [default: Cl-]')
parser.add_option('--ionic-strength', type='float', default=0.0, dest='ionic', metavar='STRENGTH', help='molar concentration of ions to add to the water box [default: 0.0]')
parser.add_option('--verbose', default=False, action='store_true', dest='verbose', metavar='VERBOSE', help='Print verbose output')
(options, args) = parser.parse_args()
if len(args) == 0:
if (len(args) == 0) and (options.pdbid==None) and (options.url==None):
parser.error('No filename specified')
if len(args) > 1:
parser.error('Must specify a single filename')
fixer = PDBFixer(filename=sys.argv[1])
parser.error('Must specify a single filename or --pdbid or --url')
if options.pdbid != None:
if options.verbose: print('Retrieving PDB "' + options.pdbid + '" from RCSB...')
fixer = PDBFixer(pdbid=options.pdbid)
elif options.url != None:
if options.verbose: print('Retrieving PDB from URL "' + options.url + '"...')
fixer = PDBFixer(url=options.url)
else:
fixer = PDBFixer(filename=sys.argv[1])
if options.residues:
if options.verbose: print('Finding missing residues...')
fixer.findMissingResidues()
else:
fixer.missingResidues = {}
if options.nonstandard:
if options.verbose: print('Finding nonstandard residues...')
fixer.findNonstandardResidues()
if options.verbose: print('Replacing nonstandard residues...')
fixer.replaceNonstandardResidues()
if options.verbose: print('Finding missing atoms...')
fixer.findMissingAtoms()
if options.atoms not in ('all', 'heavy'):
fixer.missingAtoms = {}
fixer.missingTerminals = {}
if options.verbose: print('Adding missing atoms...')
fixer.addMissingAtoms()
if options.heterogens == 'none':
fixer.removeHeterogens(False)
elif options.heterogens == 'water':
fixer.removeHeterogens(True)
if options.atoms in ('all', 'hydrogen'):
if options.verbose: print('Adding missing hydrogens...')
fixer.addMissingHydrogens(options.ph)
if options.box is not None:
fixer.addSolvent(boxSize=options.box*unit.nanometer, positiveIon=options.positiveIon,
if options.verbose: print('Adding solvent...')
fixer.addSolvent(boxSize=options.box*unit.nanometer, positiveIon=options.positiveIon,
negativeIon=options.negativeIon, ionicStrength=options.ionic*unit.molar)
with open(options.output, 'w') as f:
if options.verbose: print('Writing output...')
if fixer.source is not None:
f.write("REMARK 1 PDBFIXER FROM: %s\n" % fixer.source)
app.PDBFile.writeFile(fixer.topology, fixer.positions, f, True)
if options.verbose: print('Done.')
if __name__ == '__main__':
main()
#!/usr/bin/python
#=============================================================================================
# MODULE DOCSTRING
#=============================================================================================
"""
Test command-line interface.
"""
#=============================================================================================
# GLOBAL IMPORTS
#=============================================================================================
import subprocess
from subprocess import CalledProcessError
from nose.plugins.skip import Skip, SkipTest
#=============================================================================================
# UNIT TESTS
#=============================================================================================
def run_cli(arguments, expected_output=None):
try:
output = subprocess.check_output('pdbfixer ' + arguments, shell=True)
except CalledProcessError as e:
message = "An error return value (%s) was obtained:\n" % str(e.returncode)
message += "\n"
message += str(e.output)
message += "\n"
raise Exception(message)
if expected_output:
if output != expected_output:
message = "Output differs from expected output.\n"
message += "\n"
message += "Expected output:\n"
message += expected_output
message += "\n"
message += "Actual output:\n"
message += output
message += "\n"
raise Exception(message)
def test_help():
run_cli('--help')
def test_pdbid():
run_cli('--pdbid 1LE1')
def test_url():
run_cli('--url "http://www.rcsb.org/pdb/download/downloadFile.do?fileFormat=pdb&compression=NO&structureId=1LE1"')
......@@ -2,6 +2,7 @@ from nose.tools import ok_, eq_, raises, assert_list_equal
import simtk.openmm.app as app
import pdbfixer
import tempfile
import time
def remove_chain_ids_and_verify(pdbid, chain_ids_to_remove, expected_chain_ids_remaining):
# Create a PDBFixer instance for the given pdbid
......@@ -11,6 +12,8 @@ def remove_chain_ids_and_verify(pdbid, chain_ids_to_remove, expected_chain_ids_r
# Check to make sure asserted chains remain.
chain_ids_remaining = [c.id for c in fixer.topology.chains()]
assert_list_equal(chain_ids_remaining, expected_chain_ids_remaining)
# Slow down to prevent rapid URL retrievals
time.sleep(2)
def test_removechain_ids():
remove_chain_ids_and_verify('4JSV', [], ['B', 'D', 'A', 'C', 'B', 'A'])
......@@ -27,6 +30,8 @@ def remove_chain_indices_and_verify(pdbid, chain_indices_to_remove, expected_cha
# Check to make sure asserted chains remain.
chain_ids_remaining = [c.id for c in fixer.topology.chains()]
assert_list_equal(chain_ids_remaining, expected_chain_ids_remaining)
# Slow down to prevent rapid URL retrievals
time.sleep(2)
def test_removechain_indices():
remove_chain_indices_and_verify('4JSV', [], ['B', 'D', 'A', 'C', 'B', 'A'])
......
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