Merge pull request #2 from orbeckst/master
packaged for standalone installation (Python 3 and Python 2)
This commit is contained in:
19
INSTALL
Normal file
19
INSTALL
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
## Installation
|
||||||
|
|
||||||
|
Clone repository or unpack the tar ball and install with
|
||||||
|
[setuptools](http://pythonhosted.org/setuptools/index.html) (note: if
|
||||||
|
you don't have setuptools installed you will need an internet
|
||||||
|
connection so that the installation procedure can sownload the
|
||||||
|
required files):
|
||||||
|
|
||||||
|
cd propka-3.1
|
||||||
|
python setup.py install --user
|
||||||
|
|
||||||
|
This will install the `propka31` script in your executable directory,
|
||||||
|
as configured for setuptools, for instance `~/.local/bin`. You can
|
||||||
|
change the bin directory with the `--install-scripts` option. For
|
||||||
|
example, in order to install in my `bin` directory in my home
|
||||||
|
directory:
|
||||||
|
|
||||||
|
python setup.py install --user --install-scripts ~/bin
|
||||||
|
|
||||||
4
MANIFEST.in
Normal file
4
MANIFEST.in
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
include README.md INSTALL
|
||||||
|
include ez_setup.py setup.py
|
||||||
|
include propka.cfg
|
||||||
|
|
||||||
56
README.md
56
README.md
@@ -1,45 +1,69 @@
|
|||||||
# PROPKA 3.1
|
# PROPKA 3.1
|
||||||
|
|
||||||
PROPKA predicts the pKa values of ionizable groups in
|
PROPKA predicts the pKa values of ionizable groups in proteins
|
||||||
proteins (version 3.0) and
|
(version 3.0) and protein-ligand complexes (version 3.1)
|
||||||
protein-ligand complexes (version 3.1)
|
based on the 3D structure.
|
||||||
based in the 3D structure.
|
|
||||||
|
|
||||||
For proteins without ligands both version should produce the same result.
|
For proteins without ligands both version should produce the same result.
|
||||||
|
|
||||||
The method is described in the following papers, which you should cite
|
The method is described in the following papers, which you should cite
|
||||||
in publications:
|
in publications:
|
||||||
|
|
||||||
* Søndergaard, Chresten R., Mats HM Olsson, Michal Rostkowski, and Jan H. Jensen. "Improved Treatment of Ligands and Coupling Effects in Empirical Calculation and Rationalization of pKa Values." Journal of Chemical Theory and Computation 7, no. 7 (2011): 2284-2295.
|
* Sondergaard, Chresten R., Mats HM Olsson, Michal Rostkowski, and Jan H. Jensen. "Improved Treatment of Ligands and Coupling Effects in Empirical Calculation and Rationalization of pKa Values." Journal of Chemical Theory and Computation 7, no. 7 (2011): 2284-2295.
|
||||||
|
|
||||||
* Olsson, Mats HM, Chresten R. Søndergaard, Michal Rostkowski, and Jan H. Jensen. "PROPKA3: consistent treatment of internal and surface residues in empirical pKa predictions." Journal of Chemical Theory and Computation 7, no. 2 (2011): 525-537.
|
* Olsson, Mats HM, Chresten R. Sondergaard, Michal Rostkowski, and Jan H. Jensen. "PROPKA3: consistent treatment of internal and surface residues in empirical pKa predictions." Journal of Chemical Theory and Computation 7, no. 2 (2011): 525-537.
|
||||||
|
|
||||||
See [propka.ki.ku.dk](http://propka.ki.ku.dk/) for the PROPKA web server,
|
See [propka.ki.ku.dk](http://propka.ki.ku.dk/) for the PROPKA web server,
|
||||||
using the [tutorial](http://propka.ki.ku.dk/~luca/wiki/index.php/PROPKA_3.1_Tutorial).
|
using the [tutorial](http://propka.ki.ku.dk/~luca/wiki/index.php/PROPKA_3.1_Tutorial).
|
||||||
|
|
||||||
|
## Modifications
|
||||||
|
|
||||||
|
This release of PROPKA 3.1 was modified by Oliver Beckstein
|
||||||
|
<oliver.beckstein@asu.edu> from the released version.
|
||||||
|
|
||||||
|
* Included patches from
|
||||||
|
https://github.com/schrodinger/propka-3.1/tree/python27-compat to
|
||||||
|
make it compatible with Python 2.7
|
||||||
|
|
||||||
|
* Packaged for installation with setuptools.
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
No installation needed. Just clone and run.
|
Clone repository or unpack the tar ball and install with
|
||||||
|
[setuptools](http://pythonhosted.org/setuptools/index.html) (note: if
|
||||||
|
you don't have setuptools installed you will need an internet
|
||||||
|
connection so that the installation procedure can download the
|
||||||
|
required files):
|
||||||
|
|
||||||
|
cd propka-3.1
|
||||||
|
python setup.py install --user
|
||||||
|
|
||||||
|
This will install the `propka31` script in your executable directory,
|
||||||
|
as configured for setuptools, for instance `~/.local/bin`. You can
|
||||||
|
change the bin directory with the `--install-scripts` option. For
|
||||||
|
example, in order to install in my `bin` directory in my home
|
||||||
|
directory:
|
||||||
|
|
||||||
|
python setup.py install --user --install-scripts ~/bin
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* Python 3.1 or higher
|
* Python 2.7 or higher or Python 3.1 or higher
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
1. Clone the code from GitHub
|
1. Clone the code from GitHub
|
||||||
2. Run 'propka.py' with a .pdb file (see Examples)
|
2. `python setup.py install --user`
|
||||||
|
2. Run `propka31` with a .pdb file (see Examples)
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Calculate using pdb file
|
Calculate using pdb file
|
||||||
|
|
||||||
./propka.py 1hpx.pdb
|
propka31 1hpx.pdb
|
||||||
|
|
||||||
If for some reason your setup with python3.1+ is
|
|
||||||
not located in '/usr/bin/python3', run the script
|
|
||||||
|
|
||||||
python3.2 propka.py 1hpx.pdb
|
|
||||||
|
|
||||||
## Testing (for developers)
|
## Testing (for developers)
|
||||||
|
|
||||||
@@ -49,9 +73,9 @@ Please run `Tests/runtest.py/` after changes before pushing commits.
|
|||||||
|
|
||||||
Please cite these references in publications:
|
Please cite these references in publications:
|
||||||
|
|
||||||
* Søndergaard, Chresten R., Mats HM Olsson, Michal Rostkowski, and Jan H. Jensen. "Improved Treatment of Ligands and Coupling Effects in Empirical Calculation and Rationalization of pKa Values." Journal of Chemical Theory and Computation 7, no. 7 (2011): 2284-2295.
|
* Sondergaard, Chresten R., Mats HM Olsson, Michal Rostkowski, and Jan H. Jensen. "Improved Treatment of Ligands and Coupling Effects in Empirical Calculation and Rationalization of pKa Values." Journal of Chemical Theory and Computation 7, no. 7 (2011): 2284-2295.
|
||||||
|
|
||||||
* Olsson, Mats HM, Chresten R. Søndergaard, Michal Rostkowski, and Jan H. Jensen. "PROPKA3: consistent treatment of internal and surface residues in empirical pKa predictions." Journal of Chemical Theory and Computation 7, no. 2 (2011): 525-537.
|
* Olsson, Mats HM, Chresten R. Sondergaard, Michal Rostkowski, and Jan H. Jensen. "PROPKA3: consistent treatment of internal and surface residues in empirical pKa predictions." Journal of Chemical Theory and Computation 7, no. 2 (2011): 525-537.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/env python
|
||||||
|
|
||||||
""" Run test for test pdbs """
|
""" Run test for test pdbs """
|
||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
from subprocess import call
|
from subprocess import call
|
||||||
import os, re
|
import os, re
|
||||||
|
import sys
|
||||||
|
|
||||||
pdbs = ['1FTJ-Chain-A',
|
pdbs = ['1FTJ-Chain-A',
|
||||||
'1HPX',
|
'1HPX',
|
||||||
@@ -14,7 +18,7 @@ for pdb in pdbs:
|
|||||||
print('RUNNING '+pdb)
|
print('RUNNING '+pdb)
|
||||||
|
|
||||||
# Run pka calculation
|
# Run pka calculation
|
||||||
call(['../propka.py','pdb/'+pdb+'.pdb'], stdout = open(pdb+'.out', 'w+'))
|
call([sys.executable, '../scripts/propka31.py','pdb/'+pdb+'.pdb'], stdout = open(pdb+'.out', 'w+'))
|
||||||
|
|
||||||
# Test pka predictiona
|
# Test pka predictiona
|
||||||
result = open('results/'+pdb+'.dat','r')
|
result = open('results/'+pdb+'.dat','r')
|
||||||
|
|||||||
258
ez_setup.py
Normal file
258
ez_setup.py
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
#!python
|
||||||
|
"""Bootstrap setuptools installation
|
||||||
|
|
||||||
|
If you want to use setuptools in your package's setup.py, just include this
|
||||||
|
file in the same directory with it, and add this to the top of your setup.py::
|
||||||
|
|
||||||
|
from ez_setup import use_setuptools
|
||||||
|
use_setuptools()
|
||||||
|
|
||||||
|
If you want to require a specific version of setuptools, set a download
|
||||||
|
mirror, or use an alternate download directory, you can do so by supplying
|
||||||
|
the appropriate options to ``use_setuptools()``.
|
||||||
|
|
||||||
|
This file can also be run as a script to install or upgrade setuptools.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import tarfile
|
||||||
|
import optparse
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from distutils import log
|
||||||
|
|
||||||
|
try:
|
||||||
|
from site import USER_SITE
|
||||||
|
except ImportError:
|
||||||
|
USER_SITE = None
|
||||||
|
|
||||||
|
DEFAULT_VERSION = "0.9.6"
|
||||||
|
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
|
||||||
|
|
||||||
|
def _python_cmd(*args):
|
||||||
|
args = (sys.executable,) + args
|
||||||
|
return subprocess.call(args) == 0
|
||||||
|
|
||||||
|
def _install(tarball, install_args=()):
|
||||||
|
# extracting the tarball
|
||||||
|
tmpdir = tempfile.mkdtemp()
|
||||||
|
log.warn('Extracting in %s', tmpdir)
|
||||||
|
old_wd = os.getcwd()
|
||||||
|
try:
|
||||||
|
os.chdir(tmpdir)
|
||||||
|
tar = tarfile.open(tarball)
|
||||||
|
_extractall(tar)
|
||||||
|
tar.close()
|
||||||
|
|
||||||
|
# going in the directory
|
||||||
|
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
|
||||||
|
os.chdir(subdir)
|
||||||
|
log.warn('Now working in %s', subdir)
|
||||||
|
|
||||||
|
# installing
|
||||||
|
log.warn('Installing Setuptools')
|
||||||
|
if not _python_cmd('setup.py', 'install', *install_args):
|
||||||
|
log.warn('Something went wrong during the installation.')
|
||||||
|
log.warn('See the error message above.')
|
||||||
|
# exitcode will be 2
|
||||||
|
return 2
|
||||||
|
finally:
|
||||||
|
os.chdir(old_wd)
|
||||||
|
shutil.rmtree(tmpdir)
|
||||||
|
|
||||||
|
|
||||||
|
def _build_egg(egg, tarball, to_dir):
|
||||||
|
# extracting the tarball
|
||||||
|
tmpdir = tempfile.mkdtemp()
|
||||||
|
log.warn('Extracting in %s', tmpdir)
|
||||||
|
old_wd = os.getcwd()
|
||||||
|
try:
|
||||||
|
os.chdir(tmpdir)
|
||||||
|
tar = tarfile.open(tarball)
|
||||||
|
_extractall(tar)
|
||||||
|
tar.close()
|
||||||
|
|
||||||
|
# going in the directory
|
||||||
|
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
|
||||||
|
os.chdir(subdir)
|
||||||
|
log.warn('Now working in %s', subdir)
|
||||||
|
|
||||||
|
# building an egg
|
||||||
|
log.warn('Building a Setuptools egg in %s', to_dir)
|
||||||
|
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
os.chdir(old_wd)
|
||||||
|
shutil.rmtree(tmpdir)
|
||||||
|
# returning the result
|
||||||
|
log.warn(egg)
|
||||||
|
if not os.path.exists(egg):
|
||||||
|
raise IOError('Could not build the egg.')
|
||||||
|
|
||||||
|
|
||||||
|
def _do_download(version, download_base, to_dir, download_delay):
|
||||||
|
egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg'
|
||||||
|
% (version, sys.version_info[0], sys.version_info[1]))
|
||||||
|
if not os.path.exists(egg):
|
||||||
|
tarball = download_setuptools(version, download_base,
|
||||||
|
to_dir, download_delay)
|
||||||
|
_build_egg(egg, tarball, to_dir)
|
||||||
|
sys.path.insert(0, egg)
|
||||||
|
import setuptools
|
||||||
|
setuptools.bootstrap_install_from = egg
|
||||||
|
|
||||||
|
|
||||||
|
def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
|
||||||
|
to_dir=os.curdir, download_delay=15):
|
||||||
|
# making sure we use the absolute path
|
||||||
|
to_dir = os.path.abspath(to_dir)
|
||||||
|
was_imported = 'pkg_resources' in sys.modules or \
|
||||||
|
'setuptools' in sys.modules
|
||||||
|
try:
|
||||||
|
import pkg_resources
|
||||||
|
except ImportError:
|
||||||
|
return _do_download(version, download_base, to_dir, download_delay)
|
||||||
|
try:
|
||||||
|
pkg_resources.require("setuptools>=" + version)
|
||||||
|
return
|
||||||
|
except pkg_resources.VersionConflict:
|
||||||
|
e = sys.exc_info()[1]
|
||||||
|
if was_imported:
|
||||||
|
sys.stderr.write(
|
||||||
|
"The required version of setuptools (>=%s) is not available,\n"
|
||||||
|
"and can't be installed while this script is running. Please\n"
|
||||||
|
"install a more recent version first, using\n"
|
||||||
|
"'easy_install -U setuptools'."
|
||||||
|
"\n\n(Currently using %r)\n" % (version, e.args[0]))
|
||||||
|
sys.exit(2)
|
||||||
|
else:
|
||||||
|
del pkg_resources, sys.modules['pkg_resources'] # reload ok
|
||||||
|
return _do_download(version, download_base, to_dir,
|
||||||
|
download_delay)
|
||||||
|
except pkg_resources.DistributionNotFound:
|
||||||
|
return _do_download(version, download_base, to_dir,
|
||||||
|
download_delay)
|
||||||
|
|
||||||
|
|
||||||
|
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
|
||||||
|
to_dir=os.curdir, delay=15):
|
||||||
|
"""Download setuptools from a specified location and return its filename
|
||||||
|
|
||||||
|
`version` should be a valid setuptools version number that is available
|
||||||
|
as an egg for download under the `download_base` URL (which should end
|
||||||
|
with a '/'). `to_dir` is the directory where the egg will be downloaded.
|
||||||
|
`delay` is the number of seconds to pause before an actual download
|
||||||
|
attempt.
|
||||||
|
"""
|
||||||
|
# making sure we use the absolute path
|
||||||
|
to_dir = os.path.abspath(to_dir)
|
||||||
|
try:
|
||||||
|
from urllib.request import urlopen
|
||||||
|
except ImportError:
|
||||||
|
from urllib2 import urlopen
|
||||||
|
tgz_name = "setuptools-%s.tar.gz" % version
|
||||||
|
url = download_base + tgz_name
|
||||||
|
saveto = os.path.join(to_dir, tgz_name)
|
||||||
|
src = dst = None
|
||||||
|
if not os.path.exists(saveto): # Avoid repeated downloads
|
||||||
|
try:
|
||||||
|
log.warn("Downloading %s", url)
|
||||||
|
src = urlopen(url)
|
||||||
|
# Read/write all in one block, so we don't create a corrupt file
|
||||||
|
# if the download is interrupted.
|
||||||
|
data = src.read()
|
||||||
|
dst = open(saveto, "wb")
|
||||||
|
dst.write(data)
|
||||||
|
finally:
|
||||||
|
if src:
|
||||||
|
src.close()
|
||||||
|
if dst:
|
||||||
|
dst.close()
|
||||||
|
return os.path.realpath(saveto)
|
||||||
|
|
||||||
|
|
||||||
|
def _extractall(self, path=".", members=None):
|
||||||
|
"""Extract all members from the archive to the current working
|
||||||
|
directory and set owner, modification time and permissions on
|
||||||
|
directories afterwards. `path' specifies a different directory
|
||||||
|
to extract to. `members' is optional and must be a subset of the
|
||||||
|
list returned by getmembers().
|
||||||
|
"""
|
||||||
|
import copy
|
||||||
|
import operator
|
||||||
|
from tarfile import ExtractError
|
||||||
|
directories = []
|
||||||
|
|
||||||
|
if members is None:
|
||||||
|
members = self
|
||||||
|
|
||||||
|
for tarinfo in members:
|
||||||
|
if tarinfo.isdir():
|
||||||
|
# Extract directories with a safe mode.
|
||||||
|
directories.append(tarinfo)
|
||||||
|
tarinfo = copy.copy(tarinfo)
|
||||||
|
tarinfo.mode = 448 # decimal for oct 0700
|
||||||
|
self.extract(tarinfo, path)
|
||||||
|
|
||||||
|
# Reverse sort directories.
|
||||||
|
if sys.version_info < (2, 4):
|
||||||
|
def sorter(dir1, dir2):
|
||||||
|
return cmp(dir1.name, dir2.name)
|
||||||
|
directories.sort(sorter)
|
||||||
|
directories.reverse()
|
||||||
|
else:
|
||||||
|
directories.sort(key=operator.attrgetter('name'), reverse=True)
|
||||||
|
|
||||||
|
# Set correct owner, mtime and filemode on directories.
|
||||||
|
for tarinfo in directories:
|
||||||
|
dirpath = os.path.join(path, tarinfo.name)
|
||||||
|
try:
|
||||||
|
self.chown(tarinfo, dirpath)
|
||||||
|
self.utime(tarinfo, dirpath)
|
||||||
|
self.chmod(tarinfo, dirpath)
|
||||||
|
except ExtractError:
|
||||||
|
e = sys.exc_info()[1]
|
||||||
|
if self.errorlevel > 1:
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
self._dbg(1, "tarfile: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
|
def _build_install_args(options):
|
||||||
|
"""
|
||||||
|
Build the arguments to 'python setup.py install' on the setuptools package
|
||||||
|
"""
|
||||||
|
install_args = []
|
||||||
|
if options.user_install:
|
||||||
|
if sys.version_info < (2, 6):
|
||||||
|
log.warn("--user requires Python 2.6 or later")
|
||||||
|
raise SystemExit(1)
|
||||||
|
install_args.append('--user')
|
||||||
|
return install_args
|
||||||
|
|
||||||
|
def _parse_args():
|
||||||
|
"""
|
||||||
|
Parse the command line for options
|
||||||
|
"""
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
parser.add_option(
|
||||||
|
'--user', dest='user_install', action='store_true', default=False,
|
||||||
|
help='install in user site package (requires Python 2.6 or later)')
|
||||||
|
parser.add_option(
|
||||||
|
'--download-base', dest='download_base', metavar="URL",
|
||||||
|
default=DEFAULT_URL,
|
||||||
|
help='alternative URL from where to download the setuptools package')
|
||||||
|
options, args = parser.parse_args()
|
||||||
|
# positional arguments are ignored
|
||||||
|
return options
|
||||||
|
|
||||||
|
def main(version=DEFAULT_VERSION):
|
||||||
|
"""Install or upgrade setuptools and EasyInstall"""
|
||||||
|
options = _parse_args()
|
||||||
|
tarball = download_setuptools(download_base=options.download_base)
|
||||||
|
return _install(tarball, _build_install_args(options))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
23
propka.py
23
propka.py
@@ -1,23 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
import string,re,sys,os,math
|
|
||||||
import Source.lib, Source.molecular_container
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""
|
|
||||||
Reads in structure files, calculates pKa values, and prints pKa files
|
|
||||||
"""
|
|
||||||
# loading options, flaggs and arguments
|
|
||||||
options, pdbfiles = Source.lib.loadOptions()
|
|
||||||
|
|
||||||
for pdbfile in pdbfiles:
|
|
||||||
my_molecule = Source.molecular_container.Molecular_container(pdbfile, options)
|
|
||||||
my_molecule.calculate_pka()
|
|
||||||
my_molecule.write_pka()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
#import cProfile
|
|
||||||
#cProfile.run('main()',sort=1)
|
|
||||||
main()
|
|
||||||
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
#
|
# propka 3.1
|
||||||
|
# (Module renamed from original Source to propka to facilitate setuptools installation)
|
||||||
|
|
||||||
__all__ = ['coupled_residues', 'lib', 'parameters', 'residue', 'bonds', 'debug', 'ligand', 'pdb', 'calculator', 'determinants', 'mutate', 'protein', 'chain', 'iterative', 'output', 'protonate']
|
__all__ = ['coupled_residues', 'lib', 'parameters', 'residue', 'bonds', 'debug', 'ligand', 'pdb', 'calculator', 'determinants', 'mutate', 'protein', 'chain', 'iterative', 'output', 'protonate']
|
||||||
|
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
import string, Source.lib, Source.group
|
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import string, propka.lib, propka.group
|
||||||
|
|
||||||
|
|
||||||
class Atom:
|
class Atom:
|
||||||
@@ -8,17 +12,17 @@ class Atom:
|
|||||||
|
|
||||||
def __init__(self, line=None, verbose=False):
|
def __init__(self, line=None, verbose=False):
|
||||||
|
|
||||||
self.set_properties(line)
|
self.set_properties(line)
|
||||||
|
|
||||||
self.residue_label = "%-3s%4d%2s" % (self.name,self.resNumb, self.chainID)
|
self.residue_label = "%-3s%4d%2s" % (self.name,self.resNumb, self.chainID)
|
||||||
|
|
||||||
self.groups_extracted = 0
|
self.groups_extracted = 0
|
||||||
self.group = None
|
self.group = None
|
||||||
self.group_type = None
|
self.group_type = None
|
||||||
self.number_of_bonded_elements = {}
|
self.number_of_bonded_elements = {}
|
||||||
|
|
||||||
self.cysteine_bridge = False
|
self.cysteine_bridge = False
|
||||||
|
|
||||||
self.bonded_atoms = []
|
self.bonded_atoms = []
|
||||||
self.residue = None
|
self.residue = None
|
||||||
self.conformation_container = None
|
self.conformation_container = None
|
||||||
@@ -39,7 +43,7 @@ class Atom:
|
|||||||
self.sybyl_type = ''
|
self.sybyl_type = ''
|
||||||
self.sybyl_assigned = False
|
self.sybyl_assigned = False
|
||||||
self.marvin_pka = False
|
self.marvin_pka = False
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -122,13 +126,13 @@ class Atom:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def setProperty(self,
|
def setProperty(self,
|
||||||
numb = None,
|
numb = None,
|
||||||
name = None,
|
name = None,
|
||||||
resName = None,
|
resName = None,
|
||||||
chainID = None,
|
chainID = None,
|
||||||
resNumb = None,
|
resNumb = None,
|
||||||
x = None,
|
x = None,
|
||||||
@@ -157,7 +161,7 @@ class Atom:
|
|||||||
"""
|
"""
|
||||||
making a copy of this atom
|
making a copy of this atom
|
||||||
"""
|
"""
|
||||||
|
|
||||||
newAtom = Atom()
|
newAtom = Atom()
|
||||||
newAtom.type = self.type
|
newAtom.type = self.type
|
||||||
newAtom.numb = self.numb
|
newAtom.numb = self.numb
|
||||||
@@ -191,11 +195,11 @@ class Atom:
|
|||||||
|
|
||||||
if self.group.titratable:
|
if self.group.titratable:
|
||||||
model_pka = '%6.2f'%self.group.model_pka
|
model_pka = '%6.2f'%self.group.model_pka
|
||||||
|
|
||||||
|
|
||||||
str = "%-6s%5d %s %s%2s%4d%12.3lf%8.3lf%8.3lf%6s%6s \n" % (self.type.upper(),
|
str = "%-6s%5d %s %s%2s%4d%12.3lf%8.3lf%8.3lf%6s%6s \n" % (self.type.upper(),
|
||||||
self.numb,
|
self.numb,
|
||||||
Source.lib.makeTidyAtomLabel(self.name,
|
propka.lib.makeTidyAtomLabel(self.name,
|
||||||
self.element),
|
self.element),
|
||||||
self.resName,
|
self.resName,
|
||||||
self.chainID,
|
self.chainID,
|
||||||
@@ -213,7 +217,7 @@ class Atom:
|
|||||||
|
|
||||||
def make_conect_line(self):
|
def make_conect_line(self):
|
||||||
res = 'CONECT%5d'%self.numb
|
res = 'CONECT%5d'%self.numb
|
||||||
|
|
||||||
# extract and sort numbers of bonded residues
|
# extract and sort numbers of bonded residues
|
||||||
bonded = []
|
bonded = []
|
||||||
for atom in self.bonded_atoms:
|
for atom in self.bonded_atoms:
|
||||||
@@ -226,9 +230,9 @@ class Atom:
|
|||||||
res += '\n'
|
res += '\n'
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def get_input_parameters(self):
|
def get_input_parameters(self):
|
||||||
""" Method for getting the input parameters stored in the
|
""" Method for getting the input parameters stored in the
|
||||||
occupancy and b-factor fields in input files"""
|
occupancy and b-factor fields in input files"""
|
||||||
|
|
||||||
# Set the group type
|
# Set the group type
|
||||||
@@ -258,7 +262,7 @@ class Atom:
|
|||||||
|
|
||||||
# try to initialise the group
|
# try to initialise the group
|
||||||
try:
|
try:
|
||||||
exec('self.group = Source.group.%s_group(self)'%self.occ)
|
exec('self.group = propka.group.%s_group(self)'%self.occ)
|
||||||
except:
|
except:
|
||||||
raise Exception('%s in input_file is not recognized as a group'%self.occ)
|
raise Exception('%s in input_file is not recognized as a group'%self.occ)
|
||||||
|
|
||||||
@@ -270,7 +274,7 @@ class Atom:
|
|||||||
# set occ and beta to standard values
|
# set occ and beta to standard values
|
||||||
self.occ = '1.00'
|
self.occ = '1.00'
|
||||||
self.beta = '0.00'
|
self.beta = '0.00'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -282,7 +286,7 @@ class Atom:
|
|||||||
# making string
|
# making string
|
||||||
str = "%-6s%5d %s %s%2s%4d%12.3lf%8.3lf%8.3lf%6s%6s\n" % (self.type.upper(),
|
str = "%-6s%5d %s %s%2s%4d%12.3lf%8.3lf%8.3lf%6s%6s\n" % (self.type.upper(),
|
||||||
self.numb,
|
self.numb,
|
||||||
Source.lib.makeTidyAtomLabel(self.name,
|
propka.lib.makeTidyAtomLabel(self.name,
|
||||||
self.element),
|
self.element),
|
||||||
self.resName,
|
self.resName,
|
||||||
self.chainID,
|
self.chainID,
|
||||||
@@ -292,17 +296,17 @@ class Atom:
|
|||||||
self.z,
|
self.z,
|
||||||
self.occ,
|
self.occ,
|
||||||
self.beta)
|
self.beta)
|
||||||
|
|
||||||
|
|
||||||
return str
|
return str
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_mol2_line(self,id):
|
def make_mol2_line(self,id):
|
||||||
#1 S1 3.6147 2.0531 1.4795 S.3 1 noname -0.1785
|
#1 S1 3.6147 2.0531 1.4795 S.3 1 noname -0.1785
|
||||||
# making string
|
# making string
|
||||||
str = "%-4d %-4s %10.4f %10.4f %10.4f %6s %6d %10s %10.4f\n" % (id,
|
str = "%-4d %-4s %10.4f %10.4f %10.4f %6s %6d %10s %10.4f\n" % (id,
|
||||||
Source.lib.makeTidyAtomLabel(self.name,
|
propka.lib.makeTidyAtomLabel(self.name,
|
||||||
self.element),
|
self.element),
|
||||||
self.x,
|
self.x,
|
||||||
self.y,
|
self.y,
|
||||||
@@ -311,7 +315,7 @@ class Atom:
|
|||||||
self.resNumb,
|
self.resNumb,
|
||||||
self.resName,
|
self.resName,
|
||||||
0.0)#self.charge)
|
0.0)#self.charge)
|
||||||
|
|
||||||
|
|
||||||
return str
|
return str
|
||||||
|
|
||||||
@@ -346,7 +350,7 @@ class Atom:
|
|||||||
# making string
|
# making string
|
||||||
str = "ATOM "
|
str = "ATOM "
|
||||||
str += "%6d" % (numb)
|
str += "%6d" % (numb)
|
||||||
str += " %s" % (Source.lib.makeTidyAtomLabel(name,self.element))
|
str += " %s" % (propka.lib.makeTidyAtomLabel(name,self.element))
|
||||||
str += " %s" % (resName)
|
str += " %s" % (resName)
|
||||||
str += "%2s" % (chainID)
|
str += "%2s" % (chainID)
|
||||||
str += "%4d" % (resNumb)
|
str += "%4d" % (resNumb)
|
||||||
@@ -363,25 +367,25 @@ class Atom:
|
|||||||
"""
|
"""
|
||||||
Returns a 'tidier' atom label for printing the new pdbfile
|
Returns a 'tidier' atom label for printing the new pdbfile
|
||||||
"""
|
"""
|
||||||
return Source.lib.makeTidyAtomLabel(self.name,self.element)
|
return propka.lib.makeTidyAtomLabel(self.name,self.element)
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '%5d-%4s %5d-%3s (%1s) [%8.3f %8.3f %8.3f] %s' %(self.numb, self.name, self.resNumb, self.resName, self.chainID, self.x, self.y, self.z,self.element)
|
return '%5d-%4s %5d-%3s (%1s) [%8.3f %8.3f %8.3f] %s' %(self.numb, self.name, self.resNumb, self.resName, self.chainID, self.x, self.y, self.z,self.element)
|
||||||
|
|
||||||
|
|
||||||
# def get_element(self):
|
# def get_element(self):
|
||||||
# """ try to extract element if not already done"""
|
# """ try to extract element if not already done"""
|
||||||
# if self.element == '':
|
# if self.element == '':
|
||||||
# self.element = self.name.strip(string.digits)[0]
|
# self.element = self.name.strip(string.digits)[0]
|
||||||
# return self.element
|
# return self.element
|
||||||
|
|
||||||
|
|
||||||
def set_residue(self, residue):
|
def set_residue(self, residue):
|
||||||
""" Makes a references to the parent residue"""
|
""" Makes a references to the parent residue"""
|
||||||
if self.residue == None:
|
if self.residue == None:
|
||||||
self.residue = residue
|
self.residue = residue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,14 +1,19 @@
|
|||||||
import pickle,sys,os,math,Source.calculations
|
|
||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import pickle,sys,os,math,propka.calculations
|
||||||
|
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
class bondmaker:
|
class bondmaker:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
# predefined bonding distances
|
# predefined bonding distances
|
||||||
self.distances = {
|
self.distances = {
|
||||||
'S-S':2.5,
|
'S-S':2.5,
|
||||||
'F-F':1.7}
|
'F-F':1.7}
|
||||||
|
|
||||||
self.distances_squared = {}
|
self.distances_squared = {}
|
||||||
for k in self.distances.keys():
|
for k in self.distances.keys():
|
||||||
self.distances_squared[k]=self.distances[k]*self.distances[k]
|
self.distances_squared[k]=self.distances[k]*self.distances[k]
|
||||||
@@ -18,12 +23,11 @@ class bondmaker:
|
|||||||
|
|
||||||
self.H_dist_squared = self.H_dist * self.H_dist
|
self.H_dist_squared = self.H_dist * self.H_dist
|
||||||
self.default_dist_squared = self.default_dist * self.default_dist
|
self.default_dist_squared = self.default_dist * self.default_dist
|
||||||
|
|
||||||
self.max_sq_distance = max(list(self.distances_squared.values())+[self.default_dist_squared])
|
self.max_sq_distance = max(list(self.distances_squared.values())+[self.default_dist_squared])
|
||||||
|
|
||||||
# protein bonding data
|
# protein bonding data
|
||||||
path = os.path.split(__file__)[0]
|
self.data_file_name = pkg_resources.resource_filename(__name__, 'protein_bonds.dat')
|
||||||
self.data_file_name = os.path.join(path,'protein_bonds.dat')
|
|
||||||
|
|
||||||
data = open(self.data_file_name,'rb')
|
data = open(self.data_file_name,'rb')
|
||||||
self.protein_bonds = pickle.load(data)
|
self.protein_bonds = pickle.load(data)
|
||||||
@@ -104,13 +108,13 @@ class bondmaker:
|
|||||||
|
|
||||||
|
|
||||||
def find_bonds_for_protein(self, protein):
|
def find_bonds_for_protein(self, protein):
|
||||||
""" Finds bonds proteins based on the way atoms
|
""" Finds bonds proteins based on the way atoms
|
||||||
normally bond in proteins"""
|
normally bond in proteins"""
|
||||||
|
|
||||||
print('++++ Side chains ++++')
|
print('++++ Side chains ++++')
|
||||||
# side chains
|
# side chains
|
||||||
for chain in protein.chains:
|
for chain in protein.chains:
|
||||||
for residue in chain.residues:
|
for residue in chain.residues:
|
||||||
if residue.resName.replace(' ','') not in ['N+','C-']:
|
if residue.resName.replace(' ','') not in ['N+','C-']:
|
||||||
self.find_bonds_for_side_chain(residue.atoms)
|
self.find_bonds_for_side_chain(residue.atoms)
|
||||||
|
|
||||||
@@ -145,7 +149,7 @@ class bondmaker:
|
|||||||
if atom1.name == 'SG':
|
if atom1.name == 'SG':
|
||||||
for atom2 in cys2.atoms:
|
for atom2 in cys2.atoms:
|
||||||
if atom2.name == 'SG':
|
if atom2.name == 'SG':
|
||||||
if Source.calculations.squared_distance(atom1,atom2) < self.SS_dist_squared:
|
if propka.calculations.squared_distance(atom1,atom2) < self.SS_dist_squared:
|
||||||
self.make_bond(atom1, atom2)
|
self.make_bond(atom1, atom2)
|
||||||
|
|
||||||
|
|
||||||
@@ -174,7 +178,7 @@ class bondmaker:
|
|||||||
if atom1.name == 'C':
|
if atom1.name == 'C':
|
||||||
for atom2 in residue2.atoms:
|
for atom2 in residue2.atoms:
|
||||||
if atom2.name == 'N':
|
if atom2.name == 'N':
|
||||||
if Source.calculations.squared_distance(atom1,atom2) < self.default_dist_squared:
|
if propka.calculations.squared_distance(atom1,atom2) < self.default_dist_squared:
|
||||||
self.make_bond(atom1, atom2)
|
self.make_bond(atom1, atom2)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -209,7 +213,7 @@ class bondmaker:
|
|||||||
for atom2 in atoms:
|
for atom2 in atoms:
|
||||||
if atom2.name in self.protein_bonds[atom1.resName][atom1.name]:
|
if atom2.name in self.protein_bonds[atom1.resName][atom1.name]:
|
||||||
self.make_bond(atom1,atom2)
|
self.make_bond(atom1,atom2)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -270,7 +274,7 @@ class bondmaker:
|
|||||||
|
|
||||||
if atoms[i] in atoms[j].bonded_atoms:
|
if atoms[i] in atoms[j].bonded_atoms:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.check_distance(atoms[i], atoms[j]):
|
if self.check_distance(atoms[i], atoms[j]):
|
||||||
self.make_bond(atoms[i],atoms[j])
|
self.make_bond(atoms[i],atoms[j])
|
||||||
# di-sulphide bonds
|
# di-sulphide bonds
|
||||||
@@ -283,14 +287,14 @@ class bondmaker:
|
|||||||
|
|
||||||
|
|
||||||
def check_distance(self, atom1, atom2):
|
def check_distance(self, atom1, atom2):
|
||||||
sq_dist = Source.calculations.squared_distance(atom1, atom2)
|
sq_dist = propka.calculations.squared_distance(atom1, atom2)
|
||||||
|
|
||||||
if sq_dist > self.max_sq_distance:
|
if sq_dist > self.max_sq_distance:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
key = '%s-%s'%(atom1.element,atom2.element)
|
key = '%s-%s'%(atom1.element,atom2.element)
|
||||||
h_count = key.count('H')
|
h_count = key.count('H')
|
||||||
|
|
||||||
if sq_dist < self.H_dist_squared and h_count==1:
|
if sq_dist < self.H_dist_squared and h_count==1:
|
||||||
return True
|
return True
|
||||||
if sq_dist < self.default_dist_squared and h_count==0:
|
if sq_dist < self.default_dist_squared and h_count==0:
|
||||||
@@ -299,8 +303,8 @@ class bondmaker:
|
|||||||
if sq_dist < self.distances_squared[key]:
|
if sq_dist < self.distances_squared[key]:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def find_bonds_for_molecules_using_boxes(self, molecules):
|
def find_bonds_for_molecules_using_boxes(self, molecules):
|
||||||
@@ -320,7 +324,7 @@ class bondmaker:
|
|||||||
|
|
||||||
def find_bonds_for_atoms_using_boxes(self, atoms):
|
def find_bonds_for_atoms_using_boxes(self, atoms):
|
||||||
""" Finds all bonds for a list of atoms"""
|
""" Finds all bonds for a list of atoms"""
|
||||||
|
|
||||||
box_size = 2.5
|
box_size = 2.5
|
||||||
|
|
||||||
# find min and max coordinates
|
# find min and max coordinates
|
||||||
@@ -348,11 +352,13 @@ class bondmaker:
|
|||||||
#print('x range: [%6.2f;%6.2f] %6.2f'%(xmin,xmax,xlen))
|
#print('x range: [%6.2f;%6.2f] %6.2f'%(xmin,xmax,xlen))
|
||||||
#print('y range: [%6.2f;%6.2f] %6.2f'%(ymin,ymax,ylen))
|
#print('y range: [%6.2f;%6.2f] %6.2f'%(ymin,ymax,ylen))
|
||||||
#print('z range: [%6.2f;%6.2f] %6.2f'%(zmin,zmax,zlen))
|
#print('z range: [%6.2f;%6.2f] %6.2f'%(zmin,zmax,zlen))
|
||||||
|
|
||||||
# how many boxes do we need in each dimension?
|
# how many boxes do we need in each dimension?
|
||||||
self.no_box_x = max(1, math.ceil(xlen/box_size))
|
# NOTE: math.ceil() returns an int in python3 and a float in python2,
|
||||||
self.no_box_y = max(1, math.ceil(ylen/box_size))
|
# so we need to cast it to int for range() to work.
|
||||||
self.no_box_z = max(1, math.ceil(zlen/box_size))
|
self.no_box_x = max(1, int(math.ceil(xlen/box_size)))
|
||||||
|
self.no_box_y = max(1, int(math.ceil(ylen/box_size)))
|
||||||
|
self.no_box_z = max(1, int(math.ceil(zlen/box_size)))
|
||||||
|
|
||||||
#print('No. box x: %6.2f'%self.no_box_x)
|
#print('No. box x: %6.2f'%self.no_box_x)
|
||||||
#print('No. box y: %6.2f'%self.no_box_y)
|
#print('No. box y: %6.2f'%self.no_box_y)
|
||||||
@@ -372,12 +378,12 @@ class bondmaker:
|
|||||||
z = math.floor((atom.z-zmin)/box_size)
|
z = math.floor((atom.z-zmin)/box_size)
|
||||||
self.put_atom_in_box(x,y,z,atom)
|
self.put_atom_in_box(x,y,z,atom)
|
||||||
|
|
||||||
# assign bonds
|
# assign bonds
|
||||||
keys = self.boxes.keys()
|
keys = self.boxes.keys()
|
||||||
for key in keys:
|
for key in keys:
|
||||||
self.find_bonds_for_atoms(self.boxes[key])
|
self.find_bonds_for_atoms(self.boxes[key])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -386,7 +392,7 @@ class bondmaker:
|
|||||||
# one side of the x,y,z box in each dimension
|
# one side of the x,y,z box in each dimension
|
||||||
for bx in [x,x+1]:
|
for bx in [x,x+1]:
|
||||||
for by in [y,y+1]:
|
for by in [y,y+1]:
|
||||||
for bz in [z,z+1]:
|
for bz in [z,z+1]:
|
||||||
key = self.box_key(bx,by,bz)
|
key = self.box_key(bx,by,bz)
|
||||||
if key in self.boxes.keys():
|
if key in self.boxes.keys():
|
||||||
self.boxes[key].append(atom)
|
self.boxes[key].append(atom)
|
||||||
@@ -397,13 +403,13 @@ class bondmaker:
|
|||||||
|
|
||||||
def box_key(self, x, y, z):
|
def box_key(self, x, y, z):
|
||||||
return '%d-%d-%d'%(x,y,z)
|
return '%d-%d-%d'%(x,y,z)
|
||||||
|
|
||||||
|
|
||||||
def has_bond(self, atom1, atom2):
|
def has_bond(self, atom1, atom2):
|
||||||
if atom1 in atom2.bonded_atoms or atom2 in atom1.bonded_atoms:
|
if atom1 in atom2.bonded_atoms or atom2 in atom1.bonded_atoms:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def make_bond(self, atom1, atom2):
|
def make_bond(self, atom1, atom2):
|
||||||
""" Makes a bond between atom1 and atom2 """
|
""" Makes a bond between atom1 and atom2 """
|
||||||
@@ -413,13 +419,13 @@ class bondmaker:
|
|||||||
#print('making bond for',atom1,atom2)
|
#print('making bond for',atom1,atom2)
|
||||||
if not atom1 in atom2.bonded_atoms:
|
if not atom1 in atom2.bonded_atoms:
|
||||||
atom2.bonded_atoms.append(atom1)
|
atom2.bonded_atoms.append(atom1)
|
||||||
|
|
||||||
if not atom2 in atom1.bonded_atoms:
|
if not atom2 in atom1.bonded_atoms:
|
||||||
atom1.bonded_atoms.append(atom2)
|
atom1.bonded_atoms.append(atom2)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def generate_protein_bond_dictionary(self, atoms):
|
def generate_protein_bond_dictionary(self, atoms):
|
||||||
|
|
||||||
for atom in atoms:
|
for atom in atoms:
|
||||||
@@ -433,25 +439,25 @@ class bondmaker:
|
|||||||
not name_j in self.backbone_atoms:
|
not name_j in self.backbone_atoms:
|
||||||
if not name_i in self.terminal_oxygen_names and\
|
if not name_i in self.terminal_oxygen_names and\
|
||||||
not name_j in self.terminal_oxygen_names:
|
not name_j in self.terminal_oxygen_names:
|
||||||
|
|
||||||
if not resi_i in list(self.protein_bonds.keys()):
|
if not resi_i in list(self.protein_bonds.keys()):
|
||||||
self.protein_bonds[resi_i] = {}
|
self.protein_bonds[resi_i] = {}
|
||||||
if not name_i in self.protein_bonds[resi_i]:
|
if not name_i in self.protein_bonds[resi_i]:
|
||||||
self.protein_bonds[resi_i][name_i] = []
|
self.protein_bonds[resi_i][name_i] = []
|
||||||
|
|
||||||
if not name_j in self.protein_bonds[resi_i][name_i]:
|
if not name_j in self.protein_bonds[resi_i][name_i]:
|
||||||
self.protein_bonds[resi_i][name_i].append(name_j)
|
self.protein_bonds[resi_i][name_i].append(name_j)
|
||||||
|
|
||||||
|
|
||||||
if not resi_j in list(self.protein_bonds.keys()):
|
if not resi_j in list(self.protein_bonds.keys()):
|
||||||
self.protein_bonds[resi_j] = {}
|
self.protein_bonds[resi_j] = {}
|
||||||
if not name_j in self.protein_bonds[resi_j]:
|
if not name_j in self.protein_bonds[resi_j]:
|
||||||
self.protein_bonds[resi_j][name_j] = []
|
self.protein_bonds[resi_j][name_j] = []
|
||||||
|
|
||||||
if not name_i in self.protein_bonds[resi_j][name_j]:
|
if not name_i in self.protein_bonds[resi_j][name_j]:
|
||||||
self.protein_bonds[resi_j][name_j].append(name_i)
|
self.protein_bonds[resi_j][name_j].append(name_i)
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -467,10 +473,10 @@ if __name__ == '__main__':
|
|||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
print('Error: Could not find \"%s\"'%filename)
|
print('Error: Could not find \"%s\"'%filename)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
pdblist = pdb.readPDB(filename)
|
pdblist = pdb.readPDB(filename)
|
||||||
my_protein = protein.Protein(pdblist,'test.pdb')
|
my_protein = protein.Protein(pdblist,'test.pdb')
|
||||||
|
|
||||||
for chain in my_protein.chains:
|
for chain in my_protein.chains:
|
||||||
for residue in chain.residues:
|
for residue in chain.residues:
|
||||||
residue.atoms = [atom for atom in residue.atoms if atom.element != 'H']
|
residue.atoms = [atom for atom in residue.atoms if atom.element != 'H']
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import math, Source.protonate, Source.bonds,copy, sys
|
import math, propka.protonate, propka.bonds,copy, sys
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -17,9 +19,9 @@ def setup_bonding_and_protonation(parameters, molecular_container):
|
|||||||
# apply information on pi electrons
|
# apply information on pi electrons
|
||||||
my_bond_maker.add_pi_electron_information(molecular_container)
|
my_bond_maker.add_pi_electron_information(molecular_container)
|
||||||
|
|
||||||
# Protonate atoms
|
# Protonate atoms
|
||||||
if molecular_container.options.protonate_all:
|
if molecular_container.options.protonate_all:
|
||||||
my_protonator = Source.protonate.Protonate(verbose=False)
|
my_protonator = propka.protonate.Protonate(verbose=False)
|
||||||
my_protonator.protonate(molecular_container)
|
my_protonator.protonate(molecular_container)
|
||||||
|
|
||||||
|
|
||||||
@@ -29,7 +31,7 @@ def setup_bonding_and_protonation(parameters, molecular_container):
|
|||||||
|
|
||||||
def setup_bonding(parameters, molecular_container):
|
def setup_bonding(parameters, molecular_container):
|
||||||
# make bonds
|
# make bonds
|
||||||
my_bond_maker = Source.bonds.bondmaker()
|
my_bond_maker = propka.bonds.bondmaker()
|
||||||
my_bond_maker.find_bonds_for_molecules_using_boxes(molecular_container)
|
my_bond_maker.find_bonds_for_molecules_using_boxes(molecular_container)
|
||||||
|
|
||||||
return my_bond_maker
|
return my_bond_maker
|
||||||
@@ -46,11 +48,11 @@ def set_ligand_atom_names(molecular_container):
|
|||||||
# The following methods imitates propka3.0 protonation!
|
# The following methods imitates propka3.0 protonation!
|
||||||
#
|
#
|
||||||
def setup_bonding_and_protonation_30_style(parameters, molecular_container):
|
def setup_bonding_and_protonation_30_style(parameters, molecular_container):
|
||||||
# Protonate atoms
|
# Protonate atoms
|
||||||
protonate_30_style(molecular_container)
|
protonate_30_style(molecular_container)
|
||||||
|
|
||||||
# make bonds
|
# make bonds
|
||||||
my_bond_maker = Source.bonds.bondmaker()
|
my_bond_maker = propka.bonds.bondmaker()
|
||||||
my_bond_maker.find_bonds_for_molecules_using_boxes(molecular_container)
|
my_bond_maker.find_bonds_for_molecules_using_boxes(molecular_container)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -87,7 +89,7 @@ def protonate_30_style(molecular_container):
|
|||||||
residue = []
|
residue = []
|
||||||
if atom.type=='atom':
|
if atom.type=='atom':
|
||||||
residue.append(atom)
|
residue.append(atom)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def addArgHydrogen(residue):
|
def addArgHydrogen(residue):
|
||||||
@@ -117,7 +119,7 @@ def addArgHydrogen(residue):
|
|||||||
H4.name = "HN3"
|
H4.name = "HN3"
|
||||||
H5 = protonateDirection([NH2, NE, H1])
|
H5 = protonateDirection([NH2, NE, H1])
|
||||||
H5.name = "HN4"
|
H5.name = "HN4"
|
||||||
|
|
||||||
return [H1,H2,H3,H4,H5]
|
return [H1,H2,H3,H4,H5]
|
||||||
|
|
||||||
def addHisHydrogen(residue):
|
def addHisHydrogen(residue):
|
||||||
@@ -179,7 +181,7 @@ def addAmdHydrogen(residue):
|
|||||||
O = atom
|
O = atom
|
||||||
elif (atom.resName == "GLN" and atom.name == "NE2") or (atom.resName == "ASN" and atom.name == "ND2"):
|
elif (atom.resName == "GLN" and atom.name == "NE2") or (atom.resName == "ASN" and atom.name == "ND2"):
|
||||||
N = atom
|
N = atom
|
||||||
|
|
||||||
if C == None or O == None or N == None:
|
if C == None or O == None or N == None:
|
||||||
str = "Did not find N, C and/or O in %s%4d - in %s" % (atom.resName, atom.resNumb, "addAmdHydrogen()")
|
str = "Did not find N, C and/or O in %s%4d - in %s" % (atom.resName, atom.resNumb, "addAmdHydrogen()")
|
||||||
print(str)
|
print(str)
|
||||||
@@ -189,20 +191,20 @@ def addAmdHydrogen(residue):
|
|||||||
H1.name = "HN1"
|
H1.name = "HN1"
|
||||||
H2 = protonateAverageDirection([N, C, O])
|
H2 = protonateAverageDirection([N, C, O])
|
||||||
H2.name = "HN2"
|
H2.name = "HN2"
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def addBackBoneHydrogen(residue, O, C):
|
def addBackBoneHydrogen(residue, O, C):
|
||||||
"""
|
"""
|
||||||
Adds hydrogen backbone atoms to residues according to the old way; dR is wrong for the N-terminus
|
Adds hydrogen backbone atoms to residues according to the old way; dR is wrong for the N-terminus
|
||||||
(i.e. first residue) but it doesn't affect anything at the moment. Could be improved, but works
|
(i.e. first residue) but it doesn't affect anything at the moment. Could be improved, but works
|
||||||
for now.
|
for now.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
new_C = None
|
new_C = None
|
||||||
new_O = None
|
new_O = None
|
||||||
N = None
|
N = None
|
||||||
|
|
||||||
|
|
||||||
for atom in residue:
|
for atom in residue:
|
||||||
if atom.name == "N":
|
if atom.name == "N":
|
||||||
@@ -211,20 +213,20 @@ def addBackBoneHydrogen(residue, O, C):
|
|||||||
new_C = atom
|
new_C = atom
|
||||||
if atom.name == "O":
|
if atom.name == "O":
|
||||||
new_O = atom
|
new_O = atom
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if None in [C,O,N]:
|
if None in [C,O,N]:
|
||||||
return [new_O,new_C]
|
return [new_O,new_C]
|
||||||
|
|
||||||
|
|
||||||
if N.resName == "PRO":
|
if N.resName == "PRO":
|
||||||
""" PRO doesn't have an H-atom; do nothing """
|
""" PRO doesn't have an H-atom; do nothing """
|
||||||
else:
|
else:
|
||||||
H = protonateDirection([N, O, C])
|
H = protonateDirection([N, O, C])
|
||||||
H.name = "H"
|
H.name = "H"
|
||||||
|
|
||||||
return [new_O,new_C]
|
return [new_O,new_C]
|
||||||
|
|
||||||
|
|
||||||
@@ -247,7 +249,7 @@ def protonateDirection(list):
|
|||||||
y = X1.y + dY/length
|
y = X1.y + dY/length
|
||||||
z = X1.z + dZ/length
|
z = X1.z + dZ/length
|
||||||
|
|
||||||
|
|
||||||
H = make_new_H(X1,x,y,z)
|
H = make_new_H(X1,x,y,z)
|
||||||
H.name = "H"
|
H.name = "H"
|
||||||
|
|
||||||
@@ -277,7 +279,7 @@ def protonateAverageDirection(list):
|
|||||||
H = make_new_H(X1,x,y,z)
|
H = make_new_H(X1,x,y,z)
|
||||||
H.name = "H"
|
H.name = "H"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return H
|
return H
|
||||||
|
|
||||||
@@ -290,7 +292,7 @@ def protonateSP2(list):
|
|||||||
X1 = list[0]
|
X1 = list[0]
|
||||||
X2 = list[1]
|
X2 = list[1]
|
||||||
X3 = list[2]
|
X3 = list[2]
|
||||||
|
|
||||||
dX = (X1.x + X3.x)*0.5 - X2.x
|
dX = (X1.x + X3.x)*0.5 - X2.x
|
||||||
dY = (X1.y + X3.y)*0.5 - X2.y
|
dY = (X1.y + X3.y)*0.5 - X2.y
|
||||||
dZ = (X1.z + X3.z)*0.5 - X2.z
|
dZ = (X1.z + X3.z)*0.5 - X2.z
|
||||||
@@ -301,16 +303,16 @@ def protonateSP2(list):
|
|||||||
|
|
||||||
H = make_new_H(X2,x,y,z)
|
H = make_new_H(X2,x,y,z)
|
||||||
H.name = "H"
|
H.name = "H"
|
||||||
|
|
||||||
return H
|
return H
|
||||||
|
|
||||||
|
|
||||||
def make_new_H(atom, x,y,z):
|
def make_new_H(atom, x,y,z):
|
||||||
|
|
||||||
new_H = Source.atom.Atom()
|
new_H = propka.atom.Atom()
|
||||||
new_H.setProperty(numb = None,
|
new_H.setProperty(numb = None,
|
||||||
name = 'H%s'%atom.name[1:],
|
name = 'H%s'%atom.name[1:],
|
||||||
resName = atom.resName,
|
resName = atom.resName,
|
||||||
chainID = atom.chainID,
|
chainID = atom.chainID,
|
||||||
resNumb = atom.resNumb,
|
resNumb = atom.resNumb,
|
||||||
x = x,
|
x = x,
|
||||||
@@ -329,7 +331,7 @@ def make_new_H(atom, x,y,z):
|
|||||||
new_H.number_of_pi_electrons_in_double_and_triple_bonds = 0
|
new_H.number_of_pi_electrons_in_double_and_triple_bonds = 0
|
||||||
|
|
||||||
atom.bonded_atoms.append(new_H)
|
atom.bonded_atoms.append(new_H)
|
||||||
atom.conformation_container.add_atom(new_H)
|
atom.conformation_container.add_atom(new_H)
|
||||||
|
|
||||||
return new_H
|
return new_H
|
||||||
|
|
||||||
@@ -356,7 +358,7 @@ def radial_volume_desolvation(parameters, group):
|
|||||||
# ignore atoms in the same residue
|
# ignore atoms in the same residue
|
||||||
if atom.resNumb == group.atom.resNumb and atom.chainID == group.atom.chainID:
|
if atom.resNumb == group.atom.resNumb and atom.chainID == group.atom.chainID:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
sq_dist = squared_distance(group, atom)
|
sq_dist = squared_distance(group, atom)
|
||||||
|
|
||||||
# desolvation
|
# desolvation
|
||||||
@@ -375,7 +377,7 @@ def radial_volume_desolvation(parameters, group):
|
|||||||
# buried
|
# buried
|
||||||
if sq_dist < parameters.buried_cutoff_squared:
|
if sq_dist < parameters.buried_cutoff_squared:
|
||||||
group.Nmass += 1
|
group.Nmass += 1
|
||||||
|
|
||||||
group.buried = calculate_weight(parameters, group.Nmass)
|
group.buried = calculate_weight(parameters, group.Nmass)
|
||||||
scale_factor = calculate_scale_factor(parameters, group.buried)
|
scale_factor = calculate_scale_factor(parameters, group.buried)
|
||||||
volume_after_allowance = max(0.00, volume-parameters.desolvationAllowance)
|
volume_after_allowance = max(0.00, volume-parameters.desolvationAllowance)
|
||||||
@@ -385,9 +387,9 @@ def radial_volume_desolvation(parameters, group):
|
|||||||
# Elocl, Nlocl -> reorganisation energy (count backbone hydorgen bond acceptors, C=O)
|
# Elocl, Nlocl -> reorganisation energy (count backbone hydorgen bond acceptors, C=O)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#print('%s %5.2f %5.2f %4d'%(group, group.buried, group.Emass, group.Nmass))
|
#print('%s %5.2f %5.2f %4d'%(group, group.buried, group.Emass, group.Nmass))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -395,7 +397,7 @@ def contactDesolvation(parameters, group):
|
|||||||
"""
|
"""
|
||||||
calculates the desolvation according to the Contact Model, the old default
|
calculates the desolvation according to the Contact Model, the old default
|
||||||
"""
|
"""
|
||||||
|
|
||||||
local_radius = {'ASP': 4.5,
|
local_radius = {'ASP': 4.5,
|
||||||
'GLU': 4.5,
|
'GLU': 4.5,
|
||||||
'HIS': 4.5,
|
'HIS': 4.5,
|
||||||
@@ -405,7 +407,7 @@ def contactDesolvation(parameters, group):
|
|||||||
'ARG': 5.0,
|
'ARG': 5.0,
|
||||||
'C-': 4.5,
|
'C-': 4.5,
|
||||||
'N+': 4.5}
|
'N+': 4.5}
|
||||||
|
|
||||||
all_atoms = group.atom.conformation_container.get_non_hydrogen_atoms()
|
all_atoms = group.atom.conformation_container.get_non_hydrogen_atoms()
|
||||||
if residue.resName in version.desolvationRadii:
|
if residue.resName in version.desolvationRadii:
|
||||||
local_cutoff = version.desolvationRadii[residue.resName]
|
local_cutoff = version.desolvationRadii[residue.resName]
|
||||||
@@ -434,7 +436,7 @@ def contactDesolvation(parameters, group):
|
|||||||
# Note, there will be an unforseen problem: e.g. if one residue has Nmass > Nmax and
|
# Note, there will be an unforseen problem: e.g. if one residue has Nmass > Nmax and
|
||||||
# the other Nmass < Nmax, the Npair will not be Nmass1 + Nmass2!
|
# the other Nmass < Nmax, the Npair will not be Nmass1 + Nmass2!
|
||||||
residue.buried = calculateWeight(residue.Nmass)
|
residue.buried = calculateWeight(residue.Nmass)
|
||||||
|
|
||||||
return 0.00, 0.00, 0.00, 0.00
|
return 0.00, 0.00, 0.00, 0.00
|
||||||
|
|
||||||
|
|
||||||
@@ -455,10 +457,10 @@ def calculate_weight(parameters, Nmass):
|
|||||||
weight = float(Nmass - parameters.Nmin)/float(parameters.Nmax - parameters.Nmin)
|
weight = float(Nmass - parameters.Nmin)/float(parameters.Nmax - parameters.Nmin)
|
||||||
weight = min(1.0, weight)
|
weight = min(1.0, weight)
|
||||||
weight = max(0.0, weight)
|
weight = max(0.0, weight)
|
||||||
|
|
||||||
return weight
|
return weight
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def squared_distance(atom1, atom2):
|
def squared_distance(atom1, atom2):
|
||||||
# if atom1 in atom2.squared_distances:
|
# if atom1 in atom2.squared_distances:
|
||||||
@@ -518,9 +520,9 @@ def HydrogenBondEnergy(distance, dpka_max, cutoff, f_angle=1.0):
|
|||||||
value = 0.00
|
value = 0.00
|
||||||
else:
|
else:
|
||||||
value = 1.0-(distance-cutoff[0])/(cutoff[1]-cutoff[0])
|
value = 1.0-(distance-cutoff[0])/(cutoff[1]-cutoff[0])
|
||||||
|
|
||||||
dpKa = dpka_max*value*f_angle
|
dpKa = dpka_max*value*f_angle
|
||||||
|
|
||||||
return abs(dpKa)
|
return abs(dpKa)
|
||||||
|
|
||||||
|
|
||||||
@@ -535,13 +537,13 @@ def AngleFactorX(atom1=None, atom2=None, atom3=None, center=None):
|
|||||||
dX_32 = atom2.x - atom3.x
|
dX_32 = atom2.x - atom3.x
|
||||||
dY_32 = atom2.y - atom3.y
|
dY_32 = atom2.y - atom3.y
|
||||||
dZ_32 = atom2.z - atom3.z
|
dZ_32 = atom2.z - atom3.z
|
||||||
|
|
||||||
distance_23 = math.sqrt( dX_32*dX_32 + dY_32*dY_32 + dZ_32*dZ_32 )
|
distance_23 = math.sqrt( dX_32*dX_32 + dY_32*dY_32 + dZ_32*dZ_32 )
|
||||||
|
|
||||||
dX_32 = dX_32/distance_23
|
dX_32 = dX_32/distance_23
|
||||||
dY_32 = dY_32/distance_23
|
dY_32 = dY_32/distance_23
|
||||||
dZ_32 = dZ_32/distance_23
|
dZ_32 = dZ_32/distance_23
|
||||||
|
|
||||||
if atom1 == None:
|
if atom1 == None:
|
||||||
dX_21 = center[0] - atom2.x
|
dX_21 = center[0] - atom2.x
|
||||||
dY_21 = center[1] - atom2.y
|
dY_21 = center[1] - atom2.y
|
||||||
@@ -550,13 +552,13 @@ def AngleFactorX(atom1=None, atom2=None, atom3=None, center=None):
|
|||||||
dX_21 = atom1.x - atom2.x
|
dX_21 = atom1.x - atom2.x
|
||||||
dY_21 = atom1.y - atom2.y
|
dY_21 = atom1.y - atom2.y
|
||||||
dZ_21 = atom1.z - atom2.z
|
dZ_21 = atom1.z - atom2.z
|
||||||
|
|
||||||
distance_12 = math.sqrt( dX_21*dX_21 + dY_21*dY_21 + dZ_21*dZ_21 )
|
distance_12 = math.sqrt( dX_21*dX_21 + dY_21*dY_21 + dZ_21*dZ_21 )
|
||||||
|
|
||||||
dX_21 = dX_21/distance_12
|
dX_21 = dX_21/distance_12
|
||||||
dY_21 = dY_21/distance_12
|
dY_21 = dY_21/distance_12
|
||||||
dZ_21 = dZ_21/distance_12
|
dZ_21 = dZ_21/distance_12
|
||||||
|
|
||||||
f_angle = dX_21*dX_32 + dY_21*dY_32 + dZ_21*dZ_32
|
f_angle = dX_21*dX_32 + dY_21*dY_32 + dZ_21*dZ_32
|
||||||
|
|
||||||
|
|
||||||
@@ -569,7 +571,7 @@ def hydrogen_bond_interaction(group1, group2, version):
|
|||||||
# find the smallest distance between interacting atoms
|
# find the smallest distance between interacting atoms
|
||||||
atoms1 = group1.get_interaction_atoms(group2)
|
atoms1 = group1.get_interaction_atoms(group2)
|
||||||
atoms2 = group2.get_interaction_atoms(group1)
|
atoms2 = group2.get_interaction_atoms(group1)
|
||||||
[closest_atom1, distance, closest_atom2] = Source.calculations.get_smallest_distance(atoms1, atoms2)
|
[closest_atom1, distance, closest_atom2] = propka.calculations.get_smallest_distance(atoms1, atoms2)
|
||||||
|
|
||||||
if None in [closest_atom1, closest_atom2]:
|
if None in [closest_atom1, closest_atom2]:
|
||||||
print('Warning: Side chain interaction failed for %s and %s'%(group1.label, group2.label))
|
print('Warning: Side chain interaction failed for %s and %s'%(group1.label, group2.label))
|
||||||
@@ -577,20 +579,20 @@ def hydrogen_bond_interaction(group1, group2, version):
|
|||||||
|
|
||||||
# get the parameters
|
# get the parameters
|
||||||
[dpka_max, cutoff] = version.get_hydrogen_bond_parameters(closest_atom1,closest_atom2)
|
[dpka_max, cutoff] = version.get_hydrogen_bond_parameters(closest_atom1,closest_atom2)
|
||||||
|
|
||||||
if dpka_max==None or None in cutoff:
|
if dpka_max==None or None in cutoff:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# check that the closest atoms are close enough
|
# check that the closest atoms are close enough
|
||||||
if distance >= cutoff[1]:
|
if distance >= cutoff[1]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# check that bond distance criteria is met
|
# check that bond distance criteria is met
|
||||||
bond_distance_too_short = group1.atom.is_atom_within_bond_distance(group2.atom,
|
bond_distance_too_short = group1.atom.is_atom_within_bond_distance(group2.atom,
|
||||||
version.parameters.min_bond_distance_for_hydrogen_bonds,1)
|
version.parameters.min_bond_distance_for_hydrogen_bonds,1)
|
||||||
if bond_distance_too_short:
|
if bond_distance_too_short:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# set the angle factor
|
# set the angle factor
|
||||||
#
|
#
|
||||||
# ---closest_atom1/2
|
# ---closest_atom1/2
|
||||||
@@ -602,18 +604,18 @@ def hydrogen_bond_interaction(group1, group2, version):
|
|||||||
if closest_atom2.element == 'H':
|
if closest_atom2.element == 'H':
|
||||||
heavy_atom = closest_atom2.bonded_atoms[0]
|
heavy_atom = closest_atom2.bonded_atoms[0]
|
||||||
hydrogen = closest_atom2
|
hydrogen = closest_atom2
|
||||||
distance, f_angle, nada = Source.calculations.AngleFactorX(closest_atom1, hydrogen, heavy_atom)
|
distance, f_angle, nada = propka.calculations.AngleFactorX(closest_atom1, hydrogen, heavy_atom)
|
||||||
else:
|
else:
|
||||||
# Either the structure is corrupt (no hydrogen), or the heavy atom is closer to
|
# Either the structure is corrupt (no hydrogen), or the heavy atom is closer to
|
||||||
# the titratable atom than the hydrogen. In either case we set the angle factor
|
# the titratable atom than the hydrogen. In either case we set the angle factor
|
||||||
# to 0
|
# to 0
|
||||||
f_angle = 0.0
|
f_angle = 0.0
|
||||||
|
|
||||||
elif group1.type in version.parameters.angular_dependent_sidechain_interactions:
|
elif group1.type in version.parameters.angular_dependent_sidechain_interactions:
|
||||||
if closest_atom1.element == 'H':
|
if closest_atom1.element == 'H':
|
||||||
heavy_atom = closest_atom1.bonded_atoms[0]
|
heavy_atom = closest_atom1.bonded_atoms[0]
|
||||||
hydrogen = closest_atom1
|
hydrogen = closest_atom1
|
||||||
distance, f_angle, nada = Source.calculations.AngleFactorX(closest_atom2, hydrogen, heavy_atom)
|
distance, f_angle, nada = propka.calculations.AngleFactorX(closest_atom2, hydrogen, heavy_atom)
|
||||||
else:
|
else:
|
||||||
# Either the structure is corrupt (no hydrogen), or the heavy atom is closer to
|
# Either the structure is corrupt (no hydrogen), or the heavy atom is closer to
|
||||||
# the titratable atom than the hydrogen. In either case we set the angle factor
|
# the titratable atom than the hydrogen. In either case we set the angle factor
|
||||||
@@ -621,7 +623,7 @@ def hydrogen_bond_interaction(group1, group2, version):
|
|||||||
f_angle = 0.0
|
f_angle = 0.0
|
||||||
|
|
||||||
weight = version.calculatePairWeight(group1.Nmass, group2.Nmass)
|
weight = version.calculatePairWeight(group1.Nmass, group2.Nmass)
|
||||||
|
|
||||||
exception, value = version.checkExceptions(group1, group2)
|
exception, value = version.checkExceptions(group1, group2)
|
||||||
#exception = False # circumventing exception
|
#exception = False # circumventing exception
|
||||||
if exception == True:
|
if exception == True:
|
||||||
@@ -629,7 +631,7 @@ def hydrogen_bond_interaction(group1, group2, version):
|
|||||||
#print(" exception for %s %s %6.2lf" % (group1.label, group2.label, value))
|
#print(" exception for %s %s %6.2lf" % (group1.label, group2.label, value))
|
||||||
else:
|
else:
|
||||||
value = version.calculateSideChainEnergy(distance, dpka_max, cutoff, weight, f_angle)
|
value = version.calculateSideChainEnergy(distance, dpka_max, cutoff, weight, f_angle)
|
||||||
|
|
||||||
# print('distance',distance)
|
# print('distance',distance)
|
||||||
# print('dpka_max',dpka_max)
|
# print('dpka_max',dpka_max)
|
||||||
# print('cutoff',cutoff)
|
# print('cutoff',cutoff)
|
||||||
@@ -654,7 +656,7 @@ def HydrogenBondEnergy(distance, dpka_max, cutoff, f_angle=1.0):
|
|||||||
value = 1.0-(distance-cutoff[0])/(cutoff[1]-cutoff[0])
|
value = 1.0-(distance-cutoff[0])/(cutoff[1]-cutoff[0])
|
||||||
|
|
||||||
dpKa = dpka_max*value*f_angle
|
dpKa = dpka_max*value*f_angle
|
||||||
|
|
||||||
return abs(dpKa)
|
return abs(dpKa)
|
||||||
|
|
||||||
|
|
||||||
@@ -678,15 +680,15 @@ def checkCoulombPair(parameters, group1, group2, distance):
|
|||||||
"""
|
"""
|
||||||
Npair = group1.Nmass + group2.Nmass
|
Npair = group1.Nmass + group2.Nmass
|
||||||
do_coulomb = True
|
do_coulomb = True
|
||||||
|
|
||||||
# check if both groups are titratable (ions are taken care of in determinants::setIonDeterminants)
|
# check if both groups are titratable (ions are taken care of in determinants::setIonDeterminants)
|
||||||
if not (group1.titratable and group2.titratable):
|
if not (group1.titratable and group2.titratable):
|
||||||
do_coulomb = False
|
do_coulomb = False
|
||||||
|
|
||||||
# check if the distance is not too big
|
# check if the distance is not too big
|
||||||
if distance > parameters.coulomb_cutoff2:
|
if distance > parameters.coulomb_cutoff2:
|
||||||
do_coulomb = False
|
do_coulomb = False
|
||||||
|
|
||||||
# check that desolvation is ok
|
# check that desolvation is ok
|
||||||
if Npair < parameters.Nmin:
|
if Npair < parameters.Nmin:
|
||||||
do_coulomb = False
|
do_coulomb = False
|
||||||
@@ -725,8 +727,8 @@ def BackBoneReorganization(parameters, conformation):
|
|||||||
dpKa = 0.00
|
dpKa = 0.00
|
||||||
for BBC_group in BBC_groups:
|
for BBC_group in BBC_groups:
|
||||||
center = [titratable_group.x, titratable_group.y, titratable_group.z]
|
center = [titratable_group.x, titratable_group.y, titratable_group.z]
|
||||||
distance, f_angle, nada = AngleFactorX(atom2=BBC_group.get_interaction_atoms(titratable_group)[0],
|
distance, f_angle, nada = AngleFactorX(atom2=BBC_group.get_interaction_atoms(titratable_group)[0],
|
||||||
atom3=BBC_group.atom,
|
atom3=BBC_group.atom,
|
||||||
center=center)
|
center=center)
|
||||||
if distance < 6.0 and f_angle > 0.001:
|
if distance < 6.0 and f_angle > 0.001:
|
||||||
value = 1.0-(distance-3.0)/(6.0-3.0)
|
value = 1.0-(distance-3.0)/(6.0-3.0)
|
||||||
@@ -767,7 +769,7 @@ def checkExceptions(version, group1, group2):
|
|||||||
else:
|
else:
|
||||||
# do nothing, no exception for this pair
|
# do nothing, no exception for this pair
|
||||||
exception = False; value = None
|
exception = False; value = None
|
||||||
|
|
||||||
return exception, value
|
return exception, value
|
||||||
|
|
||||||
|
|
||||||
@@ -780,7 +782,7 @@ def checkCooArgException(group_coo, group_arg, version):
|
|||||||
str = "xxx"
|
str = "xxx"
|
||||||
exception = True
|
exception = True
|
||||||
value_tot = 0.00
|
value_tot = 0.00
|
||||||
|
|
||||||
#dpka_max = parameters.sidechain_interaction.get_value(group_coo.type,group_arg.type)
|
#dpka_max = parameters.sidechain_interaction.get_value(group_coo.type,group_arg.type)
|
||||||
#cutoff = parameters.sidechain_cutoffs.get_value(group_coo.type,group_arg.type)
|
#cutoff = parameters.sidechain_cutoffs.get_value(group_coo.type,group_arg.type)
|
||||||
|
|
||||||
@@ -801,7 +803,7 @@ def checkCooArgException(group_coo, group_arg, version):
|
|||||||
if group_arg.type in version.parameters.angular_dependent_sidechain_interactions:
|
if group_arg.type in version.parameters.angular_dependent_sidechain_interactions:
|
||||||
atom3 = closest_arg_atom.bonded_atoms[0]
|
atom3 = closest_arg_atom.bonded_atoms[0]
|
||||||
distance, f_angle, nada = AngleFactorX(closest_coo_atom, closest_arg_atom, atom3)
|
distance, f_angle, nada = AngleFactorX(closest_coo_atom, closest_arg_atom, atom3)
|
||||||
|
|
||||||
value = HydrogenBondEnergy(distance, dpka_max, cutoff, f_angle)
|
value = HydrogenBondEnergy(distance, dpka_max, cutoff, f_angle)
|
||||||
#print(iter, closest_coo_atom, closest_arg_atom,distance,value)
|
#print(iter, closest_coo_atom, closest_arg_atom,distance,value)
|
||||||
value_tot += value
|
value_tot += value
|
||||||
@@ -809,7 +811,7 @@ def checkCooArgException(group_coo, group_arg, version):
|
|||||||
atoms_coo.remove(closest_coo_atom)
|
atoms_coo.remove(closest_coo_atom)
|
||||||
atoms_arg.remove(closest_arg_atom)
|
atoms_arg.remove(closest_arg_atom)
|
||||||
|
|
||||||
|
|
||||||
return exception, value_tot
|
return exception, value_tot
|
||||||
|
|
||||||
|
|
||||||
@@ -820,7 +822,7 @@ def checkCooCooException(group1, group2, version):
|
|||||||
exception = True
|
exception = True
|
||||||
[closest_atom1, distance, closest_atom2] = get_smallest_distance(group1.get_interaction_atoms(group2),
|
[closest_atom1, distance, closest_atom2] = get_smallest_distance(group1.get_interaction_atoms(group2),
|
||||||
group2.get_interaction_atoms(group1))
|
group2.get_interaction_atoms(group1))
|
||||||
|
|
||||||
#dpka_max = parameters.sidechain_interaction.get_value(group1.type,group2.type)
|
#dpka_max = parameters.sidechain_interaction.get_value(group1.type,group2.type)
|
||||||
#cutoff = parameters.sidechain_cutoffs.get_value(group1.type,group2.type)
|
#cutoff = parameters.sidechain_cutoffs.get_value(group1.type,group2.type)
|
||||||
[dpka_max, cutoff] = version.get_hydrogen_bond_parameters(closest_atom1,closest_atom2)
|
[dpka_max, cutoff] = version.get_hydrogen_bond_parameters(closest_atom1,closest_atom2)
|
||||||
@@ -863,7 +865,7 @@ def checkCysHisException(group1, group2, version):
|
|||||||
if checkBuried(group1.Nmass, group2.Nmass):
|
if checkBuried(group1.Nmass, group2.Nmass):
|
||||||
exception = True
|
exception = True
|
||||||
|
|
||||||
return exception, version.parameters.CYS_HIS_exception
|
return exception, version.parameters.CYS_HIS_exception
|
||||||
|
|
||||||
|
|
||||||
def checkCysCysException(group1, group2, version):
|
def checkCysCysException(group1, group2, version):
|
||||||
@@ -2,7 +2,10 @@
|
|||||||
# Container for molecular conformations
|
# Container for molecular conformations
|
||||||
#
|
#
|
||||||
|
|
||||||
import Source.group, Source.determinants, Source.determinant, Source.ligand, Source.output, Source.coupled_groups, functools
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import propka.group, propka.determinants, propka.determinant, propka.ligand, propka.output, propka.coupled_groups, functools
|
||||||
|
|
||||||
class Conformation_container:
|
class Conformation_container:
|
||||||
def __init__(self, name='', parameters=None, molecular_container=None):
|
def __init__(self, name='', parameters=None, molecular_container=None):
|
||||||
@@ -13,10 +16,10 @@ class Conformation_container:
|
|||||||
self.groups = []
|
self.groups = []
|
||||||
self.chains = []
|
self.chains = []
|
||||||
self.current_iter_item = 0
|
self.current_iter_item = 0
|
||||||
|
|
||||||
self.marvin_pkas_calculated = False
|
self.marvin_pkas_calculated = False
|
||||||
self.non_covalently_coupled_groups = False
|
self.non_covalently_coupled_groups = False
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -28,21 +31,21 @@ class Conformation_container:
|
|||||||
for atom in self.get_non_hydrogen_atoms():
|
for atom in self.get_non_hydrogen_atoms():
|
||||||
# has this atom been checked for groups?
|
# has this atom been checked for groups?
|
||||||
if atom.groups_extracted == 0:
|
if atom.groups_extracted == 0:
|
||||||
self.validate_group(Source.group.is_group(self.parameters, atom))
|
self.validate_group(propka.group.is_group(self.parameters, atom))
|
||||||
# if the atom has been checked in a another conformation, check if it has a
|
# if the atom has been checked in a another conformation, check if it has a
|
||||||
# group that should be used in this conformation as well
|
# group that should be used in this conformation as well
|
||||||
elif atom.group:
|
elif atom.group:
|
||||||
self.validate_group(atom.group)
|
self.validate_group(atom.group)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def additional_setup_when_reading_input_file(self):
|
def additional_setup_when_reading_input_file(self):
|
||||||
|
|
||||||
# if a group is coupled and we are reading a .propka_input file,
|
# if a group is coupled and we are reading a .propka_input file,
|
||||||
# some more configuration might be needed
|
# some more configuration might be needed
|
||||||
|
|
||||||
# print coupling map
|
# print coupling map
|
||||||
map = Source.output.make_interaction_map('Covalent coupling map for %s'%self,
|
map = propka.output.make_interaction_map('Covalent coupling map for %s'%self,
|
||||||
self.get_covalently_coupled_groups(),
|
self.get_covalently_coupled_groups(),
|
||||||
lambda g1,g2: g1 in g2.covalently_coupled_groups)
|
lambda g1,g2: g1 in g2.covalently_coupled_groups)
|
||||||
print(map)
|
print(map)
|
||||||
@@ -50,11 +53,11 @@ class Conformation_container:
|
|||||||
# check if we should set a common charge centre as well
|
# check if we should set a common charge centre as well
|
||||||
if self.parameters.common_charge_centre:
|
if self.parameters.common_charge_centre:
|
||||||
self.set_common_charge_centres()
|
self.set_common_charge_centres()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def set_common_charge_centres(self):
|
def set_common_charge_centres(self):
|
||||||
for system in self.get_coupled_systems(self.get_covalently_coupled_groups(), Source.group.Group.get_covalently_coupled_groups):
|
for system in self.get_coupled_systems(self.get_covalently_coupled_groups(), propka.group.Group.get_covalently_coupled_groups):
|
||||||
# make a list of the charge centre coordinates
|
# make a list of the charge centre coordinates
|
||||||
all_coordinates = list(map(lambda g: [g.x, g.y, g.z], system))
|
all_coordinates = list(map(lambda g: [g.x, g.y, g.z], system))
|
||||||
# find the common charge center
|
# find the common charge center
|
||||||
@@ -82,19 +85,19 @@ class Conformation_container:
|
|||||||
continue
|
continue
|
||||||
if cg.atom.sybyl_type == group.atom.sybyl_type:
|
if cg.atom.sybyl_type == group.atom.sybyl_type:
|
||||||
group.couple_covalently(cg)
|
group.couple_covalently(cg)
|
||||||
|
|
||||||
# check if we should set a common charge centre as well
|
# check if we should set a common charge centre as well
|
||||||
if self.parameters.common_charge_centre:
|
if self.parameters.common_charge_centre:
|
||||||
self.set_common_charge_centres()
|
self.set_common_charge_centres()
|
||||||
|
|
||||||
# print coupling map
|
# print coupling map
|
||||||
map = Source.output.make_interaction_map('Covalent coupling map for %s'%self,
|
map = propka.output.make_interaction_map('Covalent coupling map for %s'%self,
|
||||||
#self.get_titratable_groups(),
|
#self.get_titratable_groups(),
|
||||||
self.get_covalently_coupled_groups(),
|
self.get_covalently_coupled_groups(),
|
||||||
lambda g1,g2: g1 in g2.covalently_coupled_groups)
|
lambda g1,g2: g1 in g2.covalently_coupled_groups)
|
||||||
print(map)
|
print(map)
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -102,8 +105,8 @@ class Conformation_container:
|
|||||||
# check if non-covalent coupling has already been set up in an input file
|
# check if non-covalent coupling has already been set up in an input file
|
||||||
if len(list(filter(lambda g: len(g.non_covalently_coupled_groups)>0, self.get_titratable_groups())))>0:
|
if len(list(filter(lambda g: len(g.non_covalently_coupled_groups)>0, self.get_titratable_groups())))>0:
|
||||||
self.non_covalently_coupled_groups = True
|
self.non_covalently_coupled_groups = True
|
||||||
|
|
||||||
Source.coupled_groups.nccg.identify_non_covalently_coupled_groups(self,verbose=verbose)
|
propka.coupled_groups.nccg.identify_non_covalently_coupled_groups(self,verbose=verbose)
|
||||||
|
|
||||||
# re-do the check
|
# re-do the check
|
||||||
if len(list(filter(lambda g: len(g.non_covalently_coupled_groups)>0, self.get_titratable_groups())))>0:
|
if len(list(filter(lambda g: len(g.non_covalently_coupled_groups)>0, self.get_titratable_groups())))>0:
|
||||||
@@ -157,26 +160,26 @@ class Conformation_container:
|
|||||||
|
|
||||||
def calculate_pka(self, version, options):
|
def calculate_pka(self, version, options):
|
||||||
print('\nCalculating pKas for',self)
|
print('\nCalculating pKas for',self)
|
||||||
|
|
||||||
# calculate desolvation
|
# calculate desolvation
|
||||||
for group in self.get_titratable_groups()+self.get_ions():
|
for group in self.get_titratable_groups()+self.get_ions():
|
||||||
version.calculate_desolvation(group)
|
version.calculate_desolvation(group)
|
||||||
|
|
||||||
# calculate backbone interactions
|
# calculate backbone interactions
|
||||||
Source.determinants.setBackBoneDeterminants(self.get_titratable_groups(), self.get_backbone_groups(), version)
|
propka.determinants.setBackBoneDeterminants(self.get_titratable_groups(), self.get_backbone_groups(), version)
|
||||||
|
|
||||||
# setting ion determinants
|
# setting ion determinants
|
||||||
Source.determinants.setIonDeterminants(self, version)
|
propka.determinants.setIonDeterminants(self, version)
|
||||||
|
|
||||||
# calculating the back-bone reorganization/desolvation term
|
# calculating the back-bone reorganization/desolvation term
|
||||||
version.calculateBackBoneReorganization(self)
|
version.calculateBackBoneReorganization(self)
|
||||||
|
|
||||||
# setting remaining non-iterative and iterative side-chain & Coulomb interaction determinants
|
# setting remaining non-iterative and iterative side-chain & Coulomb interaction determinants
|
||||||
Source.determinants.setDeterminants(self.get_sidechain_groups(), version=version, options=options)
|
propka.determinants.setDeterminants(self.get_sidechain_groups(), version=version, options=options)
|
||||||
|
|
||||||
# calculating the total pKa values
|
# calculating the total pKa values
|
||||||
for group in self.groups: group.calculate_total_pka()
|
for group in self.groups: group.calculate_total_pka()
|
||||||
|
|
||||||
# take coupling effects into account
|
# take coupling effects into account
|
||||||
penalised_labels = self.coupling_effects()
|
penalised_labels = self.coupling_effects()
|
||||||
|
|
||||||
@@ -195,20 +198,20 @@ class Conformation_container:
|
|||||||
|
|
||||||
def coupling_effects(self):
|
def coupling_effects(self):
|
||||||
#
|
#
|
||||||
# Bases: The group with the highest pKa (the most stable one in the
|
# Bases: The group with the highest pKa (the most stable one in the
|
||||||
# charged form) will be the first one to adopt a proton as pH
|
# charged form) will be the first one to adopt a proton as pH
|
||||||
# is lowered and this group is allowed to titrate.
|
# is lowered and this group is allowed to titrate.
|
||||||
# The remaining groups are penalised
|
# The remaining groups are penalised
|
||||||
#
|
#
|
||||||
# Acids: The group with the highest pKa (the least stable one in the
|
# Acids: The group with the highest pKa (the least stable one in the
|
||||||
# charged form) will be the last group to loose the proton as
|
# charged form) will be the last group to loose the proton as
|
||||||
# pH is raised and will be penalised.
|
# pH is raised and will be penalised.
|
||||||
# The remaining groups are allowed to titrate.
|
# The remaining groups are allowed to titrate.
|
||||||
#
|
#
|
||||||
penalised_labels = []
|
penalised_labels = []
|
||||||
|
|
||||||
for all_groups in self.get_coupled_systems(self.get_covalently_coupled_groups(),
|
for all_groups in self.get_coupled_systems(self.get_covalently_coupled_groups(),
|
||||||
Source.group.Group.get_covalently_coupled_groups):
|
propka.group.Group.get_covalently_coupled_groups):
|
||||||
|
|
||||||
# check if we should share determinants
|
# check if we should share determinants
|
||||||
if self.parameters.shared_determinants:
|
if self.parameters.shared_determinants:
|
||||||
@@ -227,14 +230,14 @@ class Conformation_container:
|
|||||||
for a in all_groups:
|
for a in all_groups:
|
||||||
if a == first_group:
|
if a == first_group:
|
||||||
continue # group with the highest pKa is allowed to titrate...
|
continue # group with the highest pKa is allowed to titrate...
|
||||||
a.coupled_titrating_group = first_group
|
a.coupled_titrating_group = first_group
|
||||||
penalised_labels.append(a.label) #... and the rest is penalised
|
penalised_labels.append(a.label) #... and the rest is penalised
|
||||||
|
|
||||||
return penalised_labels
|
return penalised_labels
|
||||||
|
|
||||||
|
|
||||||
def share_determinants(self, groups):
|
def share_determinants(self, groups):
|
||||||
|
|
||||||
# make a list of the determinants to share
|
# make a list of the determinants to share
|
||||||
types = ['sidechain','backbone','coulomb']
|
types = ['sidechain','backbone','coulomb']
|
||||||
for type in types:
|
for type in types:
|
||||||
@@ -250,7 +253,7 @@ class Conformation_container:
|
|||||||
|
|
||||||
# overwrite/add maximum value for each determinant
|
# overwrite/add maximum value for each determinant
|
||||||
for det_group in max_dets.keys():
|
for det_group in max_dets.keys():
|
||||||
new_determinant = Source.determinant.Determinant(det_group, max_dets[det_group])
|
new_determinant = propka.determinant.Determinant(det_group, max_dets[det_group])
|
||||||
for g in groups:
|
for g in groups:
|
||||||
g.set_determinant(new_determinant,type)
|
g.set_determinant(new_determinant,type)
|
||||||
|
|
||||||
@@ -260,7 +263,7 @@ class Conformation_container:
|
|||||||
|
|
||||||
def get_coupled_systems(self, groups, get_coupled_groups):
|
def get_coupled_systems(self, groups, get_coupled_groups):
|
||||||
""" This generator will yield one covalently coupled system at the time """
|
""" This generator will yield one covalently coupled system at the time """
|
||||||
groups = set(groups)
|
groups = set(groups)
|
||||||
while len(groups)>0:
|
while len(groups)>0:
|
||||||
# extract a system of coupled groups ...
|
# extract a system of coupled groups ...
|
||||||
system = set()
|
system = set()
|
||||||
@@ -272,7 +275,7 @@ class Conformation_container:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def get_a_coupled_system_of_groups(self, new_group, coupled_groups, get_coupled_groups):
|
def get_a_coupled_system_of_groups(self, new_group, coupled_groups, get_coupled_groups):
|
||||||
coupled_groups.add(new_group)
|
coupled_groups.add(new_group)
|
||||||
[self.get_a_coupled_system_of_groups(c, coupled_groups, get_coupled_groups) for c in get_coupled_groups(new_group) if c not in coupled_groups]
|
[self.get_a_coupled_system_of_groups(c, coupled_groups, get_coupled_groups) for c in get_coupled_groups(new_group) if c not in coupled_groups]
|
||||||
@@ -311,7 +314,7 @@ class Conformation_container:
|
|||||||
""" returns all sidechain groups needed for the pKa calculations """
|
""" returns all sidechain groups needed for the pKa calculations """
|
||||||
return [group for group in self.groups if ('BB' not in group.type\
|
return [group for group in self.groups if ('BB' not in group.type\
|
||||||
and not group.atom.cysteine_bridge)]
|
and not group.atom.cysteine_bridge)]
|
||||||
|
|
||||||
def get_covalently_coupled_groups(self):
|
def get_covalently_coupled_groups(self):
|
||||||
return [g for g in self.groups if len(g.covalently_coupled_groups)>0]
|
return [g for g in self.groups if len(g.covalently_coupled_groups)>0]
|
||||||
|
|
||||||
@@ -331,7 +334,7 @@ class Conformation_container:
|
|||||||
|
|
||||||
def get_titratable_groups(self):
|
def get_titratable_groups(self):
|
||||||
return [group for group in self.groups if group.titratable]
|
return [group for group in self.groups if group.titratable]
|
||||||
|
|
||||||
def get_titratable_groups_and_cysteine_bridges(self):
|
def get_titratable_groups_and_cysteine_bridges(self):
|
||||||
return [group for group in self.groups if group.titratable or group.residue_type == 'CYS']
|
return [group for group in self.groups if group.titratable or group.residue_type == 'CYS']
|
||||||
|
|
||||||
@@ -367,19 +370,19 @@ class Conformation_container:
|
|||||||
atom.conformation_container = self
|
atom.conformation_container = self
|
||||||
if not atom.molecular_container:
|
if not atom.molecular_container:
|
||||||
atom.molecular_container = self.molecular_container
|
atom.molecular_container = self.molecular_container
|
||||||
|
|
||||||
# store chain id for bookkeeping
|
# store chain id for bookkeeping
|
||||||
if not atom.chainID in self.chains:
|
if not atom.chainID in self.chains:
|
||||||
self.chains.append(atom.chainID)
|
self.chains.append(atom.chainID)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def copy_atom(self, atom):
|
def copy_atom(self, atom):
|
||||||
new_atom = atom.makeCopy()
|
new_atom = atom.makeCopy()
|
||||||
self.atoms.append(new_atom)
|
self.atoms.append(new_atom)
|
||||||
new_atom.conformation_container = self
|
new_atom.conformation_container = self
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_non_hydrogen_atoms(self):
|
def get_non_hydrogen_atoms(self):
|
||||||
return [atom for atom in self.atoms if atom.element!='H']
|
return [atom for atom in self.atoms if atom.element!='H']
|
||||||
@@ -391,7 +394,7 @@ class Conformation_container:
|
|||||||
if not self.have_atom(atom):
|
if not self.have_atom(atom):
|
||||||
self.copy_atom(atom)
|
self.copy_atom(atom)
|
||||||
return
|
return
|
||||||
|
|
||||||
def have_atom(self, atom):
|
def have_atom(self, atom):
|
||||||
res = False
|
res = False
|
||||||
for a in self.atoms:
|
for a in self.atoms:
|
||||||
@@ -407,12 +410,12 @@ class Conformation_container:
|
|||||||
return g
|
return g
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def set_ligand_atom_names(self):
|
def set_ligand_atom_names(self):
|
||||||
for atom in self.get_ligand_atoms():
|
for atom in self.get_ligand_atoms():
|
||||||
Source.ligand.assign_sybyl_type(atom)
|
propka.ligand.assign_sybyl_type(atom)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@@ -431,7 +434,7 @@ class Conformation_container:
|
|||||||
return
|
return
|
||||||
|
|
||||||
def sort_atoms_key(self, atom):
|
def sort_atoms_key(self, atom):
|
||||||
key = ord(atom.chainID)*1e7
|
key = ord(atom.chainID)*1e7
|
||||||
key += atom.resNumb*1000
|
key += atom.resNumb*1000
|
||||||
if len(atom.name) > len(atom.element):
|
if len(atom.name) > len(atom.element):
|
||||||
key += ord(atom.name[len(atom.element)])
|
key += ord(atom.name[len(atom.element)])
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
|
|
||||||
import math, Source.output, Source.group, Source.lib, itertools
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import math, propka.output, propka.group, propka.lib, itertools
|
||||||
|
|
||||||
|
|
||||||
class non_covalently_couple_groups:
|
class non_covalently_couple_groups:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
self.parameters = None
|
self.parameters = None
|
||||||
|
|
||||||
# self.do_intrinsic = False
|
# self.do_intrinsic = False
|
||||||
# self.do_pair_wise = False
|
# self.do_pair_wise = False
|
||||||
self.do_prot_stat = True
|
self.do_prot_stat = True
|
||||||
@@ -18,10 +21,10 @@ class non_covalently_couple_groups:
|
|||||||
# Methods for finding coupled groups
|
# Methods for finding coupled groups
|
||||||
#
|
#
|
||||||
def is_coupled_protonation_state_probability(self, group1, group2, energy_method, return_on_fail=True):
|
def is_coupled_protonation_state_probability(self, group1, group2, energy_method, return_on_fail=True):
|
||||||
|
|
||||||
# check if the interaction energy is high enough
|
# check if the interaction energy is high enough
|
||||||
interaction_energy = max(self.get_interaction(group1,group2), self.get_interaction(group2,group1))
|
interaction_energy = max(self.get_interaction(group1,group2), self.get_interaction(group2,group1))
|
||||||
|
|
||||||
if interaction_energy<=self.parameters.min_interaction_energy and return_on_fail:
|
if interaction_energy<=self.parameters.min_interaction_energy and return_on_fail:
|
||||||
return {'coupling_factor':-1.0}
|
return {'coupling_factor':-1.0}
|
||||||
|
|
||||||
@@ -29,7 +32,7 @@ class non_covalently_couple_groups:
|
|||||||
for group in [group1, group2]:
|
for group in [group1, group2]:
|
||||||
if not hasattr(group, 'intrinsic_pKa'):
|
if not hasattr(group, 'intrinsic_pKa'):
|
||||||
group.calculate_intrinsic_pka()
|
group.calculate_intrinsic_pka()
|
||||||
|
|
||||||
use_pH = self.parameters.pH
|
use_pH = self.parameters.pH
|
||||||
if self.parameters.pH == 'variable':
|
if self.parameters.pH == 'variable':
|
||||||
use_pH = min(group1.pka_value, group2.pka_value)
|
use_pH = min(group1.pka_value, group2.pka_value)
|
||||||
@@ -61,7 +64,7 @@ class non_covalently_couple_groups:
|
|||||||
self.swap_interactions([group1], [group2])
|
self.swap_interactions([group1], [group2])
|
||||||
group1.calculate_total_pka()
|
group1.calculate_total_pka()
|
||||||
group2.calculate_total_pka()
|
group2.calculate_total_pka()
|
||||||
|
|
||||||
# check difference in free energy
|
# check difference in free energy
|
||||||
if abs(default_energy - swapped_energy) > self.parameters.max_free_energy_diff and return_on_fail:
|
if abs(default_energy - swapped_energy) > self.parameters.max_free_energy_diff and return_on_fail:
|
||||||
return {'coupling_factor':-1.0}
|
return {'coupling_factor':-1.0}
|
||||||
@@ -80,21 +83,21 @@ class non_covalently_couple_groups:
|
|||||||
self.get_interaction_factor(interaction_energy)
|
self.get_interaction_factor(interaction_energy)
|
||||||
|
|
||||||
return {'coupling_factor':factor,
|
return {'coupling_factor':factor,
|
||||||
'default_energy':default_energy,
|
'default_energy':default_energy,
|
||||||
'swapped_energy':swapped_energy,
|
'swapped_energy':swapped_energy,
|
||||||
'interaction_energy':interaction_energy,
|
'interaction_energy':interaction_energy,
|
||||||
'swapped_pka1':swapped_pka1,
|
'swapped_pka1':swapped_pka1,
|
||||||
'swapped_pka2':swapped_pka2,
|
'swapped_pka2':swapped_pka2,
|
||||||
'pka_shift1':pka_shift1,
|
'pka_shift1':pka_shift1,
|
||||||
'pka_shift2':pka_shift2,
|
'pka_shift2':pka_shift2,
|
||||||
'pH':use_pH}
|
'pH':use_pH}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Methods for calculating the coupling factor
|
# Methods for calculating the coupling factor
|
||||||
#
|
#
|
||||||
|
|
||||||
def get_pka_diff_factor(self, pka1, pka2):
|
def get_pka_diff_factor(self, pka1, pka2):
|
||||||
intrinsic_pka_diff = abs(pka1-pka2)
|
intrinsic_pka_diff = abs(pka1-pka2)
|
||||||
res = 0.0
|
res = 0.0
|
||||||
@@ -120,10 +123,10 @@ class non_covalently_couple_groups:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def identify_non_covalently_coupled_groups(self, conformation, verbose=True):
|
def identify_non_covalently_coupled_groups(self, conformation, verbose=True):
|
||||||
""" Finds coupled residues in protein """
|
""" Finds coupled residues in protein """
|
||||||
|
|
||||||
self.parameters = conformation.parameters
|
self.parameters = conformation.parameters
|
||||||
if verbose:
|
if verbose:
|
||||||
print('')
|
print('')
|
||||||
@@ -156,19 +159,19 @@ class non_covalently_couple_groups:
|
|||||||
data = self.is_coupled_protonation_state_probability(g1, g2,conformation.calculate_folding_energy)
|
data = self.is_coupled_protonation_state_probability(g1, g2,conformation.calculate_folding_energy)
|
||||||
if data['coupling_factor'] >0.0:
|
if data['coupling_factor'] >0.0:
|
||||||
g1.couple_non_covalently(g2)
|
g1.couple_non_covalently(g2)
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
self.print_out_swaps(conformation)
|
self.print_out_swaps(conformation)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def print_out_swaps(self, conformation, verbose=True):
|
def print_out_swaps(self, conformation, verbose=True):
|
||||||
map = Source.output.make_interaction_map('Non-covalent coupling map for %s'%conformation,
|
map = propka.output.make_interaction_map('Non-covalent coupling map for %s'%conformation,
|
||||||
conformation.get_non_covalently_coupled_groups(),
|
conformation.get_non_covalently_coupled_groups(),
|
||||||
lambda g1,g2: g1 in g2.non_covalently_coupled_groups)
|
lambda g1,g2: g1 in g2.non_covalently_coupled_groups)
|
||||||
print(map)
|
print(map)
|
||||||
|
|
||||||
for system in conformation.get_coupled_systems(conformation.get_non_covalently_coupled_groups(),Source.group.Group.get_non_covalently_coupled_groups):
|
for system in conformation.get_coupled_systems(conformation.get_non_covalently_coupled_groups(),propka.group.Group.get_non_covalently_coupled_groups):
|
||||||
self.print_system(conformation, list(system))
|
self.print_system(conformation, list(system))
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -187,7 +190,7 @@ class non_covalently_couple_groups:
|
|||||||
print(coup_info)
|
print(coup_info)
|
||||||
|
|
||||||
# make list of possible combinations of swap to try out
|
# make list of possible combinations of swap to try out
|
||||||
combinations = Source.lib.generate_combinations(interactions)
|
combinations = propka.lib.generate_combinations(interactions)
|
||||||
|
|
||||||
# Make possible swap combinations
|
# Make possible swap combinations
|
||||||
swap_info = ''
|
swap_info = ''
|
||||||
@@ -199,7 +202,7 @@ class non_covalently_couple_groups:
|
|||||||
for interaction in combination:
|
for interaction in combination:
|
||||||
swap_info += ' %s %s\n'%(interaction[0].label, interaction[1].label)
|
swap_info += ' %s %s\n'%(interaction[0].label, interaction[1].label)
|
||||||
|
|
||||||
# swap...
|
# swap...
|
||||||
for interaction in combination:
|
for interaction in combination:
|
||||||
self.swap_interactions([interaction[0]],[interaction[1]])
|
self.swap_interactions([interaction[0]],[interaction[1]])
|
||||||
|
|
||||||
@@ -213,13 +216,13 @@ class non_covalently_couple_groups:
|
|||||||
return
|
return
|
||||||
#
|
#
|
||||||
# Interaction and swapping methods
|
# Interaction and swapping methods
|
||||||
#
|
#
|
||||||
|
|
||||||
def get_interaction(self, group1, group2, include_side_chain_hbs = True):
|
def get_interaction(self, group1, group2, include_side_chain_hbs = True):
|
||||||
determinants = group1.determinants['coulomb']
|
determinants = group1.determinants['coulomb']
|
||||||
if include_side_chain_hbs:
|
if include_side_chain_hbs:
|
||||||
determinants = group1.determinants['sidechain'] + group1.determinants['coulomb']
|
determinants = group1.determinants['sidechain'] + group1.determinants['coulomb']
|
||||||
|
|
||||||
interaction_energy = 0.0
|
interaction_energy = 0.0
|
||||||
for det in determinants:
|
for det in determinants:
|
||||||
if group2 == det.group:
|
if group2 == det.group:
|
||||||
@@ -234,7 +237,7 @@ class non_covalently_couple_groups:
|
|||||||
s = ' '+'-'*113+'\n'
|
s = ' '+'-'*113+'\n'
|
||||||
for group in system:
|
for group in system:
|
||||||
s += self.tagged_print(' %-8s|'%tag,group.getDeterminantString(), all_labels)
|
s += self.tagged_print(' %-8s|'%tag,group.getDeterminantString(), all_labels)
|
||||||
|
|
||||||
return s+'\n'
|
return s+'\n'
|
||||||
|
|
||||||
def swap_interactions(self, groups1, groups2, include_side_chain_hbs = True):
|
def swap_interactions(self, groups1, groups2, include_side_chain_hbs = True):
|
||||||
@@ -242,7 +245,7 @@ class non_covalently_couple_groups:
|
|||||||
for i in range(len(groups1)):
|
for i in range(len(groups1)):
|
||||||
group1 = groups1[i]
|
group1 = groups1[i]
|
||||||
group2 = groups2[i]
|
group2 = groups2[i]
|
||||||
|
|
||||||
# swap the interactions!
|
# swap the interactions!
|
||||||
self.transfer_determinant(group1.determinants['coulomb'], group2.determinants['coulomb'], group1.label, group2.label)
|
self.transfer_determinant(group1.determinants['coulomb'], group2.determinants['coulomb'], group1.label, group2.label)
|
||||||
if include_side_chain_hbs:
|
if include_side_chain_hbs:
|
||||||
@@ -266,7 +269,7 @@ class non_covalently_couple_groups:
|
|||||||
for det in determinants2:
|
for det in determinants2:
|
||||||
if det.label == label1:
|
if det.label == label1:
|
||||||
from2to1.append(det)
|
from2to1.append(det)
|
||||||
|
|
||||||
# ...and transfer it!
|
# ...and transfer it!
|
||||||
for det in from1to2:
|
for det in from1to2:
|
||||||
det.label = label1
|
det.label = label1
|
||||||
@@ -280,7 +283,7 @@ class non_covalently_couple_groups:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
#
|
#
|
||||||
# Output methods
|
# Output methods
|
||||||
#
|
#
|
||||||
|
|
||||||
@@ -295,7 +298,7 @@ class non_covalently_couple_groups:
|
|||||||
def make_data_to_string(self, data, group1, group2):
|
def make_data_to_string(self, data, group1, group2):
|
||||||
s = """ %s and %s coupled (prot.state): %5.2f
|
s = """ %s and %s coupled (prot.state): %5.2f
|
||||||
Energy levels: %6.2f, %6.2f (difference: %6.2f) at pH %6.2f
|
Energy levels: %6.2f, %6.2f (difference: %6.2f) at pH %6.2f
|
||||||
Interaction energy: %6.2f
|
Interaction energy: %6.2f
|
||||||
Intrinsic pka's: %6.2f, %6.2f (difference: %6.2f)
|
Intrinsic pka's: %6.2f, %6.2f (difference: %6.2f)
|
||||||
Swapped pKa's: %6.2f, %6.2f (difference: %6.2f, %6.2f)"""%(group1.label,
|
Swapped pKa's: %6.2f, %6.2f (difference: %6.2f, %6.2f)"""%(group1.label,
|
||||||
group2.label,
|
group2.label,
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
class Determinant:
|
class Determinant:
|
||||||
"""
|
"""
|
||||||
Determinant class - set up for later structurization
|
Determinant class - set up for later structurization
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import math, time
|
import math, time
|
||||||
|
|
||||||
import Source.iterative, Source.lib, Source.vector_algebra
|
import propka.iterative, propka.lib, propka.vector_algebra
|
||||||
import Source.calculations
|
import propka.calculations
|
||||||
from Source.determinant import Determinant
|
from propka.determinant import Determinant
|
||||||
|
|
||||||
|
|
||||||
def setDeterminants(propka_groups, version=None, options=None):
|
def setDeterminants(propka_groups, version=None, options=None):
|
||||||
@@ -19,19 +23,19 @@ def setDeterminants(propka_groups, version=None, options=None):
|
|||||||
# do not calculate interactions for coupled groups
|
# do not calculate interactions for coupled groups
|
||||||
if group2 in group1.covalently_coupled_groups:
|
if group2 in group1.covalently_coupled_groups:
|
||||||
break
|
break
|
||||||
|
|
||||||
distance = Source.calculations.distance(group1, group2)
|
distance = propka.calculations.distance(group1, group2)
|
||||||
|
|
||||||
if distance < version.parameters.coulomb_cutoff2:
|
if distance < version.parameters.coulomb_cutoff2:
|
||||||
interaction_type = version.parameters.interaction_matrix.get_value(group1.type,group2.type)
|
interaction_type = version.parameters.interaction_matrix.get_value(group1.type,group2.type)
|
||||||
if interaction_type == 'I':
|
if interaction_type == 'I':
|
||||||
Source.iterative.addtoDeterminantList(group1, group2, distance, iterative_interactions, version=version)
|
propka.iterative.addtoDeterminantList(group1, group2, distance, iterative_interactions, version=version)
|
||||||
elif interaction_type == 'N':
|
elif interaction_type == 'N':
|
||||||
addDeterminants(group1, group2, distance, version)
|
addDeterminants(group1, group2, distance, version)
|
||||||
|
|
||||||
|
|
||||||
# --- Iterative section ---#
|
# --- Iterative section ---#
|
||||||
Source.iterative.addDeterminants(iterative_interactions, version, options=options)
|
propka.iterative.addDeterminants(iterative_interactions, version, options=options)
|
||||||
|
|
||||||
|
|
||||||
def addDeterminants(group1, group2, distance, version):
|
def addDeterminants(group1, group2, distance, version):
|
||||||
@@ -52,11 +56,11 @@ def addSidechainDeterminants(group1, group2, version=None):
|
|||||||
adding side-chain determinants/perturbations
|
adding side-chain determinants/perturbations
|
||||||
Note, resNumb1 > resNumb2
|
Note, resNumb1 > resNumb2
|
||||||
"""
|
"""
|
||||||
|
|
||||||
hbond_interaction = version.hydrogen_bond_interaction(group1, group2)
|
hbond_interaction = version.hydrogen_bond_interaction(group1, group2)
|
||||||
|
|
||||||
if hbond_interaction:
|
if hbond_interaction:
|
||||||
|
|
||||||
if group1.charge == group2.charge:
|
if group1.charge == group2.charge:
|
||||||
# acid pair or base pair
|
# acid pair or base pair
|
||||||
if group1.model_pka < group2.model_pka:
|
if group1.model_pka < group2.model_pka:
|
||||||
@@ -78,7 +82,7 @@ def addCoulombDeterminants(group1, group2, distance, version):
|
|||||||
"""
|
"""
|
||||||
adding NonIterative Coulomb determinants/perturbations
|
adding NonIterative Coulomb determinants/perturbations
|
||||||
"""
|
"""
|
||||||
|
|
||||||
coulomb_interaction = version.electrostatic_interaction(group1, group2, distance)
|
coulomb_interaction = version.electrostatic_interaction(group1, group2, distance)
|
||||||
|
|
||||||
if coulomb_interaction:
|
if coulomb_interaction:
|
||||||
@@ -104,7 +108,7 @@ def addCoulombAcidPair(object1, object2, value):
|
|||||||
Adding the Coulomb interaction (an acid pair):
|
Adding the Coulomb interaction (an acid pair):
|
||||||
the higher pKa is raised
|
the higher pKa is raised
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if object1.model_pka > object2.model_pka:
|
if object1.model_pka > object2.model_pka:
|
||||||
newDeterminant = Determinant(object2, value)
|
newDeterminant = Determinant(object2, value)
|
||||||
object1.determinants['coulomb'].append(newDeterminant)
|
object1.determinants['coulomb'].append(newDeterminant)
|
||||||
@@ -151,7 +155,7 @@ def setIonDeterminants(conformation_container, version):
|
|||||||
"""
|
"""
|
||||||
for titratable_group in conformation_container.get_titratable_groups():
|
for titratable_group in conformation_container.get_titratable_groups():
|
||||||
for ion_group in conformation_container.get_ions():
|
for ion_group in conformation_container.get_ions():
|
||||||
squared_distance = Source.calculations.squared_distance(titratable_group, ion_group)
|
squared_distance = propka.calculations.squared_distance(titratable_group, ion_group)
|
||||||
if squared_distance < version.parameters.coulomb_cutoff2_squared:
|
if squared_distance < version.parameters.coulomb_cutoff2_squared:
|
||||||
weight = version.calculatePairWeight(titratable_group.Nmass, ion_group.Nmass)
|
weight = version.calculatePairWeight(titratable_group.Nmass, ion_group.Nmass)
|
||||||
# the pKa of both acids and bases are shifted up by negative ions (and vice versa)
|
# the pKa of both acids and bases are shifted up by negative ions (and vice versa)
|
||||||
@@ -162,16 +166,16 @@ def setIonDeterminants(conformation_container, version):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def setBackBoneDeterminants(titratable_groups, backbone_groups, version):
|
def setBackBoneDeterminants(titratable_groups, backbone_groups, version):
|
||||||
|
|
||||||
for titratable_group in titratable_groups:
|
for titratable_group in titratable_groups:
|
||||||
# find out which backbone groups this titratable is interacting with
|
# find out which backbone groups this titratable is interacting with
|
||||||
for backbone_group in backbone_groups:
|
for backbone_group in backbone_groups:
|
||||||
# find the interacting atoms
|
# find the interacting atoms
|
||||||
backbone_interaction_atoms = backbone_group.get_interaction_atoms(titratable_group)
|
backbone_interaction_atoms = backbone_group.get_interaction_atoms(titratable_group)
|
||||||
titratable_group_interaction_atoms = titratable_group.interaction_atoms_for_acids
|
titratable_group_interaction_atoms = titratable_group.interaction_atoms_for_acids
|
||||||
|
|
||||||
# find the smallest distance
|
# find the smallest distance
|
||||||
[backbone_atom, distance, titratable_atom] = Source.calculations.get_smallest_distance(backbone_interaction_atoms,
|
[backbone_atom, distance, titratable_atom] = propka.calculations.get_smallest_distance(backbone_interaction_atoms,
|
||||||
titratable_group_interaction_atoms)
|
titratable_group_interaction_atoms)
|
||||||
# get the parameters
|
# get the parameters
|
||||||
parameters = version.get_backbone_hydrogen_bond_parameters(backbone_atom, titratable_atom)
|
parameters = version.get_backbone_hydrogen_bond_parameters(backbone_atom, titratable_atom)
|
||||||
@@ -186,7 +190,7 @@ def setBackBoneDeterminants(titratable_groups, backbone_groups, version):
|
|||||||
# for BBC groups, the hydrogen is on the titratable group
|
# for BBC groups, the hydrogen is on the titratable group
|
||||||
#
|
#
|
||||||
# Titra.
|
# Titra.
|
||||||
# /
|
# /
|
||||||
# H
|
# H
|
||||||
# .
|
# .
|
||||||
# O
|
# O
|
||||||
@@ -197,7 +201,7 @@ def setBackBoneDeterminants(titratable_groups, backbone_groups, version):
|
|||||||
if titratable_atom.element == 'H':
|
if titratable_atom.element == 'H':
|
||||||
heavy_atom = titratable_atom.bonded_atoms[0]
|
heavy_atom = titratable_atom.bonded_atoms[0]
|
||||||
hydrogen_atom = titratable_atom
|
hydrogen_atom = titratable_atom
|
||||||
[d1, f_angle, d2] = Source.calculations.AngleFactorX(atom1=heavy_atom,
|
[d1, f_angle, d2] = propka.calculations.AngleFactorX(atom1=heavy_atom,
|
||||||
atom2=hydrogen_atom,
|
atom2=hydrogen_atom,
|
||||||
atom3=backbone_atom)
|
atom3=backbone_atom)
|
||||||
else:
|
else:
|
||||||
@@ -218,7 +222,7 @@ def setBackBoneDeterminants(titratable_groups, backbone_groups, version):
|
|||||||
if backbone_atom.element == 'H':
|
if backbone_atom.element == 'H':
|
||||||
backbone_N = backbone_atom.bonded_atoms[0]
|
backbone_N = backbone_atom.bonded_atoms[0]
|
||||||
backbone_H = backbone_atom
|
backbone_H = backbone_atom
|
||||||
[d1, f_angle, d2] = Source.calculations.AngleFactorX(atom1=titratable_atom,
|
[d1, f_angle, d2] = propka.calculations.AngleFactorX(atom1=titratable_atom,
|
||||||
atom2=backbone_H,
|
atom2=backbone_H,
|
||||||
atom3=backbone_N)
|
atom3=backbone_N)
|
||||||
else:
|
else:
|
||||||
@@ -226,13 +230,13 @@ def setBackBoneDeterminants(titratable_groups, backbone_groups, version):
|
|||||||
# the titratable atom than the hydrogen. In either case we set the angle factor
|
# the titratable atom than the hydrogen. In either case we set the angle factor
|
||||||
# to 0
|
# to 0
|
||||||
f_angle = 0.0
|
f_angle = 0.0
|
||||||
|
|
||||||
|
|
||||||
if f_angle > 0.001:
|
if f_angle > 0.001:
|
||||||
value = titratable_group.charge * Source.calculations.HydrogenBondEnergy(distance, dpKa_max, [cutoff1,cutoff2], f_angle)
|
value = titratable_group.charge * propka.calculations.HydrogenBondEnergy(distance, dpKa_max, [cutoff1,cutoff2], f_angle)
|
||||||
|
|
||||||
newDeterminant = Determinant(backbone_group, value)
|
newDeterminant = Determinant(backbone_group, value)
|
||||||
titratable_group.determinants['backbone'].append(newDeterminant)
|
titratable_group.determinants['backbone'].append(newDeterminant)
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -2,9 +2,12 @@
|
|||||||
# Class for storing groups important for propka calculations
|
# Class for storing groups important for propka calculations
|
||||||
#
|
#
|
||||||
|
|
||||||
import Source.ligand, Source.determinant, Source.ligand_pka_values, math, Source.protonate
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
my_protonator = Source.protonate.Protonate(verbose=False)
|
import propka.ligand, propka.determinant, propka.ligand_pka_values, math, propka.protonate
|
||||||
|
|
||||||
|
my_protonator = propka.protonate.Protonate(verbose=False)
|
||||||
|
|
||||||
expected_atoms_acid_interactions = {
|
expected_atoms_acid_interactions = {
|
||||||
'COO':{'O':2},
|
'COO':{'O':2},
|
||||||
@@ -65,7 +68,7 @@ expected_atoms_base_interactions = {
|
|||||||
'SH': {'S':1},
|
'SH': {'S':1},
|
||||||
'CG': {'N':3},
|
'CG': {'N':3},
|
||||||
'C2N':{'N':2},
|
'C2N':{'N':2},
|
||||||
'OCO':{'O':2},
|
'OCO':{'O':2},
|
||||||
'N30':{'N':1},
|
'N30':{'N':1},
|
||||||
'N31':{'N':1},
|
'N31':{'N':1},
|
||||||
'N32':{'N':1},
|
'N32':{'N':1},
|
||||||
@@ -86,7 +89,7 @@ class Group:
|
|||||||
self.determinants = {'sidechain':[],'backbone':[],'coulomb':[]}
|
self.determinants = {'sidechain':[],'backbone':[],'coulomb':[]}
|
||||||
self.pka_value = 0.0
|
self.pka_value = 0.0
|
||||||
self.model_pka = 0.0
|
self.model_pka = 0.0
|
||||||
|
|
||||||
self.Emass = 0.0
|
self.Emass = 0.0
|
||||||
self.Nmass = 0.0
|
self.Nmass = 0.0
|
||||||
self.Elocl = 0.0
|
self.Elocl = 0.0
|
||||||
@@ -99,18 +102,18 @@ class Group:
|
|||||||
self.interaction_atoms_for_acids = []
|
self.interaction_atoms_for_acids = []
|
||||||
self.interaction_atoms_for_bases = []
|
self.interaction_atoms_for_bases = []
|
||||||
self.model_pka_set = False
|
self.model_pka_set = False
|
||||||
|
|
||||||
# information on covalent and non-covalent coupling
|
# information on covalent and non-covalent coupling
|
||||||
self.non_covalently_coupled_groups = []
|
self.non_covalently_coupled_groups = []
|
||||||
self.covalently_coupled_groups = []
|
self.covalently_coupled_groups = []
|
||||||
self.coupled_titrating_group = None
|
self.coupled_titrating_group = None
|
||||||
self.common_charge_centre = False
|
self.common_charge_centre = False
|
||||||
|
|
||||||
|
|
||||||
self.residue_type = self.atom.resName
|
self.residue_type = self.atom.resName
|
||||||
if self.atom.terminal:
|
if self.atom.terminal:
|
||||||
self.residue_type = self.atom.terminal
|
self.residue_type = self.atom.terminal
|
||||||
|
|
||||||
if self.atom.type=='atom':
|
if self.atom.type=='atom':
|
||||||
self.label = '%-3s%4d%2s'%(self.residue_type, atom.resNumb, atom.chainID)
|
self.label = '%-3s%4d%2s'%(self.residue_type, atom.resNumb, atom.chainID)
|
||||||
elif self.atom.resName in ['DA ','DC ','DG ','DT ']:
|
elif self.atom.resName in ['DA ','DC ','DG ','DT ']:
|
||||||
@@ -119,7 +122,7 @@ class Group:
|
|||||||
atom.name.replace('\'','')[-1],
|
atom.name.replace('\'','')[-1],
|
||||||
atom.resNumb,
|
atom.resNumb,
|
||||||
atom.chainID)
|
atom.chainID)
|
||||||
|
|
||||||
# self.label = '%1s%1s%1s%4d%2s'%(self.residue_type[1], atom.element,atom.name[-1], atom.resNumb, atom.chainID)
|
# self.label = '%1s%1s%1s%4d%2s'%(self.residue_type[1], atom.element,atom.name[-1], atom.resNumb, atom.chainID)
|
||||||
else:
|
else:
|
||||||
self.label = '%-3s%4s%2s'%(self.residue_type, atom.name, atom.chainID)
|
self.label = '%-3s%4s%2s'%(self.residue_type, atom.name, atom.chainID)
|
||||||
@@ -133,28 +136,28 @@ class Group:
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Coupling-related methods
|
# Coupling-related methods
|
||||||
#
|
#
|
||||||
def couple_covalently(self, other):
|
def couple_covalently(self, other):
|
||||||
""" Couple this group with another group """
|
""" Couple this group with another group """
|
||||||
# do the coupling
|
# do the coupling
|
||||||
if not other in self.covalently_coupled_groups:
|
if not other in self.covalently_coupled_groups:
|
||||||
self.covalently_coupled_groups.append(other)
|
self.covalently_coupled_groups.append(other)
|
||||||
|
|
||||||
if not self in other.covalently_coupled_groups:
|
if not self in other.covalently_coupled_groups:
|
||||||
other.covalently_coupled_groups.append(self)
|
other.covalently_coupled_groups.append(self)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def couple_non_covalently(self, other):
|
def couple_non_covalently(self, other):
|
||||||
""" Couple this group with another group """
|
""" Couple this group with another group """
|
||||||
# do the coupling
|
# do the coupling
|
||||||
if not other in self.non_covalently_coupled_groups:
|
if not other in self.non_covalently_coupled_groups:
|
||||||
self.non_covalently_coupled_groups.append(other)
|
self.non_covalently_coupled_groups.append(other)
|
||||||
|
|
||||||
if not self in other.non_covalently_coupled_groups:
|
if not self in other.non_covalently_coupled_groups:
|
||||||
other.non_covalently_coupled_groups.append(self)
|
other.non_covalently_coupled_groups.append(self)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_covalently_coupled_groups(self): return self.covalently_coupled_groups
|
def get_covalently_coupled_groups(self): return self.covalently_coupled_groups
|
||||||
def get_non_covalently_coupled_groups(self): return self.non_covalently_coupled_groups
|
def get_non_covalently_coupled_groups(self): return self.non_covalently_coupled_groups
|
||||||
@@ -168,12 +171,12 @@ class Group:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for type in ['sidechain','backbone','coulomb']:
|
for type in ['sidechain','backbone','coulomb']:
|
||||||
for g in other.determinants[type]: self.share_determinant(g,type)
|
for g in other.determinants[type]: self.share_determinant(g,type)
|
||||||
|
|
||||||
# recalculate pka values
|
# recalculate pka values
|
||||||
self.calculate_total_pka()
|
self.calculate_total_pka()
|
||||||
other.calculate_total_pka()
|
other.calculate_total_pka()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -190,19 +193,19 @@ class Group:
|
|||||||
|
|
||||||
# otherwise we just add the determinant to our list
|
# otherwise we just add the determinant to our list
|
||||||
if not added:
|
if not added:
|
||||||
self.determinants[type].append(Source.determinant.Determinant(new_determinant.group,
|
self.determinants[type].append(propka.determinant.Determinant(new_determinant.group,
|
||||||
new_determinant.value))
|
new_determinant.value))
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def make_covalently_coupled_line(self):
|
def make_covalently_coupled_line(self):
|
||||||
|
|
||||||
# first check if there are any coupled groups at all
|
# first check if there are any coupled groups at all
|
||||||
if len(self.covalently_coupled_groups) == 0:
|
if len(self.covalently_coupled_groups) == 0:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
line = 'CCOUPL%5d'%self.atom.numb
|
line = 'CCOUPL%5d'%self.atom.numb
|
||||||
|
|
||||||
# extract and sort numbers of coupled groups
|
# extract and sort numbers of coupled groups
|
||||||
coupled = []
|
coupled = []
|
||||||
for g in self.covalently_coupled_groups:
|
for g in self.covalently_coupled_groups:
|
||||||
@@ -213,7 +216,7 @@ class Group:
|
|||||||
for b in coupled:
|
for b in coupled:
|
||||||
line += '%5d'%b
|
line += '%5d'%b
|
||||||
line += '\n'
|
line += '\n'
|
||||||
|
|
||||||
return line
|
return line
|
||||||
|
|
||||||
def make_non_covalently_coupled_line(self):
|
def make_non_covalently_coupled_line(self):
|
||||||
@@ -222,7 +225,7 @@ class Group:
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
line = 'NCOUPL%5d'%self.atom.numb
|
line = 'NCOUPL%5d'%self.atom.numb
|
||||||
|
|
||||||
# extract and sort numbers of coupled groups
|
# extract and sort numbers of coupled groups
|
||||||
coupled = []
|
coupled = []
|
||||||
for g in self.non_covalently_coupled_groups:
|
for g in self.non_covalently_coupled_groups:
|
||||||
@@ -233,7 +236,7 @@ class Group:
|
|||||||
for b in coupled:
|
for b in coupled:
|
||||||
line += '%5d'%b
|
line += '%5d'%b
|
||||||
line += '\n'
|
line += '\n'
|
||||||
|
|
||||||
|
|
||||||
return line
|
return line
|
||||||
|
|
||||||
@@ -283,7 +286,7 @@ class Group:
|
|||||||
return
|
return
|
||||||
|
|
||||||
# otherwise we just add the determinant to our list
|
# otherwise we just add the determinant to our list
|
||||||
self.determinants[type].append(Source.determinant.Determinant(new_determinant.group,
|
self.determinants[type].append(propka.determinant.Determinant(new_determinant.group,
|
||||||
new_determinant.value))
|
new_determinant.value))
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -298,7 +301,7 @@ class Group:
|
|||||||
return
|
return
|
||||||
|
|
||||||
# otherwise we just add the determinant to our list
|
# otherwise we just add the determinant to our list
|
||||||
self.determinants[type].append(Source.determinant.Determinant(new_determinant.group,
|
self.determinants[type].append(propka.determinant.Determinant(new_determinant.group,
|
||||||
new_determinant.value))
|
new_determinant.value))
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -344,12 +347,12 @@ class Group:
|
|||||||
self.charge = self.parameters.charge[self.type]
|
self.charge = self.parameters.charge[self.type]
|
||||||
if self.residue_type in self.parameters.ions.keys():
|
if self.residue_type in self.parameters.ions.keys():
|
||||||
self.charge = self.parameters.ions[self.residue_type]
|
self.charge = self.parameters.ions[self.residue_type]
|
||||||
|
|
||||||
#print('ION setup',self,self.residue_type, self.charge)
|
#print('ION setup',self,self.residue_type, self.charge)
|
||||||
|
|
||||||
# find the center and the interaction atoms
|
# find the center and the interaction atoms
|
||||||
self.setup_atoms()
|
self.setup_atoms()
|
||||||
|
|
||||||
# set the model pka value
|
# set the model pka value
|
||||||
self.titratable = False
|
self.titratable = False
|
||||||
if self.residue_type in self.parameters.model_pkas.keys():
|
if self.residue_type in self.parameters.model_pkas.keys():
|
||||||
@@ -365,7 +368,7 @@ class Group:
|
|||||||
if self.model_pka_set and not self.atom.cysteine_bridge:
|
if self.model_pka_set and not self.atom.cysteine_bridge:
|
||||||
self.titratable = True
|
self.titratable = True
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def setup_atoms(self):
|
def setup_atoms(self):
|
||||||
@@ -378,7 +381,7 @@ class Group:
|
|||||||
|
|
||||||
def set_interaction_atoms(self, interaction_atoms_for_acids, interaction_atoms_for_bases):
|
def set_interaction_atoms(self, interaction_atoms_for_acids, interaction_atoms_for_bases):
|
||||||
[a.set_group_type(self.type) for a in interaction_atoms_for_acids+interaction_atoms_for_bases]
|
[a.set_group_type(self.type) for a in interaction_atoms_for_acids+interaction_atoms_for_bases]
|
||||||
|
|
||||||
self.interaction_atoms_for_acids = interaction_atoms_for_acids
|
self.interaction_atoms_for_acids = interaction_atoms_for_acids
|
||||||
self.interaction_atoms_for_bases = interaction_atoms_for_bases
|
self.interaction_atoms_for_bases = interaction_atoms_for_bases
|
||||||
|
|
||||||
@@ -400,11 +403,11 @@ class Group:
|
|||||||
print(' Expected %d interaction atoms for acids, found:'%Na)
|
print(' Expected %d interaction atoms for acids, found:'%Na)
|
||||||
for i in range(len(self.interaction_atoms_for_acids)):
|
for i in range(len(self.interaction_atoms_for_acids)):
|
||||||
print(' %s'%self.interaction_atoms_for_acids[i])
|
print(' %s'%self.interaction_atoms_for_acids[i])
|
||||||
|
|
||||||
print(' Expected %d interaction atoms for bases, found:'%Nb)
|
print(' Expected %d interaction atoms for bases, found:'%Nb)
|
||||||
for i in range(len(self.interaction_atoms_for_bases)):
|
for i in range(len(self.interaction_atoms_for_bases)):
|
||||||
print(' %s'%self.interaction_atoms_for_bases[i])
|
print(' %s'%self.interaction_atoms_for_bases[i])
|
||||||
|
|
||||||
|
|
||||||
#return
|
#return
|
||||||
|
|
||||||
@@ -437,7 +440,7 @@ class Group:
|
|||||||
number_of_sidechain = len(self.determinants['sidechain'])
|
number_of_sidechain = len(self.determinants['sidechain'])
|
||||||
number_of_backbone = len(self.determinants['backbone'])
|
number_of_backbone = len(self.determinants['backbone'])
|
||||||
number_of_coulomb = len(self.determinants['coulomb'])
|
number_of_coulomb = len(self.determinants['coulomb'])
|
||||||
|
|
||||||
number_of_lines = max(1, number_of_sidechain, number_of_backbone, number_of_coulomb)
|
number_of_lines = max(1, number_of_sidechain, number_of_backbone, number_of_coulomb)
|
||||||
str = ""
|
str = ""
|
||||||
for line_number in range(number_of_lines):
|
for line_number in range(number_of_lines):
|
||||||
@@ -458,11 +461,11 @@ class Group:
|
|||||||
str += " %6.2lf %4d" % (self.Elocl, self.Nlocl)
|
str += " %6.2lf %4d" % (self.Elocl, self.Nlocl)
|
||||||
else:
|
else:
|
||||||
str += "%40s" % (" ")
|
str += "%40s" % (" ")
|
||||||
|
|
||||||
# add the determinants
|
# add the determinants
|
||||||
for type in ['sidechain','backbone','coulomb']:
|
for type in ['sidechain','backbone','coulomb']:
|
||||||
str += self.get_determinant_for_string(type,line_number)
|
str += self.get_determinant_for_string(type,line_number)
|
||||||
|
|
||||||
# adding end-of-line
|
# adding end-of-line
|
||||||
str += "\n"
|
str += "\n"
|
||||||
|
|
||||||
@@ -484,7 +487,7 @@ class Group:
|
|||||||
if self.atom.cysteine_bridge:
|
if self.atom.cysteine_bridge:
|
||||||
self.pka_value = 99.99
|
self.pka_value = 99.99
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
self.pka_value = self.model_pka + self.Emass + self.Elocl
|
self.pka_value = self.model_pka + self.Emass + self.Elocl
|
||||||
|
|
||||||
@@ -494,12 +497,12 @@ class Group:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def calculate_intrinsic_pka(self):
|
def calculate_intrinsic_pka(self):
|
||||||
"""
|
"""
|
||||||
Calculates the intrinsic pKa values from the desolvation determinants, back-bone hydrogen bonds,
|
Calculates the intrinsic pKa values from the desolvation determinants, back-bone hydrogen bonds,
|
||||||
and side-chain hydrogen bond to non-titratable residues
|
and side-chain hydrogen bond to non-titratable residues
|
||||||
"""
|
"""
|
||||||
back_bone = 0.0
|
back_bone = 0.0
|
||||||
@@ -528,18 +531,18 @@ class Group:
|
|||||||
ligand_type = ''
|
ligand_type = ''
|
||||||
if self.atom.type == 'hetatm':
|
if self.atom.type == 'hetatm':
|
||||||
ligand_type = self.type
|
ligand_type = self.type
|
||||||
|
|
||||||
penalty = ''
|
penalty = ''
|
||||||
if self.coupled_titrating_group:
|
if self.coupled_titrating_group:
|
||||||
penalty = ' NB: Discarded due to coupling with %s'%self.coupled_titrating_group.label
|
penalty = ' NB: Discarded due to coupling with %s'%self.coupled_titrating_group.label
|
||||||
|
|
||||||
str = " %9s %8.2lf %10.2lf %18s %s\n" % (self.label,
|
str = " %9s %8.2lf %10.2lf %18s %s\n" % (self.label,
|
||||||
self.pka_value,
|
self.pka_value,
|
||||||
self.model_pka,ligand_type,
|
self.model_pka,ligand_type,
|
||||||
penalty)
|
penalty)
|
||||||
|
|
||||||
return str
|
return str
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Group (%s) for %s'%(self.type,self.atom)
|
return 'Group (%s) for %s'%(self.type,self.atom)
|
||||||
|
|
||||||
@@ -559,7 +562,7 @@ class Group:
|
|||||||
reference = parameters.reference
|
reference = parameters.reference
|
||||||
|
|
||||||
# If not titratable, the contribution is zero
|
# If not titratable, the contribution is zero
|
||||||
|
|
||||||
if not self.titratable:
|
if not self.titratable:
|
||||||
return 0.00
|
return 0.00
|
||||||
|
|
||||||
@@ -571,25 +574,25 @@ class Group:
|
|||||||
if determinant.value > 0.00:
|
if determinant.value > 0.00:
|
||||||
pka_prime -= determinant.value
|
pka_prime -= determinant.value
|
||||||
ddG_neutral = -1.36*(pka_prime - self.model_pka)
|
ddG_neutral = -1.36*(pka_prime - self.model_pka)
|
||||||
|
|
||||||
# calculating the ddG(low-pH --> pH) contribution
|
# calculating the ddG(low-pH --> pH) contribution
|
||||||
# folded
|
# folded
|
||||||
x = pH - self.pka_value
|
x = pH - self.pka_value
|
||||||
y = 10**x
|
y = 10**x
|
||||||
Q_pro = math.log10(1+y)
|
Q_pro = math.log10(1+y)
|
||||||
|
|
||||||
# unfolded
|
# unfolded
|
||||||
x = pH - self.model_pka
|
x = pH - self.model_pka
|
||||||
y = 10**x
|
y = 10**x
|
||||||
Q_mod = math.log10(1+y)
|
Q_mod = math.log10(1+y)
|
||||||
|
|
||||||
ddG_low = -1.36*(Q_pro - Q_mod)
|
ddG_low = -1.36*(Q_pro - Q_mod)
|
||||||
ddG = ddG_neutral + ddG_low
|
ddG = ddG_neutral + ddG_low
|
||||||
|
|
||||||
return ddG
|
return ddG
|
||||||
|
|
||||||
def calculate_charge(self, parmaeters, pH=7.0, state='folded'):
|
def calculate_charge(self, parmaeters, pH=7.0, state='folded'):
|
||||||
|
|
||||||
if state == "unfolded":
|
if state == "unfolded":
|
||||||
x = self.charge * (self.model_pka - pH)
|
x = self.charge * (self.model_pka - pH)
|
||||||
else:
|
else:
|
||||||
@@ -597,7 +600,7 @@ class Group:
|
|||||||
|
|
||||||
y = 10**x
|
y = 10**x
|
||||||
charge = self.charge*(y/(1.0+y))
|
charge = self.charge*(y/(1.0+y))
|
||||||
|
|
||||||
return charge
|
return charge
|
||||||
|
|
||||||
|
|
||||||
@@ -610,7 +613,7 @@ class COO_group(Group):
|
|||||||
def setup_atoms(self):
|
def setup_atoms(self):
|
||||||
# Identify the two caroxyl oxygen atoms
|
# Identify the two caroxyl oxygen atoms
|
||||||
the_oxygens = self.atom.get_bonded_elements('O')
|
the_oxygens = self.atom.get_bonded_elements('O')
|
||||||
|
|
||||||
# set the center using the two oxygen carboxyl atoms
|
# set the center using the two oxygen carboxyl atoms
|
||||||
self.set_center(the_oxygens)
|
self.set_center(the_oxygens)
|
||||||
self.set_interaction_atoms(the_oxygens, the_oxygens)
|
self.set_interaction_atoms(the_oxygens, the_oxygens)
|
||||||
@@ -624,7 +627,7 @@ class HIS_group(Group):
|
|||||||
|
|
||||||
def setup_atoms(self):
|
def setup_atoms(self):
|
||||||
# Find the atoms in the histidine ring
|
# Find the atoms in the histidine ring
|
||||||
ring_atoms = Source.ligand.is_ring_member(self.atom)
|
ring_atoms = propka.ligand.is_ring_member(self.atom)
|
||||||
if len(ring_atoms) != 5:
|
if len(ring_atoms) != 5:
|
||||||
print('Warning: His group does not seem to contain a ring',self)
|
print('Warning: His group does not seem to contain a ring',self)
|
||||||
|
|
||||||
@@ -634,11 +637,11 @@ class HIS_group(Group):
|
|||||||
|
|
||||||
# set the center using the ring atoms
|
# set the center using the ring atoms
|
||||||
self.set_center(ring_atoms)
|
self.set_center(ring_atoms)
|
||||||
|
|
||||||
# find the hydrogens on the ring-nitrogens
|
# find the hydrogens on the ring-nitrogens
|
||||||
hydrogens = []
|
hydrogens = []
|
||||||
nitrogens = [ra for ra in ring_atoms if ra.element == 'N']
|
nitrogens = [ra for ra in ring_atoms if ra.element == 'N']
|
||||||
|
|
||||||
for nitrogen in nitrogens:
|
for nitrogen in nitrogens:
|
||||||
hydrogens.extend(nitrogen.get_bonded_elements('H'))
|
hydrogens.extend(nitrogen.get_bonded_elements('H'))
|
||||||
|
|
||||||
@@ -673,12 +676,12 @@ class ARG_group(Group):
|
|||||||
def setup_atoms(self):
|
def setup_atoms(self):
|
||||||
# set the center at the position of the main atom
|
# set the center at the position of the main atom
|
||||||
self.set_center([self.atom])
|
self.set_center([self.atom])
|
||||||
|
|
||||||
# find all the hydrogens on the nitrogen atoms
|
# find all the hydrogens on the nitrogen atoms
|
||||||
nitrogens = self.atom.get_bonded_elements('N')
|
nitrogens = self.atom.get_bonded_elements('N')
|
||||||
for n in nitrogens:
|
for n in nitrogens:
|
||||||
my_protonator.protonate_atom(n)
|
my_protonator.protonate_atom(n)
|
||||||
|
|
||||||
hydrogens = []
|
hydrogens = []
|
||||||
for nitrogen in nitrogens:
|
for nitrogen in nitrogens:
|
||||||
hydrogens.extend(nitrogen.get_bonded_elements('H'))
|
hydrogens.extend(nitrogen.get_bonded_elements('H'))
|
||||||
@@ -705,19 +708,19 @@ class AMD_group(Group):
|
|||||||
def setup_atoms(self):
|
def setup_atoms(self):
|
||||||
# Identify the oxygen and nitrogen amide atoms
|
# Identify the oxygen and nitrogen amide atoms
|
||||||
the_oxygen = self.atom.get_bonded_elements('O')
|
the_oxygen = self.atom.get_bonded_elements('O')
|
||||||
the_nitrogen = self.atom.get_bonded_elements('N')
|
the_nitrogen = self.atom.get_bonded_elements('N')
|
||||||
|
|
||||||
# add protons to the nitrogen
|
# add protons to the nitrogen
|
||||||
my_protonator.protonate_atom(the_nitrogen[0])
|
my_protonator.protonate_atom(the_nitrogen[0])
|
||||||
the_hydrogens = the_nitrogen[0].get_bonded_elements('H')
|
the_hydrogens = the_nitrogen[0].get_bonded_elements('H')
|
||||||
|
|
||||||
# set the center using the oxygen and nitrogen amide atoms
|
# set the center using the oxygen and nitrogen amide atoms
|
||||||
self.set_center(the_oxygen+the_nitrogen)
|
self.set_center(the_oxygen+the_nitrogen)
|
||||||
|
|
||||||
self.set_interaction_atoms(the_nitrogen+the_hydrogens,the_oxygen)
|
self.set_interaction_atoms(the_nitrogen+the_hydrogens,the_oxygen)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
class TRP_group(Group):
|
class TRP_group(Group):
|
||||||
def __init__(self, atom):
|
def __init__(self, atom):
|
||||||
@@ -727,7 +730,7 @@ class TRP_group(Group):
|
|||||||
def setup_atoms(self):
|
def setup_atoms(self):
|
||||||
# set the center at the position of the main atom
|
# set the center at the position of the main atom
|
||||||
self.set_center([self.atom])
|
self.set_center([self.atom])
|
||||||
|
|
||||||
# find the hydrogen on the nitrogen atom
|
# find the hydrogen on the nitrogen atom
|
||||||
my_protonator.protonate_atom(self.atom)
|
my_protonator.protonate_atom(self.atom)
|
||||||
the_hydrogen = self.atom.get_bonded_elements('H')
|
the_hydrogen = self.atom.get_bonded_elements('H')
|
||||||
@@ -751,12 +754,12 @@ class Cterm_group(Group):
|
|||||||
the_carbon = self.atom.get_bonded_elements('C')
|
the_carbon = self.atom.get_bonded_elements('C')
|
||||||
the_other_oxygen = the_carbon[0].get_bonded_elements('O')
|
the_other_oxygen = the_carbon[0].get_bonded_elements('O')
|
||||||
the_other_oxygen.remove(self.atom)
|
the_other_oxygen.remove(self.atom)
|
||||||
|
|
||||||
# set the center and interaction atoms
|
# set the center and interaction atoms
|
||||||
the_oxygens = [self.atom]+ the_other_oxygen
|
the_oxygens = [self.atom]+ the_other_oxygen
|
||||||
self.set_center(the_oxygens)
|
self.set_center(the_oxygens)
|
||||||
self.set_interaction_atoms(the_oxygens, the_oxygens)
|
self.set_interaction_atoms(the_oxygens, the_oxygens)
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -802,7 +805,7 @@ class NAR_group(Group):
|
|||||||
self.residue_type = 'NAR'
|
self.residue_type = 'NAR'
|
||||||
print('Found NAR group:',atom)
|
print('Found NAR group:',atom)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def setup_atoms(self):
|
def setup_atoms(self):
|
||||||
# Identify the hydrogen
|
# Identify the hydrogen
|
||||||
@@ -825,7 +828,7 @@ class NAM_group(Group):
|
|||||||
self.residue_type = 'NAM'
|
self.residue_type = 'NAM'
|
||||||
print('Found NAM group:',atom)
|
print('Found NAM group:',atom)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def setup_atoms(self):
|
def setup_atoms(self):
|
||||||
# Identify the hydrogen
|
# Identify the hydrogen
|
||||||
@@ -936,7 +939,7 @@ class CG_group(Group):
|
|||||||
|
|
||||||
# set the center using the nitrogen
|
# set the center using the nitrogen
|
||||||
self.set_center([self.atom])
|
self.set_center([self.atom])
|
||||||
|
|
||||||
the_hydrogens = []
|
the_hydrogens = []
|
||||||
for n in the_nitrogens:
|
for n in the_nitrogens:
|
||||||
my_protonator.protonate_atom(n)
|
my_protonator.protonate_atom(n)
|
||||||
@@ -1065,7 +1068,7 @@ class NP1_group(Group):
|
|||||||
print('Found NP1 group:',atom)
|
print('Found NP1 group:',atom)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def setup_atoms(self):
|
def setup_atoms(self):
|
||||||
# Identify the nitrogens
|
# Identify the nitrogens
|
||||||
my_protonator.protonate_atom(self.atom)
|
my_protonator.protonate_atom(self.atom)
|
||||||
@@ -1123,16 +1126,16 @@ class titratable_ligand_group(Group):
|
|||||||
self.model_pka = atom.marvin_pka
|
self.model_pka = atom.marvin_pka
|
||||||
print('Titratable ligand group ',atom, self.model_pka, self.charge)
|
print('Titratable ligand group ',atom, self.model_pka, self.charge)
|
||||||
self.model_pka_set = True
|
self.model_pka_set = True
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def is_group(parameters, atom):
|
def is_group(parameters, atom):
|
||||||
atom.groups_extracted = 1
|
atom.groups_extracted = 1
|
||||||
|
|
||||||
# check if this atom belongs to a protein group
|
# check if this atom belongs to a protein group
|
||||||
protein_group = is_protein_group(parameters, atom)
|
protein_group = is_protein_group(parameters, atom)
|
||||||
if protein_group: return protein_group
|
if protein_group: return protein_group
|
||||||
|
|
||||||
# check if this atom belongs to a ion group
|
# check if this atom belongs to a ion group
|
||||||
ion_group = is_ion_group(parameters, atom)
|
ion_group = is_ion_group(parameters, atom)
|
||||||
@@ -1168,7 +1171,7 @@ def is_protein_group(parameters,atom):
|
|||||||
### Backbone
|
### Backbone
|
||||||
if atom.type == 'atom' and atom.name == 'N':
|
if atom.type == 'atom' and atom.name == 'N':
|
||||||
# ignore proline backbone nitrogens
|
# ignore proline backbone nitrogens
|
||||||
if atom.resName != 'PRO':
|
if atom.resName != 'PRO':
|
||||||
return BBN_group(atom)
|
return BBN_group(atom)
|
||||||
if atom.type == 'atom' and atom.name == 'C':
|
if atom.type == 'atom' and atom.name == 'C':
|
||||||
# ignore C- carboxyl
|
# ignore C- carboxyl
|
||||||
@@ -1199,10 +1202,10 @@ def is_ligand_group_by_groups(parameters, atom):
|
|||||||
if atom.sybyl_type == 'N.ar':
|
if atom.sybyl_type == 'N.ar':
|
||||||
if len(atom.get_bonded_heavy_atoms())==2:
|
if len(atom.get_bonded_heavy_atoms())==2:
|
||||||
return NAR_group(atom)
|
return NAR_group(atom)
|
||||||
|
|
||||||
if atom.sybyl_type == 'N.am':
|
if atom.sybyl_type == 'N.am':
|
||||||
return NAM_group(atom)
|
return NAM_group(atom)
|
||||||
|
|
||||||
if atom.sybyl_type in ['N.3', 'N.4']:
|
if atom.sybyl_type in ['N.3', 'N.4']:
|
||||||
heavy_bonded = atom.get_bonded_heavy_atoms()
|
heavy_bonded = atom.get_bonded_heavy_atoms()
|
||||||
if len(heavy_bonded) == 0:
|
if len(heavy_bonded) == 0:
|
||||||
@@ -1218,14 +1221,14 @@ def is_ligand_group_by_groups(parameters, atom):
|
|||||||
return N1_group(atom)
|
return N1_group(atom)
|
||||||
|
|
||||||
if atom.sybyl_type == 'N.pl3':
|
if atom.sybyl_type == 'N.pl3':
|
||||||
# make sure that this atom is not part of a guadinium or amidinium group
|
# make sure that this atom is not part of a guadinium or amidinium group
|
||||||
bonded_carbons = atom.get_bonded_elements('C')
|
bonded_carbons = atom.get_bonded_elements('C')
|
||||||
if len(bonded_carbons) == 1:
|
if len(bonded_carbons) == 1:
|
||||||
bonded_nitrogens = bonded_carbons[0].get_bonded_elements('N')
|
bonded_nitrogens = bonded_carbons[0].get_bonded_elements('N')
|
||||||
if len(bonded_nitrogens) == 1:
|
if len(bonded_nitrogens) == 1:
|
||||||
return NP1_group(atom)
|
return NP1_group(atom)
|
||||||
|
|
||||||
|
|
||||||
if atom.sybyl_type == 'C.2':
|
if atom.sybyl_type == 'C.2':
|
||||||
# Guadinium and amidinium groups
|
# Guadinium and amidinium groups
|
||||||
bonded_nitrogens = atom.get_bonded_elements('N')
|
bonded_nitrogens = atom.get_bonded_elements('N')
|
||||||
@@ -1263,7 +1266,7 @@ def is_ligand_group_by_groups(parameters, atom):
|
|||||||
|
|
||||||
if atom.sybyl_type == 'O.2':
|
if atom.sybyl_type == 'O.2':
|
||||||
return O2_group(atom)
|
return O2_group(atom)
|
||||||
|
|
||||||
|
|
||||||
if atom.sybyl_type == 'S.3':
|
if atom.sybyl_type == 'S.3':
|
||||||
# sulphide group
|
# sulphide group
|
||||||
@@ -1272,8 +1275,8 @@ def is_ligand_group_by_groups(parameters, atom):
|
|||||||
# other SP3 oxygen
|
# other SP3 oxygen
|
||||||
#else:
|
#else:
|
||||||
# return S3_group(atom)
|
# return S3_group(atom)
|
||||||
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -1284,11 +1287,11 @@ def is_ligand_group_by_marvin_pkas(parameters, atom):
|
|||||||
# calculate Marvin ligand pkas for this conformation container
|
# calculate Marvin ligand pkas for this conformation container
|
||||||
# if not already done
|
# if not already done
|
||||||
if not atom.conformation_container.marvin_pkas_calculated:
|
if not atom.conformation_container.marvin_pkas_calculated:
|
||||||
lpka = Source.ligand_pka_values.ligand_pka_values(parameters)
|
lpka = propka.ligand_pka_values.ligand_pka_values(parameters)
|
||||||
lpka.get_marvin_pkas_for_molecular_container(atom.molecular_container,
|
lpka.get_marvin_pkas_for_molecular_container(atom.molecular_container,
|
||||||
min_pH=parameters.min_ligand_model_pka,
|
min_pH=parameters.min_ligand_model_pka,
|
||||||
max_pH=parameters.max_ligand_model_pka)
|
max_pH=parameters.max_ligand_model_pka)
|
||||||
|
|
||||||
|
|
||||||
if atom.marvin_pka:
|
if atom.marvin_pka:
|
||||||
return titratable_ligand_group(atom)
|
return titratable_ligand_group(atom)
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import math, time
|
import math, time
|
||||||
import Source.lib as lib
|
|
||||||
from Source.determinant import Determinant
|
import propka.lib as lib
|
||||||
import Source.calculations
|
from propka.determinant import Determinant
|
||||||
|
import propka.calculations
|
||||||
|
|
||||||
# Some library functions for the interative pKa determinants
|
# Some library functions for the interative pKa determinants
|
||||||
|
|
||||||
@@ -32,11 +37,11 @@ def addtoDeterminantList(group1, group2, distance, iterative_interactions, versi
|
|||||||
|
|
||||||
|
|
||||||
def addIterativeAcidPair(object1, object2, interaction):
|
def addIterativeAcidPair(object1, object2, interaction):
|
||||||
"""
|
"""
|
||||||
Adding the Coulomb 'iterative' interaction (an acid pair):
|
Adding the Coulomb 'iterative' interaction (an acid pair):
|
||||||
the higher pKa is raised with QQ+HB
|
the higher pKa is raised with QQ+HB
|
||||||
the lower pKa is lowered with HB
|
the lower pKa is lowered with HB
|
||||||
"""
|
"""
|
||||||
values = interaction[1]
|
values = interaction[1]
|
||||||
annihilation = interaction[2]
|
annihilation = interaction[2]
|
||||||
hbond_value = values[0]
|
hbond_value = values[0]
|
||||||
@@ -69,10 +74,10 @@ def addIterativeAcidPair(object1, object2, interaction):
|
|||||||
|
|
||||||
|
|
||||||
def addIterativeBasePair(object1, object2, interaction):
|
def addIterativeBasePair(object1, object2, interaction):
|
||||||
"""
|
"""
|
||||||
Adding the Coulomb 'iterative' interaction (a base pair):
|
Adding the Coulomb 'iterative' interaction (a base pair):
|
||||||
the lower pKa is lowered
|
the lower pKa is lowered
|
||||||
"""
|
"""
|
||||||
values = interaction[1]
|
values = interaction[1]
|
||||||
annihilation = interaction[2]
|
annihilation = interaction[2]
|
||||||
hbond_value = values[0]
|
hbond_value = values[0]
|
||||||
@@ -106,10 +111,10 @@ def addIterativeBasePair(object1, object2, interaction):
|
|||||||
|
|
||||||
|
|
||||||
def addIterativeIonPair(object1, object2, interaction, version):
|
def addIterativeIonPair(object1, object2, interaction, version):
|
||||||
"""
|
"""
|
||||||
Adding the Coulomb 'iterative' interaction (an acid-base pair):
|
Adding the Coulomb 'iterative' interaction (an acid-base pair):
|
||||||
the pKa of the acid is lowered & the pKa of the base is raised
|
the pKa of the acid is lowered & the pKa of the base is raised
|
||||||
"""
|
"""
|
||||||
values = interaction[1]
|
values = interaction[1]
|
||||||
annihilation = interaction[2]
|
annihilation = interaction[2]
|
||||||
hbond_value = values[0]
|
hbond_value = values[0]
|
||||||
@@ -132,7 +137,7 @@ def addIterativeIonPair(object1, object2, interaction, version):
|
|||||||
|
|
||||||
annihilation[0] = 0.00
|
annihilation[0] = 0.00
|
||||||
annihilation[1] = 0.00
|
annihilation[1] = 0.00
|
||||||
|
|
||||||
if add_term == True:
|
if add_term == True:
|
||||||
|
|
||||||
# Coulomb
|
# Coulomb
|
||||||
@@ -161,9 +166,9 @@ def addIterativeIonPair(object1, object2, interaction, version):
|
|||||||
|
|
||||||
|
|
||||||
def addDeterminants(iterative_interactions, version, options=None):
|
def addDeterminants(iterative_interactions, version, options=None):
|
||||||
"""
|
"""
|
||||||
The iterative pKa scheme. Later it is all added in 'calculateTotalPKA'
|
The iterative pKa scheme. Later it is all added in 'calculateTotalPKA'
|
||||||
"""
|
"""
|
||||||
# --- setup ---
|
# --- setup ---
|
||||||
iteratives = []
|
iteratives = []
|
||||||
done_group = []
|
done_group = []
|
||||||
@@ -270,7 +275,7 @@ def addDeterminants(iterative_interactions, version, options=None):
|
|||||||
g = interaction[0]
|
g = interaction[0]
|
||||||
newDeterminant = Determinant(g, value)
|
newDeterminant = Determinant(g, value)
|
||||||
itres.group.determinants[type].append(newDeterminant)
|
itres.group.determinants[type].append(newDeterminant)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def findIterative(pair, iteratives):
|
def findIterative(pair, iteratives):
|
||||||
52
Source/lib.py → propka/lib.py
Executable file → Normal file
52
Source/lib.py → propka/lib.py
Executable file → Normal file
@@ -1,23 +1,27 @@
|
|||||||
#!/usr/bin/python
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import string, sys, copy, math, os
|
import string, sys, copy, math, os
|
||||||
|
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
#
|
#
|
||||||
# file I/O
|
# file I/O
|
||||||
#
|
#
|
||||||
def open_file_for_reading(filename):
|
def open_file_for_reading(filename):
|
||||||
if not os.path.isfile(filename):
|
try:
|
||||||
|
f = open(filename,'r')
|
||||||
|
except:
|
||||||
raise Exception('Cannot find file %s' %filename)
|
raise Exception('Cannot find file %s' %filename)
|
||||||
|
return f
|
||||||
return open(filename,'r')
|
|
||||||
|
|
||||||
def open_file_for_writing(filename):
|
def open_file_for_writing(filename):
|
||||||
res = open(filename,'w')
|
try:
|
||||||
if not res:
|
res = open(filename,'w')
|
||||||
|
except:
|
||||||
raise Exception('Could not open %s'%filename)
|
raise Exception('Could not open %s'%filename)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
#
|
#
|
||||||
# bookkeeping etc.
|
# bookkeeping etc.
|
||||||
#
|
#
|
||||||
@@ -43,7 +47,7 @@ def make_molecule(atom, atoms):
|
|||||||
if ba in atoms:
|
if ba in atoms:
|
||||||
atoms.remove(ba)
|
atoms.remove(ba)
|
||||||
res_atoms.extend(make_molecule(ba, atoms))
|
res_atoms.extend(make_molecule(ba, atoms))
|
||||||
|
|
||||||
return res_atoms
|
return res_atoms
|
||||||
|
|
||||||
|
|
||||||
@@ -61,7 +65,7 @@ def generate_combinations(interactions):
|
|||||||
res.remove([])
|
res.remove([])
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def make_combination(combis, interaction):
|
def make_combination(combis, interaction):
|
||||||
res = []
|
res = []
|
||||||
@@ -85,37 +89,37 @@ def loadOptions():
|
|||||||
parser = OptionParser(usage)
|
parser = OptionParser(usage)
|
||||||
|
|
||||||
# loading the parser
|
# loading the parser
|
||||||
parser.add_option("-f", "--file", action="append", dest="filenames",
|
parser.add_option("-f", "--file", action="append", dest="filenames",
|
||||||
help="read data from <filename>, i.e. <filename> is added to arguments")
|
help="read data from <filename>, i.e. <filename> is added to arguments")
|
||||||
parser.add_option("-r", "--reference", dest="reference", default="neutral",
|
parser.add_option("-r", "--reference", dest="reference", default="neutral",
|
||||||
help="setting which reference to use for stability calculations [neutral/low-pH]")
|
help="setting which reference to use for stability calculations [neutral/low-pH]")
|
||||||
parser.add_option("-c", "--chain", action="append", dest="chains",
|
parser.add_option("-c", "--chain", action="append", dest="chains",
|
||||||
help="creating the protein with only a specified chain, note, chains without ID are labeled 'A' [all]")
|
help="creating the protein with only a specified chain, note, chains without ID are labeled 'A' [all]")
|
||||||
parser.add_option("-t", "--thermophile", action="append", dest="thermophiles",
|
parser.add_option("-t", "--thermophile", action="append", dest="thermophiles",
|
||||||
help="defining a thermophile filename; usually used in 'alignment-mutations'")
|
help="defining a thermophile filename; usually used in 'alignment-mutations'")
|
||||||
parser.add_option("-a", "--alignment", action="append", dest="alignment",
|
parser.add_option("-a", "--alignment", action="append", dest="alignment",
|
||||||
help="alignment file connecting <filename> and <thermophile> [<thermophile>.pir]")
|
help="alignment file connecting <filename> and <thermophile> [<thermophile>.pir]")
|
||||||
parser.add_option("-m", "--mutation", action="append", dest="mutations",
|
parser.add_option("-m", "--mutation", action="append", dest="mutations",
|
||||||
help="specifying mutation labels which is used to modify <filename> according to, e.g. N25R/N181D")
|
help="specifying mutation labels which is used to modify <filename> according to, e.g. N25R/N181D")
|
||||||
parser.add_option("-v", "--version", dest="version_label", default="Jan15",
|
parser.add_option("-v", "--version", dest="version_label", default="Jan15",
|
||||||
help="specifying the sub-version of propka [Jan15/Dec19]")
|
help="specifying the sub-version of propka [Jan15/Dec19]")
|
||||||
parser.add_option("-p", "--parameters",dest="parameters", default="propka.cfg",
|
parser.add_option("-p", "--parameters",dest="parameters", default=pkg_resources.resource_filename(__name__, "propka.cfg"),
|
||||||
help="set the parameter file")
|
help="set the parameter file [%default]")
|
||||||
parser.add_option("-z", "--verbose", dest="verbose", action="store_true", default=True,
|
parser.add_option("-z", "--verbose", dest="verbose", action="store_true", default=True,
|
||||||
help="sleep during calculations")
|
help="sleep during calculations")
|
||||||
parser.add_option("-q", "--quiet", dest="verbose", action="store_false",
|
parser.add_option("-q", "--quiet", dest="verbose", action="store_false",
|
||||||
help="sleep during calculations")
|
help="sleep during calculations")
|
||||||
parser.add_option("-s", "--silent", dest="verbose", action="store_false",
|
parser.add_option("-s", "--silent", dest="verbose", action="store_false",
|
||||||
help="not activated yet")
|
help="not activated yet")
|
||||||
parser.add_option("--verbosity", dest="verbosity", action="store_const",
|
parser.add_option("--verbosity", dest="verbosity", action="store_const",
|
||||||
help="level of printout - not activated yet")
|
help="level of printout - not activated yet")
|
||||||
parser.add_option("-o", "--pH", dest="pH", type="float", default=7.0,
|
parser.add_option("-o", "--pH", dest="pH", type="float", default=7.0,
|
||||||
help="setting pH-value used in e.g. stability calculations [7.0]")
|
help="setting pH-value used in e.g. stability calculations [7.0]")
|
||||||
parser.add_option("-w", "--window", dest="window", nargs=3, type="float", default=(0.0, 14.0, 1.0),
|
parser.add_option("-w", "--window", dest="window", nargs=3, type="float", default=(0.0, 14.0, 1.0),
|
||||||
help="setting the pH-window to show e.g. stability profiles [0.0, 14.0, 1.0]")
|
help="setting the pH-window to show e.g. stability profiles [0.0, 14.0, 1.0]")
|
||||||
parser.add_option("-g", "--grid", dest="grid", nargs=3, type="float", default=(0.0, 14.0, 0.1),
|
parser.add_option("-g", "--grid", dest="grid", nargs=3, type="float", default=(0.0, 14.0, 0.1),
|
||||||
help="setting the pH-grid to calculate e.g. stability related properties [0.0, 14.0, 0.1]")
|
help="setting the pH-grid to calculate e.g. stability related properties [0.0, 14.0, 0.1]")
|
||||||
parser.add_option("--mutator", dest="mutator",
|
parser.add_option("--mutator", dest="mutator",
|
||||||
help="setting approach for mutating <filename> [alignment/scwrl/jackal]")
|
help="setting approach for mutating <filename> [alignment/scwrl/jackal]")
|
||||||
parser.add_option("--mutator-option", dest="mutator_options", action="append",
|
parser.add_option("--mutator-option", dest="mutator_options", action="append",
|
||||||
help="setting property for mutator [e.g. type=\"side-chain\"]")
|
help="setting property for mutator [e.g. type=\"side-chain\"]")
|
||||||
@@ -156,7 +160,7 @@ def makeTidyAtomLabel(name,element):
|
|||||||
"""
|
"""
|
||||||
Returns a 'tidier' atom label for printing the new pdbfile
|
Returns a 'tidier' atom label for printing the new pdbfile
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if len(name)>4:# if longer than 4, just truncate the name
|
if len(name)>4:# if longer than 4, just truncate the name
|
||||||
label=name[0:4]
|
label=name[0:4]
|
||||||
elif len(name)==4:# if lenght is 4, otherwise use the name as it is
|
elif len(name)==4:# if lenght is 4, otherwise use the name as it is
|
||||||
45
Source/ligand.py → propka/ligand.py
Executable file → Normal file
45
Source/ligand.py → propka/ligand.py
Executable file → Normal file
@@ -1,7 +1,12 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
import sys, Source.calculations
|
from __future__ import division
|
||||||
from Source.vector_algebra import *
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import propka.calculations
|
||||||
|
from propka.vector_algebra import *
|
||||||
|
|
||||||
|
|
||||||
all_sybyl_types = [
|
all_sybyl_types = [
|
||||||
@@ -157,7 +162,7 @@ def assign_sybyl_type(atom):
|
|||||||
bonded_elements[i]=atom.bonded_atoms[i].element
|
bonded_elements[i]=atom.bonded_atoms[i].element
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Aromatic carbon/nitrogen
|
# Aromatic carbon/nitrogen
|
||||||
if aromatic:
|
if aromatic:
|
||||||
for ra in ring_atoms:
|
for ra in ring_atoms:
|
||||||
@@ -187,7 +192,7 @@ def assign_sybyl_type(atom):
|
|||||||
nitrogens = atom.get_bonded_elements('N')
|
nitrogens = atom.get_bonded_elements('N')
|
||||||
oxygens = atom.get_bonded_elements('O')
|
oxygens = atom.get_bonded_elements('O')
|
||||||
if len(nitrogens)==1 and len(oxygens)==1:
|
if len(nitrogens)==1 and len(oxygens)==1:
|
||||||
C = atom
|
C = atom
|
||||||
N = nitrogens[0]
|
N = nitrogens[0]
|
||||||
O = oxygens[0]
|
O = oxygens[0]
|
||||||
|
|
||||||
@@ -199,9 +204,9 @@ def assign_sybyl_type(atom):
|
|||||||
set_type(C,'C.2')
|
set_type(C,'C.2')
|
||||||
set_type(O,'O.2')
|
set_type(O,'O.2')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
if atom.element=='C':
|
|
||||||
|
if atom.element=='C':
|
||||||
# check for carboxyl
|
# check for carboxyl
|
||||||
if len(atom.bonded_atoms)==3 and list(bonded_elements.values()).count('O')==2:
|
if len(atom.bonded_atoms)==3 and list(bonded_elements.values()).count('O')==2:
|
||||||
i1 = list(bonded_elements.values()).index('O')
|
i1 = list(bonded_elements.values()).index('O')
|
||||||
@@ -213,11 +218,11 @@ def assign_sybyl_type(atom):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# sp carbon
|
# sp carbon
|
||||||
if len(atom.bonded_atoms)<=2:
|
if len(atom.bonded_atoms)<=2:
|
||||||
for b in atom.bonded_atoms:
|
for b in atom.bonded_atoms:
|
||||||
if Source.calculations.squared_distance(atom, b) < max_C_triple_bond_squared:
|
if propka.calculations.squared_distance(atom, b) < max_C_triple_bond_squared:
|
||||||
set_type(atom,'C.1')
|
set_type(atom,'C.1')
|
||||||
set_type(b,b.element+'.1')
|
set_type(b,b.element+'.1')
|
||||||
if atom.sybyl_assigned:
|
if atom.sybyl_assigned:
|
||||||
@@ -232,7 +237,7 @@ def assign_sybyl_type(atom):
|
|||||||
if len(b.bonded_atoms)<3 or is_planar(b):
|
if len(b.bonded_atoms)<3 or is_planar(b):
|
||||||
set_type(b,'N.pl3')
|
set_type(b,'N.pl3')
|
||||||
return
|
return
|
||||||
|
|
||||||
# sp3 carbon
|
# sp3 carbon
|
||||||
set_type(atom, 'C.3')
|
set_type(atom, 'C.3')
|
||||||
return
|
return
|
||||||
@@ -244,11 +249,11 @@ def assign_sybyl_type(atom):
|
|||||||
if is_planar(atom.bonded_atoms[0]):
|
if is_planar(atom.bonded_atoms[0]):
|
||||||
set_type(atom,'N.pl3')
|
set_type(atom,'N.pl3')
|
||||||
return
|
return
|
||||||
|
|
||||||
if planar:
|
if planar:
|
||||||
set_type(atom,'N.pl3')
|
set_type(atom,'N.pl3')
|
||||||
return
|
return
|
||||||
|
|
||||||
set_type(atom,'N.3')
|
set_type(atom,'N.3')
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -262,7 +267,7 @@ def assign_sybyl_type(atom):
|
|||||||
the_carbon = atom.bonded_atoms[0]
|
the_carbon = atom.bonded_atoms[0]
|
||||||
if len(the_carbon.bonded_atoms)==3 and the_carbon.count_bonded_elements('O')==2:
|
if len(the_carbon.bonded_atoms)==3 and the_carbon.count_bonded_elements('O')==2:
|
||||||
[O1,O2] = the_carbon.get_bonded_elements('O')
|
[O1,O2] = the_carbon.get_bonded_elements('O')
|
||||||
|
|
||||||
if len(O1.bonded_atoms)==1 and len(O2.bonded_atoms)==1:
|
if len(O1.bonded_atoms)==1 and len(O2.bonded_atoms)==1:
|
||||||
set_type(O1,'O.co2-')
|
set_type(O1,'O.co2-')
|
||||||
set_type(O2,'O.co2')
|
set_type(O2,'O.co2')
|
||||||
@@ -270,7 +275,7 @@ def assign_sybyl_type(atom):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# check for X=O
|
# check for X=O
|
||||||
if Source.calculations.squared_distance(atom, atom.bonded_atoms[0]) < max_C_double_bond_squared:
|
if propka.calculations.squared_distance(atom, atom.bonded_atoms[0]) < max_C_double_bond_squared:
|
||||||
set_type(atom,'O.2')
|
set_type(atom,'O.2')
|
||||||
if atom.bonded_atoms[0].element=='C':
|
if atom.bonded_atoms[0].element=='C':
|
||||||
set_type(atom.bonded_atoms[0],'C.2')
|
set_type(atom.bonded_atoms[0],'C.2')
|
||||||
@@ -287,7 +292,7 @@ def assign_sybyl_type(atom):
|
|||||||
set_type(atom.bonded_atoms[i2],'O.2')
|
set_type(atom.bonded_atoms[i2],'O.2')
|
||||||
set_type(atom,'S.o2')
|
set_type(atom,'S.o2')
|
||||||
return
|
return
|
||||||
|
|
||||||
# check for SO4
|
# check for SO4
|
||||||
if list(bonded_elements.values()).count('O')==4:
|
if list(bonded_elements.values()).count('O')==4:
|
||||||
no_O2 = 0
|
no_O2 = 0
|
||||||
@@ -297,7 +302,7 @@ def assign_sybyl_type(atom):
|
|||||||
no_O2+=1
|
no_O2+=1
|
||||||
else:
|
else:
|
||||||
set_type(atom.bonded_atoms[i],'O.3')
|
set_type(atom.bonded_atoms[i],'O.3')
|
||||||
|
|
||||||
set_type(atom,'S.3')
|
set_type(atom,'S.3')
|
||||||
|
|
||||||
|
|
||||||
@@ -315,8 +320,8 @@ def assign_sybyl_type(atom):
|
|||||||
# # find oxygens only bonded to current phosphorus
|
# # find oxygens only bonded to current phosphorus
|
||||||
# bonded_oxygens_1 = [o for o in bonded_oxygens if len(o.get_bonded_heavy_atoms())==1]
|
# bonded_oxygens_1 = [o for o in bonded_oxygens if len(o.get_bonded_heavy_atoms())==1]
|
||||||
# # find the closest oxygen ...
|
# # find the closest oxygen ...
|
||||||
# closest_oxygen = min(bonded_oxygens_1,
|
# closest_oxygen = min(bonded_oxygens_1,
|
||||||
# key= lambda o:Source.calculations.squared_distance(atom,o))
|
# key= lambda o:propka.calculations.squared_distance(atom,o))
|
||||||
# # ... and set it to O.2
|
# # ... and set it to O.2
|
||||||
# set_type(closest_oxygen,'O.2')
|
# set_type(closest_oxygen,'O.2')
|
||||||
|
|
||||||
@@ -378,20 +383,20 @@ def are_atoms_planar(atoms):
|
|||||||
v1 = vector(atom1=atoms[0], atom2=atoms[1])
|
v1 = vector(atom1=atoms[0], atom2=atoms[1])
|
||||||
v2 = vector(atom1=atoms[0], atom2=atoms[2])
|
v2 = vector(atom1=atoms[0], atom2=atoms[2])
|
||||||
n = (v1**v2).rescale(1.0)
|
n = (v1**v2).rescale(1.0)
|
||||||
|
|
||||||
margin = 0.20
|
margin = 0.20
|
||||||
for b in atoms[3:]:
|
for b in atoms[3:]:
|
||||||
v = vector(atom1=atoms[0], atom2=b).rescale(1.0)
|
v = vector(atom1=atoms[0], atom2=b).rescale(1.0)
|
||||||
#print(atoms[0],abs(v*n) )
|
#print(atoms[0],abs(v*n) )
|
||||||
if abs(v*n)>margin:
|
if abs(v*n)>margin:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def is_aromatic_ring(atoms):
|
def is_aromatic_ring(atoms):
|
||||||
if len(atoms)<5:
|
if len(atoms)<5:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for i in range(len(atoms)):
|
for i in range(len(atoms)):
|
||||||
if not are_atoms_planar(atoms[i:]+atoms[:i]):
|
if not are_atoms_planar(atoms[i:]+atoms[:i]):
|
||||||
return False
|
return False
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import Source.molecular_container, Source.calculations, Source.calculations, Source.parameters, Source.pdb, Source.lib, os, subprocess, sys
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import propka.molecular_container, propka.calculations, propka.calculations, propka.parameters, propka.pdb, propka.lib, os, subprocess, sys
|
||||||
|
|
||||||
class ligand_pka_values:
|
class ligand_pka_values:
|
||||||
def __init__(self, parameters):
|
def __init__(self, parameters):
|
||||||
@@ -14,14 +17,14 @@ class ligand_pka_values:
|
|||||||
print(self.molconvert)
|
print(self.molconvert)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def find_in_path(self, program):
|
def find_in_path(self, program):
|
||||||
path = os.environ.get('PATH').split(os.pathsep)
|
path = os.environ.get('PATH').split(os.pathsep)
|
||||||
|
|
||||||
l = [i for i in filter(lambda loc: os.access(loc, os.F_OK),
|
l = [i for i in filter(lambda loc: os.access(loc, os.F_OK),
|
||||||
map(lambda dir: os.path.join(dir, program),path))]
|
map(lambda dir: os.path.join(dir, program),path))]
|
||||||
|
|
||||||
if len(l) == 0:
|
if len(l) == 0:
|
||||||
print('Error: Could not find %s. Please make sure that it is found in the path.'%program)
|
print('Error: Could not find %s. Please make sure that it is found in the path.'%program)
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
@@ -29,14 +32,14 @@ class ligand_pka_values:
|
|||||||
return l[0]
|
return l[0]
|
||||||
|
|
||||||
def get_marvin_pkas_for_pdb_file(self, file, no_pkas=10, min_pH =-10, max_pH=20):
|
def get_marvin_pkas_for_pdb_file(self, file, no_pkas=10, min_pH =-10, max_pH=20):
|
||||||
molecule = Source.molecular_container.Molecular_container(file)
|
molecule = propka.molecular_container.Molecular_container(file)
|
||||||
self.get_marvin_pkas_for_molecular_container(molecule, no_pkas=no_pkas, min_pH =min_pH, max_pH=max_pH)
|
self.get_marvin_pkas_for_molecular_container(molecule, no_pkas=no_pkas, min_pH =min_pH, max_pH=max_pH)
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_marvin_pkas_for_molecular_container(self, molecule, no_pkas=10, min_pH =-10, max_pH=20):
|
def get_marvin_pkas_for_molecular_container(self, molecule, no_pkas=10, min_pH =-10, max_pH=20):
|
||||||
for name in molecule.conformation_names:
|
for name in molecule.conformation_names:
|
||||||
filename = '%s_%s'%(molecule.name,name)
|
filename = '%s_%s'%(molecule.name,name)
|
||||||
self.get_marvin_pkas_for_conformation_container(molecule.conformations[name], name=filename, reuse=molecule.options.reuse_ligand_mol2_file,
|
self.get_marvin_pkas_for_conformation_container(molecule.conformations[name], name=filename, reuse=molecule.options.reuse_ligand_mol2_file,
|
||||||
no_pkas=no_pkas, min_pH =min_pH, max_pH=max_pH)
|
no_pkas=no_pkas, min_pH =min_pH, max_pH=max_pH)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -50,7 +53,7 @@ class ligand_pka_values:
|
|||||||
|
|
||||||
def get_marvin_pkas_for_atoms(self, atoms, name='temp', reuse=False, no_pkas=10, min_pH =-10, max_pH=20):
|
def get_marvin_pkas_for_atoms(self, atoms, name='temp', reuse=False, no_pkas=10, min_pH =-10, max_pH=20):
|
||||||
# do one molecule at the time so we don't confuse marvin
|
# do one molecule at the time so we don't confuse marvin
|
||||||
molecules = Source.lib.split_atoms_into_molecules(atoms)
|
molecules = propka.lib.split_atoms_into_molecules(atoms)
|
||||||
for i in range(len(molecules)):
|
for i in range(len(molecules)):
|
||||||
filename = '%s_%d.mol2'%(name, i+1)
|
filename = '%s_%d.mol2'%(name, i+1)
|
||||||
self.get_marvin_pkas_for_molecule(molecules[i], filename=filename, reuse=reuse, no_pkas=no_pkas, min_pH =min_pH, max_pH=max_pH)
|
self.get_marvin_pkas_for_molecule(molecules[i], filename=filename, reuse=reuse, no_pkas=no_pkas, min_pH =min_pH, max_pH=max_pH)
|
||||||
@@ -61,18 +64,18 @@ class ligand_pka_values:
|
|||||||
def get_marvin_pkas_for_molecule(self, atoms, filename='__tmp_ligand.mol2', reuse=False, no_pkas=10, min_pH =-10, max_pH=20):
|
def get_marvin_pkas_for_molecule(self, atoms, filename='__tmp_ligand.mol2', reuse=False, no_pkas=10, min_pH =-10, max_pH=20):
|
||||||
# print out structure unless we are using user-modified structure
|
# print out structure unless we are using user-modified structure
|
||||||
if not reuse:
|
if not reuse:
|
||||||
Source.pdb.write_mol2_for_atoms(atoms, filename)
|
propka.pdb.write_mol2_for_atoms(atoms, filename)
|
||||||
# check that we actually have a file to work with
|
# check that we actually have a file to work with
|
||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
print('Warning: Didn\'t find a user-modified file \'%s\' - generating one'%filename)
|
print('Warning: Didn\'t find a user-modified file \'%s\' - generating one'%filename)
|
||||||
Source.pdb.write_mol2_for_atoms(atoms, filename)
|
propka.pdb.write_mol2_for_atoms(atoms, filename)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Marvin
|
# Marvin
|
||||||
# calculate pKa values
|
# calculate pKa values
|
||||||
options = 'pka -a %d -b %d --min %f --max %f -d large'%(no_pkas, no_pkas, min_pH, max_pH)
|
options = 'pka -a %d -b %d --min %f --max %f -d large'%(no_pkas, no_pkas, min_pH, max_pH)
|
||||||
(output,errors) = subprocess.Popen([self.cxcalc, filename]+options.split(),
|
(output,errors) = subprocess.Popen([self.cxcalc, filename]+options.split(),
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
|
||||||
|
|
||||||
if len(errors)>0:
|
if len(errors)>0:
|
||||||
@@ -86,7 +89,7 @@ class ligand_pka_values:
|
|||||||
|
|
||||||
# extract calculated pkas
|
# extract calculated pkas
|
||||||
indices,pkas,types = self.extract_pkas(output)
|
indices,pkas,types = self.extract_pkas(output)
|
||||||
|
|
||||||
# store calculated pka values
|
# store calculated pka values
|
||||||
for i in range(len(indices)):
|
for i in range(len(indices)):
|
||||||
atoms[indices[i]].marvin_pka = pkas[i]
|
atoms[indices[i]].marvin_pka = pkas[i]
|
||||||
@@ -104,10 +107,10 @@ class ligand_pka_values:
|
|||||||
values = values.split('\t')
|
values = values.split('\t')
|
||||||
|
|
||||||
# format values
|
# format values
|
||||||
types = [tags[i][0] for i in range(1,len(tags)-1) if len(values)>i and values[i] != '']
|
types = [tags[i][0] for i in range(1,len(tags)-1) if len(values)>i and values[i] != '']
|
||||||
indices = [int(a)-1 for a in values[-1].split(',') if a !='']
|
indices = [int(a)-1 for a in values[-1].split(',') if a !='']
|
||||||
values = [float(v.replace(',','.')) for v in values[1:-1] if v != '']
|
values = [float(v.replace(',','.')) for v in values[1:-1] if v != '']
|
||||||
|
|
||||||
if len(indices) != len(values) != len(types):
|
if len(indices) != len(values) != len(types):
|
||||||
raise Exception('Lengths of atoms and pka values mismatch')
|
raise Exception('Lengths of atoms and pka values mismatch')
|
||||||
|
|
||||||
66
Source/molecular_container.py → propka/molecular_container.py
Executable file → Normal file
66
Source/molecular_container.py → propka/molecular_container.py
Executable file → Normal file
@@ -1,15 +1,19 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
#
|
#
|
||||||
# Molecular container for storing all contents of pdb files
|
# Molecular container for storing all contents of pdb files
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import os, Source.pdb, sys, Source.version, Source.output, Source.conformation_container, Source.group, Source.lib
|
import os, sys
|
||||||
|
|
||||||
|
import propka.pdb, propka.version, propka.output, propka.conformation_container, propka.group, propka.lib
|
||||||
|
|
||||||
class Molecular_container:
|
class Molecular_container:
|
||||||
def __init__(self, input_file, options=None):
|
def __init__(self, input_file, options=None):
|
||||||
# printing out header before parsing input
|
# printing out header before parsing input
|
||||||
Source.output.printHeader()
|
propka.output.printHeader()
|
||||||
|
|
||||||
# set up some values
|
# set up some values
|
||||||
self.options = options
|
self.options = options
|
||||||
@@ -21,11 +25,11 @@ class Molecular_container:
|
|||||||
|
|
||||||
# set the version
|
# set the version
|
||||||
if options:
|
if options:
|
||||||
parameters = Source.parameters.Parameters(self.options.parameters)
|
parameters = propka.parameters.Parameters(self.options.parameters)
|
||||||
else:
|
else:
|
||||||
parameters = Source.parameters.Parameters('propka.cfg')
|
parameters = propka.parameters.Parameters('propka.cfg')
|
||||||
try:
|
try:
|
||||||
exec('self.version = Source.version.%s(parameters)'%parameters.version)
|
exec('self.version = propka.version.%s(parameters)'%parameters.version)
|
||||||
except:
|
except:
|
||||||
raise Exception('Error: Version %s does not exist'%parameters.version)
|
raise Exception('Error: Version %s does not exist'%parameters.version)
|
||||||
|
|
||||||
@@ -33,7 +37,7 @@ class Molecular_container:
|
|||||||
if input_file_extension[0:4] == '.pdb':
|
if input_file_extension[0:4] == '.pdb':
|
||||||
# input is a pdb file
|
# input is a pdb file
|
||||||
# read in atoms and top up containers to make sure that all atoms are present in all conformations
|
# read in atoms and top up containers to make sure that all atoms are present in all conformations
|
||||||
[self.conformations, self.conformation_names] = Source.pdb.read_pdb(input_file, self.version.parameters,self)
|
[self.conformations, self.conformation_names] = propka.pdb.read_pdb(input_file, self.version.parameters,self)
|
||||||
if len(self.conformations)==0:
|
if len(self.conformations)==0:
|
||||||
print('Error: The pdb file does not seems to contain any molecular conformations')
|
print('Error: The pdb file does not seems to contain any molecular conformations')
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
@@ -41,7 +45,7 @@ class Molecular_container:
|
|||||||
self.top_up_conformations()
|
self.top_up_conformations()
|
||||||
|
|
||||||
# make a structure precheck
|
# make a structure precheck
|
||||||
Source.pdb.protein_precheck(self.conformations, self.conformation_names)
|
propka.pdb.protein_precheck(self.conformations, self.conformation_names)
|
||||||
|
|
||||||
# set up atom bonding and protonation
|
# set up atom bonding and protonation
|
||||||
self.version.setup_bonding_and_protonation(self)
|
self.version.setup_bonding_and_protonation(self)
|
||||||
@@ -58,12 +62,12 @@ class Molecular_container:
|
|||||||
|
|
||||||
# write out the input file
|
# write out the input file
|
||||||
filename = self.file.replace(input_file_extension,'.propka_input')
|
filename = self.file.replace(input_file_extension,'.propka_input')
|
||||||
Source.pdb.write_input(self, filename)
|
propka.pdb.write_input(self, filename)
|
||||||
|
|
||||||
|
|
||||||
elif input_file_extension == '.propka_input':
|
elif input_file_extension == '.propka_input':
|
||||||
#input is a propka_input file
|
#input is a propka_input file
|
||||||
[self.conformations, self.conformation_names] = Source.pdb.read_input(input_file, self.version.parameters, self)
|
[self.conformations, self.conformation_names] = propka.pdb.read_input(input_file, self.version.parameters, self)
|
||||||
|
|
||||||
# Extract groups - this merely sets up the groups found in the input file
|
# Extract groups - this merely sets up the groups found in the input file
|
||||||
self.extract_groups()
|
self.extract_groups()
|
||||||
@@ -103,15 +107,15 @@ class Molecular_container:
|
|||||||
""" Identify the groups needed for pKa calculation """
|
""" Identify the groups needed for pKa calculation """
|
||||||
for name in self.conformation_names:
|
for name in self.conformation_names:
|
||||||
self.conformations[name].extract_groups()
|
self.conformations[name].extract_groups()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def additional_setup_when_reading_input_file(self):
|
def additional_setup_when_reading_input_file(self):
|
||||||
for name in self.conformation_names:
|
for name in self.conformation_names:
|
||||||
self.conformations[name].additional_setup_when_reading_input_file()
|
self.conformations[name].additional_setup_when_reading_input_file()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def calculate_pka(self):
|
def calculate_pka(self):
|
||||||
# calculate for each conformation
|
# calculate for each conformation
|
||||||
@@ -120,21 +124,21 @@ class Molecular_container:
|
|||||||
|
|
||||||
# find non-covalently coupled groups
|
# find non-covalently coupled groups
|
||||||
self.find_non_covalently_coupled_groups()
|
self.find_non_covalently_coupled_groups()
|
||||||
|
|
||||||
# find the average of the conformations
|
# find the average of the conformations
|
||||||
self.average_of_conformations()
|
self.average_of_conformations()
|
||||||
|
|
||||||
# print out the conformation-average results
|
# print out the conformation-average results
|
||||||
Source.output.printResult(self, 'AVR', self.version.parameters)
|
propka.output.printResult(self, 'AVR', self.version.parameters)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def average_of_conformations(self):
|
def average_of_conformations(self):
|
||||||
# make a new configuration to hold the average values
|
# make a new configuration to hold the average values
|
||||||
avr_conformation = Source.conformation_container.Conformation_container(name='average',
|
avr_conformation = propka.conformation_container.Conformation_container(name='average',
|
||||||
parameters=self.conformations[self.conformation_names[0]].parameters,
|
parameters=self.conformations[self.conformation_names[0]].parameters,
|
||||||
molecular_container=self)
|
molecular_container=self)
|
||||||
|
|
||||||
for group in self.conformations[self.conformation_names[0]].get_titratable_groups_and_cysteine_bridges():
|
for group in self.conformations[self.conformation_names[0]].get_titratable_groups_and_cysteine_bridges():
|
||||||
# new group to hold average values
|
# new group to hold average values
|
||||||
avr_group = group.clone()
|
avr_group = group.clone()
|
||||||
@@ -161,13 +165,13 @@ class Molecular_container:
|
|||||||
|
|
||||||
def write_pka(self, filename=None, reference="neutral", direction="folding", options=None):
|
def write_pka(self, filename=None, reference="neutral", direction="folding", options=None):
|
||||||
#for name in self.conformation_names:
|
#for name in self.conformation_names:
|
||||||
# Source.output.writePKA(self, self.version.parameters, filename='%s_3.1_%s.pka'%(self.name, name),
|
# propka.output.writePKA(self, self.version.parameters, filename='%s_3.1_%s.pka'%(self.name, name),
|
||||||
# conformation=name,reference=reference,
|
# conformation=name,reference=reference,
|
||||||
# direction=direction, options=options)
|
# direction=direction, options=options)
|
||||||
|
|
||||||
# write out the average conformation
|
# write out the average conformation
|
||||||
filename=os.path.join('%s.pka'%(self.name))
|
filename=os.path.join('%s.pka'%(self.name))
|
||||||
|
|
||||||
# if the display_coupled_residues option is true,
|
# if the display_coupled_residues option is true,
|
||||||
# write the results out to an alternative pka file
|
# write the results out to an alternative pka file
|
||||||
if self.options.display_coupled_residues:
|
if self.options.display_coupled_residues:
|
||||||
@@ -176,8 +180,8 @@ class Molecular_container:
|
|||||||
if hasattr(self.version.parameters, 'output_file_tag') and len(self.version.parameters.output_file_tag)>0:
|
if hasattr(self.version.parameters, 'output_file_tag') and len(self.version.parameters.output_file_tag)>0:
|
||||||
filename=os.path.join('%s_%s.pka'%(self.name,self.version.parameters.output_file_tag))
|
filename=os.path.join('%s_%s.pka'%(self.name,self.version.parameters.output_file_tag))
|
||||||
|
|
||||||
Source.output.writePKA(self, self.version.parameters, filename=filename,
|
propka.output.writePKA(self, self.version.parameters, filename=filename,
|
||||||
conformation='AVR',reference=reference,
|
conformation='AVR',reference=reference,
|
||||||
direction=direction, options=options)
|
direction=direction, options=options)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -185,7 +189,7 @@ class Molecular_container:
|
|||||||
def getFoldingProfile(self, conformation='AVR',reference="neutral", direction="folding", grid=[0., 14., 0.1], options=None):
|
def getFoldingProfile(self, conformation='AVR',reference="neutral", direction="folding", grid=[0., 14., 0.1], options=None):
|
||||||
# calculate stability profile
|
# calculate stability profile
|
||||||
profile = []
|
profile = []
|
||||||
for ph in Source.lib.make_grid(*grid):
|
for ph in propka.lib.make_grid(*grid):
|
||||||
ddg = self.conformations[conformation].calculate_folding_energy( pH=ph, reference=reference)
|
ddg = self.conformations[conformation].calculate_folding_energy( pH=ph, reference=reference)
|
||||||
#print(ph,ddg)
|
#print(ph,ddg)
|
||||||
profile.append([ph, ddg])
|
profile.append([ph, ddg])
|
||||||
@@ -196,29 +200,29 @@ class Molecular_container:
|
|||||||
opt = min(opt, point, key=lambda v:v[1])
|
opt = min(opt, point, key=lambda v:v[1])
|
||||||
|
|
||||||
# find values within 80 % of optimum
|
# find values within 80 % of optimum
|
||||||
range_80pct = [None, None]
|
range_80pct = [None, None]
|
||||||
values_within_80pct = [p[0] for p in profile if p[1]< 0.8*opt[1]]
|
values_within_80pct = [p[0] for p in profile if p[1]< 0.8*opt[1]]
|
||||||
if len(values_within_80pct)>0:
|
if len(values_within_80pct)>0:
|
||||||
range_80pct = [min(values_within_80pct), max(values_within_80pct)]
|
range_80pct = [min(values_within_80pct), max(values_within_80pct)]
|
||||||
|
|
||||||
# find stability range
|
# find stability range
|
||||||
stability_range = [None, None]
|
stability_range = [None, None]
|
||||||
stable_values = [p[0] for p in profile if p[1]< 0.0]
|
stable_values = [p[0] for p in profile if p[1]< 0.0]
|
||||||
|
|
||||||
if len(stable_values)>0:
|
if len(stable_values)>0:
|
||||||
stability_range = [min(stable_values), max(stable_values)]
|
stability_range = [min(stable_values), max(stable_values)]
|
||||||
|
|
||||||
return profile, opt, range_80pct, stability_range
|
return profile, opt, range_80pct, stability_range
|
||||||
|
|
||||||
|
|
||||||
def getChargeProfile(self, conformation='AVR', grid=[0., 14., .1]):
|
def getChargeProfile(self, conformation='AVR', grid=[0., 14., .1]):
|
||||||
charge_profile = []
|
charge_profile = []
|
||||||
for ph in Source.lib.make_grid(*grid):
|
for ph in propka.lib.make_grid(*grid):
|
||||||
q_unfolded, q_folded = self.conformations[conformation].calculate_charge(self.version.parameters, pH=ph)
|
q_unfolded, q_folded = self.conformations[conformation].calculate_charge(self.version.parameters, pH=ph)
|
||||||
charge_profile.append([ph, q_unfolded, q_folded])
|
charge_profile.append([ph, q_unfolded, q_folded])
|
||||||
|
|
||||||
return charge_profile
|
return charge_profile
|
||||||
|
|
||||||
def getPI(self, conformation='AVR', grid=[0., 14., 1], iteration=0):
|
def getPI(self, conformation='AVR', grid=[0., 14., 1], iteration=0):
|
||||||
#print('staring',grid, iteration)
|
#print('staring',grid, iteration)
|
||||||
# search
|
# search
|
||||||
@@ -240,7 +244,7 @@ class Molecular_container:
|
|||||||
|
|
||||||
return pi_folded_value, pi_unfolded_value
|
return pi_folded_value, pi_unfolded_value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
input_file = sys.argv[1]
|
input_file = sys.argv[1]
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import Source.lib
|
|
||||||
|
import propka.lib
|
||||||
|
|
||||||
|
|
||||||
def printHeader():
|
def printHeader():
|
||||||
@@ -17,7 +22,7 @@ def writePDB(protein, file=None, filename=None, include_hydrogens=False, options
|
|||||||
"""
|
"""
|
||||||
Write the residue to the new pdbfile
|
Write the residue to the new pdbfile
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if file == None:
|
if file == None:
|
||||||
# opening file if not given
|
# opening file if not given
|
||||||
if filename == None:
|
if filename == None:
|
||||||
@@ -124,7 +129,7 @@ def getDeterminantSection(protein, conformation, parameters):
|
|||||||
# printing determinants
|
# printing determinants
|
||||||
for chain in protein.conformations[conformation].chains:
|
for chain in protein.conformations[conformation].chains:
|
||||||
for residue_type in parameters.write_out_order:
|
for residue_type in parameters.write_out_order:
|
||||||
groups = [g for g in protein.conformations[conformation].groups if g.atom.chainID == chain]
|
groups = [g for g in protein.conformations[conformation].groups if g.atom.chainID == chain]
|
||||||
for group in groups:
|
for group in groups:
|
||||||
if group.residue_type == residue_type:
|
if group.residue_type == residue_type:
|
||||||
str += "%s" % ( group.getDeterminantString(parameters.remove_penalised_group) )
|
str += "%s" % ( group.getDeterminantString(parameters.remove_penalised_group) )
|
||||||
@@ -158,8 +163,8 @@ def getFoldingProfileSection(protein, conformation='AVR', direction="folding", r
|
|||||||
str += "\n"
|
str += "\n"
|
||||||
str += "Free energy of %9s (kcal/mol) as a function of pH (using %s reference)\n" % (direction, reference)
|
str += "Free energy of %9s (kcal/mol) as a function of pH (using %s reference)\n" % (direction, reference)
|
||||||
|
|
||||||
profile, [pH_opt, dG_opt], [dG_min, dG_max], [pH_min, pH_max] = protein.getFoldingProfile(conformation=conformation,
|
profile, [pH_opt, dG_opt], [dG_min, dG_max], [pH_min, pH_max] = protein.getFoldingProfile(conformation=conformation,
|
||||||
reference=reference,
|
reference=reference,
|
||||||
direction=direction, grid=[0., 14., 0.1], options=options)
|
direction=direction, grid=[0., 14., 0.1], options=options)
|
||||||
if profile == None:
|
if profile == None:
|
||||||
str += "Could not determine folding profile\n"
|
str += "Could not determine folding profile\n"
|
||||||
@@ -183,7 +188,7 @@ def getFoldingProfileSection(protein, conformation='AVR', direction="folding", r
|
|||||||
str += "Could not determine the pH-range where the free energy is negative\n\n"
|
str += "Could not determine the pH-range where the free energy is negative\n\n"
|
||||||
else:
|
else:
|
||||||
str += "The free energy is negative in the range %4.1lf - %4.1lf\n\n" % (pH_min, pH_max)
|
str += "The free energy is negative in the range %4.1lf - %4.1lf\n\n" % (pH_min, pH_max)
|
||||||
|
|
||||||
|
|
||||||
return str
|
return str
|
||||||
|
|
||||||
@@ -209,7 +214,7 @@ def getChargeProfileSection(protein, conformation='AVR', options=None):
|
|||||||
str += "Could not determine the pI\n\n"
|
str += "Could not determine the pI\n\n"
|
||||||
else:
|
else:
|
||||||
str += "The pI is %5.2lf (folded) and %5.2lf (unfolded)\n" % (pI_pro, pI_mod)
|
str += "The pI is %5.2lf (folded) and %5.2lf (unfolded)\n" % (pI_pro, pI_mod)
|
||||||
|
|
||||||
|
|
||||||
return str
|
return str
|
||||||
|
|
||||||
@@ -300,8 +305,8 @@ def getReferencesHeader():
|
|||||||
str += " Journal of Chemical Theory and Computation, 7(2):525-537 (2011)\n"
|
str += " Journal of Chemical Theory and Computation, 7(2):525-537 (2011)\n"
|
||||||
str += " \n"
|
str += " \n"
|
||||||
str += " Improved Treatment of Ligands and Coupling Effects in Empirical Calculation\n"
|
str += " Improved Treatment of Ligands and Coupling Effects in Empirical Calculation\n"
|
||||||
str += " and Rationalization of pKa Values\n"
|
str += " and Rationalization of pKa Values\n"
|
||||||
str += " Chresten R. Sondergaard, Mats H.M. Olsson, Michal Rostkowski, and Jan H. Jensen\n"
|
str += " Chresten R. Sondergaard, Mats H.M. Olsson, Michal Rostkowski, and Jan H. Jensen\n"
|
||||||
str += " Journal of Chemical Theory and Computation, (2011)\n"
|
str += " Journal of Chemical Theory and Computation, (2011)\n"
|
||||||
str += " \n"
|
str += " \n"
|
||||||
str += "-------------------------------------------------------------------------------------------------------\n"
|
str += "-------------------------------------------------------------------------------------------------------\n"
|
||||||
@@ -357,13 +362,13 @@ def getTheLine():
|
|||||||
|
|
||||||
# Interaction maps
|
# Interaction maps
|
||||||
def make_interaction_map(name, list, interaction):
|
def make_interaction_map(name, list, interaction):
|
||||||
""" Print out an interaction map named 'name' of the groups in 'list'
|
""" Print out an interaction map named 'name' of the groups in 'list'
|
||||||
based on the function 'interaction' """
|
based on the function 'interaction' """
|
||||||
|
|
||||||
# return an empty string, if the list is empty
|
# return an empty string, if the list is empty
|
||||||
if len(list)==0:
|
if len(list)==0:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
# for long list, use condensed formatting
|
# for long list, use condensed formatting
|
||||||
if len(list)>10:
|
if len(list)>10:
|
||||||
res = 'Condensed form:\n'
|
res = 'Condensed form:\n'
|
||||||
@@ -377,7 +382,7 @@ def make_interaction_map(name, list, interaction):
|
|||||||
res = '%s\n%12s'%(name,'')
|
res = '%s\n%12s'%(name,'')
|
||||||
for g in list:
|
for g in list:
|
||||||
res += '%9s | '%g.label
|
res += '%9s | '%g.label
|
||||||
|
|
||||||
# do the map
|
# do the map
|
||||||
for g1 in list:
|
for g1 in list:
|
||||||
res += '\n%-12s'%(g1.label)
|
res += '\n%-12s'%(g1.label)
|
||||||
@@ -386,6 +391,6 @@ def make_interaction_map(name, list, interaction):
|
|||||||
if interaction(g1, g2):
|
if interaction(g1, g2):
|
||||||
tag = ' X '
|
tag = ' X '
|
||||||
res += '%10s| '%tag
|
res += '%10s| '%tag
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import Source.lib as lib
|
import propka.lib as lib
|
||||||
import sys, os
|
import sys, os
|
||||||
|
|
||||||
|
import pkg_resources
|
||||||
|
|
||||||
# names and types of all key words in configuration file
|
# names and types of all key words in configuration file
|
||||||
matrices = ['interaction_matrix']
|
matrices = ['interaction_matrix']
|
||||||
@@ -45,16 +50,15 @@ class Parameters:
|
|||||||
#self.print_interaction_parameters_latex()
|
#self.print_interaction_parameters_latex()
|
||||||
#####self.print_interactions_latex()
|
#####self.print_interactions_latex()
|
||||||
#sys.exit(0)
|
#sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def read_parameters(self, file):
|
def read_parameters(self, file):
|
||||||
# try to locate the parameters file
|
# try to locate the parameters file
|
||||||
try:
|
try:
|
||||||
path = os.path.dirname(__file__)
|
ifile = pkg_resources.resource_filename(__name__, file)
|
||||||
ifile = os.path.join(path,'../'+file)
|
|
||||||
input = lib.open_file_for_reading(ifile)
|
input = lib.open_file_for_reading(ifile)
|
||||||
except:
|
except:
|
||||||
input = lib.open_file_for_reading(file)
|
input = lib.open_file_for_reading(file)
|
||||||
@@ -94,7 +98,7 @@ class Parameters:
|
|||||||
elif len(words)==3 and words[0] in string_dictionaries:
|
elif len(words)==3 and words[0] in string_dictionaries:
|
||||||
self.parse_to_string_dictionary(words)
|
self.parse_to_string_dictionary(words)
|
||||||
|
|
||||||
|
|
||||||
#print(words)
|
#print(words)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -226,25 +230,25 @@ class Parameters:
|
|||||||
print("""
|
print("""
|
||||||
Titratable:
|
Titratable:
|
||||||
CG ARG
|
CG ARG
|
||||||
C2N ARG
|
C2N ARG
|
||||||
N30 N+/LYS
|
N30 N+/LYS
|
||||||
N31 N+/LYS
|
N31 N+/LYS
|
||||||
N32 N+/LYS
|
N32 N+/LYS
|
||||||
N33 N+/LYS
|
N33 N+/LYS
|
||||||
NAR HIS
|
NAR HIS
|
||||||
OCO COO
|
OCO COO
|
||||||
OP TYR/SER?
|
OP TYR/SER?
|
||||||
SH CYS
|
SH CYS
|
||||||
|
|
||||||
Non-titratable:
|
Non-titratable:
|
||||||
NP1 AMD?
|
NP1 AMD?
|
||||||
OH ROH
|
OH ROH
|
||||||
O3 ?
|
O3 ?
|
||||||
CL
|
CL
|
||||||
F
|
F
|
||||||
NAM
|
NAM
|
||||||
N1
|
N1
|
||||||
O2
|
O2
|
||||||
""")
|
""")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -283,7 +287,7 @@ O2
|
|||||||
'N1' :[],
|
'N1' :[],
|
||||||
'O2' :[]}
|
'O2' :[]}
|
||||||
|
|
||||||
|
|
||||||
s = """
|
s = """
|
||||||
\\begin{longtable}{lllll}
|
\\begin{longtable}{lllll}
|
||||||
\\caption{Ligand interaction parameters. For interactions not listed, the default value of %s is applied.}
|
\\caption{Ligand interaction parameters. For interactions not listed, the default value of %s is applied.}
|
||||||
@@ -296,11 +300,11 @@ Group1 & Group2 & Interaction & c1 &c2 \\\\
|
|||||||
|
|
||||||
\\multicolumn{5}{l}{\\emph{continued from the previous page}}\\\\
|
\\multicolumn{5}{l}{\\emph{continued from the previous page}}\\\\
|
||||||
\\toprule
|
\\toprule
|
||||||
Group1 & Group2 & Interaction & c1 &c2 \\\\
|
Group1 & Group2 & Interaction & c1 &c2 \\\\
|
||||||
\\midrule
|
\\midrule
|
||||||
\\endhead
|
\\endhead
|
||||||
|
|
||||||
\\midrule
|
\\midrule
|
||||||
\\multicolumn{5}{r}{\\emph{continued on the next page}}\\\\
|
\\multicolumn{5}{r}{\\emph{continued on the next page}}\\\\
|
||||||
\\endfoot
|
\\endfoot
|
||||||
|
|
||||||
@@ -332,7 +336,7 @@ Group1 & Group2 & Interaction & c1 &c2 \\\\
|
|||||||
agroups = ['COO', 'HIS', 'CYS', 'TYR', 'SER', 'N+', 'LYS', 'AMD', 'ARG', 'TRP', 'ROH', 'CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
|
agroups = ['COO', 'HIS', 'CYS', 'TYR', 'SER', 'N+', 'LYS', 'AMD', 'ARG', 'TRP', 'ROH', 'CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
|
||||||
lgroups = ['CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
|
lgroups = ['CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
|
||||||
|
|
||||||
|
|
||||||
s = """
|
s = """
|
||||||
\\begin{longtable}{%s}
|
\\begin{longtable}{%s}
|
||||||
\\caption{Ligand interaction parameters. For interactions not listed, the default value of %s is applied.}
|
\\caption{Ligand interaction parameters. For interactions not listed, the default value of %s is applied.}
|
||||||
@@ -345,11 +349,11 @@ Group1 & Group2 & Interaction & c1 &c2 \\\\
|
|||||||
|
|
||||||
\\multicolumn{5}{l}{\\emph{continued from the previous page}}\\\\
|
\\multicolumn{5}{l}{\\emph{continued from the previous page}}\\\\
|
||||||
\\toprule
|
\\toprule
|
||||||
Group1 & Group2 & Interaction & c1 &c2 \\\\
|
Group1 & Group2 & Interaction & c1 &c2 \\\\
|
||||||
\\midrule
|
\\midrule
|
||||||
\\endhead
|
\\endhead
|
||||||
|
|
||||||
\\midrule
|
\\midrule
|
||||||
\\multicolumn{5}{r}{\\emph{continued on the next page}}\\\\
|
\\multicolumn{5}{r}{\\emph{continued on the next page}}\\\\
|
||||||
\\endfoot
|
\\endfoot
|
||||||
|
|
||||||
@@ -399,14 +403,14 @@ class Interaction_matrix:
|
|||||||
self.dictionary[group][new_group] = self.value
|
self.dictionary[group][new_group] = self.value
|
||||||
self.dictionary[new_group][group] = self.value
|
self.dictionary[new_group][group] = self.value
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_value(self, item1, item2):
|
def get_value(self, item1, item2):
|
||||||
try:
|
try:
|
||||||
return self.dictionary[item1][item2]
|
return self.dictionary[item1][item2]
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __getitem__(self, group):
|
def __getitem__(self, group):
|
||||||
if group not in self.dictionary.keys():
|
if group not in self.dictionary.keys():
|
||||||
@@ -430,7 +434,7 @@ class Interaction_matrix:
|
|||||||
|
|
||||||
return s
|
return s
|
||||||
# ks = ['COO', 'SER', 'ARG', 'LYS', 'HIS', 'AMD', 'CYS', 'TRP','ROH','TYR','N+','CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
|
# ks = ['COO', 'SER', 'ARG', 'LYS', 'HIS', 'AMD', 'CYS', 'TRP','ROH','TYR','N+','CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
|
||||||
|
|
||||||
# p = ''
|
# p = ''
|
||||||
# n=0
|
# n=0
|
||||||
# for i in range(len(ks)):
|
# for i in range(len(ks)):
|
||||||
@@ -442,7 +446,7 @@ class Interaction_matrix:
|
|||||||
|
|
||||||
# print('total',n,len(ks))
|
# print('total',n,len(ks))
|
||||||
# return p
|
# return p
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Pair_wise_matrix:
|
class Pair_wise_matrix:
|
||||||
@@ -451,7 +455,7 @@ class Pair_wise_matrix:
|
|||||||
self.dictionary = {}
|
self.dictionary = {}
|
||||||
self.default = [0.0, 0.0]
|
self.default = [0.0, 0.0]
|
||||||
return
|
return
|
||||||
|
|
||||||
def add(self,words):
|
def add(self,words):
|
||||||
# assign the default value
|
# assign the default value
|
||||||
if len(words)==3 and words[0]=='default':
|
if len(words)==3 and words[0]=='default':
|
||||||
@@ -462,7 +466,7 @@ class Pair_wise_matrix:
|
|||||||
g1 = words[0]
|
g1 = words[0]
|
||||||
g2 = words[1]
|
g2 = words[1]
|
||||||
v = [float(words[2]), float(words[3])]
|
v = [float(words[2]), float(words[3])]
|
||||||
|
|
||||||
self.insert(g1,g2,v)
|
self.insert(g1,g2,v)
|
||||||
self.insert(g2,g1,v)
|
self.insert(g2,g1,v)
|
||||||
|
|
||||||
@@ -482,7 +486,7 @@ class Pair_wise_matrix:
|
|||||||
return
|
return
|
||||||
|
|
||||||
def get_value(self, item1, item2):
|
def get_value(self, item1, item2):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return self.dictionary[item1][item2]
|
return self.dictionary[item1][item2]
|
||||||
except:
|
except:
|
||||||
@@ -504,7 +508,7 @@ class Pair_wise_matrix:
|
|||||||
s += '%s %s %s\n'%(k1,k2,self[k1][k2])
|
s += '%s %s %s\n'%(k1,k2,self[k1][k2])
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
import string, sys, copy, Source.lib
|
|
||||||
from Source.atom import Atom
|
from __future__ import division
|
||||||
from Source.conformation_container import Conformation_container
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import string, sys, copy
|
||||||
|
|
||||||
|
import propka.lib
|
||||||
|
from propka.atom import Atom
|
||||||
|
from propka.conformation_container import Conformation_container
|
||||||
|
|
||||||
expected_atom_numbers = {'ALA':5,
|
expected_atom_numbers = {'ALA':5,
|
||||||
'ARG':11,
|
'ARG':11,
|
||||||
@@ -35,23 +41,23 @@ def read_pdb(pdb_file, parameters, molecule):
|
|||||||
conformations[name].add_atom(atom)
|
conformations[name].add_atom(atom)
|
||||||
|
|
||||||
# make a sorted list of conformation names
|
# make a sorted list of conformation names
|
||||||
names = sorted(conformations.keys(), key=Source.lib.conformation_sorter)
|
names = sorted(conformations.keys(), key=propka.lib.conformation_sorter)
|
||||||
|
|
||||||
return [conformations, names]
|
return [conformations, names]
|
||||||
|
|
||||||
def protein_precheck(conformations, names):
|
def protein_precheck(conformations, names):
|
||||||
|
|
||||||
for name in names:
|
for name in names:
|
||||||
atoms = conformations[name].atoms
|
atoms = conformations[name].atoms
|
||||||
|
|
||||||
res_ids = []
|
res_ids = []
|
||||||
[res_ids.append(resid_from_atom(a)) for a in atoms if not res_ids.count(resid_from_atom(a))]
|
[res_ids.append(resid_from_atom(a)) for a in atoms if not res_ids.count(resid_from_atom(a))]
|
||||||
|
|
||||||
for res_id in res_ids:
|
for res_id in res_ids:
|
||||||
res_atoms = [a for a in atoms if resid_from_atom(a) == res_id and a.element != 'H']
|
res_atoms = [a for a in atoms if resid_from_atom(a) == res_id and a.element != 'H']
|
||||||
resname = res_atoms[0].resName
|
resname = res_atoms[0].resName
|
||||||
residue_label = '%3s%5s'%(resname, res_id)
|
residue_label = '%3s%5s'%(resname, res_id)
|
||||||
|
|
||||||
# ignore ligand residues
|
# ignore ligand residues
|
||||||
if resname not in expected_atom_numbers:
|
if resname not in expected_atom_numbers:
|
||||||
continue
|
continue
|
||||||
@@ -65,7 +71,7 @@ def protein_precheck(conformations, names):
|
|||||||
# check number of atoms in residue
|
# check number of atoms in residue
|
||||||
if len(res_atoms) != expected_atom_numbers[resname]:
|
if len(res_atoms) != expected_atom_numbers[resname]:
|
||||||
print('Warning: Unexpected number (%d) of atoms in residue %s in conformation %s'%(len(res_atoms),residue_label, name))
|
print('Warning: Unexpected number (%d) of atoms in residue %s in conformation %s'%(len(res_atoms),residue_label, name))
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def resid_from_atom(a):
|
def resid_from_atom(a):
|
||||||
@@ -74,7 +80,7 @@ def resid_from_atom(a):
|
|||||||
|
|
||||||
def get_atom_lines_from_pdb(pdb_file, ignore_residues = [], keep_protons=False, tags = ['ATOM ', 'HETATM'], chains=None):
|
def get_atom_lines_from_pdb(pdb_file, ignore_residues = [], keep_protons=False, tags = ['ATOM ', 'HETATM'], chains=None):
|
||||||
|
|
||||||
lines = Source.lib.open_file_for_reading(pdb_file).readlines()
|
lines = propka.lib.open_file_for_reading(pdb_file).readlines()
|
||||||
nterm_residue = 'next_residue'
|
nterm_residue = 'next_residue'
|
||||||
old_residue = None
|
old_residue = None
|
||||||
terminal = None
|
terminal = None
|
||||||
@@ -88,7 +94,7 @@ def get_atom_lines_from_pdb(pdb_file, ignore_residues = [], keep_protons=False,
|
|||||||
if tag == 'MODEL ':
|
if tag == 'MODEL ':
|
||||||
model = int(line[6:])
|
model = int(line[6:])
|
||||||
nterm_residue = 'next_residue'
|
nterm_residue = 'next_residue'
|
||||||
|
|
||||||
if tag == 'TER ':
|
if tag == 'TER ':
|
||||||
nterm_residue = 'next_residue'
|
nterm_residue = 'next_residue'
|
||||||
|
|
||||||
@@ -102,21 +108,21 @@ def get_atom_lines_from_pdb(pdb_file, ignore_residues = [], keep_protons=False,
|
|||||||
continue
|
continue
|
||||||
if chains and line[21] not in chains:
|
if chains and line[21] not in chains:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# set the Nterm residue number - nessecary because we may need to
|
# set the Nterm residue number - nessecary because we may need to
|
||||||
# identify more than one N+ group for structures with alt_conf tags
|
# identify more than one N+ group for structures with alt_conf tags
|
||||||
if nterm_residue == 'next_residue' and tag == 'ATOM ':
|
if nterm_residue == 'next_residue' and tag == 'ATOM ':
|
||||||
# make sure that we reached a new residue - nessecary if OXT is not the last atom in
|
# make sure that we reached a new residue - nessecary if OXT is not the last atom in
|
||||||
# the previous residue
|
# the previous residue
|
||||||
if old_residue != residue_number:
|
if old_residue != residue_number:
|
||||||
nterm_residue = residue_number
|
nterm_residue = residue_number
|
||||||
old_residue = None
|
old_residue = None
|
||||||
|
|
||||||
|
|
||||||
# Identify the configuration
|
# Identify the configuration
|
||||||
# convert digits to letters
|
# convert digits to letters
|
||||||
if alt_conf_tag in '123456789':
|
if alt_conf_tag in '123456789':
|
||||||
alt_conf_tag = chr(ord(alt_conf_tag)+16)
|
alt_conf_tag = chr(ord(alt_conf_tag)+16)
|
||||||
if alt_conf_tag == ' ':
|
if alt_conf_tag == ' ':
|
||||||
alt_conf_tag = 'A'
|
alt_conf_tag = 'A'
|
||||||
conformation = '%d%s'%(model, alt_conf_tag)
|
conformation = '%d%s'%(model, alt_conf_tag)
|
||||||
@@ -145,10 +151,10 @@ def get_atom_lines_from_pdb(pdb_file, ignore_residues = [], keep_protons=False,
|
|||||||
def write_pdb(conformation, filename):
|
def write_pdb(conformation, filename):
|
||||||
write_pdb_for_atoms(conformation.atoms, filename)
|
write_pdb_for_atoms(conformation.atoms, filename)
|
||||||
return
|
return
|
||||||
|
|
||||||
def write_pdb_for_atoms(atoms, filename, make_conect_section=False):
|
def write_pdb_for_atoms(atoms, filename, make_conect_section=False):
|
||||||
out = Source.lib.open_file_for_writing(filename)
|
out = propka.lib.open_file_for_writing(filename)
|
||||||
|
|
||||||
for atom in atoms:
|
for atom in atoms:
|
||||||
out.write(atom.make_pdb_line())
|
out.write(atom.make_pdb_line())
|
||||||
|
|
||||||
@@ -171,7 +177,7 @@ def write_mol2_for_atoms(atoms, filename):
|
|||||||
for i in range(len(atoms)):
|
for i in range(len(atoms)):
|
||||||
atoms_section += atoms[i].make_mol2_line(i+1)
|
atoms_section += atoms[i].make_mol2_line(i+1)
|
||||||
|
|
||||||
|
|
||||||
bonds_section = '@<TRIPOS>BOND\n'
|
bonds_section = '@<TRIPOS>BOND\n'
|
||||||
id = 1
|
id = 1
|
||||||
for i in range(len(atoms)):
|
for i in range(len(atoms)):
|
||||||
@@ -180,12 +186,12 @@ def write_mol2_for_atoms(atoms, filename):
|
|||||||
type = get_bond_order(atoms[i],atoms[j])
|
type = get_bond_order(atoms[i],atoms[j])
|
||||||
bonds_section += '%7d %7d %7d %7s\n'%(id, i+1, j+1, type)
|
bonds_section += '%7d %7d %7d %7s\n'%(id, i+1, j+1, type)
|
||||||
id+=1
|
id+=1
|
||||||
|
|
||||||
substructure_section = '@<TRIPOS>SUBSTRUCTURE\n\n'
|
substructure_section = '@<TRIPOS>SUBSTRUCTURE\n\n'
|
||||||
if len(atoms)>0:
|
if len(atoms)>0:
|
||||||
substructure_section = '@<TRIPOS>SUBSTRUCTURE\n%-7d %10s %7d\n'%(atoms[0].resNumb,atoms[0].resName,atoms[0].numb)
|
substructure_section = '@<TRIPOS>SUBSTRUCTURE\n%-7d %10s %7d\n'%(atoms[0].resNumb,atoms[0].resName,atoms[0].numb)
|
||||||
|
|
||||||
out = Source.lib.open_file_for_writing(filename)
|
out = propka.lib.open_file_for_writing(filename)
|
||||||
out.write(header%(len(atoms),id-1))
|
out.write(header%(len(atoms),id-1))
|
||||||
out.write(atoms_section)
|
out.write(atoms_section)
|
||||||
out.write(bonds_section)
|
out.write(bonds_section)
|
||||||
@@ -209,14 +215,14 @@ def get_bond_order(atom1, atom2):
|
|||||||
|
|
||||||
if '.ar' in atom1.sybyl_type and '.ar' in atom2.sybyl_type:
|
if '.ar' in atom1.sybyl_type and '.ar' in atom2.sybyl_type:
|
||||||
type = 'ar'
|
type = 'ar'
|
||||||
|
|
||||||
|
|
||||||
return type
|
return type
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def write_input(molecular_container, filename):
|
def write_input(molecular_container, filename):
|
||||||
out = Source.lib.open_file_for_writing(filename)
|
out = propka.lib.open_file_for_writing(filename)
|
||||||
|
|
||||||
for conformation_name in molecular_container.conformation_names:
|
for conformation_name in molecular_container.conformation_names:
|
||||||
out.write('MODEL %s\n'%conformation_name)
|
out.write('MODEL %s\n'%conformation_name)
|
||||||
@@ -250,14 +256,14 @@ def read_input(input_file, parameters,molecule):
|
|||||||
conformations[name].add_atom(atom)
|
conformations[name].add_atom(atom)
|
||||||
|
|
||||||
# make a sorted list of conformation names
|
# make a sorted list of conformation names
|
||||||
names = sorted(conformations.keys(), key=Source.lib.conformation_sorter)
|
names = sorted(conformations.keys(), key=propka.lib.conformation_sorter)
|
||||||
|
|
||||||
return [conformations, names]
|
return [conformations, names]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_atom_lines_from_input(input_file, tags = ['ATOM ','HETATM']):
|
def get_atom_lines_from_input(input_file, tags = ['ATOM ','HETATM']):
|
||||||
lines = Source.lib.open_file_for_reading(input_file).readlines()
|
lines = propka.lib.open_file_for_reading(input_file).readlines()
|
||||||
conformation = ''
|
conformation = ''
|
||||||
|
|
||||||
atoms = {}
|
atoms = {}
|
||||||
@@ -278,7 +284,7 @@ def get_atom_lines_from_input(input_file, tags = ['ATOM ','HETATM']):
|
|||||||
atom.is_protonated = True
|
atom.is_protonated = True
|
||||||
atoms[atom.numb] = atom
|
atoms[atom.numb] = atom
|
||||||
numbers.append(atom.numb)
|
numbers.append(atom.numb)
|
||||||
|
|
||||||
# found bonding information - apply it
|
# found bonding information - apply it
|
||||||
if tag == 'CONECT' and len(line)>14:
|
if tag == 'CONECT' and len(line)>14:
|
||||||
conect_numbers = [line[i:i+5] for i in range(6, len(line)-1, 5)]
|
conect_numbers = [line[i:i+5] for i in range(6, len(line)-1, 5)]
|
||||||
@@ -301,7 +307,7 @@ def get_atom_lines_from_input(input_file, tags = ['ATOM ','HETATM']):
|
|||||||
center_atom = atoms[int(conect_numbers[0])]
|
center_atom = atoms[int(conect_numbers[0])]
|
||||||
for n in conect_numbers[1:]:
|
for n in conect_numbers[1:]:
|
||||||
cg = atoms[int(n)]
|
cg = atoms[int(n)]
|
||||||
center_atom.group.couple_covalently(cg.group)
|
center_atom.group.couple_covalently(cg.group)
|
||||||
|
|
||||||
# found info on non-covalent coupling
|
# found info on non-covalent coupling
|
||||||
if tag == 'NCOUPL' and len(line)>14:
|
if tag == 'NCOUPL' and len(line)>14:
|
||||||
@@ -309,8 +315,8 @@ def get_atom_lines_from_input(input_file, tags = ['ATOM ','HETATM']):
|
|||||||
center_atom = atoms[int(conect_numbers[0])]
|
center_atom = atoms[int(conect_numbers[0])]
|
||||||
for n in conect_numbers[1:]:
|
for n in conect_numbers[1:]:
|
||||||
cg = atoms[int(n)]
|
cg = atoms[int(n)]
|
||||||
center_atom.group.couple_non_covalently(cg.group)
|
center_atom.group.couple_non_covalently(cg.group)
|
||||||
|
|
||||||
# this conformation is done - yield the atoms
|
# this conformation is done - yield the atoms
|
||||||
if tag == 'ENDMDL':
|
if tag == 'ENDMDL':
|
||||||
for n in numbers:
|
for n in numbers:
|
||||||
398
propka/propka.cfg
Normal file
398
propka/propka.cfg
Normal file
@@ -0,0 +1,398 @@
|
|||||||
|
# PropKa configuration file
|
||||||
|
|
||||||
|
version version_A
|
||||||
|
|
||||||
|
# Model pKa values
|
||||||
|
model_pkas C- 3.20
|
||||||
|
model_pkas ASP 3.80
|
||||||
|
model_pkas GLU 4.50
|
||||||
|
model_pkas HIS 6.50
|
||||||
|
model_pkas CYS 9.00
|
||||||
|
model_pkas TYR 10.00
|
||||||
|
model_pkas LYS 10.50
|
||||||
|
model_pkas ARG 12.50
|
||||||
|
#model_pkas SER 14.20 Jack Kyte: Structure in Protein Chemistry, 1995, Garland Publishing, Inc New York and London
|
||||||
|
model_pkas N+ 8.00
|
||||||
|
model_pkas CG 11.50
|
||||||
|
model_pkas C2N 11.50
|
||||||
|
model_pkas N30 10.00
|
||||||
|
model_pkas N31 10.00
|
||||||
|
model_pkas N32 10.00
|
||||||
|
model_pkas N33 10.00
|
||||||
|
model_pkas NAR 5.00
|
||||||
|
model_pkas OCO 4.50
|
||||||
|
model_pkas SH 10.00
|
||||||
|
model_pkas OP 6.00
|
||||||
|
|
||||||
|
# Custom ligand pKa values
|
||||||
|
# P. Acharya, P. Cheruku, S. Chatterjee, S. Acharya, and, J. Chattopadhyaya:
|
||||||
|
# Measurement of Nucleobase pKa Values in Model Mononucleotides
|
||||||
|
# Shows RNA-RNA Duplexes To Be More Stable than DNA-DNA Duplexes
|
||||||
|
# Journal of the American Chemical Society 2004 126 (9), 2862-2869
|
||||||
|
#
|
||||||
|
custom_model_pkas DA-N1 3.82
|
||||||
|
custom_model_pkas DA-N3 3.82
|
||||||
|
custom_model_pkas DA-N7 3.82
|
||||||
|
custom_model_pkas DA-OP1 1.00
|
||||||
|
custom_model_pkas DA-OP2 1.00
|
||||||
|
|
||||||
|
custom_model_pkas DG-N1 9.59
|
||||||
|
custom_model_pkas DG-N3 9.59
|
||||||
|
custom_model_pkas DG-N7 9.59
|
||||||
|
custom_model_pkas DG-OP1 1.00
|
||||||
|
custom_model_pkas DG-OP2 1.00
|
||||||
|
|
||||||
|
custom_model_pkas DC-N3 4.34
|
||||||
|
custom_model_pkas DC-OP1 1.00
|
||||||
|
custom_model_pkas DC-OP2 1.00
|
||||||
|
|
||||||
|
custom_model_pkas DT-N3 10.12
|
||||||
|
custom_model_pkas DT-OP1 1.00
|
||||||
|
custom_model_pkas DT-OP2 1.00
|
||||||
|
|
||||||
|
|
||||||
|
# protein group mapping
|
||||||
|
protein_group_mapping ASP-CG COO
|
||||||
|
protein_group_mapping GLU-CD COO
|
||||||
|
protein_group_mapping HIS-CG HIS
|
||||||
|
protein_group_mapping CYS-SG CYS
|
||||||
|
protein_group_mapping TYR-OH TYR
|
||||||
|
protein_group_mapping LYS-NZ LYS
|
||||||
|
protein_group_mapping ARG-CZ ARG
|
||||||
|
#protein_group_mapping SER-OG SER
|
||||||
|
protein_group_mapping THR-OG1 ROH
|
||||||
|
protein_group_mapping SER-OG ROH#
|
||||||
|
protein_group_mapping ASN-CG AMD
|
||||||
|
protein_group_mapping GLN-CD AMD
|
||||||
|
protein_group_mapping TRP-NE1 TRP
|
||||||
|
|
||||||
|
|
||||||
|
# matrix for propka interactions
|
||||||
|
# 'N' non-iterative interaction
|
||||||
|
# 'I' iterative interaction
|
||||||
|
# '-' no interaction
|
||||||
|
#CYS
|
||||||
|
interaction_matrix CYS I#N+
|
||||||
|
interaction_matrix N+ N I#HIS
|
||||||
|
interaction_matrix HIS I N I#LYS
|
||||||
|
interaction_matrix LYS N N N I#AMD
|
||||||
|
interaction_matrix AMD N - N - -#COO
|
||||||
|
interaction_matrix COO I N I N N I#ARG
|
||||||
|
interaction_matrix ARG N N N N - N I#TRP
|
||||||
|
interaction_matrix TRP N - - - - N - -#ROH
|
||||||
|
interaction_matrix ROH N - - - - N - - -#TYR
|
||||||
|
interaction_matrix TYR N I I I N N N N N I#SER
|
||||||
|
interaction_matrix SER N N N N N N I N N N I #CG
|
||||||
|
interaction_matrix CG N N N N - N I - - N I I#C2N
|
||||||
|
interaction_matrix C2N N N N N - N I - - N I I I#N30
|
||||||
|
interaction_matrix N30 N I N N - N N - - I N I I I#N31
|
||||||
|
interaction_matrix N31 N I N N - N N - - I N I I I I#N32
|
||||||
|
interaction_matrix N32 N I N N - N N - - I N I I I I I#N33
|
||||||
|
interaction_matrix N33 N I N N - N N - - I N I I I I I I#NAR
|
||||||
|
interaction_matrix NAR I N I I N I N - - I N N N N N N N I#OCO
|
||||||
|
interaction_matrix OCO I N I N N I N N N N N N N N N N N I I#NP1
|
||||||
|
interaction_matrix NP1 N - N - - N - - - N N - - - - - - N N -#OH
|
||||||
|
interaction_matrix OH N - - - - N - - - N N - - - - - - - N - -#O3
|
||||||
|
interaction_matrix O3 N - N - - N - - - N N - - - - - - N N - - -#CL
|
||||||
|
interaction_matrix CL N - N - - N - - - N N - - - - - - N N - - - -#F
|
||||||
|
interaction_matrix F N - N - - N - - - N N - - - - - - N N - - - - -#NAM
|
||||||
|
interaction_matrix NAM N - N - - N - - - N N - - - - - - N N - - - - - -#N1
|
||||||
|
interaction_matrix N1 N - N - - N - - - N N - - - - - - N N - - - - - - -#O2
|
||||||
|
interaction_matrix O2 N - N - - N - - - N N - - - - - - N N - - - - - - - -#OP
|
||||||
|
interaction_matrix OP I N I N N I N N N N N N N N N N N I I N N N N N N N N I#SH
|
||||||
|
interaction_matrix SH I N N N N N N N N N N I I I I I I N N N N N N N N N N N I
|
||||||
|
|
||||||
|
# Cutoff values for side chain interactions
|
||||||
|
# default value
|
||||||
|
sidechain_cutoffs default 3.0 4.0
|
||||||
|
# COO
|
||||||
|
sidechain_cutoffs COO COO 2.5 3.5
|
||||||
|
Sidechain_cutoffs COO SER 2.65 3.65
|
||||||
|
sidechain_cutoffs COO ARG 1.85 2.85
|
||||||
|
sidechain_cutoffs COO LYS 2.85 3.85
|
||||||
|
sidechain_cutoffs COO HIS 2.0 3.0
|
||||||
|
sidechain_cutoffs COO AMD 2.0 3.0
|
||||||
|
sidechain_cutoffs COO TRP 2.0 3.0
|
||||||
|
sidechain_cutoffs COO ROH 2.65 3.65
|
||||||
|
sidechain_cutoffs COO TYR 2.65 3.65
|
||||||
|
sidechain_cutoffs COO N+ 2.85 3.85
|
||||||
|
sidechain_cutoffs COO CG 1.85 2.85
|
||||||
|
sidechain_cutoffs COO C2N 1.85 2.85
|
||||||
|
sidechain_cutoffs COO N30 2.85 3.85
|
||||||
|
sidechain_cutoffs COO N31 2.85 3.85
|
||||||
|
sidechain_cutoffs COO N32 2.85 3.85
|
||||||
|
sidechain_cutoffs COO N33 2.85 3.85
|
||||||
|
sidechain_cutoffs COO NAR 2.0 3.0
|
||||||
|
sidechain_cutoffs COO OCO 2.5 3.5
|
||||||
|
sidechain_cutoffs COO OH 2.65 3.65
|
||||||
|
sidechain_cutoffs COO NAM 2.0 3.0
|
||||||
|
# SER
|
||||||
|
sidechain_cutoffs SER SER 3.5 4.5
|
||||||
|
sidechain_cutoffs SER ARG 2.5 4.0
|
||||||
|
sidechain_cutoffs SER HIS 2.0 3.0
|
||||||
|
sidechain_cutoffs SER AMD 2.5 3.5
|
||||||
|
sidechain_cutoffs SER CYS 3.5 4.5
|
||||||
|
sidechain_cutoffs SER TRP 2.5 3.5
|
||||||
|
sidechain_cutoffs SER ROH 3.5 4.5
|
||||||
|
sidechain_cutoffs SER CG 2.5 4.0
|
||||||
|
sidechain_cutoffs SER C2N 2.5 4.0
|
||||||
|
sidechain_cutoffs SER NAR 2.0 3.0
|
||||||
|
sidechain_cutoffs SER OH 3.5 4.5
|
||||||
|
sidechain_cutoffs SER SH 3.5 4.5
|
||||||
|
sidechain_cutoffs SER TYR 3.5 4.5
|
||||||
|
sidechain_cutoffs SER N+ 3.0 4.5
|
||||||
|
sidechain_cutoffs SER NAM 2.5 3.5
|
||||||
|
# ARG
|
||||||
|
sidechain_cutoffs ARG CYS 2.5 4.0
|
||||||
|
sidechain_cutoffs ARG TYR 2.5 4.0
|
||||||
|
sidechain_cutoffs ARG OCO 1.85 2.85
|
||||||
|
sidechain_cutoffs ARG SH 2.5 4.0
|
||||||
|
# HIS
|
||||||
|
sidechain_cutoffs HIS AMD 2.0 3.0
|
||||||
|
sidechain_cutoffs HIS TYR 2.0 3.0
|
||||||
|
sidechain_cutoffs HIS OCO 2.0 3.0
|
||||||
|
# CYS
|
||||||
|
sidechain_cutoffs CYS CYS 3.0 5.0
|
||||||
|
sidechain_cutoffs CYS TRP 2.5 3.5
|
||||||
|
sidechain_cutoffs CYS ROH 3.5 4.5
|
||||||
|
sidechain_cutoffs CYS AMD 2.5 3.5
|
||||||
|
sidechain_cutoffs CYS TYR 3.5 4.5
|
||||||
|
sidechain_cutoffs CYS N+ 3.0 4.5
|
||||||
|
sidechain_cutoffs CYS CG 2.5 4.0
|
||||||
|
sidechain_cutoffs CYS C2N 2.5 4.0
|
||||||
|
sidechain_cutoffs CYS N30 3.0 4.5
|
||||||
|
sidechain_cutoffs CYS N31 3.0 4.5
|
||||||
|
sidechain_cutoffs CYS N32 3.0 4.5
|
||||||
|
sidechain_cutoffs CYS N33 3.0 4.5
|
||||||
|
sidechain_cutoffs CYS OH 3.5 4.5
|
||||||
|
sidechain_cutoffs CYS NAM 2.5 3.5
|
||||||
|
sidechain_cutoffs CYS SH 3.0 5.0
|
||||||
|
# TYR
|
||||||
|
sidechain_cutoffs TYR TYR 3.5 4.5
|
||||||
|
sidechain_cutoffs TYR N+ 3.0 4.5
|
||||||
|
sidechain_cutoffs TYR AMD 2.5 3.5
|
||||||
|
sidechain_cutoffs TYR TRP 2.5 3.5
|
||||||
|
sidechain_cutoffs TYR ROH 3.5 4.5
|
||||||
|
sidechain_cutoffs TYR CG 2.5 4.0
|
||||||
|
sidechain_cutoffs TYR C2N 2.5 4.0
|
||||||
|
sidechain_cutoffs TYR OCO 2.65 3.65
|
||||||
|
sidechain_cutoffs TYR NAR 2.0 3.0
|
||||||
|
sidechain_cutoffs TYR OH 3.5 4.5
|
||||||
|
sidechain_cutoffs TYR NAM 2.5 3.5
|
||||||
|
sidechain_cutoffs TYR SH 3.5 4.5
|
||||||
|
# N+
|
||||||
|
sidechain_cutoffs N+ OCO 2.85 3.85
|
||||||
|
sidechain_cutoffs N+ SH 3.0 4.5
|
||||||
|
# LYS
|
||||||
|
sidechain_cutoffs LYS OCO 2.85 3.85
|
||||||
|
# OCO
|
||||||
|
sidechain_cutoffs OCO OCO 2.5 3.5
|
||||||
|
sidechain_cutoffs OCO TRP 2.0 3.0
|
||||||
|
sidechain_cutoffs OCO ROH 2.65 3.65
|
||||||
|
sidechain_cutoffs OCO AMD 2.0 3.0
|
||||||
|
sidechain_cutoffs OCO CG 1.85 2.85
|
||||||
|
sidechain_cutoffs OCO C2N 1.85 2.85
|
||||||
|
sidechain_cutoffs OCO N30 2.85 3.85
|
||||||
|
sidechain_cutoffs OCO N31 2.85 3.85
|
||||||
|
sidechain_cutoffs OCO N32 2.85 3.85
|
||||||
|
sidechain_cutoffs OCO N33 2.85 3.85
|
||||||
|
sidechain_cutoffs OCO NAR 2.0 3.0
|
||||||
|
sidechain_cutoffs OCO OH 2.65 3.65
|
||||||
|
sidechain_cutoffs OCO NAM 2.0 3.0
|
||||||
|
# NAR
|
||||||
|
sidechain_cutoffs NAR AMD 2.0 3.0
|
||||||
|
# SH
|
||||||
|
sidechain_cutoffs SH ROH 3.5 4.5
|
||||||
|
sidechain_cutoffs SH TRP 2.5 3.5
|
||||||
|
sidechain_cutoffs SH AMD 2.5 3.5
|
||||||
|
sidechain_cutoffs SH NAM 2.5 3.5
|
||||||
|
sidechain_cutoffs SH CG 2.5 4.0
|
||||||
|
sidechain_cutoffs SH C2N 2.5 4.0
|
||||||
|
sidechain_cutoffs SH OH 3.5 4.5
|
||||||
|
sidechain_cutoffs SH SH 3.0 5.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Maximal interaction energies for side chains
|
||||||
|
sidechain_interaction 0.85
|
||||||
|
|
||||||
|
# Angular dependent sidechain interactions
|
||||||
|
angular_dependent_sidechain_interactions HIS
|
||||||
|
angular_dependent_sidechain_interactions ARG
|
||||||
|
angular_dependent_sidechain_interactions AMD
|
||||||
|
angular_dependent_sidechain_interactions TRP
|
||||||
|
|
||||||
|
# exception interaction values
|
||||||
|
COO_HIS_exception 1.60
|
||||||
|
OCO_HIS_exception 1.60
|
||||||
|
CYS_HIS_exception 1.60
|
||||||
|
CYS_CYS_exception 3.60
|
||||||
|
|
||||||
|
# Coulomb interaction parameters
|
||||||
|
coulomb_cutoff1 4.0
|
||||||
|
coulomb_cutoff2 10.0
|
||||||
|
coulomb_diel 80.0
|
||||||
|
|
||||||
|
# Backbone hydrogen bond parameters
|
||||||
|
backbone_NH_hydrogen_bond COO -0.85 2.00 3.00
|
||||||
|
#backbone_NH_hydrogen_bond C- -0.85 2.00 3.00
|
||||||
|
backbone_NH_hydrogen_bond CYS -0.85 3.00 4.00
|
||||||
|
backbone_NH_hydrogen_bond TYR -0.85 2.20 3.20
|
||||||
|
backbone_NH_hydrogen_bond OCO -0.85 2.00 3.50
|
||||||
|
backbone_NH_hydrogen_bond NAR -0.85 2.00 3.50
|
||||||
|
|
||||||
|
backbone_CO_hydrogen_bond HIS 0.85 2.00 3.00
|
||||||
|
backbone_CO_hydrogen_bond OCO 0.85 3.00 4.00
|
||||||
|
backbone_CO_hydrogen_bond CG 0.85 2.00 4.00
|
||||||
|
backbone_CO_hydrogen_bond C2N 0.85 2.00 4.00
|
||||||
|
backbone_CO_hydrogen_bond N30 0.85 2.00 4.00
|
||||||
|
backbone_CO_hydrogen_bond N31 0.85 2.00 4.00
|
||||||
|
backbone_CO_hydrogen_bond N32 0.85 2.00 4.00
|
||||||
|
backbone_CO_hydrogen_bond N33 0.85 2.00 4.00
|
||||||
|
backbone_CO_hydrogen_bond NAR 0.85 2.00 3.50
|
||||||
|
|
||||||
|
# Group charges
|
||||||
|
charge COO -1
|
||||||
|
charge HIS +1
|
||||||
|
charge CYS -1
|
||||||
|
charge TYR -1
|
||||||
|
charge LYS +1
|
||||||
|
charge ARG +1
|
||||||
|
charge N+ +1
|
||||||
|
charge C- -1
|
||||||
|
charge OCO -1
|
||||||
|
charge SER -1
|
||||||
|
charge CG +1
|
||||||
|
charge C2N +1
|
||||||
|
charge N30 +1
|
||||||
|
charge N31 +1
|
||||||
|
charge N32 +1
|
||||||
|
charge N33 +1
|
||||||
|
charge NAR +1
|
||||||
|
charge SH -1
|
||||||
|
charge OP -1
|
||||||
|
|
||||||
|
# list of acids
|
||||||
|
acid_list ASP
|
||||||
|
acid_list GLU
|
||||||
|
acid_list CYS
|
||||||
|
acid_list TYR
|
||||||
|
acid_list SER
|
||||||
|
acid_list C-
|
||||||
|
acid_list OCO
|
||||||
|
acid_list OP
|
||||||
|
acid_list SH
|
||||||
|
|
||||||
|
# list of bases
|
||||||
|
base_list ARG
|
||||||
|
base_list LYS
|
||||||
|
base_list HIS
|
||||||
|
base_list N+
|
||||||
|
base_list CG
|
||||||
|
base_list C2N
|
||||||
|
base_list N30
|
||||||
|
base_list N31
|
||||||
|
base_list N32
|
||||||
|
base_list N33
|
||||||
|
base_list NAR
|
||||||
|
|
||||||
|
# list of groups used in backbone reorganisation calculations
|
||||||
|
backbone_reorganisation_list ASP
|
||||||
|
backbone_reorganisation_list GLU
|
||||||
|
|
||||||
|
# Residues that should be ignored
|
||||||
|
ignore_residues HOH
|
||||||
|
ignore_residues H2O
|
||||||
|
ignore_residues HOH
|
||||||
|
ignore_residues SO4
|
||||||
|
ignore_residues PO4
|
||||||
|
ignore_residues PEG
|
||||||
|
ignore_residues EPE
|
||||||
|
#ignore_residues NAG
|
||||||
|
ignore_residues TRS
|
||||||
|
|
||||||
|
# Relative Van der Waals volume parameters for the radial volume model
|
||||||
|
# Radii adopted from Bondi, A. (1964). "Van der Waals Volumes and Radii". J. Phys. Chem. 68 (3): 441-51
|
||||||
|
VanDerWaalsVolume C 1.40 # radius: 1.70, volume: 20.58 all 'C' and 'CA' atoms
|
||||||
|
VanDerWaalsVolume C4 2.64 # 38.79 hydrodphobic carbon atoms + unidentified atoms
|
||||||
|
VanDerWaalsVolume N 1.06 # radius: 1.55, volume: 15.60 all nitrogen atoms
|
||||||
|
VanDerWaalsVolume O 1.00 # radius: 1.52, volume: 14.71 all oxygen atoms
|
||||||
|
VanDerWaalsVolume S 1.66 # radius: 1.80, volume: 24.43 all sulphur atoms
|
||||||
|
VanDerWaalsVolume F 0.90 # raidus: 1.47, volume: 13.30 for fluorine
|
||||||
|
VanDerWaalsVolume Cl 1.53 # radius: 1.75, volume: 22.44 for chlorine
|
||||||
|
VanDerWaalsVolume P 1.66 # radius: 1.80, volume: 24.42 for phosphorus
|
||||||
|
|
||||||
|
# Other desolvation parameters
|
||||||
|
desolvationSurfaceScalingFactor 0.25
|
||||||
|
desolvationPrefactor -13.0
|
||||||
|
desolvationAllowance 0.0
|
||||||
|
desolv_cutoff 20.0
|
||||||
|
buried_cutoff 15.0
|
||||||
|
Nmin 280
|
||||||
|
Nmax 560
|
||||||
|
|
||||||
|
# Ligand groups
|
||||||
|
ligand_typing groups
|
||||||
|
min_bond_distance_for_hydrogen_bonds 4
|
||||||
|
|
||||||
|
# covalent coupling
|
||||||
|
coupling_max_number_of_bonds 3
|
||||||
|
shared_determinants 0
|
||||||
|
common_charge_centre 0
|
||||||
|
remove_penalised_group 1
|
||||||
|
|
||||||
|
# non-covalent coupling
|
||||||
|
max_intrinsic_pKa_diff 2.0
|
||||||
|
min_interaction_energy 0.5
|
||||||
|
max_free_energy_diff 1.0
|
||||||
|
min_swap_pka_shift 1.0
|
||||||
|
min_pka 0.0
|
||||||
|
max_pka 10.0
|
||||||
|
pH variable
|
||||||
|
reference neutral
|
||||||
|
|
||||||
|
# ions
|
||||||
|
ions 1P 1 # generic charged atoms
|
||||||
|
ions 2P 2
|
||||||
|
ions 1N -1
|
||||||
|
ions 2N -2
|
||||||
|
|
||||||
|
ions MG 2 #Magnesium Ion
|
||||||
|
ions CA 2 #Calcium Ion
|
||||||
|
ions ZN 2 #Zinc Ion
|
||||||
|
ions NA 1 #Sodium Ion
|
||||||
|
ions CL -1 #Chloride Ion
|
||||||
|
ions MN 2 #Manganese (ii) Ion
|
||||||
|
ions K 1 #Potassium Ion
|
||||||
|
ions CD 2 #Cadmium Ion
|
||||||
|
ions FE 3 #Fe (iii) Ion
|
||||||
|
ions SR 2 #Strontium Ion
|
||||||
|
ions CU 2 #Copper (ii) Ion
|
||||||
|
ions IOD -1 #Iodide Ion
|
||||||
|
ions HG 2 #Mercury (ii) Ion
|
||||||
|
ions BR -1 #Bromide Ion
|
||||||
|
ions CO 2 #Cobalt (ii) Ion
|
||||||
|
ions NI 2 #Nickel (ii) Ion
|
||||||
|
ions FE2 2 #Fe (ii) Ion
|
||||||
|
|
||||||
|
# write out order of residues
|
||||||
|
write_out_order ASP
|
||||||
|
write_out_order GLU
|
||||||
|
write_out_order C-
|
||||||
|
write_out_order HIS
|
||||||
|
write_out_order CYS
|
||||||
|
write_out_order TYR
|
||||||
|
write_out_order LYS
|
||||||
|
write_out_order ARG
|
||||||
|
write_out_order SER
|
||||||
|
write_out_order N+
|
||||||
|
write_out_order CG
|
||||||
|
write_out_order C2N
|
||||||
|
write_out_order N30
|
||||||
|
write_out_order N31
|
||||||
|
write_out_order N32
|
||||||
|
write_out_order N33
|
||||||
|
write_out_order NAR
|
||||||
|
write_out_order OCO
|
||||||
|
write_out_order SH
|
||||||
|
write_out_order OP
|
||||||
97
Source/protonate.py → propka/protonate.py
Executable file → Normal file
97
Source/protonate.py → propka/protonate.py
Executable file → Normal file
@@ -1,11 +1,14 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
from Source.vector_algebra import *
|
from __future__ import division
|
||||||
import Source.bonds, Source.pdb, Source.atom
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from propka.vector_algebra import *
|
||||||
|
import propka.bonds, propka.pdb, propka.atom
|
||||||
|
|
||||||
class Protonate:
|
class Protonate:
|
||||||
""" Protonates atoms using VSEPR theory """
|
""" Protonates atoms using VSEPR theory """
|
||||||
|
|
||||||
def __init__(self, verbose=False):
|
def __init__(self, verbose=False):
|
||||||
self.verbose=verbose
|
self.verbose=verbose
|
||||||
|
|
||||||
@@ -56,9 +59,9 @@ class Protonate:
|
|||||||
'HIS-ND1':1.0,
|
'HIS-ND1':1.0,
|
||||||
'LYS-NZ':1.0,
|
'LYS-NZ':1.0,
|
||||||
'N+':1.0,
|
'N+':1.0,
|
||||||
'C-':-1.0}
|
'C-':-1.0}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.sybyl_charges = {'N.pl3':+1,
|
self.sybyl_charges = {'N.pl3':+1,
|
||||||
'N.3':+1,
|
'N.3':+1,
|
||||||
'N.4':+1,
|
'N.4':+1,
|
||||||
@@ -92,17 +95,17 @@ class Protonate:
|
|||||||
self.display('----- Protonation started -----')
|
self.display('----- Protonation started -----')
|
||||||
# Remove all currently present hydrogen atoms
|
# Remove all currently present hydrogen atoms
|
||||||
self.remove_all_hydrogen_atoms(molecules)
|
self.remove_all_hydrogen_atoms(molecules)
|
||||||
|
|
||||||
# protonate all atoms
|
# protonate all atoms
|
||||||
for name in molecules.conformation_names:
|
for name in molecules.conformation_names:
|
||||||
non_H_atoms = molecules.conformations[name].get_non_hydrogen_atoms()
|
non_H_atoms = molecules.conformations[name].get_non_hydrogen_atoms()
|
||||||
|
|
||||||
for atom in non_H_atoms:
|
for atom in non_H_atoms:
|
||||||
self.protonate_atom(atom)
|
self.protonate_atom(atom)
|
||||||
|
|
||||||
# fix hydrogen names
|
# fix hydrogen names
|
||||||
#self.set_proton_names(non_H_atoms)
|
#self.set_proton_names(non_H_atoms)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -110,7 +113,7 @@ class Protonate:
|
|||||||
for name in molecular_container.conformation_names:
|
for name in molecular_container.conformation_names:
|
||||||
molecular_container.conformations[name].atoms = molecular_container.conformations[name].get_non_hydrogen_atoms()
|
molecular_container.conformations[name].atoms = molecular_container.conformations[name].get_non_hydrogen_atoms()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def set_charge(self, atom):
|
def set_charge(self, atom):
|
||||||
# atom is a protein atom
|
# atom is a protein atom
|
||||||
@@ -148,11 +151,11 @@ class Protonate:
|
|||||||
for heavy_atom in heavy_atoms:
|
for heavy_atom in heavy_atoms:
|
||||||
i = 1
|
i = 1
|
||||||
for bonded in heavy_atom.bonded_atoms:
|
for bonded in heavy_atom.bonded_atoms:
|
||||||
|
|
||||||
if bonded.element == 'H':
|
if bonded.element == 'H':
|
||||||
bonded.name+='%d'%i
|
bonded.name+='%d'%i
|
||||||
i+=1
|
i+=1
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -160,7 +163,7 @@ class Protonate:
|
|||||||
def set_number_of_protons_to_add(self, atom):
|
def set_number_of_protons_to_add(self, atom):
|
||||||
self.display('*'*10)
|
self.display('*'*10)
|
||||||
self.display('Setting number of protons to add for',atom)
|
self.display('Setting number of protons to add for',atom)
|
||||||
atom.number_of_protons_to_add = 8
|
atom.number_of_protons_to_add = 8
|
||||||
self.display(' %4d'%8)
|
self.display(' %4d'%8)
|
||||||
atom.number_of_protons_to_add -= self.valence_electrons[atom.element]
|
atom.number_of_protons_to_add -= self.valence_electrons[atom.element]
|
||||||
self.display('Valence eletrons: %4d'%-self.valence_electrons[atom.element])
|
self.display('Valence eletrons: %4d'%-self.valence_electrons[atom.element])
|
||||||
@@ -177,7 +180,7 @@ class Protonate:
|
|||||||
return
|
return
|
||||||
|
|
||||||
def set_steric_number_and_lone_pairs(self, atom):
|
def set_steric_number_and_lone_pairs(self, atom):
|
||||||
|
|
||||||
# If we already did this, there is no reason to do it again
|
# If we already did this, there is no reason to do it again
|
||||||
if atom.steric_number_and_lone_pairs_set:
|
if atom.steric_number_and_lone_pairs_set:
|
||||||
return
|
return
|
||||||
@@ -195,10 +198,10 @@ class Protonate:
|
|||||||
|
|
||||||
|
|
||||||
atom.steric_number = 0
|
atom.steric_number = 0
|
||||||
|
|
||||||
self.display('%65s: %4d'%('Valence electrons',self.valence_electrons[atom.element]))
|
self.display('%65s: %4d'%('Valence electrons',self.valence_electrons[atom.element]))
|
||||||
atom.steric_number += self.valence_electrons[atom.element]
|
atom.steric_number += self.valence_electrons[atom.element]
|
||||||
|
|
||||||
self.display('%65s: %4d'%('Number of bonds',len(atom.bonded_atoms)))
|
self.display('%65s: %4d'%('Number of bonds',len(atom.bonded_atoms)))
|
||||||
atom.steric_number += len(atom.bonded_atoms)
|
atom.steric_number += len(atom.bonded_atoms)
|
||||||
|
|
||||||
@@ -216,7 +219,7 @@ class Protonate:
|
|||||||
|
|
||||||
self.display('%65s: %4.1f'%('Charge(-)',atom.charge))
|
self.display('%65s: %4.1f'%('Charge(-)',atom.charge))
|
||||||
atom.steric_number -= atom.charge
|
atom.steric_number -= atom.charge
|
||||||
|
|
||||||
atom.steric_number = math.floor(atom.steric_number/2.0)
|
atom.steric_number = math.floor(atom.steric_number/2.0)
|
||||||
|
|
||||||
atom.number_of_lone_pairs = atom.steric_number - len(atom.bonded_atoms) - atom.number_of_protons_to_add
|
atom.number_of_lone_pairs = atom.steric_number - len(atom.bonded_atoms) - atom.number_of_protons_to_add
|
||||||
@@ -240,9 +243,9 @@ class Protonate:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def trigonal(self, atom):
|
def trigonal(self, atom):
|
||||||
self.display('TRIGONAL - %d bonded atoms'%(len(atom.bonded_atoms)))
|
self.display('TRIGONAL - %d bonded atoms'%(len(atom.bonded_atoms)))
|
||||||
rot_angle = math.radians(120.0)
|
rot_angle = math.radians(120.0)
|
||||||
|
|
||||||
c = vector(atom1 = atom)
|
c = vector(atom1 = atom)
|
||||||
@@ -250,13 +253,13 @@ class Protonate:
|
|||||||
# 0 bonds
|
# 0 bonds
|
||||||
if len(atom.bonded_atoms) == 0:
|
if len(atom.bonded_atoms) == 0:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# 1 bond
|
# 1 bond
|
||||||
if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0:
|
if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0:
|
||||||
# Add another atom with the right angle to the first one
|
# Add another atom with the right angle to the first one
|
||||||
a = vector(atom1 = atom, atom2 = atom.bonded_atoms[0])
|
a = vector(atom1 = atom, atom2 = atom.bonded_atoms[0])
|
||||||
# use plane of bonded trigonal atom - e.g. arg
|
# use plane of bonded trigonal atom - e.g. arg
|
||||||
|
|
||||||
self.set_steric_number_and_lone_pairs(atom.bonded_atoms[0])
|
self.set_steric_number_and_lone_pairs(atom.bonded_atoms[0])
|
||||||
if atom.bonded_atoms[0].steric_number == 3 and len(atom.bonded_atoms[0].bonded_atoms)>1:
|
if atom.bonded_atoms[0].steric_number == 3 and len(atom.bonded_atoms[0].bonded_atoms)>1:
|
||||||
# use other atoms bonded to the neighbour to establish the plane, if possible
|
# use other atoms bonded to the neighbour to establish the plane, if possible
|
||||||
@@ -265,21 +268,21 @@ class Protonate:
|
|||||||
if atom.bonded_atoms[0].bonded_atoms[i] != atom:
|
if atom.bonded_atoms[0].bonded_atoms[i] != atom:
|
||||||
other_atom_indices.append(i)
|
other_atom_indices.append(i)
|
||||||
|
|
||||||
|
|
||||||
v1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0])
|
v1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0])
|
||||||
v2 = vector(atom1 = atom.bonded_atoms[0],
|
v2 = vector(atom1 = atom.bonded_atoms[0],
|
||||||
atom2 = atom.bonded_atoms[0].bonded_atoms[other_atom_indices[0]])
|
atom2 = atom.bonded_atoms[0].bonded_atoms[other_atom_indices[0]])
|
||||||
|
|
||||||
axis = v1**v2
|
axis = v1**v2
|
||||||
|
|
||||||
# this is a trick to make sure that the order of atoms doesn't influence
|
# this is a trick to make sure that the order of atoms doesn't influence
|
||||||
# the final postions of added protons
|
# the final postions of added protons
|
||||||
if len(other_atom_indices)>1:
|
if len(other_atom_indices)>1:
|
||||||
v3 = vector(atom1 = atom.bonded_atoms[0],
|
v3 = vector(atom1 = atom.bonded_atoms[0],
|
||||||
atom2 = atom.bonded_atoms[0].bonded_atoms[other_atom_indices[1]])
|
atom2 = atom.bonded_atoms[0].bonded_atoms[other_atom_indices[1]])
|
||||||
|
|
||||||
axis2 = v1**v3
|
axis2 = v1**v3
|
||||||
|
|
||||||
if axis * axis2>0:
|
if axis * axis2>0:
|
||||||
axis = axis+axis2
|
axis = axis+axis2
|
||||||
else:
|
else:
|
||||||
@@ -294,12 +297,12 @@ class Protonate:
|
|||||||
|
|
||||||
# 2 bonds
|
# 2 bonds
|
||||||
if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0:
|
if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0:
|
||||||
# Add another atom with the right angle to the first two
|
# Add another atom with the right angle to the first two
|
||||||
a1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]).rescale(1.0)
|
a1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]).rescale(1.0)
|
||||||
a2 = vector(atom1 = atom, atom2 = atom.bonded_atoms[1]).rescale(1.0)
|
a2 = vector(atom1 = atom, atom2 = atom.bonded_atoms[1]).rescale(1.0)
|
||||||
|
|
||||||
new_a = -a1 - a2
|
new_a = -a1 - a2
|
||||||
new_a = self.set_bond_distance(new_a, atom.element)
|
new_a = self.set_bond_distance(new_a, atom.element)
|
||||||
self.add_proton(atom, c+new_a)
|
self.add_proton(atom, c+new_a)
|
||||||
|
|
||||||
|
|
||||||
@@ -307,20 +310,20 @@ class Protonate:
|
|||||||
|
|
||||||
|
|
||||||
def tetrahedral(self, atom):
|
def tetrahedral(self, atom):
|
||||||
self.display('TETRAHEDRAL - %d bonded atoms'%(len(atom.bonded_atoms)))
|
self.display('TETRAHEDRAL - %d bonded atoms'%(len(atom.bonded_atoms)))
|
||||||
rot_angle = math.radians(109.5)
|
rot_angle = math.radians(109.5)
|
||||||
|
|
||||||
# sanity check
|
# sanity check
|
||||||
# if atom.number_of_protons_to_add + len(atom.bonded_atoms) != 4:
|
# if atom.number_of_protons_to_add + len(atom.bonded_atoms) != 4:
|
||||||
# self.display 'Error: Attempting tetrahedral structure with %d bonds'%(atom.number_of_protons_to_add +
|
# self.display 'Error: Attempting tetrahedral structure with %d bonds'%(atom.number_of_protons_to_add +
|
||||||
# len(atom.bonded_atoms))
|
# len(atom.bonded_atoms))
|
||||||
|
|
||||||
c = vector(atom1 = atom)
|
c = vector(atom1 = atom)
|
||||||
|
|
||||||
# 0 bonds
|
# 0 bonds
|
||||||
if len(atom.bonded_atoms) == 0:
|
if len(atom.bonded_atoms) == 0:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# 1 bond
|
# 1 bond
|
||||||
if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0:
|
if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0:
|
||||||
# Add another atom with the right angle to the first one
|
# Add another atom with the right angle to the first one
|
||||||
@@ -332,7 +335,7 @@ class Protonate:
|
|||||||
|
|
||||||
# 2 bonds
|
# 2 bonds
|
||||||
if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0:
|
if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0:
|
||||||
# Add another atom with the right angle to the first two
|
# Add another atom with the right angle to the first two
|
||||||
a1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]).rescale(1.0)
|
a1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]).rescale(1.0)
|
||||||
a2 = vector(atom1 = atom, atom2 = atom.bonded_atoms[1]).rescale(1.0)
|
a2 = vector(atom1 = atom, atom2 = atom.bonded_atoms[1]).rescale(1.0)
|
||||||
|
|
||||||
@@ -351,16 +354,16 @@ class Protonate:
|
|||||||
new_a = -a1-a2-a3
|
new_a = -a1-a2-a3
|
||||||
new_a = self.set_bond_distance(new_a, atom.element)
|
new_a = self.set_bond_distance(new_a, atom.element)
|
||||||
self.add_proton(atom, c+new_a)
|
self.add_proton(atom, c+new_a)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def add_proton(self, atom, position):
|
def add_proton(self, atom, position):
|
||||||
# Create the new proton
|
# Create the new proton
|
||||||
new_H = Source.atom.Atom()
|
new_H = propka.atom.Atom()
|
||||||
new_H.setProperty(numb = None,
|
new_H.setProperty(numb = None,
|
||||||
name = 'H%s'%atom.name[1:],
|
name = 'H%s'%atom.name[1:],
|
||||||
resName = atom.resName,
|
resName = atom.resName,
|
||||||
chainID = atom.chainID,
|
chainID = atom.chainID,
|
||||||
resNumb = atom.resNumb,
|
resNumb = atom.resNumb,
|
||||||
x = round(position.x,3), # round of to three digimal points
|
x = round(position.x,3), # round of to three digimal points
|
||||||
@@ -381,19 +384,19 @@ class Protonate:
|
|||||||
|
|
||||||
atom.bonded_atoms.append(new_H)
|
atom.bonded_atoms.append(new_H)
|
||||||
atom.number_of_protons_to_add -=1
|
atom.number_of_protons_to_add -=1
|
||||||
atom.conformation_container.add_atom(new_H)
|
atom.conformation_container.add_atom(new_H)
|
||||||
|
|
||||||
# update names of all protons on this atom
|
# update names of all protons on this atom
|
||||||
new_H.residue_label = "%-3s%4d%2s" % (new_H.name,new_H.resNumb, new_H.chainID)
|
new_H.residue_label = "%-3s%4d%2s" % (new_H.name,new_H.resNumb, new_H.chainID)
|
||||||
no_protons = atom.count_bonded_elements('H')
|
no_protons = atom.count_bonded_elements('H')
|
||||||
if no_protons > 1:
|
if no_protons > 1:
|
||||||
i = 1
|
i = 1
|
||||||
for proton in atom.get_bonded_elements('H'):
|
for proton in atom.get_bonded_elements('H'):
|
||||||
proton.name = 'H%s%d'%(atom.name[1:],i)
|
proton.name = 'H%s%d'%(atom.name[1:],i)
|
||||||
proton.residue_label = "%-3s%4d%2s" % (proton.name,proton.resNumb, proton.chainID)
|
proton.residue_label = "%-3s%4d%2s" % (proton.name,proton.resNumb, proton.chainID)
|
||||||
i+=1
|
i+=1
|
||||||
|
|
||||||
|
|
||||||
self.display('added',new_H, 'to',atom)
|
self.display('added',new_H, 'to',atom)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -407,7 +410,7 @@ class Protonate:
|
|||||||
a = a.rescale(d)
|
a = a.rescale(d)
|
||||||
|
|
||||||
return a
|
return a
|
||||||
|
|
||||||
def display(self,*text):
|
def display(self,*text):
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
s = ''
|
s = ''
|
||||||
@@ -429,11 +432,11 @@ if __name__ == '__main__':
|
|||||||
print('Error: Could not find \"%s\"'%filename)
|
print('Error: Could not find \"%s\"'%filename)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
p = Protonate()
|
p = Protonate()
|
||||||
pdblist = pdb.readPDB(filename)
|
pdblist = pdb.readPDB(filename)
|
||||||
my_protein = protein.Protein(pdblist,'test.pdb')
|
my_protein = protein.Protein(pdblist,'test.pdb')
|
||||||
|
|
||||||
p.remove_all_hydrogen_atoms_from_protein(my_protein)
|
p.remove_all_hydrogen_atoms_from_protein(my_protein)
|
||||||
my_protein.writePDB('before_protonation.pdb')
|
my_protein.writePDB('before_protonation.pdb')
|
||||||
|
|
||||||
15
propka/run.py
Normal file
15
propka/run.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# entry point for propka script
|
||||||
|
|
||||||
|
import propka.lib, propka.molecular_container
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
Reads in structure files, calculates pKa values, and prints pKa files
|
||||||
|
"""
|
||||||
|
# loading options, flaggs and arguments
|
||||||
|
options, pdbfiles = propka.lib.loadOptions()
|
||||||
|
|
||||||
|
for pdbfile in pdbfiles:
|
||||||
|
my_molecule = propka.molecular_container.Molecular_container(pdbfile, options)
|
||||||
|
my_molecule.calculate_pka()
|
||||||
|
my_molecule.write_pka()
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
import math
|
import math
|
||||||
|
|
||||||
class vector:
|
class vector:
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
import math
|
import math
|
||||||
import Source.lib as lib
|
|
||||||
import sys, os
|
import sys, os
|
||||||
import Source.calculations as calculations
|
|
||||||
import Source.parameters
|
import propka.lib as lib
|
||||||
|
import propka.calculations as calculations
|
||||||
|
import propka.parameters
|
||||||
|
|
||||||
|
|
||||||
class version:
|
class version:
|
||||||
@@ -21,7 +24,7 @@ class version:
|
|||||||
def hydrogen_bond_interaction(self, group1, group2):
|
def hydrogen_bond_interaction(self, group1, group2):
|
||||||
return self.hydrogen_bond_interaction_model(group1, group2, self)
|
return self.hydrogen_bond_interaction_model(group1, group2, self)
|
||||||
|
|
||||||
def calculateSideChainEnergy(self, distance, dpka_max, cutoff, weight, f_angle):
|
def calculateSideChainEnergy(self, distance, dpka_max, cutoff, weight, f_angle):
|
||||||
return self.sidechain_interaction_model(distance, dpka_max, cutoff, f_angle) # weight is ignored in 3.0 Sep07
|
return self.sidechain_interaction_model(distance, dpka_max, cutoff, f_angle) # weight is ignored in 3.0 Sep07
|
||||||
|
|
||||||
# coulomb
|
# coulomb
|
||||||
@@ -47,38 +50,38 @@ class version:
|
|||||||
|
|
||||||
def setup_bonding(self, molecular_container):
|
def setup_bonding(self, molecular_container):
|
||||||
return self.prepare_bonds(self.parameters, molecular_container)
|
return self.prepare_bonds(self.parameters, molecular_container)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class version_A(version):
|
class version_A(version):
|
||||||
def __init__(self, parameters):
|
def __init__(self, parameters):
|
||||||
# set the calculation rutines used in this version
|
# set the calculation rutines used in this version
|
||||||
version.__init__(self, parameters)
|
version.__init__(self, parameters)
|
||||||
|
|
||||||
# atom naming, bonding, and protonation
|
# atom naming, bonding, and protonation
|
||||||
self.molecular_preparation_method = Source.calculations.setup_bonding_and_protonation
|
self.molecular_preparation_method = propka.calculations.setup_bonding_and_protonation
|
||||||
self.prepare_bonds = Source.calculations.setup_bonding
|
self.prepare_bonds = propka.calculations.setup_bonding
|
||||||
|
|
||||||
|
|
||||||
# desolvation related methods
|
# desolvation related methods
|
||||||
self.desolvation_model = calculations.radial_volume_desolvation
|
self.desolvation_model = calculations.radial_volume_desolvation
|
||||||
self.weight_pair_method = calculations.calculatePairWeight
|
self.weight_pair_method = calculations.calculatePairWeight
|
||||||
|
|
||||||
# side chain methods
|
# side chain methods
|
||||||
self.sidechain_interaction_model = Source.calculations.HydrogenBondEnergy
|
self.sidechain_interaction_model = propka.calculations.HydrogenBondEnergy
|
||||||
self.hydrogen_bond_interaction_model = Source.calculations.hydrogen_bond_interaction
|
self.hydrogen_bond_interaction_model = propka.calculations.hydrogen_bond_interaction
|
||||||
|
|
||||||
# colomb methods
|
# colomb methods
|
||||||
self.electrostatic_interaction_model = Source.calculations.electrostatic_interaction
|
self.electrostatic_interaction_model = propka.calculations.electrostatic_interaction
|
||||||
self.check_coulomb_pair_method = Source.calculations.checkCoulombPair
|
self.check_coulomb_pair_method = propka.calculations.checkCoulombPair
|
||||||
self.coulomb_interaction_model = Source.calculations.CoulombEnergy
|
self.coulomb_interaction_model = propka.calculations.CoulombEnergy
|
||||||
|
|
||||||
#backbone
|
#backbone
|
||||||
self.backbone_interaction_model = Source.calculations.HydrogenBondEnergy
|
self.backbone_interaction_model = propka.calculations.HydrogenBondEnergy
|
||||||
self.backbone_reorganisation_method = Source.calculations.BackBoneReorganization
|
self.backbone_reorganisation_method = propka.calculations.BackBoneReorganization
|
||||||
|
|
||||||
# exception methods
|
# exception methods
|
||||||
self.exception_check_method = Source.calculations.checkExceptions
|
self.exception_check_method = propka.calculations.checkExceptions
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_hydrogen_bond_parameters(self, atom1, atom2):
|
def get_hydrogen_bond_parameters(self, atom1, atom2):
|
||||||
@@ -91,7 +94,7 @@ class version_A(version):
|
|||||||
if atom.group_type in self.parameters.backbone_CO_hydrogen_bond.keys():
|
if atom.group_type in self.parameters.backbone_CO_hydrogen_bond.keys():
|
||||||
[v,c1,c2] = self.parameters.backbone_CO_hydrogen_bond[atom.group_type]
|
[v,c1,c2] = self.parameters.backbone_CO_hydrogen_bond[atom.group_type]
|
||||||
return [v,[c1,c2]]
|
return [v,[c1,c2]]
|
||||||
|
|
||||||
if backbone_atom.group_type == 'BBN':
|
if backbone_atom.group_type == 'BBN':
|
||||||
if atom.group_type in self.parameters.backbone_NH_hydrogen_bond.keys():
|
if atom.group_type in self.parameters.backbone_NH_hydrogen_bond.keys():
|
||||||
[v,c1,c2] = self.parameters.backbone_NH_hydrogen_bond[atom.group_type]
|
[v,c1,c2] = self.parameters.backbone_NH_hydrogen_bond[atom.group_type]
|
||||||
@@ -104,7 +107,7 @@ class version_A(version):
|
|||||||
|
|
||||||
class simple_hb(version_A):
|
class simple_hb(version_A):
|
||||||
def __init__(self, parameters):
|
def __init__(self, parameters):
|
||||||
# set the calculation rutines used in this version
|
# set the calculation rutines used in this version
|
||||||
version_A.__init__(self, parameters)
|
version_A.__init__(self, parameters)
|
||||||
print('Using simple hb model')
|
print('Using simple hb model')
|
||||||
return
|
return
|
||||||
@@ -116,23 +119,23 @@ class simple_hb(version_A):
|
|||||||
def get_backbone_hydrogen_bond_parameters(self, backbone_atom, atom):
|
def get_backbone_hydrogen_bond_parameters(self, backbone_atom, atom):
|
||||||
return self.parameters.hydrogen_bonds.get_value(backbone_atom.element, atom.element)
|
return self.parameters.hydrogen_bonds.get_value(backbone_atom.element, atom.element)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class element_based_ligand_interactions(version_A):
|
class element_based_ligand_interactions(version_A):
|
||||||
def __init__(self, parameters):
|
def __init__(self, parameters):
|
||||||
# set the calculation rutines used in this version
|
# set the calculation rutines used in this version
|
||||||
version_A.__init__(self, parameters)
|
version_A.__init__(self, parameters)
|
||||||
print('Using detailed SC model!')
|
print('Using detailed SC model!')
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_hydrogen_bond_parameters(self, atom1, atom2):
|
def get_hydrogen_bond_parameters(self, atom1, atom2):
|
||||||
if not 'hetatm' in [atom1.type, atom2.type]:
|
if not 'hetatm' in [atom1.type, atom2.type]:
|
||||||
# this is a protein-protein interaction
|
# this is a protein-protein interaction
|
||||||
dpka_max = self.parameters.sidechain_interaction.get_value(atom1.group_type, atom2.group_type)
|
dpka_max = self.parameters.sidechain_interaction.get_value(atom1.group_type, atom2.group_type)
|
||||||
cutoff = self.parameters.sidechain_cutoffs.get_value(atom1.group_type, atom2.group_type)
|
cutoff = self.parameters.sidechain_cutoffs.get_value(atom1.group_type, atom2.group_type)
|
||||||
return [dpka_max, cutoff]
|
return [dpka_max, cutoff]
|
||||||
|
|
||||||
# at least one ligand atom is involved in this interaction
|
# at least one ligand atom is involved in this interaction
|
||||||
# make sure that we are using the heavy atoms for finding paramters
|
# make sure that we are using the heavy atoms for finding paramters
|
||||||
elements = []
|
elements = []
|
||||||
@@ -140,17 +143,17 @@ class element_based_ligand_interactions(version_A):
|
|||||||
if a.element == 'H': elements.append(a.bonded_atoms[0].element)
|
if a.element == 'H': elements.append(a.bonded_atoms[0].element)
|
||||||
else: elements.append(a.element)
|
else: elements.append(a.element)
|
||||||
|
|
||||||
return self.parameters.hydrogen_bonds.get_value(elements[0], elements[1])
|
return self.parameters.hydrogen_bonds.get_value(elements[0], elements[1])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_backbone_hydrogen_bond_parameters(self, backbone_atom, atom):
|
def get_backbone_hydrogen_bond_parameters(self, backbone_atom, atom):
|
||||||
if atom.type == 'atom':
|
if atom.type == 'atom':
|
||||||
# this is a backbone-protein interaction
|
# this is a backbone-protein interaction
|
||||||
if backbone_atom.group_type == 'BBC' and\
|
if backbone_atom.group_type == 'BBC' and\
|
||||||
atom.group_type in self.parameters.backbone_CO_hydrogen_bond.keys():
|
atom.group_type in self.parameters.backbone_CO_hydrogen_bond.keys():
|
||||||
[v,c1,c2] = self.parameters.backbone_CO_hydrogen_bond[atom.group_type]
|
[v,c1,c2] = self.parameters.backbone_CO_hydrogen_bond[atom.group_type]
|
||||||
return [v,[c1,c2]]
|
return [v,[c1,c2]]
|
||||||
|
|
||||||
if backbone_atom.group_type == 'BBN' and\
|
if backbone_atom.group_type == 'BBN' and\
|
||||||
atom.group_type in self.parameters.backbone_NH_hydrogen_bond.keys():
|
atom.group_type in self.parameters.backbone_NH_hydrogen_bond.keys():
|
||||||
[v,c1,c2] = self.parameters.backbone_NH_hydrogen_bond[atom.group_type]
|
[v,c1,c2] = self.parameters.backbone_NH_hydrogen_bond[atom.group_type]
|
||||||
@@ -168,7 +171,7 @@ class element_based_ligand_interactions(version_A):
|
|||||||
print('Could not determine backbone interaction parameters for:',
|
print('Could not determine backbone interaction parameters for:',
|
||||||
backbone_atom,atom)
|
backbone_atom,atom)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -176,28 +179,28 @@ class element_based_ligand_interactions(version_A):
|
|||||||
|
|
||||||
class propka30(version):
|
class propka30(version):
|
||||||
def __init__(self, parameters):
|
def __init__(self, parameters):
|
||||||
# set the calculation rutines used in this version
|
# set the calculation rutines used in this version
|
||||||
version.__init__(self, parameters)
|
version.__init__(self, parameters)
|
||||||
|
|
||||||
# atom naming, bonding, and protonation
|
# atom naming, bonding, and protonation
|
||||||
self.molecular_preparation_method = Source.calculations.setup_bonding_and_protonation_30_style
|
self.molecular_preparation_method = propka.calculations.setup_bonding_and_protonation_30_style
|
||||||
|
|
||||||
# desolvation related methods
|
# desolvation related methods
|
||||||
self.desolvation_model = calculations.radial_volume_desolvation
|
self.desolvation_model = calculations.radial_volume_desolvation
|
||||||
self.weight_pair_method = calculations.calculatePairWeight
|
self.weight_pair_method = calculations.calculatePairWeight
|
||||||
|
|
||||||
# side chain methods
|
# side chain methods
|
||||||
self.sidechain_interaction_model = Source.calculations.HydrogenBondEnergy
|
self.sidechain_interaction_model = propka.calculations.HydrogenBondEnergy
|
||||||
|
|
||||||
# colomb methods
|
# colomb methods
|
||||||
self.check_coulomb_pair_method = Source.calculations.checkCoulombPair
|
self.check_coulomb_pair_method = propka.calculations.checkCoulombPair
|
||||||
self.coulomb_interaction_model = Source.calculations.CoulombEnergy
|
self.coulomb_interaction_model = propka.calculations.CoulombEnergy
|
||||||
|
|
||||||
#backbone
|
#backbone
|
||||||
self.backbone_reorganisation_method = Source.calculations.BackBoneReorganization
|
self.backbone_reorganisation_method = propka.calculations.BackBoneReorganization
|
||||||
|
|
||||||
# exception methods
|
# exception methods
|
||||||
self.exception_check_method = Source.calculations.checkExceptions
|
self.exception_check_method = propka.calculations.checkExceptions
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
31
scripts/propka31.py
Executable file
31
scripts/propka31.py
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# This is the original propka script. However, this distribute-based
|
||||||
|
# installation moved the main() function into propka.run.main and just
|
||||||
|
# generates a script called propka31 from the setup.py installation
|
||||||
|
# script. You should not need to use this script.
|
||||||
|
#
|
||||||
|
# (Also note that there can be import problems because the script name
|
||||||
|
# is the same as the module name; that's why the new script is called
|
||||||
|
# propka31.)
|
||||||
|
|
||||||
|
import propka.lib, propka.molecular_container
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
Reads in structure files, calculates pKa values, and prints pKa files
|
||||||
|
"""
|
||||||
|
# loading options, flaggs and arguments
|
||||||
|
options, pdbfiles = propka.lib.loadOptions()
|
||||||
|
|
||||||
|
for pdbfile in pdbfiles:
|
||||||
|
my_molecule = propka.molecular_container.Molecular_container(pdbfile, options)
|
||||||
|
my_molecule.calculate_pka()
|
||||||
|
my_molecule.write_pka()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
#import cProfile
|
||||||
|
#cProfile.run('main()',sort=1)
|
||||||
|
main()
|
||||||
|
|
||||||
51
setup.py
Normal file
51
setup.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# PROPKA 3.1
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# setuptools installation of PROPKA 3.1
|
||||||
|
|
||||||
|
import ez_setup
|
||||||
|
ez_setup.use_setuptools()
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
VERSION = "3.1"
|
||||||
|
|
||||||
|
setup(name="PROPKA",
|
||||||
|
version=VERSION,
|
||||||
|
description="Heuristic pKa calculations with ligands",
|
||||||
|
long_description="""
|
||||||
|
PROPKA predicts the pKa values of ionizable groups in proteins (version 3.0) and
|
||||||
|
protein-ligand complexes (version 3.1) based on the 3D structure.
|
||||||
|
|
||||||
|
For proteins without ligands both version should produce the same result.
|
||||||
|
|
||||||
|
The method is described in the following papers, which you should cite
|
||||||
|
in publications:
|
||||||
|
|
||||||
|
* Sondergaard, Chresten R., Mats HM Olsson, Michal Rostkowski, and Jan
|
||||||
|
H. Jensen. "Improved Treatment of Ligands and Coupling Effects in
|
||||||
|
Empirical Calculation and Rationalization of pKa Values." Journal of
|
||||||
|
Chemical Theory and Computation 7, no. 7 (2011): 2284-2295.
|
||||||
|
|
||||||
|
* Olsson, Mats HM, Chresten R. Sondergaard, Michal Rostkowski, and Jan
|
||||||
|
H. Jensen. "PROPKA3: consistent treatment of internal and surface
|
||||||
|
residues in empirical pKa predictions." Journal of Chemical Theory
|
||||||
|
and Computation 7, no. 2 (2011): 525-537.
|
||||||
|
|
||||||
|
See http://propka.ki.ku.dk/ for the PROPKA web server,
|
||||||
|
using the tutorial http://propka.ki.ku.dk/~luca/wiki/index.php/PROPKA_3.1_Tutorial .
|
||||||
|
""",
|
||||||
|
author="Jan H. Jensen",
|
||||||
|
author_email="jhjensen@chem.ku.dk",
|
||||||
|
license="",
|
||||||
|
url="http://propka.ki.ku.dk/",
|
||||||
|
keywords="science",
|
||||||
|
packages=find_packages(exclude=['scripts']),
|
||||||
|
package_data = {'propka': ['*.dat', '*.cfg']},
|
||||||
|
#scripts = ["scripts/propka31.py"], # use entry point below
|
||||||
|
entry_points = {
|
||||||
|
'console_scripts': [
|
||||||
|
'propka31 = propka.run:main',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
zip_safe=True,
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user