From 894806356d7f0ee77d4a09b4ab9a9689d3df372b Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 17 Apr 2024 15:49:44 +0200 Subject: [PATCH 01/68] fix setup.py to copy hpb --- setup.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index ff26c5f96..c9080278c 100644 --- a/setup.py +++ b/setup.py @@ -7,6 +7,8 @@ from setuptools import setup from setuptools import Extension +import shutil + if sys.version_info[:2] < (2, 7): sys.stderr.write('Python 2.6 and older is not supported\n') sys.exit() @@ -94,7 +96,15 @@ from glob import glob tntDir = join('prody', 'utilities', 'tnt') -hpbDir = join('prody', 'proteins', 'hpbmodule') +hpbSoDir = join('prody', 'proteins', 'hpbmodule', + 'hpb_Python{0}.{1}'.format(sys.version_info[0], + sys.version_info[1])) +proteinsDir = join('prody', 'proteins') + +try: + shutil.copy(hpbSoDir + "/hpb.so", proteinsDir) +except FileNotFoundError: + pass EXTENSIONS = [ Extension('prody.dynamics.rtbtools', @@ -164,8 +174,8 @@ setup( name='ProDy', version=__version__, - author='James Krieger, She Zhang, Hongchun Li, Cihan Kaya, Ahmet Bakan, and others', - author_email='kriegerj@pitt.edu', + author='James Krieger, Karolina Mikulska-Ruminska, She Zhang, Hongchun Li, Cihan Kaya, Ahmet Bakan, and others', + author_email='jamesmkrieger@gmail.com', description='A Python Package for Protein Dynamics Analysis', long_description=long_description, url='http://www.csb.pitt.edu/ProDy', From 2ef2316c31329aa047aad7cd78c859ef59ab7d0a Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 17 Apr 2024 16:01:20 +0200 Subject: [PATCH 02/68] add test imported hpb --- prody/tests/proteins/test_insty.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/prody/tests/proteins/test_insty.py b/prody/tests/proteins/test_insty.py index 0fd6a47ac..ae364bb0b 100644 --- a/prody/tests/proteins/test_insty.py +++ b/prody/tests/proteins/test_insty.py @@ -12,6 +12,8 @@ from prody.proteins.interactions import calcPiCationTrajectory, calcHydrophobicTrajectory from prody.proteins.interactions import calcDisulfideBondsTrajectory, calcProteinInteractions +import sys + class TestInteractions(unittest.TestCase): def setUp(self): @@ -132,4 +134,20 @@ def testDisulfideBonds(self): assert_equal(sorted([i[-1][-1] for i in data_test if i]), sorted([i[-1][-1] for i in self.DISU_INTERACTIONS if i]), 'failed to get correct disulfide bonds') - + def testImportHpb(self): + imported_hpb = False + + try: + import prody.proteins.hpb as hpb + imported_hpb = True + except ImportError: + try: + import hpb + imported_hpb = True + except ImportError: + raise ImportError('Please provide hpb.so file.') + + if sys.version_info[1] < 11: + self.assertTrue(imported_hpb) + else: + self.assertFalse(imported_hpb) From 2ccd6a2ce424a71869d76c3ae1d661af7e480a54 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 17 Apr 2024 17:12:41 +0200 Subject: [PATCH 03/68] fix 311 test --- prody/tests/proteins/test_insty.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/prody/tests/proteins/test_insty.py b/prody/tests/proteins/test_insty.py index ae364bb0b..086fe3732 100644 --- a/prody/tests/proteins/test_insty.py +++ b/prody/tests/proteins/test_insty.py @@ -135,7 +135,6 @@ def testDisulfideBonds(self): 'failed to get correct disulfide bonds') def testImportHpb(self): - imported_hpb = False try: import prody.proteins.hpb as hpb @@ -145,7 +144,7 @@ def testImportHpb(self): import hpb imported_hpb = True except ImportError: - raise ImportError('Please provide hpb.so file.') + imported_hpb = False if sys.version_info[1] < 11: self.assertTrue(imported_hpb) From 9f4bf305945ee4f975fe41316e5ed51eb7aad6f7 Mon Sep 17 00:00:00 2001 From: exx Date: Sat, 27 Apr 2024 19:27:51 +0000 Subject: [PATCH 04/68] update --- docs/docs | 2 +- prody/chromatin/functions.py | 4 ++-- prody/dynamics/plotting.py | 4 ++-- prody/proteins/functions.py | 2 +- prody/proteins/pdbfile.py | 4 +--- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/docs b/docs/docs index 945c9b46d..7099f6ab8 120000 --- a/docs/docs +++ b/docs/docs @@ -1 +1 @@ -. \ No newline at end of file +ProDy/docs \ No newline at end of file diff --git a/prody/chromatin/functions.py b/prody/chromatin/functions.py index a9ed3a472..314fea2f3 100644 --- a/prody/chromatin/functions.py +++ b/prody/chromatin/functions.py @@ -212,7 +212,7 @@ def showEmbedding(modes, labels=None, trace=True, headtail=True, cmap='prism'): X, Y, Z = V[:,:3].T f = figure() - ax = f.add_subplot(projection="3d") + ax = f.add_subplot(1,1,1,projection="3d") if trace: ax.plot(X, Y, Z, ':', color=[0.3, 0.3, 0.3]) if labels is None: @@ -240,4 +240,4 @@ def getDomainList(labels): ends = sites[1:] domains = np.array([starts, ends]).T - return domains \ No newline at end of file + return domains diff --git a/prody/dynamics/plotting.py b/prody/dynamics/plotting.py index 37581c208..c81f343ed 100644 --- a/prody/dynamics/plotting.py +++ b/prody/dynamics/plotting.py @@ -109,7 +109,7 @@ def showEllipsoid(modes, onto=None, n_std=2, scale=1., *args, **kwargs): show = child break if show is None: - show = cf.add_subplot(projection="3d") + show = cf.add_subplot(1,1,1,projection="3d") show.plot_wireframe(x, y, z, rstride=6, cstride=6, *args, **kwargs) if onto is not None: onto = list(onto) @@ -408,7 +408,7 @@ def showProjection(ensemble, modes, *args, **kwargs): show = child break if show is None: - show = cf.add_subplot(projection="3d") + show = cf.add_subplot(1,1,1,projection="3d") plot = show.plot text = show.text diff --git a/prody/proteins/functions.py b/prody/proteins/functions.py index 1cf051a7c..f98eb50f6 100644 --- a/prody/proteins/functions.py +++ b/prody/proteins/functions.py @@ -266,7 +266,7 @@ def showProtein(*atoms, **kwargs): show = child break if show is None: - show = cf.add_subplot(projection="3d") + show = cf.add_subplot(1,1,1,projection="3d") #supports python 2.7 and matplotlib 2.2.5 from matplotlib import colors cnames = dict(colors.cnames) wcolor = kwargs.get('water', 'red').lower() diff --git a/prody/proteins/pdbfile.py b/prody/proteins/pdbfile.py index 127aae19a..5f132cc3c 100644 --- a/prody/proteins/pdbfile.py +++ b/prody/proteins/pdbfile.py @@ -122,7 +122,6 @@ def parsePDB(*pdb, **kwargs): if isListLike(pdb[0]) or isinstance(pdb[0], dict): pdb = pdb[0] n_pdb = len(pdb) - if n_pdb == 1: return _parsePDB(pdb[0], **kwargs) else: @@ -230,8 +229,7 @@ def _parsePDB(pdb, **kwargs): if len(title) == 7 and title.startswith('pdb'): title = title[3:] kwargs['title'] = title - - if pdb.endswith('.pdb') or pdb.endswith('.pdb.gz'): + if pdb.endswith('.pdb') or pdb.endswith('.pdb.gz') or pdb.endswith('.coor'): stream = openFile(pdb, 'rt') if chain != '': kwargs['chain'] = chain From c5734a32dcda48172e2e79065d542eece6522816 Mon Sep 17 00:00:00 2001 From: exx Date: Sat, 27 Apr 2024 19:31:02 +0000 Subject: [PATCH 05/68] Revert "update" This reverts commit 9f4bf305945ee4f975fe41316e5ed51eb7aad6f7. no update, fix conflicts. --- docs/docs | 2 +- prody/chromatin/functions.py | 4 ++-- prody/dynamics/plotting.py | 4 ++-- prody/proteins/functions.py | 2 +- prody/proteins/pdbfile.py | 4 +++- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/docs b/docs/docs index 7099f6ab8..945c9b46d 120000 --- a/docs/docs +++ b/docs/docs @@ -1 +1 @@ -ProDy/docs \ No newline at end of file +. \ No newline at end of file diff --git a/prody/chromatin/functions.py b/prody/chromatin/functions.py index 314fea2f3..a9ed3a472 100644 --- a/prody/chromatin/functions.py +++ b/prody/chromatin/functions.py @@ -212,7 +212,7 @@ def showEmbedding(modes, labels=None, trace=True, headtail=True, cmap='prism'): X, Y, Z = V[:,:3].T f = figure() - ax = f.add_subplot(1,1,1,projection="3d") + ax = f.add_subplot(projection="3d") if trace: ax.plot(X, Y, Z, ':', color=[0.3, 0.3, 0.3]) if labels is None: @@ -240,4 +240,4 @@ def getDomainList(labels): ends = sites[1:] domains = np.array([starts, ends]).T - return domains + return domains \ No newline at end of file diff --git a/prody/dynamics/plotting.py b/prody/dynamics/plotting.py index c81f343ed..37581c208 100644 --- a/prody/dynamics/plotting.py +++ b/prody/dynamics/plotting.py @@ -109,7 +109,7 @@ def showEllipsoid(modes, onto=None, n_std=2, scale=1., *args, **kwargs): show = child break if show is None: - show = cf.add_subplot(1,1,1,projection="3d") + show = cf.add_subplot(projection="3d") show.plot_wireframe(x, y, z, rstride=6, cstride=6, *args, **kwargs) if onto is not None: onto = list(onto) @@ -408,7 +408,7 @@ def showProjection(ensemble, modes, *args, **kwargs): show = child break if show is None: - show = cf.add_subplot(1,1,1,projection="3d") + show = cf.add_subplot(projection="3d") plot = show.plot text = show.text diff --git a/prody/proteins/functions.py b/prody/proteins/functions.py index f98eb50f6..1cf051a7c 100644 --- a/prody/proteins/functions.py +++ b/prody/proteins/functions.py @@ -266,7 +266,7 @@ def showProtein(*atoms, **kwargs): show = child break if show is None: - show = cf.add_subplot(1,1,1,projection="3d") #supports python 2.7 and matplotlib 2.2.5 + show = cf.add_subplot(projection="3d") from matplotlib import colors cnames = dict(colors.cnames) wcolor = kwargs.get('water', 'red').lower() diff --git a/prody/proteins/pdbfile.py b/prody/proteins/pdbfile.py index 5f132cc3c..127aae19a 100644 --- a/prody/proteins/pdbfile.py +++ b/prody/proteins/pdbfile.py @@ -122,6 +122,7 @@ def parsePDB(*pdb, **kwargs): if isListLike(pdb[0]) or isinstance(pdb[0], dict): pdb = pdb[0] n_pdb = len(pdb) + if n_pdb == 1: return _parsePDB(pdb[0], **kwargs) else: @@ -229,7 +230,8 @@ def _parsePDB(pdb, **kwargs): if len(title) == 7 and title.startswith('pdb'): title = title[3:] kwargs['title'] = title - if pdb.endswith('.pdb') or pdb.endswith('.pdb.gz') or pdb.endswith('.coor'): + + if pdb.endswith('.pdb') or pdb.endswith('.pdb.gz'): stream = openFile(pdb, 'rt') if chain != '': kwargs['chain'] = chain From ccbde645243df63ec665f5fc10912cc84edf8e10 Mon Sep 17 00:00:00 2001 From: exx Date: Fri, 7 Jun 2024 16:21:06 -0400 Subject: [PATCH 06/68] remote f"" string --- prody/proteins/waterbridges.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prody/proteins/waterbridges.py b/prody/proteins/waterbridges.py index a01c9f114..77b3b0d9e 100644 --- a/prody/proteins/waterbridges.py +++ b/prody/proteins/waterbridges.py @@ -257,8 +257,8 @@ def getInfoOutput(waterBridgesAtomic): bridgeOutput = [] for atom in bridge.proteins: - residueInfo = f"{atom.getResname()}{atom.getResnum()}" - atomInfo = f"{atom.getName()}_{atom.getIndex()}" + residueInfo = "{atom.getResname()}{atom.getResnum()}" + atomInfo = "{atom.getName()}_{atom.getIndex()}" chainInfo = atom.getChid() bridgeOutput += [residueInfo, atomInfo, chainInfo] @@ -267,7 +267,7 @@ def getInfoOutput(waterBridgesAtomic): bridgeOutput += [len(bridge.waters)] bridgeOutput += [ - list(map(lambda w: f"{w.getChid()}_{w.getIndex()}", bridge.waters))] + list(map(lambda w: "{w.getChid()}_{w.getIndex()}", bridge.waters))] output.append(bridgeOutput) @@ -308,7 +308,7 @@ def getAtomicOutput(waterBridges, relations): def getElementsRegex(elements): - return f'[{"|".join(elements)}].*' + return '[{"|".join(elements)}].*' def calcWaterBridges(atoms, **kwargs): From 42718b40be485c1c82663ea65236f3b7b49d39c9 Mon Sep 17 00:00:00 2001 From: exx Date: Mon, 5 Aug 2024 09:33:58 -0400 Subject: [PATCH 07/68] update --- docs/about/people.rst | 25 +++++++++++++++++------- docs/docs | 2 +- docs/reference/proteins/waterbridges.rst | 2 +- docs/release/index.rst | 23 ++-------------------- prody/chromatin/functions.py | 4 ++-- prody/dynamics/plotting.py | 4 ++-- prody/dynamics/sampling.py | 4 ++-- prody/proteins/functions.py | 2 +- 8 files changed, 29 insertions(+), 37 deletions(-) diff --git a/docs/about/people.rst b/docs/about/people.rst index a46c0516a..a092a2098 100644 --- a/docs/about/people.rst +++ b/docs/about/people.rst @@ -21,10 +21,12 @@ Development Team `James Krieger`_ was helping develop *ProDy* from 2017 and became the main overseer and developer in mid 2020. -`Hongchun Li`_ is currently maintaining and developing ANM and GNM servers, +`Hongchun Li`_ has helped maintain and develop ANM and GNM servers, and made significant contributions to :mod:`.database` and :mod:`.dynamics` including *SignDy* and Adaptive ANM. +`JiYoung Lee`_ is the main developer of :mod:`.Pharmmaker`, for constructing pharmacophore models using the outputs from :mod:`.DruGUI`. + `Yan Zhang`_ contributed significantly to the development of the *cryo-EM* module, :mod:`.protein.emdmap`. @@ -32,9 +34,9 @@ the *cryo-EM* module, :mod:`.protein.emdmap`. :mod:`.domain_decomposition`, :mod:`.dynamics.essa`, and :mod:`.dynamics.clustenm`. -`Karolina Mikulska-Ruminska`_ contributed significantly to the development of +`Karolina Mikulska-Ruminska`_ is one of the main developers since 2022, with the addition of the new modules :mod:`.protein.interactions` (*InSty*), :mod:`.protein.waterbridges` -(*WatFinder*), and :mod:`.dynamics.mechstiff` (*MechStiff*). +(*WatFinder*), in addition to being the developer of :mod:`.dynamics.mechstiff` (*MechStiff*). `Anthony Bogetti`_ is overseeing the overall development of *ProDy* since 2024. @@ -50,6 +52,12 @@ Blocks and Membrane ENM. `Lidio Meireles`_ provided insightful comments on the design of *ProDy*, and contributed to the development of :ref:`prody-apps`. +`Mustafa Tekpinar`_ contributed to the development of MechStiff. + +`Luca Ponzoni`_ contributed to the development of SignDy. + +`David Koes`_ contributed to the development of drug discovery tools. + Contributors ------------ @@ -67,7 +75,6 @@ contributions and feedback from the following individuals: insights. - .. _Ahmet Bakan: https://scholar.google.com/citations?user=-QAYVgMAAAAJ&hl=en .. _Cihan Kaya: https://www.linkedin.com/in/cihan-kaya/ .. _Bahar Lab: http://www.bahargroup.org/Faculty/bahar/ @@ -75,9 +82,9 @@ insights. .. _Anindita Dutta: http://www.linkedin.com/pub/anindita-dutta/5a/568/a90 .. _Wenzhi Mao: http://www.linkedin.com/pub/wenzhi-mao/2a/29a/29 .. _Lidio Meireles: http://www.linkedin.com/in/lidio -.. _Ying Liu: http://www.linkedin.com/pub/ying-liu/15/48b/5a9 +.. _Ying Liu: https://www.linkedin.com/in/yingliu03/ .. _Kian Ho: https://github.com/kianho -.. _Gökçen Eraslan: http://blog.yeredusuncedernegi.com/ +.. _Gökçen Eraslan: https://github.com/gokceneraslan .. _Tim Lezon: https://scholar.google.pl/citations?user=1MwNI3EAAAAJ&hl=pl&oi=ao .. _Chakra Chennubhotla: http://www.csb.pitt.edu/Faculty/Chakra/ .. _She (John) Zhang: https://www.linkedin.com/in/she-zhang-49164399/ @@ -87,4 +94,8 @@ insights. .. _Burak Kaynak: https://scholar.google.pl/citations?user=gP8RokwAAAAJ&hl=pl&oi=ao .. _Karolina Mikulska-Ruminska: https://scholar.google.pl/citations?user=IpyPHRwAAAAJ&hl=pl .. _Anthony Bogetti: https://scholar.google.pl/citations?hl=pl&user=9qQClIcAAAAJ -.. _Frane Doljanin: https://github.com/fdoljanin \ No newline at end of file +.. _Frane Doljanin: https://github.com/fdoljanin +.. _JiYoung Lee: https://scholar.google.com/citations?user=odKQmZcAAAAJ&hl=en +.. _David Koes: https://bits.csb.pitt.edu/ +.. _Luca Ponzoni: https://scholar.google.it/citations?user=8vfPOYUAAAAJ&hl=en +.. _Mustafa Tekpinar: https://scholar.google.com/citations?user=qeVv6o8AAAAJ&hl=en diff --git a/docs/docs b/docs/docs index 945c9b46d..7099f6ab8 120000 --- a/docs/docs +++ b/docs/docs @@ -1 +1 @@ -. \ No newline at end of file +ProDy/docs \ No newline at end of file diff --git a/docs/reference/proteins/waterbridges.rst b/docs/reference/proteins/waterbridges.rst index a41a8e09b..148fab777 100644 --- a/docs/reference/proteins/waterbridges.rst +++ b/docs/reference/proteins/waterbridges.rst @@ -3,4 +3,4 @@ Water bridge finder (WatFinder) .. automodule:: prody.proteins.waterbridges :members: - :undoc-members: \ No newline at end of file + :undoc-members: diff --git a/docs/release/index.rst b/docs/release/index.rst index 2007f5566..e56673ff5 100644 --- a/docs/release/index.rst +++ b/docs/release/index.rst @@ -9,24 +9,5 @@ Release Notes .. toctree:: :maxdepth: 2 :glob: - - v2.0_series - v1.11_series - v1.10_series - v1.9_series - v1.8_series - v1.7_series - v1.6_series - v1.5_series - v1.4_series - v1.3_series - v1.2_series - v1.1_series - v1.0_series - v0.9_series - v0.8_series - v0.7_series - v0.6_series - v0.5_series - v0.2_series - v0.1_series + + ./v* diff --git a/prody/chromatin/functions.py b/prody/chromatin/functions.py index a9ed3a472..314fea2f3 100644 --- a/prody/chromatin/functions.py +++ b/prody/chromatin/functions.py @@ -212,7 +212,7 @@ def showEmbedding(modes, labels=None, trace=True, headtail=True, cmap='prism'): X, Y, Z = V[:,:3].T f = figure() - ax = f.add_subplot(projection="3d") + ax = f.add_subplot(1,1,1,projection="3d") if trace: ax.plot(X, Y, Z, ':', color=[0.3, 0.3, 0.3]) if labels is None: @@ -240,4 +240,4 @@ def getDomainList(labels): ends = sites[1:] domains = np.array([starts, ends]).T - return domains \ No newline at end of file + return domains diff --git a/prody/dynamics/plotting.py b/prody/dynamics/plotting.py index e8bc603e4..d814d3f4c 100644 --- a/prody/dynamics/plotting.py +++ b/prody/dynamics/plotting.py @@ -110,7 +110,7 @@ def showEllipsoid(modes, onto=None, n_std=2, scale=1., *args, **kwargs): show = child break if show is None: - show = cf.add_subplot(projection="3d") + show = cf.add_subplot(111,projection="3d") show.plot_wireframe(x, y, z, rstride=6, cstride=6, *args, **kwargs) if onto is not None: onto = list(onto) @@ -421,7 +421,7 @@ def showProjection(ensemble=None, modes=None, projection=None, *args, **kwargs): show = child break if show is None: - show = cf.add_subplot(projection="3d") + show = cf.add_subplot(111,projection="3d") plot = show.plot text = show.text diff --git a/prody/dynamics/sampling.py b/prody/dynamics/sampling.py index dd2c66453..d6393d692 100644 --- a/prody/dynamics/sampling.py +++ b/prody/dynamics/sampling.py @@ -49,11 +49,11 @@ def sampleModes(modes, atoms=None, n_confs=1000, rmsd=1.0): :math:`[r_1^k r_2^k ... r_m^k]` are normally distributed random numbers generated for conformation :math:`k` using :func:`numpy.random.randn`. - RMSD of the new conformation from :math:`R_0` can be calculated as + RMSD of the new TEST conformation from :math:`R_0` can be calculated as .. math:: - RMSD^k = \\sqrt{ {\\left( s \\sum_{i=1}^{m} r_i^k \\lambda^{-0.5}_i u_i \\right)}^{2} / N } = \\frac{s}{ \\sqrt{N}} \\sqrt{ \\sum_{i=1}^{m} (r_i^k)^2 \\lambda^{-1}_i } + RMSD^k = \\sqrt{ { \\left( s \\sum_{i=1}^{m} r_i^k \\lambda^{-0.5}_i u_i \\right ) }^{2} / N } = \\frac{s}{ \\sqrt{N}} \\sqrt{ \\sum_{i=1}^{m} (r_i^k)^2 \\lambda^{-1}_i } Average :math:`RMSD` of the generated conformations from the initial conformation is: diff --git a/prody/proteins/functions.py b/prody/proteins/functions.py index 1cf051a7c..a07dcb1c1 100644 --- a/prody/proteins/functions.py +++ b/prody/proteins/functions.py @@ -266,7 +266,7 @@ def showProtein(*atoms, **kwargs): show = child break if show is None: - show = cf.add_subplot(projection="3d") + show = cf.add_subplot(1,1,1,projection="3d") from matplotlib import colors cnames = dict(colors.cnames) wcolor = kwargs.get('water', 'red').lower() From ef357ce73b24f2e6f138c7dd57798b9b706cb067 Mon Sep 17 00:00:00 2001 From: exx Date: Mon, 5 Aug 2024 09:49:40 -0400 Subject: [PATCH 08/68] update waterbridges.py --- prody/proteins/waterbridges.py | 44 +++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/prody/proteins/waterbridges.py b/prody/proteins/waterbridges.py index 9a504e486..acc35d58b 100644 --- a/prody/proteins/waterbridges.py +++ b/prody/proteins/waterbridges.py @@ -12,7 +12,17 @@ from itertools import combinations from collections import deque -from enum import Enum, auto +import sys +if sys.version_info[0] == 3: + from enum import Enum, auto +else: + from enum import Enum + import enum + from itertools import count + def auto(it=count()): + return next(it) + enum.auto=auto +#from enum import Enum, auto from copy import copy from prody import LOGGER, SETTINGS @@ -393,7 +403,7 @@ def calcWaterBridges(atoms, **kwargs): relations = RelationList(len(atoms)) tooFarAtoms = atoms.select( - f'water and not within {distWR} of protein') + 'water and not within {distWR} of protein') if tooFarAtoms is None: consideredAtoms = atoms else: @@ -410,9 +420,9 @@ def calcWaterBridges(atoms, **kwargs): relations[oxygen].hydrogens.append(hydrogen) proteinHydrophilic = consideredAtoms.select( - f'protein and name "{getElementsRegex(set(donors+acceptors))}" and within {distWR} of water') + 'protein and name "{getElementsRegex(set(donors+acceptors))}" and within {distWR} of water') - proteinHydrogens = consideredAtoms.select(f'protein and hydrogen') or [] + proteinHydrogens = consideredAtoms.select('protein and hydrogen') or [] proteinHydroPairs = findNeighbors( proteinHydrophilic, DIST_COVALENT_H, proteinHydrogens) for hydrophilic in proteinHydrophilic: @@ -451,7 +461,7 @@ def calcWaterBridges(atoms, **kwargs): waterBridgesWithIndices, getChainBridgeTuple) LOGGER.info( - f'{len(waterBridgesWithIndices)} water bridges detected using method {method}.') + '{len(waterBridgesWithIndices)} water bridges detected using method {method}.') if method == 'atomic': LOGGER.info('Call getInfoOutput to convert atomic to info output.') @@ -527,7 +537,7 @@ def calcWaterBridgesTrajectory(atoms, trajectory, **kwargs): def getResidueName(atom): - return f'{atom.getResname()}{atom.getResnum()}{atom.getChid()}' + return '{atom.getResname()}{atom.getResnum()}{atom.getChid()}' class DictionaryList: @@ -561,7 +571,7 @@ def getResInfo(atoms): chids = atoms.select('protein').getChids() for i, num in enumerate(nums): - dict[num] = f"{names[i]}{num}{chids[i]}" + dict[num] = "{names[i]}{num}{chids[i]}" return dict @@ -642,7 +652,7 @@ def calcWaterBridgesStatistics(frames, trajectory, **kwargs): interactionCount.removeDuplicateKeys( lambda keys, key: (key[1], key[0]) in keys) - tableHeader = f'{"RES1":<15}{"RES2":<15}{"PERC":<10}{"DIST_AVG":<10}{"DIST_STD":<10}' + tableHeader = '{"RES1":<15}{"RES2":<15}{"PERC":<10}{"DIST_AVG":<10}{"DIST_STD":<10}' LOGGER.info(tableHeader) info = {} file = open(filename, 'w') if filename else None @@ -665,7 +675,7 @@ def calcWaterBridgesStatistics(frames, trajectory, **kwargs): key1, key2 = (x, y), (y, x) info[key1], info[key2] = pairInfo, pairInfo - tableRow = f'{resNames[x]:<15}{resNames[y]:<15}{percentage:<10.3f}{distAvg:<10.3f}{distStd:<10.3f}' + tableRow = '{resNames[x]:<15}{resNames[y]:<15}{percentage:<10.3f}{distAvg:<10.3f}{distStd:<10.3f}' LOGGER.info(tableRow) if file: file.write(tableRow + '\n') @@ -731,7 +741,7 @@ def mofifyBeta(bridgeFrames, atoms): atoms.setBetas(0) for resnum, value in residueOccurances.items(): residueAtoms = atoms.select( - f'resnum {resnum}') + 'resnum {resnum}') beta = value/len(bridgeFrames) residueAtoms.setBetas(beta) @@ -915,7 +925,7 @@ def calcWaterBridgesDistribution(frames, res_a, res_b=None, **kwargs): plt.hist(result, rwidth=0.95, density=True) plt.xlabel('Value') plt.ylabel('Probability') - plt.title(f'Distribution: {metric}') + plt.title('Distribution: {metric}') if SETTINGS['auto_show']: showFigure() @@ -948,7 +958,7 @@ def savePDBWaterBridges(bridges, atoms, filename): waterOxygens = reduceTo1D( bridges, lambda w: w.getIndex(), lambda b: b.waters) waterAtoms = atoms.select( - f'same residue as water within 1.6 of index {" ".join(map(str, waterOxygens))}') + 'same residue as water within 1.6 of index {" ".join(map(str, waterOxygens))}') atomsToSave = proteinAtoms.toAtomGroup() + waterAtoms.toAtomGroup() return writePDB(filename, atomsToSave) @@ -985,21 +995,21 @@ def savePDBWaterBridgesTrajectory(bridgeFrames, atoms, filename, trajectory=None waterAtoms = reduceTo1D(frame, sublistSel=lambda b: b.waters) waterResidues = atoms.select( - f'same residue as water within 1.6 of index {" ".join(map(lambda a: str(a.getIndex()), waterAtoms))}') + 'same residue as water within 1.6 of index {" ".join(map(lambda a: str(a.getIndex()), waterAtoms))}') bridgeProteinAtoms = reduceTo1D( frame, lambda p: p.getResnum(), lambda b: b.proteins) atoms.setOccupancies(0) atoms.select( - f'resid {" ".join(map(str, bridgeProteinAtoms))}').setOccupancies(1) + 'resid {" ".join(map(str, bridgeProteinAtoms))}').setOccupancies(1) atomsToSave = atoms.select( 'protein').toAtomGroup() + waterResidues.toAtomGroup() if trajectory: - writePDB(f'{filename}_{frameIndex}.pdb', atomsToSave) + writePDB('{filename}_{frameIndex}.pdb', atomsToSave) else: - writePDB(f'{filename}_{frameIndex}.pdb', + writePDB('{filename}_{frameIndex}.pdb', atomsToSave, csets=frameIndex) @@ -1028,7 +1038,7 @@ def saveWaterBridges(atomicBridges, filename): if isInfoOutput: info = getWaterBridgesInfoOutput(atomicBridges) for frameIndex, frame in enumerate(info): - file.write(f'FRAME {frameIndex}\n') + file.write('FRAME {frameIndex}\n') for bridge in frame: file.write(' '.join(map(str, bridge)) + '\n') From b328d3ab4b45755dba525178d3a351f999dab152 Mon Sep 17 00:00:00 2001 From: exx Date: Mon, 5 Aug 2024 10:00:32 -0400 Subject: [PATCH 09/68] plotting update --- prody/chromatin/functions.py | 4 ++-- prody/dynamics/plotting.py | 4 ++-- prody/dynamics/sampling.py | 3 ++- prody/proteins/functions.py | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/prody/chromatin/functions.py b/prody/chromatin/functions.py index a9ed3a472..314fea2f3 100644 --- a/prody/chromatin/functions.py +++ b/prody/chromatin/functions.py @@ -212,7 +212,7 @@ def showEmbedding(modes, labels=None, trace=True, headtail=True, cmap='prism'): X, Y, Z = V[:,:3].T f = figure() - ax = f.add_subplot(projection="3d") + ax = f.add_subplot(1,1,1,projection="3d") if trace: ax.plot(X, Y, Z, ':', color=[0.3, 0.3, 0.3]) if labels is None: @@ -240,4 +240,4 @@ def getDomainList(labels): ends = sites[1:] domains = np.array([starts, ends]).T - return domains \ No newline at end of file + return domains diff --git a/prody/dynamics/plotting.py b/prody/dynamics/plotting.py index e8bc603e4..d814d3f4c 100644 --- a/prody/dynamics/plotting.py +++ b/prody/dynamics/plotting.py @@ -110,7 +110,7 @@ def showEllipsoid(modes, onto=None, n_std=2, scale=1., *args, **kwargs): show = child break if show is None: - show = cf.add_subplot(projection="3d") + show = cf.add_subplot(111,projection="3d") show.plot_wireframe(x, y, z, rstride=6, cstride=6, *args, **kwargs) if onto is not None: onto = list(onto) @@ -421,7 +421,7 @@ def showProjection(ensemble=None, modes=None, projection=None, *args, **kwargs): show = child break if show is None: - show = cf.add_subplot(projection="3d") + show = cf.add_subplot(111,projection="3d") plot = show.plot text = show.text diff --git a/prody/dynamics/sampling.py b/prody/dynamics/sampling.py index dd2c66453..272b230bd 100644 --- a/prody/dynamics/sampling.py +++ b/prody/dynamics/sampling.py @@ -51,9 +51,10 @@ def sampleModes(modes, atoms=None, n_confs=1000, rmsd=1.0): RMSD of the new conformation from :math:`R_0` can be calculated as + .. math:: - RMSD^k = \\sqrt{ {\\left( s \\sum_{i=1}^{m} r_i^k \\lambda^{-0.5}_i u_i \\right)}^{2} / N } = \\frac{s}{ \\sqrt{N}} \\sqrt{ \\sum_{i=1}^{m} (r_i^k)^2 \\lambda^{-1}_i } + RMSD^k = \\sqrt{ \\left[ s \\sum_{i=1}^{m} r_i^k \\lambda^{-0.5}_i u_i \\right] ^{2} / N } = \\frac{s}{ \\sqrt{N}} \\sqrt{ \\sum_{i=1}^{m} (r_i^k)^2 \\lambda^{-1}_i } Average :math:`RMSD` of the generated conformations from the initial conformation is: diff --git a/prody/proteins/functions.py b/prody/proteins/functions.py index 1cf051a7c..a07dcb1c1 100644 --- a/prody/proteins/functions.py +++ b/prody/proteins/functions.py @@ -266,7 +266,7 @@ def showProtein(*atoms, **kwargs): show = child break if show is None: - show = cf.add_subplot(projection="3d") + show = cf.add_subplot(1,1,1,projection="3d") from matplotlib import colors cnames = dict(colors.cnames) wcolor = kwargs.get('water', 'red').lower() From b770882436ac859217aa9f5ef0f90066f68a8ed3 Mon Sep 17 00:00:00 2001 From: exx Date: Thu, 15 Aug 2024 15:51:25 -0400 Subject: [PATCH 10/68] update index.rst, release --- docs/release/index.rst | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/release/index.rst b/docs/release/index.rst index e56673ff5..48fed306a 100644 --- a/docs/release/index.rst +++ b/docs/release/index.rst @@ -10,4 +10,27 @@ Release Notes :maxdepth: 2 :glob: - ./v* + v2.4_series + v2.3_series + v2.2_series + v2.1_series + v2.0_series + v1.11_series + v1.10_series + v1.9_series + v1.8_series + v1.7_series + v1.6_series + v1.5_series + v1.4_series + v1.3_series + v1.2_series + v1.1_series + v1.0_series + v0.9_series + v0.8_series + v0.7_series + v0.6_series + v0.5_series + v0.2_series + v0.1_series From 7a81abc16428cd891d951a12b06b5eb62c73e944 Mon Sep 17 00:00:00 2001 From: exx Date: Thu, 15 Aug 2024 18:15:25 -0400 Subject: [PATCH 11/68] update --- docs/release/index.rst | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/release/index.rst b/docs/release/index.rst index 48ce69e53..f017b8870 100644 --- a/docs/release/index.rst +++ b/docs/release/index.rst @@ -9,12 +9,8 @@ Release Notes .. toctree:: :maxdepth: 2 :glob: -<<<<<<< HEAD -======= - ->>>>>>> fd07b1ddad9b500e4536af16fe13d0b2f357cf60 - v2.4_series + v2.3_series v2.2_series v2.1_series From 596a9592ccd2d8a5035619813135b415df28d365 Mon Sep 17 00:00:00 2001 From: exx Date: Thu, 15 Aug 2024 20:55:19 -0400 Subject: [PATCH 12/68] update --- docs/release/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release/index.rst b/docs/release/index.rst index f017b8870..48fed306a 100644 --- a/docs/release/index.rst +++ b/docs/release/index.rst @@ -10,7 +10,7 @@ Release Notes :maxdepth: 2 :glob: - + v2.4_series v2.3_series v2.2_series v2.1_series From ad1b6f9222297c80522dad9e5f94bc31fb2c6f22 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Fri, 16 Aug 2024 19:07:31 +0200 Subject: [PATCH 13/68] fix watfinder conflicts --- prody/proteins/waterbridges.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/prody/proteins/waterbridges.py b/prody/proteins/waterbridges.py index 87f393ae6..3dbb3daba 100644 --- a/prody/proteins/waterbridges.py +++ b/prody/proteins/waterbridges.py @@ -484,16 +484,11 @@ def calcWaterBridges(atoms, **kwargs): waterBridgesWithIndices = getUniqueElements( waterBridgesWithIndices, getChainBridgeTuple) -<<<<<<< HEAD - LOGGER.info( - '{len(waterBridgesWithIndices)} water bridges detected using method {method}.') -======= log_string = f'{len(waterBridgesWithIndices)} water bridges detected using method {method}' if prefix != '': log_string += ' for ' + prefix LOGGER.info(log_string) ->>>>>>> 922b42658bcb002f4d54572ba2795f290c656ec9 if method == 'atomic': LOGGER.info('Call getInfoOutput to convert atomic to info output.') @@ -691,17 +686,12 @@ def analyseFrame(i, interactions_all): return interactions_all -<<<<<<< HEAD -def getResidueName(atom): - return '{atom.getResname()}{atom.getResnum()}{atom.getChid()}' -======= def getResidueName(atom, use_segname=False): result = f'{atom.getResname()}{atom.getResnum()}{atom.getChid()}' if use_segname: result += f'{atom.getSegname()}' return result ->>>>>>> 922b42658bcb002f4d54572ba2795f290c656ec9 class DictionaryList: From abd23e70406989b445f1958478694fff34918b47 Mon Sep 17 00:00:00 2001 From: exx Date: Mon, 19 Aug 2024 10:22:57 -0400 Subject: [PATCH 14/68] update sampling --- prody/dynamics/sampling.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/prody/dynamics/sampling.py b/prody/dynamics/sampling.py index 7ee55ebf7..272b230bd 100644 --- a/prody/dynamics/sampling.py +++ b/prody/dynamics/sampling.py @@ -49,16 +49,12 @@ def sampleModes(modes, atoms=None, n_confs=1000, rmsd=1.0): :math:`[r_1^k r_2^k ... r_m^k]` are normally distributed random numbers generated for conformation :math:`k` using :func:`numpy.random.randn`. - RMSD of the new TEST conformation from :math:`R_0` can be calculated as + RMSD of the new conformation from :math:`R_0` can be calculated as .. math:: -<<<<<<< HEAD - RMSD^k = \\sqrt{ { \\left( s \\sum_{i=1}^{m} r_i^k \\lambda^{-0.5}_i u_i \\right ) }^{2} / N } = \\frac{s}{ \\sqrt{N}} \\sqrt{ \\sum_{i=1}^{m} (r_i^k)^2 \\lambda^{-1}_i } -======= RMSD^k = \\sqrt{ \\left[ s \\sum_{i=1}^{m} r_i^k \\lambda^{-0.5}_i u_i \\right] ^{2} / N } = \\frac{s}{ \\sqrt{N}} \\sqrt{ \\sum_{i=1}^{m} (r_i^k)^2 \\lambda^{-1}_i } ->>>>>>> 4444f17f192dd0e9957c3eb63e5851ccafabd339 Average :math:`RMSD` of the generated conformations from the initial conformation is: From 4bd4f50306d2e5f50a6b8343cef0a16b13948187 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Mon, 19 Aug 2024 17:45:35 +0200 Subject: [PATCH 15/68] fix replace fstrings --- prody/proteins/waterbridges.py | 52 +++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/prody/proteins/waterbridges.py b/prody/proteins/waterbridges.py index 3dbb3daba..e8485944c 100644 --- a/prody/proteins/waterbridges.py +++ b/prody/proteins/waterbridges.py @@ -15,8 +15,9 @@ from itertools import combinations from collections import deque -import sys -if sys.version_info[0] == 3: + +from prody import PY3K +if PY3K: from enum import Enum, auto else: from enum import Enum @@ -25,7 +26,7 @@ def auto(it=count()): return next(it) enum.auto=auto -#from enum import Enum, auto + from copy import copy from prody import LOGGER, SETTINGS @@ -273,8 +274,10 @@ def getInfoOutput(waterBridgesAtomic): bridgeOutput = [] for atom in bridge.proteins: - residueInfo = "{atom.getResname()}{atom.getResnum()}" - atomInfo = "{atom.getName()}_{atom.getIndex()}" + residueInfo = "{0}{1}".format(atom.getResname(), + atom.getResnum()) + atomInfo = "{0}_{1}".format(atom.getName(), + atom.getIndex()) chainInfo = atom.getChid() bridgeOutput += [residueInfo, atomInfo, chainInfo] @@ -283,7 +286,9 @@ def getInfoOutput(waterBridgesAtomic): bridgeOutput += [len(bridge.waters)] bridgeOutput += [ - list(map(lambda w: "{w.getChid()}_{w.getIndex()}", bridge.waters))] + list(map(lambda w: "{0}_{1}".format(w.getChid(), + w.getIndex()), + bridge.waters))] output.append(bridgeOutput) @@ -427,7 +432,7 @@ def calcWaterBridges(atoms, **kwargs): relations = RelationList(len(atoms)) tooFarAtoms = atoms.select( - 'water and not within {distWR} of protein') + 'water and not within {0} of protein'.format(distWR)) if tooFarAtoms is None: consideredAtoms = atoms else: @@ -444,7 +449,8 @@ def calcWaterBridges(atoms, **kwargs): relations[oxygen].hydrogens.append(hydrogen) proteinHydrophilic = consideredAtoms.select( - 'protein and name "{getElementsRegex(set(donors+acceptors))}" and within {distWR} of water') + 'protein and name "{0}" and within {1} of water'.format( + getElementsRegex(set(donors+acceptors)), distWR)) proteinHydrogens = consideredAtoms.select('protein and hydrogen') or [] proteinHydroPairs = findNeighbors( @@ -484,7 +490,8 @@ def calcWaterBridges(atoms, **kwargs): waterBridgesWithIndices = getUniqueElements( waterBridgesWithIndices, getChainBridgeTuple) - log_string = f'{len(waterBridgesWithIndices)} water bridges detected using method {method}' + log_string = '{0} water bridges detected using method {1}'.format( + len(waterBridgesWithIndices), method) if prefix != '': log_string += ' for ' + prefix LOGGER.info(log_string) @@ -806,7 +813,8 @@ def calcWaterBridgesStatistics(frames, trajectory, **kwargs): interactionCount.removeDuplicateKeys( lambda keys, key: (key[1], key[0]) in keys) - tableHeader = '{"RES1":<15}{"RES2":<15}{"PERC":<10}{"DIST_AVG":<10}{"DIST_STD":<10}' + tableHeader = '{0:<15}{1:<15}{2:<10}{3:<10}{4:<10}'.format( + "RES1", "RES2", "PERC", "DIST_AVG", "DIST_STD") LOGGER.info(tableHeader) info = {} file = open(filename, 'w') if filename else None @@ -829,7 +837,8 @@ def calcWaterBridgesStatistics(frames, trajectory, **kwargs): key1, key2 = (x, y), (y, x) info[key1], info[key2] = pairInfo, pairInfo - tableRow = '{resNames[x]:<15}{resNames[y]:<15}{percentage:<10.3f}{distAvg:<10.3f}{distStd:<10.3f}' + tableRow = '{0:<15}{1:<15}{2:<10.3f}{3:<10.3f}{4:<10.3f}'.format( + resNames[x], resNames[y], percentage, distAvg, distStd) LOGGER.info(tableRow) if file: file.write(tableRow + '\n') @@ -895,7 +904,7 @@ def mofifyBeta(bridgeFrames, atoms): atoms.setBetas(0) for resnum, value in residueOccurances.items(): residueAtoms = atoms.select( - 'resnum {resnum}') + 'resnum {0}'.format(resnum)) beta = value/len(bridgeFrames) residueAtoms.setBetas(beta) @@ -1085,7 +1094,7 @@ def calcWaterBridgesDistribution(frames, res_a, res_b=None, **kwargs): plt.hist(result, rwidth=0.95, density=True) plt.xlabel('Value') plt.ylabel('Probability') - plt.title('Distribution: {metric}') + plt.title('Distribution: {0}'.format(metric)) if SETTINGS['auto_show']: showFigure() @@ -1118,7 +1127,8 @@ def savePDBWaterBridges(bridges, atoms, filename): waterOxygens = reduceTo1D( bridges, lambda w: w.getIndex(), lambda b: b.waters) waterAtoms = atoms.select( - 'same residue as water within 1.6 of index {" ".join(map(str, waterOxygens))}') + 'same residue as water within 1.6 of index {0}'.format( + " ".join(map(str, waterOxygens)))) atomsToSave = proteinAtoms.toAtomGroup() + waterAtoms.toAtomGroup() return writePDB(filename, atomsToSave) @@ -1157,21 +1167,23 @@ def saveBridgesFrame(trajectory, atoms, frameIndex, frame): waterAtoms = reduceTo1D(frame, sublistSel=lambda b: b.waters) waterResidues = atoms.select( - 'same residue as water within 1.6 of index {" ".join(map(lambda a: str(a.getIndex()), waterAtoms))}') + 'same residue as water within 1.6 of index {0}'.format( + " ".join(map(lambda a: str(a.getIndex()), waterAtoms)))) bridgeProteinAtoms = reduceTo1D( frame, lambda p: p.getResnum(), lambda b: b.proteins) atoms.setOccupancies(0) - atoms.select( - 'resid {" ".join(map(str, bridgeProteinAtoms))}').setOccupancies(1) + atoms.select('resid {0}'.format( + " ".join(map(str, bridgeProteinAtoms)))).setOccupancies(1) atomsToSave = atoms.select( 'protein').toAtomGroup() + waterResidues.toAtomGroup() if trajectory: - writePDB('{filename}_{frameIndex}.pdb', atomsToSave) + writePDB('{0}_{1}.pdb'.format(filename, frameIndex), + atomsToSave) else: - writePDB('{filename}_{frameIndex}.pdb', + writePDB('{0}_{1}.pdb'.format(filename, frameIndex), atomsToSave, csets=frameIndex) if max_proc == 1: @@ -1220,7 +1232,7 @@ def saveWaterBridges(atomicBridges, filename): if isInfoOutput: info = getWaterBridgesInfoOutput(atomicBridges) for frameIndex, frame in enumerate(info): - file.write('FRAME {frameIndex}\n') + file.write('FRAME {0}\n'.format(frameIndex)) for bridge in frame: file.write(' '.join(map(str, bridge)) + '\n') From 863b0cbf750ad3d8e25e246e21b8b94435a283df Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 21 Aug 2024 13:01:48 +0200 Subject: [PATCH 16/68] fix missed getElementsRegex --- prody/proteins/waterbridges.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prody/proteins/waterbridges.py b/prody/proteins/waterbridges.py index e8485944c..95c12808e 100644 --- a/prody/proteins/waterbridges.py +++ b/prody/proteins/waterbridges.py @@ -329,7 +329,7 @@ def getAtomicOutput(waterBridges, relations): def getElementsRegex(elements): - return '[{"|".join(elements)}].*' + return '[{0}].*'.format("|".join(elements)) def calcWaterBridges(atoms, **kwargs): From e5a8fcd6485599b2f9c13a2048e741d9e53df326 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 21 Aug 2024 19:47:56 +0200 Subject: [PATCH 17/68] fix localpdb gz check --- prody/proteins/localpdb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prody/proteins/localpdb.py b/prody/proteins/localpdb.py index ed032953f..a28cd74b5 100644 --- a/prody/proteins/localpdb.py +++ b/prody/proteins/localpdb.py @@ -485,8 +485,8 @@ def findPDBFiles(path, case=None, **kwargs): for fn in iterPDBFilenames(path, sort=True, reverse=True, **kwargs): fn = normpath(fn) pdb = splitext(split(fn)[1])[0] - ending = splitext(splitext(split(fn)[1])[0])[1] - if ending == 'gz': + ending = splitext(split(fn)[1])[1] + if ending == '.gz': pdb = splitext(pdb)[0] if len(pdb) == 7 and pdb.startswith('pdb'): pdb = pdb[3:] From a93f2f65ac4aea44df33ef90c5a06c9332235ee2 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 13:50:23 +0200 Subject: [PATCH 18/68] change overlaping to overlapping in docs, comments and logging --- prody/proteins/interactions.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 40f3dd3d6..c8d04acca 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -163,7 +163,7 @@ def calcHydrophobicOverlapingAreas(atoms, **kwargs): :arg selection: selection string of hydrophobic residues :type selection: str - :arg hpb_cutoff: cutoff for hydrophobic overlaping area values + :arg hpb_cutoff: cutoff for hydrophobic overlapping area values default is 0.0 :type hpb_cutoff: float, int @@ -200,7 +200,7 @@ def calcHydrophobicOverlapingAreas(atoms, **kwargs): lA = [ [x[i] + str(y[i]), z[i] +'_'+ str(w[i]), ch[i]] for i in range(len(x))] output = hpb.hpb((lB,lA)) - LOGGER.info("Hydrophobic Overlaping Areas are computed.") + LOGGER.info("Hydrophobic Overlapping Areas are computed.") output_final = [i for i in output if i[-1] >= hpb_cutoff] if cumulative_values == None: @@ -1000,11 +1000,11 @@ def calcHydrophobic(atoms, **kwargs): non_standard works too :type non_standard_Hph: dict - :arg zerosHPh: zero values of hydrophobic overlaping areas included + :arg zerosHPh: zero values of hydrophobic overlapping areas included default is False :type zerosHPh: bool - Last value in the output corresponds to the total hydrophobic overlaping area for two residues + Last value in the output corresponds to the total hydrophobic overlapping area for two residues not only for the atoms that are included in the list. Atoms that which are listed are the closest between two residues and they will be inluded to draw the line in VMD_. @@ -1065,7 +1065,7 @@ def calcHydrophobic(atoms, **kwargs): aromatic_nr = list(set(zip(atoms.aromatic.getResnums(),atoms.aromatic.getChids()))) aromatic = list(set(atoms.aromatic.getResnames())) - # Computing hydrophobic overlaping areas for pairs of residues: + # Computing hydrophobic overlapping areas for pairs of residues: try: hpb_overlaping_results = calcHydrophobicOverlapingAreas(atoms_hydrophobic, cumulative_values='pairs') except: From 92abc7286418dc1348e957ffc9cea8eb4ddcbcda Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 14:33:47 +0200 Subject: [PATCH 19/68] remove files at end of test --- prody/tests/proteins/test_insty.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/prody/tests/proteins/test_insty.py b/prody/tests/proteins/test_insty.py index 086fe3732..a378407a4 100644 --- a/prody/tests/proteins/test_insty.py +++ b/prody/tests/proteins/test_insty.py @@ -150,3 +150,11 @@ def testImportHpb(self): self.assertTrue(imported_hpb) else: self.assertFalse(imported_hpb) + + @classmethod + def tearDownClass(cls): + import os + for filename in ['test_2k39_all.npy', 'test_2k39_hbs.npy', 'test_2k39_sbs.npy', + 'test_2k39_rib.npy', 'test_2k39_PiStack.npy', 'test_2k39_PiCat.npy', + 'test_2k39_hph.npy', 'test_2k39_disu.npy']: + os.remove(filename) From a48d4d0880b92d30608c2615606aab04a7d4dcd5 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 14:34:25 +0200 Subject: [PATCH 20/68] fix test name not used elsewhere --- prody/tests/proteins/test_insty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prody/tests/proteins/test_insty.py b/prody/tests/proteins/test_insty.py index a378407a4..7ea6a08f1 100644 --- a/prody/tests/proteins/test_insty.py +++ b/prody/tests/proteins/test_insty.py @@ -57,7 +57,7 @@ def setUp(self): self.data_disu = calcDisulfideBondsTrajectory(self.ATOMS) np.save('test_2k39_disu.npy', np.array(self.data_disu, dtype=object), allow_pickle=True) - def testAllInsteractions(self): + def testAllInteractions(self): """Test for all types of interactions.""" if prody.PY3K: From 83224a4104509206e7c807f8f55ee2e430184058 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 12:31:57 +0200 Subject: [PATCH 21/68] add so files to manifest.in --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index c58a255b9..a33dfffad 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -9,6 +9,7 @@ include prody/*/*.cpp include prody/*/*/*.cpp include prody/*/*.h include prody/*/*/*.h +include prody/*/*/*/*.so include prody/tests/*/*.py include prody/tests/datafiles/*.coo include prody/tests/datafiles/*.dcd From dbaff7ea7de3123ac71adce2dab85b0ff3097b79 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 15:30:07 +0200 Subject: [PATCH 22/68] remove files with PY3 --- prody/tests/proteins/test_insty.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/prody/tests/proteins/test_insty.py b/prody/tests/proteins/test_insty.py index 7ea6a08f1..5f6eeb22f 100644 --- a/prody/tests/proteins/test_insty.py +++ b/prody/tests/proteins/test_insty.py @@ -153,8 +153,9 @@ def testImportHpb(self): @classmethod def tearDownClass(cls): - import os - for filename in ['test_2k39_all.npy', 'test_2k39_hbs.npy', 'test_2k39_sbs.npy', - 'test_2k39_rib.npy', 'test_2k39_PiStack.npy', 'test_2k39_PiCat.npy', - 'test_2k39_hph.npy', 'test_2k39_disu.npy']: - os.remove(filename) + if PY3K: + import os + for filename in ['test_2k39_all.npy', 'test_2k39_hbs.npy', 'test_2k39_sbs.npy', + 'test_2k39_rib.npy', 'test_2k39_PiStack.npy', 'test_2k39_PiCat.npy', + 'test_2k39_hph.npy', 'test_2k39_disu.npy']: + os.remove(filename) From 9ae04c55f3d06c69deee34c62bf67a5a5540fab6 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 16:57:57 +0200 Subject: [PATCH 23/68] fix PY3K to prody.PY3K in tear down --- prody/tests/proteins/test_insty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prody/tests/proteins/test_insty.py b/prody/tests/proteins/test_insty.py index 5f6eeb22f..fefe27258 100644 --- a/prody/tests/proteins/test_insty.py +++ b/prody/tests/proteins/test_insty.py @@ -153,7 +153,7 @@ def testImportHpb(self): @classmethod def tearDownClass(cls): - if PY3K: + if prody.PY3K: import os for filename in ['test_2k39_all.npy', 'test_2k39_hbs.npy', 'test_2k39_sbs.npy', 'test_2k39_rib.npy', 'test_2k39_PiStack.npy', 'test_2k39_PiCat.npy', From 27f2a3b78f52b8423a967fa65e8ed2e3bf1cc6cf Mon Sep 17 00:00:00 2001 From: exx Date: Thu, 22 Aug 2024 12:07:15 -0400 Subject: [PATCH 24/68] update website.rst --- docs/devel/website.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/devel/website.rst b/docs/devel/website.rst index e1ef59965..3de4d9bb4 100644 --- a/docs/devel/website.rst +++ b/docs/devel/website.rst @@ -14,7 +14,7 @@ This is a short guide for building the ProDy website. Environment Setup -------------- -First log in to the ProDy webserver (prody.csb.pitt.edu) then run the following:: +First log in to your ProDy webserver and then run the following:: $ conda deactivate @@ -34,7 +34,7 @@ ProDy-website-workdir. You can then copy files back over afterwards. It's recommended to have the symbolic link called test_prody pointing to your build directory instead and then you can monitor changes by going to -http://prody.csb.pitt.edu/test_prody/_build/html/ in your web browser. +http://yourdomainname/test_prody/_build/html/ in your web browser. Updating from GitHub From 47e14ebe9b0b2b7d6bb2d3a424ee405905e10d99 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 20:27:08 +0200 Subject: [PATCH 25/68] add v2.5_series to release index --- docs/release/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release/index.rst b/docs/release/index.rst index 48fed306a..f838d806b 100644 --- a/docs/release/index.rst +++ b/docs/release/index.rst @@ -10,6 +10,7 @@ Release Notes :maxdepth: 2 :glob: + v2.5_series v2.4_series v2.3_series v2.2_series From bc004a6f646cb08e498e700302815e7c48ae974d Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Thu, 29 Aug 2024 23:02:06 +0200 Subject: [PATCH 26/68] Function to get energy for pair of residues [by Anthony with modification is added] --- prody/proteins/interactions.py | 22 ++ prody/proteins/tabulated_energies.txt | 400 ++++++++++++++++++++++++++ 2 files changed, 422 insertions(+) create mode 100644 prody/proteins/tabulated_energies.txt diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index c8d04acca..15c8d03f6 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -153,6 +153,28 @@ def filterInteractions(list_of_interactions, atoms, **kwargs): return final +def get_energy(pair, source): + """Return energies based on the pairs of interacting residues (without distance criteria) + Taking information from tabulated_energies.txt file""" + + import numpy as np + import importlib.resources as pkg_resources + + with pkg_resources.path('prody.proteins', 'tabulated_energies.txt') as file_path: + data = np.loadtxt(file_path, skiprows=1, dtype=str) + + sources = ["ivet_nosolv", "ivet_solv", "carlos"] + aa_pairs = [] + + for row in data: + aa_pairs.append(row[0]+row[1]) + + lookup = pair[0]+pair[1] + + return data[np.where(np.array(aa_pairs)==lookup)[0]][0][2:][np.where(np.array(sources)==source)][0] + + + def calcHydrophobicOverlapingAreas(atoms, **kwargs): """Provide information about hydrophobic contacts between pairs of residues based on the regsurf program. To use this function compiled hpb.so is needed. diff --git a/prody/proteins/tabulated_energies.txt b/prody/proteins/tabulated_energies.txt new file mode 100644 index 000000000..009c8c1b5 --- /dev/null +++ b/prody/proteins/tabulated_energies.txt @@ -0,0 +1,400 @@ +GLY GLY -0.27 -1.77 0.0 +GLY ALA 0.08 -2.24 0.0 +GLY VAL 0.17 -2.77 0.0 +GLY ILE 0.05 -3.5 0.0 +GLY LEU 0.33 -3.79 0.0 +GLY CYS -0.26 -3.43 0.0 +GLY MET 0.31 -3.02 0.0 +GLY PHE -0.15 -3.76 0.0 +GLY TYR -0.21 -3.34 0.0 +GLY TRP -0.31 -3.77 0.0 +GLY SER 0.08 -1.68 0.0 +GLY THR -0.11 -1.81 0.0 +GLY ASP 0.11 -1.84 0.0 +GLY ASN -0.09 -1.63 0.0 +GLY GLU 0.5 -1.58 0.0 +GLY GLN -0.11 -3.02 0.0 +GLY LYS -0.17 -1.32 0.0 +GLY ARG -0.1 -2.71 0.0 +GLY HIS 0.01 -2.47 0.0 +GLY PRO 0.13 -1.01 0.0 +ALA GLY 0.08 -2.24 0.0 +ALA ALA -0.38 -3.51 0.0 +ALA VAL -0.11 -3.86 0.0 +ALA ILE -0.08 -4.45 0.0 +ALA LEU -0.09 -5.02 0.0 +ALA CYS 0.0 -3.99 0.0 +ALA MET -0.27 -4.42 0.0 +ALA PHE 0.01 -4.43 0.0 +ALA TYR 0.0 -3.96 0.0 +ALA TRP -0.38 -4.66 0.0 +ALA SER 0.08 -2.49 0.0 +ALA THR 0.14 -2.38 0.0 +ALA ASP 0.02 -2.74 0.0 +ALA ASN 0.31 -2.06 0.0 +ALA GLU 0.2 -2.69 0.0 +ALA GLN 0.08 -3.65 0.0 +ALA LYS 0.06 -1.91 0.0 +ALA ARG 0.16 -3.26 0.0 +ALA HIS 0.01 -3.29 0.0 +ALA PRO 0.19 -1.78 0.0 +VAL GLY 0.17 -2.77 0.0 +VAL ALA -0.11 -3.86 0.0 +VAL VAL -0.49 -4.86 -1.0 +VAL ILE -0.33 -5.31 -1.2 +VAL LEU -0.48 -6.03 -1.0 +VAL CYS -0.22 -4.82 -0.4 +VAL MET -0.4 -5.16 -0.6 +VAL PHE -0.27 -5.33 -1.2 +VAL TYR 0.03 -4.54 -0.8 +VAL TRP 0.2 -4.7 -1.0 +VAL SER 0.25 -2.95 -1.0 +VAL THR 0.27 -2.87 -0.7 +VAL ASP 0.11 -3.28 0.0 +VAL ASN 0.22 -2.76 -0.5 +VAL GLU 0.3 -3.2 -0.2 +VAL GLN 0.05 -4.29 -1.1 +VAL LYS 0.4 -2.19 -1.1 +VAL ARG 0.35 -3.7 0.0 +VAL HIS -0.23 -4.14 -1.1 +VAL PRO 0.16 -2.43 0.0 +ILE GLY 0.05 -3.5 0.0 +ILE ALA -0.08 -4.45 0.0 +ILE VAL -0.33 -5.31 -1.2 +ILE ILE -0.37 -5.97 -0.6 +ILE LEU -0.5 -6.67 -1.1 +ILE CYS -0.3 -5.53 -0.4 +ILE MET 0.0 -5.37 -0.7 +ILE PHE -0.44 -6.11 -0.5 +ILE TYR -0.12 -5.39 -0.5 +ILE TRP -0.26 -5.79 -1.0 +ILE SER 0.33 -3.47 -0.9 +ILE THR 0.14 -3.61 -0.7 +ILE ASP 0.54 -3.46 -0.2 +ILE ASN 0.16 -3.42 -0.5 +ILE GLU 0.13 -3.99 -0.2 +ILE GLN 0.33 -4.65 -0.6 +ILE LYS 0.32 -2.88 -1.1 +ILE ARG 0.37 -4.29 0.0 +ILE HIS -0.02 -4.55 -1.1 +ILE PRO 0.11 -3.09 0.0 +LEU GLY 0.33 -3.79 0.0 +LEU ALA -0.09 -5.02 0.0 +LEU VAL -0.48 -6.03 -1.0 +LEU ILE -0.5 -6.67 -1.1 +LEU LEU -0.42 -7.16 -0.8 +LEU CYS -0.34 -6.13 -0.4 +LEU MET -0.3 -6.24 -0.6 +LEU PHE -0.4 -6.65 -1.2 +LEU TYR 0.08 -5.67 -1.3 +LEU TRP -0.31 -6.4 -1.0 +LEU SER 0.26 -4.12 -0.9 +LEU THR 0.04 -4.28 -0.7 +LEU ASP 0.41 -4.16 -0.2 +LEU ASN 0.23 -3.94 -0.5 +LEU GLU 0.34 -4.35 -0.2 +LEU GLN 0.17 -5.36 -1.1 +LEU LYS 0.52 -3.24 -1.1 +LEU ARG 0.21 -5.01 0.0 +LEU HIS 0.25 -4.85 -1.1 +LEU PRO 0.01 -3.75 0.0 +CYS GLY -0.26 -3.43 0.0 +CYS ALA 0.0 -3.99 0.0 +CYS VAL -0.22 -4.82 -0.4 +CYS ILE -0.3 -5.53 -0.4 +CYS LEU -0.34 -6.13 -0.4 +CYS CYS -2.38 -7.23 0.0 +CYS MET -0.08 -5.07 -0.4 +CYS PHE 0.49 -4.81 -1.3 +CYS TYR 0.1 -4.71 -1.3 +CYS TRP 0.44 4.7 -0.6 +CYS SER 0.02 -3.41 0.0 +CYS THR 0.46 -2.92 -0.8 +CYS ASP 0.06 -3.56 -0.2 +CYS ASN 1.46 -1.76 -0.9 +CYS GLU 0.72 -3.02 -0.2 +CYS GLN 0.21 -4.37 -0.9 +CYS LYS -0.5 -2.28 -0.2 +CYS ARG -0.12 -4.41 -0.2 +CYS HIS -0.64 -4.79 -0.8 +CYS PRO -0.15 -2.97 0.0 +MET GLY 0.31 -3.02 0.0 +MET ALA -0.27 -4.42 0.0 +MET VAL -0.4 -5.16 -0.6 +MET ILE 0.0 -5.37 -0.7 +MET LEU -0.3 -6.24 -0.6 +MET CYS -0.08 -5.07 -0.4 +MET MET -0.74 -5.89 -0.7 +MET PHE -0.14 -5.58 -0.8 +MET TYR -0.05 -5.01 -1.2 +MET TRP -0.2 -5.49 -1.0 +MET SER 0.25 -3.33 -0.6 +MET THR 0.19 -3.33 -1.0 +MET ASP 0.09 -3.69 0.0 +MET ASN 0.32 -3.05 -0.8 +MET GLU 0.13 -3.76 -0.2 +MET GLN 0.27 -4.46 -0.5 +MET LYS 0.61 -2.36 0.0 +MET ARG 0.3 -4.13 -0.8 +MET HIS -0.17 -4.47 -0.5 +MET PRO -0.14 -3.11 0.0 +PHE GLY -0.15 -3.76 0.0 +PHE ALA 0.01 -4.43 0.0 +PHE VAL -0.27 -5.33 -1.2 +PHE ILE -0.44 -6.11 -0.5 +PHE LEU -0.4 -6.65 -1.2 +PHE CYS 0.49 -4.81 -1.3 +PHE MET -0.14 -5.58 -0.8 +PHE PHE -0.71 -6.45 -1.2 +PHE TYR -0.07 -5.33 -1.2 +PHE TRP -0.13 -5.72 -1.2 +PHE SER -0.14 -4.01 -0.6 +PHE THR -0.02 -3.85 0.0 +PHE ASP 0.55 -3.52 0.0 +PHE ASN -0.22 -3.89 -0.2 +PHE GLU 0.09 -4.1 -0.4 +PHE GLN 0.14 -4.89 -1.7 +PHE LYS 0.57 -2.7 -0.9 +PHE ARG 0.22 -4.51 -1.1 +PHE HIS 0.79 -3.82 -0.6 +PHE PRO -0.19 -3.46 0.0 +TYR GLY -0.21 -3.34 0.0 +TYR ALA 0.0 -3.96 0.0 +TYR VAL 0.03 -4.54 -0.8 +TYR ILE -0.12 -5.39 -0.5 +TYR LEU 0.08 -5.67 -1.3 +TYR CYS 0.1 -4.71 -1.3 +TYR MET -0.05 -5.01 -1.2 +TYR PHE -0.07 -5.33 -1.2 +TYR TYR 0.2 -4.58 -1.5 +TYR TRP -0.02 -5.12 -1.2 +TYR SER -0.03 -3.43 -0.2 +TYR THR 0.0 -3.33 -0.6 +TYR ASP -0.04 -3.63 -0.6 +TYR ASN 0.04 -3.14 0.0 +TYR GLU 0.08 -3.62 -0.6 +TYR GLN -0.21 -4.75 -0.7 +TYR LYS 0.14 -2.64 -0.1 +TYR ARG -0.07 -4.32 -2.1 +TYR HIS 0.34 -3.78 -1.1 +TYR PRO -0.13 -2.92 0.0 +TRP GLY -0.31 -3.77 0.0 +TRP ALA -0.38 -4.66 0.0 +TRP VAL 0.2 -4.7 -1.0 +TRP ILE -0.26 -5.79 -1.0 +TRP LEU -0.31 -6.4 -1.0 +TRP CYS 0.44 4.7 -0.6 +TRP MET -0.2 -5.49 -1.0 +TRP PHE -0.13 -5.72 -1.2 +TRP TYR -0.02 -5.12 -1.2 +TRP TRP 0.27 -5.16 -1.2 +TRP SER 0.86 -2.86 -0.9 +TRP THR 0.18 -3.48 -0.9 +TRP ASP 0.11 -3.81 -0.5 +TRP ASN 0.2 -3.31 -1.3 +TRP GLU 0.2 -3.84 -0.5 +TRP GLN 0.01 -4.87 -1.3 +TRP LYS 1.0 -3.12 -1.2 +TRP ARG 0.04 -4.54 -1.8 +TRP HIS -0.05 -4.5 -1.7 +TRP PRO -0.85 -3.96 0.0 +SER GLY 0.08 -1.68 0.0 +SER ALA 0.08 -2.49 0.0 +SER VAL 0.25 -2.95 -1.0 +SER ILE 0.33 -3.47 -0.9 +SER LEU 0.26 -4.12 -0.9 +SER CYS 0.02 -3.41 0.0 +SER MET 0.25 -3.33 -0.6 +SER PHE -0.14 -4.01 -0.6 +SER TYR -0.03 -3.43 -0.2 +SER TRP 0.86 -2.86 -0.9 +SER SER -0.14 -2.14 -0.4 +SER THR -0.27 -2.22 -0.9 +SER ASP -0.13 -2.34 -0.2 +SER ASN -0.32 -2.13 0.2 +SER GLU -0.25 -2.57 -0.2 +SER GLN 0.1 -3.06 0.2 +SER LYS -0.5 -1.91 -1.2 +SER ARG 0.08 -2.78 -0.1 +SER HIS -0.38 -3.12 -0.5 +SER PRO -0.15 -1.56 0.0 +THR GLY -0.11 -1.81 0.0 +THR ALA 0.14 -2.38 0.0 +THR VAL 0.27 -2.87 -0.7 +THR ILE 0.14 -3.61 -0.7 +THR LEU 0.04 -4.28 -0.7 +THR CYS 0.46 -2.92 -0.8 +THR MET 0.19 -3.33 -1.0 +THR PHE -0.02 -3.85 0.0 +THR TYR 0.0 -3.33 -0.6 +THR TRP 0.18 -3.48 -0.9 +THR SER -0.27 -2.22 -0.9 +THR THR -0.22 -2.12 -0.9 +THR ASP -0.26 -2.41 -0.2 +THR ASN -0.3 -2.05 0.2 +THR GLU -0.07 -2.34 -0.5 +THR GLN -0.32 -3.44 0.2 +THR LYS -0.29 -1.64 -1.2 +THR ARG 0.38 -2.43 0.4 +THR HIS -0.05 -2.73 -0.5 +THR PRO 0.11 -1.24 0.0 +ASP GLY 0.11 -1.84 0.0 +ASP ALA 0.02 -2.74 0.0 +ASP VAL 0.11 -3.28 0.0 +ASP ILE 0.54 -3.46 -0.2 +ASP LEU 0.41 -4.16 -0.2 +ASP CYS 0.06 -3.56 -0.2 +ASP MET 0.09 -3.69 0.0 +ASP PHE 0.55 -3.52 0.0 +ASP TYR -0.04 -3.63 -0.6 +ASP TRP 0.11 -3.81 -0.5 +ASP SER -0.13 -2.34 -0.2 +ASP THR -0.26 -2.41 -0.2 +ASP ASP -0.07 -2.47 0.3 +ASP ASN -0.51 -2.5 -0.2 +ASP GLU 0.17 -2.35 0.3 +ASP GLN 0.21 -3.15 -0.2 +ASP LYS -0.87 -2.47 -1.4 +ASP ARG -0.87 -3.92 -1.4 +ASP HIS 0.0 -2.93 -0.4 +ASP PRO 0.36 -1.24 0.0 +ASN GLY -0.09 -1.63 0.0 +ASN ALA 0.31 -2.06 0.0 +ASN VAL 0.22 -2.76 -0.5 +ASN ILE 0.16 -3.42 -0.5 +ASN LEU 0.23 -3.94 -0.5 +ASN CYS 1.46 -1.76 -0.9 +ASN MET 0.32 -3.05 -0.8 +ASN PHE -0.22 -3.89 -0.2 +ASN TYR 0.04 -3.14 0.0 +ASN TRP 0.2 -3.31 -1.3 +ASN SER -0.32 -2.13 0.2 +ASN THR -0.3 -2.05 0.2 +ASN ASP -0.51 -2.5 -0.2 +ASN ASN -0.4 -1.99 -0.1 +ASN GLU -0.3 -2.43 0.1 +ASN GLN -0.05 -3.0 -0.1 +ASN LYS -0.44 -1.63 0.1 +ASN ARG -0.02 -2.67 0.2 +ASN HIS -0.52 -3.05 -1.2 +ASN PRO 0.19 -1.01 0.0 +GLU GLY 0.5 -1.58 0.0 +GLU ALA 0.2 -2.69 0.0 +GLU VAL 0.3 -3.2 -0.2 +GLU ILE 0.13 -3.99 -0.2 +GLU LEU 0.34 -4.35 -0.2 +GLU CYS 0.72 -3.02 -0.2 +GLU MET 0.13 -3.76 -0.2 +GLU PHE 0.09 -4.1 -0.4 +GLU TYR 0.08 -3.62 -0.6 +GLU TRP 0.2 -3.84 -0.5 +GLU SER -0.25 -2.57 -0.2 +GLU THR -0.07 -2.34 -0.5 +GLU ASP 0.17 -2.35 0.3 +GLU ASN -0.3 -2.43 0.1 +GLU GLU -0.2 -2.85 0.3 +GLU GLN 0.03 -3.45 0.1 +GLU LYS -1.11 -2.83 -1.0 +GLU ARG -0.87 -4.05 -1.6 +GLU HIS -0.1 -3.15 -0.4 +GLU PRO 0.01 -1.7 0.0 +GLN GLY -0.11 -3.02 0.0 +GLN ALA 0.08 -3.65 0.0 +GLN VAL 0.05 -4.29 -1.1 +GLN ILE 0.33 -4.65 -0.6 +GLN LEU 0.17 -5.36 -1.1 +GLN CYS 0.21 -4.37 -0.9 +GLN MET 0.27 -4.46 -0.5 +GLN PHE 0.14 -4.89 -1.7 +GLN TYR -0.21 -4.75 -0.7 +GLN TRP 0.01 -4.87 -1.3 +GLN SER 0.1 -3.06 0.2 +GLN THR -0.32 -3.44 0.2 +GLN ASP 0.21 -3.15 -0.2 +GLN ASN -0.05 -3.0 -0.1 +GLN GLU 0.03 -3.45 0.1 +GLN GLN -0.38 -4.71 -0.1 +GLN LYS 0.0 -2.56 0.1 +GLN ARG -0.11 -4.13 0.2 +GLN HIS -0.31 -4.2 -1.2 +GLN PRO -0.11 -2.67 0.0 +LYS GLY -0.17 -1.32 0.0 +LYS ALA 0.06 -1.91 0.0 +LYS VAL 0.4 -2.19 -1.1 +LYS ILE 0.32 -2.88 -1.1 +LYS LEU 0.52 -3.24 -1.1 +LYS CYS -0.5 -2.28 -0.2 +LYS MET 0.61 -2.36 0.0 +LYS PHE 0.57 -2.7 -0.9 +LYS TYR 0.14 -2.64 -0.1 +LYS TRP 1.0 -3.12 -1.2 +LYS SER -0.5 -1.91 -1.2 +LYS THR -0.29 -1.64 -1.2 +LYS ASP -0.87 -2.47 -1.4 +LYS ASN -0.44 -1.63 0.1 +LYS GLU -1.11 -2.83 -1.0 +LYS GLN 0.0 -2.56 0.1 +LYS LYS -0.22 -1.02 0.2 +LYS ARG 0.15 -2.11 0.0 +LYS HIS -0.01 -2.14 0.0 +LYS PRO 0.3 -0.5 0.0 +ARG GLY -0.1 -2.71 0.0 +ARG ALA 0.16 -3.26 0.0 +ARG VAL 0.35 -3.7 0.0 +ARG ILE 0.37 -4.29 0.0 +ARG LEU 0.21 -5.01 0.0 +ARG CYS -0.12 -4.41 -0.2 +ARG MET 0.3 -4.13 -0.8 +ARG PHE 0.22 -4.51 -1.1 +ARG TYR -0.07 -4.32 -2.1 +ARG TRP 0.04 -4.54 -1.8 +ARG SER 0.08 -2.78 -0.1 +ARG THR 0.38 -2.43 0.4 +ARG ASP -0.87 -3.92 -1.4 +ARG ASN -0.02 -2.67 0.2 +ARG GLU -0.87 -4.05 -1.6 +ARG GLN -0.11 -4.13 0.2 +ARG LYS 0.15 -2.11 0.0 +ARG ARG -0.26 -3.98 -0.6 +ARG HIS 0.35 -3.24 -0.4 +ARG PRO -0.17 -2.43 0.0 +HIS GLY 0.01 -2.47 0.0 +HIS ALA 0.01 -3.29 0.0 +HIS VAL -0.23 -4.14 -1.1 +HIS ILE -0.02 -4.55 -1.1 +HIS LEU 0.25 -4.85 -1.1 +HIS CYS -0.64 -4.79 -0.8 +HIS MET -0.17 -4.47 -0.5 +HIS PHE 0.79 -3.82 -0.6 +HIS TYR 0.34 -3.78 -1.1 +HIS TRP -0.05 -4.5 -1.7 +HIS SER -0.38 -3.12 -0.5 +HIS THR -0.05 -2.73 -0.5 +HIS ASP 0.0 -2.93 -0.4 +HIS ASN -0.52 -3.05 -1.2 +HIS GLU -0.1 -3.15 -0.4 +HIS GLN -0.31 -4.2 -1.2 +HIS LYS -0.01 -2.14 0.0 +HIS ARG 0.35 -3.24 -0.4 +HIS HIS 0.38 -3.08 -0.5 +HIS PRO 0.33 -1.8 0.0 +PRO GLY 0.13 -1.01 0.0 +PRO ALA 0.19 -1.78 0.0 +PRO VAL 0.16 -2.43 0.0 +PRO ILE 0.11 -3.09 0.0 +PRO LEU 0.01 -3.75 0.0 +PRO CYS -0.15 -2.97 0.0 +PRO MET -0.14 -3.11 0.0 +PRO PHE -0.19 -3.46 0.0 +PRO TYR -0.13 -2.92 0.0 +PRO TRP -0.85 -3.96 0.0 +PRO SER -0.15 -1.56 0.0 +PRO THR 0.11 -1.24 0.0 +PRO ASP 0.36 -1.24 0.0 +PRO ASN 0.19 -1.01 0.0 +PRO GLU 0.01 -1.7 0.0 +PRO GLN -0.11 -2.67 0.0 +PRO LYS 0.3 -0.5 0.0 +PRO ARG -0.17 -2.43 0.0 +PRO HIS 0.33 -1.8 0.0 +PRO PRO -0.03 -0.83 0.0 From dab4767bfb5d3d5bbd3a7885d0be5b02b8c81813 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 09:01:48 +0200 Subject: [PATCH 27/68] tabulated_energies.txt imports during installation [sstup.py, MANIFEST.in] --- MANIFEST.in | 1 + setup.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index a33dfffad..8aeafdcd4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -21,3 +21,4 @@ include prody/utilities/datafiles/*.dat include prody/utilities/datafiles/*.txt include scripts/prody* include scripts/evol* +include prody/protein/tabulated_energies.txt \ No newline at end of file diff --git a/setup.py b/setup.py index 33980ad1c..f85413b04 100644 --- a/setup.py +++ b/setup.py @@ -87,7 +87,8 @@ 'datafiles/dcd*.dcd', 'datafiles/xml*.xml', 'datafiles/msa*', - 'datafiles/mmcif*cif',] + 'datafiles/mmcif*cif',], + 'prody.proteins': ['tabulated_energies.txt'], } PACKAGE_DIR = {} From 1f4f7e9b36b0ff6448a4bc75e7f9673b001ec2eb Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 10:39:16 +0200 Subject: [PATCH 28/68] showPairEnergy function to obtain energies form InSty calculations --- prody/proteins/interactions.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 15c8d03f6..344227e52 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -46,7 +46,7 @@ 'calcHydrogenBondsTrajectory', 'calcHydrophobicOverlapingAreas', 'Interactions', 'InteractionsTrajectory', 'LigandInteractionsTrajectory', 'calcSminaBindingAffinity', 'calcSminaPerAtomInteractions', 'calcSminaTermValues', - 'showSminaTermValues'] + 'showSminaTermValues', 'showPairEnergy'] def cleanNumbers(listContacts): @@ -163,7 +163,7 @@ def get_energy(pair, source): with pkg_resources.path('prody.proteins', 'tabulated_energies.txt') as file_path: data = np.loadtxt(file_path, skiprows=1, dtype=str) - sources = ["ivet_nosolv", "ivet_solv", "carlos"] + sources = ["IB_nosolv", "IB_solv", "CS"] aa_pairs = [] for row in data: @@ -172,7 +172,29 @@ def get_energy(pair, source): lookup = pair[0]+pair[1] return data[np.where(np.array(aa_pairs)==lookup)[0]][0][2:][np.where(np.array(sources)==source)][0] + + +def showPairEnergy(list_of_interactions, energy_list_type): + """Return energies when a list of interactions is given. Energies will be added to each pair of residues + at the last position in the list. Energy is based on the residue types and not on the distances. + The unit of energy is kcal/mol. The energies defined as 'IB_nosolv', 'IB_solv' are taken from XX and + 'CS' from YY. + + :arg list_of_interactions: list with interactions from calcHydrogenBonds() or other types + :type list_of_interactions: list + + :arg energy_list_type: name of the list with energies + :type energy_list_type: 'IB_nosolv', 'IB_solv', 'CS' + """ + + energy_type = "IB_solv" + for i in list_of_interactions: + energy = get_energy([i[0][:3], i[3][:3]], energy_list_type) + i.append(float(energy)) + + return list_of_interactions + def calcHydrophobicOverlapingAreas(atoms, **kwargs): From 53689d79efd8cabcebbd81fcf738fbfe68e40992 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 11:20:55 +0200 Subject: [PATCH 29/68] additional improvement of showPairEnergy() --- prody/proteins/interactions.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 344227e52..be248830c 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -174,7 +174,7 @@ def get_energy(pair, source): return data[np.where(np.array(aa_pairs)==lookup)[0]][0][2:][np.where(np.array(sources)==source)][0] -def showPairEnergy(list_of_interactions, energy_list_type): +def showPairEnergy(list_of_interactions, **kwargs): """Return energies when a list of interactions is given. Energies will be added to each pair of residues at the last position in the list. Energy is based on the residue types and not on the distances. The unit of energy is kcal/mol. The energies defined as 'IB_nosolv', 'IB_solv' are taken from XX and @@ -184,10 +184,14 @@ def showPairEnergy(list_of_interactions, energy_list_type): :type list_of_interactions: list :arg energy_list_type: name of the list with energies + default is 'IB_solv' :type energy_list_type: 'IB_nosolv', 'IB_solv', 'CS' """ - energy_type = "IB_solv" + if not isinstance(list_of_interactions, list): + raise TypeError('list_of_interactions must be a list of interactions.') + + energy_list_type = kwargs.pop('energy_list_type', 'IB_solv') for i in list_of_interactions: energy = get_energy([i[0][:3], i[3][:3]], energy_list_type) From 4e409e8dcbb12304b0ec9fcef66189abb4cca2e7 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 11:32:06 +0200 Subject: [PATCH 30/68] showPairEnergy() - imports for python 2.7 --- prody/proteins/interactions.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index be248830c..0870d3f2f 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -160,8 +160,17 @@ def get_energy(pair, source): import numpy as np import importlib.resources as pkg_resources - with pkg_resources.path('prody.proteins', 'tabulated_energies.txt') as file_path: - data = np.loadtxt(file_path, skiprows=1, dtype=str) + try: + # Python 3 + with pkg_resources.path('prody.proteins', 'tabulated_energies.txt') as file_path: + data = np.loadtxt(file_path, skiprows=1, dtype=str) + except: + # Python 2.7 + import pkg_resources + file_path = pkg_resources.resource_filename('prody.proteins', 'tabulated_energies.txt') + with open(file_path) as f: + data = np.loadtxt(f, skiprows=1, dtype=str) + sources = ["IB_nosolv", "IB_solv", "CS"] aa_pairs = [] From 59170bcc630330b396c9216a586940fa39005c91 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 11:38:24 +0200 Subject: [PATCH 31/68] cosmetic changes in showPairEnergy() func --- prody/proteins/interactions.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 0870d3f2f..a0f6e95b6 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -183,30 +183,30 @@ def get_energy(pair, source): return data[np.where(np.array(aa_pairs)==lookup)[0]][0][2:][np.where(np.array(sources)==source)][0] -def showPairEnergy(list_of_interactions, **kwargs): +def showPairEnergy(data, **kwargs): """Return energies when a list of interactions is given. Energies will be added to each pair of residues at the last position in the list. Energy is based on the residue types and not on the distances. The unit of energy is kcal/mol. The energies defined as 'IB_nosolv', 'IB_solv' are taken from XX and 'CS' from YY. - :arg list_of_interactions: list with interactions from calcHydrogenBonds() or other types - :type list_of_interactions: list + :arg data: list with interactions from calcHydrogenBonds() or other types + :type data: list :arg energy_list_type: name of the list with energies default is 'IB_solv' :type energy_list_type: 'IB_nosolv', 'IB_solv', 'CS' """ - if not isinstance(list_of_interactions, list): + if not isinstance(data, list): raise TypeError('list_of_interactions must be a list of interactions.') energy_list_type = kwargs.pop('energy_list_type', 'IB_solv') - for i in list_of_interactions: + for i in data: energy = get_energy([i[0][:3], i[3][:3]], energy_list_type) i.append(float(energy)) - return list_of_interactions + return data From fe219d16e4dcde85cf01e416674ff7b467a7fbe2 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 12:18:40 +0200 Subject: [PATCH 32/68] energy info is now added to calcStatisticsInteractions() --- prody/proteins/interactions.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index a0f6e95b6..e2bce926b 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -1955,6 +1955,11 @@ def calcStatisticsInteractions(data, **kwargs): default value is 0.2 (in 20% of conformations contact appeared) :type weight_cutoff: int, float + :arg energy_list_type: name of the list with energies + default is 'IB_solv' + :type energy_list_type: 'IB_nosolv', 'IB_solv', 'CS' + + Example of usage: >>> atoms = parsePDB('PDBfile.pdb') >>> dcd = Trajectory('DCDfile.dcd') @@ -1969,6 +1974,7 @@ def calcStatisticsInteractions(data, **kwargs): interactions_list = [ (jj[0]+jj[2]+'-'+jj[3]+jj[5], jj[6]) for ii in data for jj in ii] weight_cutoff = kwargs.pop('weight_cutoff', 0.2) + energy_list_type = kwargs.pop('energy_list_type', 'IB_solv') import numpy as np elements = [t[0] for t in interactions_list] @@ -1981,6 +1987,7 @@ def calcStatisticsInteractions(data, **kwargs): "stddev": np.round(np.std(values),6), "mean": np.round(np.mean(values),6), "weight": np.round(float(len(values))/len(data), 6) + "energy": get_energy([element.split('-')[0][:3], element.split('-')[1][:3]], energy_list_type) } statistic = [] @@ -1990,7 +1997,8 @@ def calcStatisticsInteractions(data, **kwargs): LOGGER.info(" Average [Ang.]: {}".format(value['mean'])) LOGGER.info(" Standard deviation [Ang.]: {0}".format(value['stddev'])) LOGGER.info(" Weight: {0}".format(value['weight'])) - statistic.append([key, value['weight'], value['mean'], value['stddev']]) + LOGGER.info(" Energy [kcal/mol]: {0}".format(value['energy'])) + statistic.append([key, value['weight'], value['mean'], value['stddev'], value['energy']]) else: pass statistic.sort(key=lambda x: x[1], reverse=True) From de96bd847324f9cb1952479cc73595a72ad045b1 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 12:33:45 +0200 Subject: [PATCH 33/68] missing comma added --- prody/proteins/interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index e2bce926b..47351bb99 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -1986,7 +1986,7 @@ def calcStatisticsInteractions(data, **kwargs): stats[element] = { "stddev": np.round(np.std(values),6), "mean": np.round(np.mean(values),6), - "weight": np.round(float(len(values))/len(data), 6) + "weight": np.round(float(len(values))/len(data), 6), "energy": get_energy([element.split('-')[0][:3], element.split('-')[1][:3]], energy_list_type) } From d3078d26021511f31bfd8d62e9c0200ced076161 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 13:36:25 +0200 Subject: [PATCH 34/68] changes in showInteractionsGraph() after adding energies --- prody/proteins/interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 47351bb99..692a46318 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -1873,7 +1873,7 @@ def showInteractionsGraph(statistics, **kwargs): 'HIS': 'H', 'HSD': 'H','HSE': 'H', 'LEU': 'L', 'ARG': 'R', 'TRP': 'W', 'ALA': 'A', 'VAL':'V', 'GLU': 'E', 'TYR': 'Y', 'MET': 'M'} - if len(statistics[0]) != 4: + if len(statistics[0]) != 5: raise TypeError('data must be a list obtained from calcStatisticsInteractions') else: if isinstance(statistics, int) or isinstance(statistics, str): From fab94127303fee73ca76a338a820d95bf96f83c3 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 17:20:50 +0200 Subject: [PATCH 35/68] TypeError changed in showInteractionsGraph() --- prody/proteins/interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 692a46318..887e1b5e5 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -1877,7 +1877,7 @@ def showInteractionsGraph(statistics, **kwargs): raise TypeError('data must be a list obtained from calcStatisticsInteractions') else: if isinstance(statistics, int) or isinstance(statistics, str): - raise TypeError('node_size must be a list') + raise TypeError('statistics must be a list') code = kwargs.pop('code', None) if code is None: From 9d821c1a424fcec6d25319345cbac69b5e9a4cea Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 21:53:00 +0200 Subject: [PATCH 36/68] additional checks for showInteractionsGraph --- prody/proteins/interactions.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 887e1b5e5..3437a4852 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -1873,11 +1873,16 @@ def showInteractionsGraph(statistics, **kwargs): 'HIS': 'H', 'HSD': 'H','HSE': 'H', 'LEU': 'L', 'ARG': 'R', 'TRP': 'W', 'ALA': 'A', 'VAL':'V', 'GLU': 'E', 'TYR': 'Y', 'MET': 'M'} - if len(statistics[0]) != 5: - raise TypeError('data must be a list obtained from calcStatisticsInteractions') + + if isinstance(statistics, int) or isinstance(statistics, str) or isinstance(statistics, Atomic): + raise TypeError('input data must be a list, use calcStatisticsInteractions to obtain statistics for a particular interaction type') + + if isinstance(statistics, InteractionsTrajectory) or isinstance(statistics, Interactions): + raise TypeError('use calcStatisticsInteractions to obtain statistics for a particular interaction type') + else: - if isinstance(statistics, int) or isinstance(statistics, str): - raise TypeError('statistics must be a list') + if len(statistics[0]) != 5: + raise TypeError('input data must be a list obtained from calcStatisticsInteractions') code = kwargs.pop('code', None) if code is None: From aa7aeb976c7d0de06a77c1644fabce65c8684c1a Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Fri, 30 Aug 2024 23:00:02 +0200 Subject: [PATCH 37/68] new function - buildInteractionMatrixEnergy() --- prody/proteins/interactions.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 3437a4852..9d6bab435 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -3157,6 +3157,40 @@ def buildInteractionMatrix(self, **kwargs): return InteractionsMap + def buildInteractionMatrixEnergy(self, **kwargs): + """Build matrix with interaction energy comming from energy of pairs of specific residues. + + :arg energy_list_type: name of the list with energies + default is 'IB_solv' + :type energy_list_type: 'IB_nosolv', 'IB_solv', 'CS' + """ + + import numpy as np + import matplotlib + import matplotlib.pyplot as plt + from prody.dynamics.plotting import pplot + + atoms = self._atoms + interactions = self._interactions + start_frame = kwargs.pop('energy_list_type', 'IS_solv') + + LOGGER.info('Calculating interactions') + InteractionsMap = np.zeros([atoms.select('name CA').numAtoms(),atoms.select('name CA').numAtoms()]) + resIDs = list(atoms.select('name CA').getResnums()) + resChIDs = list(atoms.select('name CA').getChids()) + resIDs_with_resChIDs = list(zip(resIDs, resChIDs)) + + for nr_i,i in enumerate(interactions): + if i != []: + for ii in i: + m1 = resIDs_with_resChIDs.index((int(ii[0][3:]),ii[2])) + m2 = resIDs_with_resChIDs.index((int(ii[3][3:]),ii[5])) + scoring = get_energy([ii[0][:3], ii[3][:3]], "IB_solv") + InteractionsMap[m1][m2] = InteractionsMap[m2][m1] = InteractionsMap[m1][m2] + float(scoring) + + return InteractionsMap + + def showInteractors(self, **kwargs): """Display protein residues and their number of potential interactions with other residues from protein structure. """ From 71fa5ae6151890f9c4cb61406ea8a65ea9f580e0 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Sat, 31 Aug 2024 07:56:04 +0200 Subject: [PATCH 38/68] buildInteractionMatrixEnergy improvement, added to self --- prody/proteins/interactions.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 9d6bab435..52f8c4171 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -2758,6 +2758,7 @@ def __init__(self, title='Unknown'): self._atoms = None self._interactions = None self._interactions_matrix = None + self._interactions_matrix_en = None self._hbs = None self._sbs = None self._rib = None @@ -3172,7 +3173,7 @@ def buildInteractionMatrixEnergy(self, **kwargs): atoms = self._atoms interactions = self._interactions - start_frame = kwargs.pop('energy_list_type', 'IS_solv') + energy_list_type = kwargs.pop('energy_list_type', 'IB_solv') LOGGER.info('Calculating interactions') InteractionsMap = np.zeros([atoms.select('name CA').numAtoms(),atoms.select('name CA').numAtoms()]) @@ -3185,8 +3186,10 @@ def buildInteractionMatrixEnergy(self, **kwargs): for ii in i: m1 = resIDs_with_resChIDs.index((int(ii[0][3:]),ii[2])) m2 = resIDs_with_resChIDs.index((int(ii[3][3:]),ii[5])) - scoring = get_energy([ii[0][:3], ii[3][:3]], "IB_solv") + scoring = get_energy([ii[0][:3], ii[3][:3]], energy_list_type) InteractionsMap[m1][m2] = InteractionsMap[m2][m1] = InteractionsMap[m1][m2] + float(scoring) + + self._interactions_matrix_en = InteractionsMap return InteractionsMap From 5b60c9d6ee314ed9dd2bac9d95d2fca07cd841c7 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Sat, 31 Aug 2024 08:25:54 +0200 Subject: [PATCH 39/68] energy in showCumulativeInteractionTypes --- prody/proteins/interactions.py | 175 +++++++++++++++++++-------------- 1 file changed, 101 insertions(+), 74 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 52f8c4171..d509edab0 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -3399,7 +3399,12 @@ def showCumulativeInteractionTypes(self, **kwargs): :type HPh: int, float :arg DiBs: score per disulfide bond - :type DiBs: int, float """ + :type DiBs: int, float + + :arg energy: sum of the energy between residues + default is False + :type energy: True, False + """ import numpy as np import matplotlib @@ -3412,87 +3417,109 @@ def showCumulativeInteractionTypes(self, **kwargs): 'ALA': 'A', 'VAL':'V', 'GLU': 'E', 'TYR': 'Y', 'MET': 'M', 'HSE': 'H', 'HSD': 'H'} atoms = self._atoms + energy = kwargs.pop('energy', False) ResNumb = atoms.select('protein and name CA').getResnums() ResName = atoms.select('protein and name CA').getResnames() ResChid = atoms.select('protein and name CA').getChids() ResList = [ i[0]+str(i[1])+i[2] for i in list(zip([ aa_dic[i] for i in ResName ], ResNumb, ResChid)) ] - replace_matrix = kwargs.get('replace_matrix', False) - matrix_all = self._interactions_matrix - - HBs = kwargs.get('HBs', 1) - SBs = kwargs.get('SBs', 1) - RIB = kwargs.get('RIB', 1) - PiStack = kwargs.get('PiStack', 1) - PiCat = kwargs.get('PiCat', 1) - HPh = kwargs.get('HPh', 1) - DiBs = kwargs.get('DiBs', 1) - - matrix_hbs = self.buildInteractionMatrix(HBs=HBs, SBs=0, RIB=0,PiStack=0,PiCat=0,HPh=0,DiBs=0) - matrix_sbs = self.buildInteractionMatrix(HBs=0, SBs=SBs, RIB=0,PiStack=0,PiCat=0,HPh=0,DiBs=0) - matrix_rib = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=RIB,PiStack=0,PiCat=0,HPh=0,DiBs=0) - matrix_pistack = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=0,PiStack=PiStack,PiCat=0,HPh=0,DiBs=0) - matrix_picat = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=0,PiStack=0,PiCat=PiCat,HPh=0,DiBs=0) - matrix_hph = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=0,PiStack=0,PiCat=0,HPh=HPh,DiBs=0) - matrix_dibs = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=0,PiStack=0,PiCat=0,HPh=0,DiBs=DiBs) - - matrix_hbs_sum = np.sum(matrix_hbs, axis=0) - matrix_sbs_sum = np.sum(matrix_sbs, axis=0) - matrix_rib_sum = np.sum(matrix_rib, axis=0) - matrix_pistack_sum = np.sum(matrix_pistack, axis=0) - matrix_picat_sum = np.sum(matrix_picat, axis=0) - matrix_hph_sum = np.sum(matrix_hph, axis=0) - matrix_dibs_sum = np.sum(matrix_dibs, axis=0) - - width = 0.8 - fig, ax = plt.subplots(num=None, figsize=(20,6), facecolor='w') - matplotlib.rcParams['font.size'] = '24' - - sum_matrix = np.zeros(matrix_hbs_sum.shape) - pplot(sum_matrix, atoms=atoms.ca) - - if HBs != 0: - ax.bar(ResList, matrix_hbs_sum, width, color = 'blue', bottom = 0, label='HBs') - sum_matrix += matrix_hbs_sum - - if SBs != 0: - ax.bar(ResList, matrix_sbs_sum, width, color = 'yellow', bottom = sum_matrix, label='SBs') - sum_matrix += matrix_sbs_sum - - if HPh != 0: - ax.bar(ResList, matrix_hph_sum, width, color = 'silver', bottom = sum_matrix, label='HPh') - sum_matrix += matrix_hph_sum - - if RIB != 0: - ax.bar(ResList, matrix_rib_sum, width, color = 'red', bottom = sum_matrix, label='RIB') - sum_matrix += matrix_rib_sum - - if PiStack != 0: - ax.bar(ResList, matrix_pistack_sum, width, color = 'green', bottom = sum_matrix, label='PiStack') - sum_matrix += matrix_pistack_sum - - if PiCat != 0: - ax.bar(ResList, matrix_picat_sum, width, color = 'orange', bottom = sum_matrix, label='PiCat') - sum_matrix += matrix_picat_sum - - if DiBs != 0: - ax.bar(ResList, matrix_dibs_sum, width, color = 'black', bottom = sum_matrix, label='DiBs') - sum_matrix += matrix_dibs_sum - - if replace_matrix: - self._interactions_matrix = np.sum([matrix_hbs, matrix_sbs, matrix_rib, matrix_pistack, - matrix_picat, matrix_hph, matrix_dibs], axis=0) + + if energy == True: + matrix_en = self._interactions_matrix_en + matrix_en_sum = np.sum(matrix_en, axis=0) + + width = 0.8 + fig, ax = plt.subplots(num=None, figsize=(20,6), facecolor='w') + matplotlib.rcParams['font.size'] = '24' + + ax.bar(ResNumb, matrix_en_sum, width, color='blue') + + plt.xlim([ResNumb[0]-0.5, ResNumb[-1]+0.5]) + plt.tight_layout() + plt.xlabel('Residue') + plt.ylabel('Cumulative Energy [kcal/mol]') + plt.show() + + return matrix_en_sum + + else: - self._interactions_matrix = matrix_all + replace_matrix = kwargs.get('replace_matrix', False) + matrix_all = self._interactions_matrix + + HBs = kwargs.get('HBs', 1) + SBs = kwargs.get('SBs', 1) + RIB = kwargs.get('RIB', 1) + PiStack = kwargs.get('PiStack', 1) + PiCat = kwargs.get('PiCat', 1) + HPh = kwargs.get('HPh', 1) + DiBs = kwargs.get('DiBs', 1) + + matrix_hbs = self.buildInteractionMatrix(HBs=HBs, SBs=0, RIB=0,PiStack=0,PiCat=0,HPh=0,DiBs=0) + matrix_sbs = self.buildInteractionMatrix(HBs=0, SBs=SBs, RIB=0,PiStack=0,PiCat=0,HPh=0,DiBs=0) + matrix_rib = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=RIB,PiStack=0,PiCat=0,HPh=0,DiBs=0) + matrix_pistack = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=0,PiStack=PiStack,PiCat=0,HPh=0,DiBs=0) + matrix_picat = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=0,PiStack=0,PiCat=PiCat,HPh=0,DiBs=0) + matrix_hph = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=0,PiStack=0,PiCat=0,HPh=HPh,DiBs=0) + matrix_dibs = self.buildInteractionMatrix(HBs=0, SBs=0, RIB=0,PiStack=0,PiCat=0,HPh=0,DiBs=DiBs) + + matrix_hbs_sum = np.sum(matrix_hbs, axis=0) + matrix_sbs_sum = np.sum(matrix_sbs, axis=0) + matrix_rib_sum = np.sum(matrix_rib, axis=0) + matrix_pistack_sum = np.sum(matrix_pistack, axis=0) + matrix_picat_sum = np.sum(matrix_picat, axis=0) + matrix_hph_sum = np.sum(matrix_hph, axis=0) + matrix_dibs_sum = np.sum(matrix_dibs, axis=0) + + width = 0.8 + fig, ax = plt.subplots(num=None, figsize=(20,6), facecolor='w') + matplotlib.rcParams['font.size'] = '24' + + sum_matrix = np.zeros(matrix_hbs_sum.shape) + pplot(sum_matrix, atoms=atoms.ca) + + if HBs != 0: + ax.bar(ResList, matrix_hbs_sum, width, color = 'blue', bottom = 0, label='HBs') + sum_matrix += matrix_hbs_sum + + if SBs != 0: + ax.bar(ResList, matrix_sbs_sum, width, color = 'yellow', bottom = sum_matrix, label='SBs') + sum_matrix += matrix_sbs_sum + + if HPh != 0: + ax.bar(ResList, matrix_hph_sum, width, color = 'silver', bottom = sum_matrix, label='HPh') + sum_matrix += matrix_hph_sum + + if RIB != 0: + ax.bar(ResList, matrix_rib_sum, width, color = 'red', bottom = sum_matrix, label='RIB') + sum_matrix += matrix_rib_sum - ax.legend(ncol=7, loc='upper center') - plt.ylim([0,max(sum_matrix)+3]) - plt.tight_layout() - plt.xlabel('Residue') - plt.ylabel('Number of counts') - - return matrix_hbs_sum, matrix_sbs_sum, matrix_rib_sum, matrix_pistack_sum, matrix_picat_sum, matrix_hph_sum, matrix_dibs_sum + if PiStack != 0: + ax.bar(ResList, matrix_pistack_sum, width, color = 'green', bottom = sum_matrix, label='PiStack') + sum_matrix += matrix_pistack_sum + + if PiCat != 0: + ax.bar(ResList, matrix_picat_sum, width, color = 'orange', bottom = sum_matrix, label='PiCat') + sum_matrix += matrix_picat_sum + + if DiBs != 0: + ax.bar(ResList, matrix_dibs_sum, width, color = 'black', bottom = sum_matrix, label='DiBs') + sum_matrix += matrix_dibs_sum + + if replace_matrix: + self._interactions_matrix = np.sum([matrix_hbs, matrix_sbs, matrix_rib, matrix_pistack, + matrix_picat, matrix_hph, matrix_dibs], axis=0) + else: + self._interactions_matrix = matrix_all + + ax.legend(ncol=7, loc='upper center') + plt.ylim([0,max(sum_matrix)+3]) + plt.tight_layout() + plt.xlabel('Residue') + plt.ylabel('Number of counts') + + return matrix_hbs_sum, matrix_sbs_sum, matrix_rib_sum, matrix_pistack_sum, matrix_picat_sum, matrix_hph_sum, matrix_dibs_sum class InteractionsTrajectory(object): From 5917b42bbbf4d64943236edc6d31cdcb540c059c Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Sat, 31 Aug 2024 09:11:02 +0200 Subject: [PATCH 40/68] energy in saveInteractionsPDB --- prody/proteins/interactions.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index d509edab0..82c8fd18c 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -3234,23 +3234,37 @@ def saveInteractionsPDB(self, **kwargs): :arg filename: name of the PDB file which will be saved for visualization, it will contain the results in occupancy column. - :type filename: str """ + :type filename: str + + :arg energy: sum of the energy between residues + default is False + :type energy: True, False + """ if not hasattr(self, '_interactions_matrix') or self._interactions_matrix is None: raise ValueError('Please calculate interactions matrix first.') - + import numpy as np + from collections import Counter + + energy = kwargs.pop('energy', False) + + atoms = self._atoms interaction_matrix = self._interactions_matrix - atoms = self._atoms - freq_contacts_residues = np.sum(interaction_matrix, axis=0) + interaction_matrix_en = self._interactions_matrix_en - from collections import Counter - lista_ext = [] atoms = atoms.select("protein and noh") + lista_ext = [] aa_counter = Counter(atoms.getResindices()) calphas = atoms.select('name CA') + for i in range(calphas.numAtoms()): - lista_ext.extend(list(aa_counter.values())[i]*[round(freq_contacts_residues[i], 8)]) + if energy == True: + matrix_en_sum = np.sum(interaction_matrix_en, axis=0) + lista_ext.extend(list(aa_counter.values())[i]*[round(matrix_en_sum[i], 8)]) + else: + freq_contacts_residues = np.sum(interaction_matrix, axis=0) + lista_ext.extend(list(aa_counter.values())[i]*[round(freq_contacts_residues[i], 8)]) kw = {'occupancy': lista_ext} if 'filename' in kwargs: @@ -3260,6 +3274,7 @@ def saveInteractionsPDB(self, **kwargs): writePDB('filename', atoms, **kw) LOGGER.info('PDB file saved.') + def getFrequentInteractors(self, contacts_min=3): """Provide a list of residues with the most frequent interactions based on the following interactions: From 66786ade5001a85fdada77b637f4d335ea0d5a09 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Tue, 3 Sep 2024 11:40:44 +0200 Subject: [PATCH 41/68] Energy optional in calcStatisticsInteractions() [InSty] --- prody/proteins/interactions.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 82c8fd18c..8ec8a2476 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -1988,12 +1988,20 @@ def calcStatisticsInteractions(data, **kwargs): for element in elements: if element not in stats: values = [t[1] for t in interactions_list if t[0] == element] - stats[element] = { - "stddev": np.round(np.std(values),6), - "mean": np.round(np.mean(values),6), - "weight": np.round(float(len(values))/len(data), 6), - "energy": get_energy([element.split('-')[0][:3], element.split('-')[1][:3]], energy_list_type) - } + + try: + stats[element] = { + "stddev": np.round(np.std(values),6), + "mean": np.round(np.mean(values),6), + "weight": np.round(float(len(values))/len(data), 6), + "energy": get_energy([element.split('-')[0][:3], element.split('-')[1][:3]], energy_list_type) + } + except: + stats[element] = { + "stddev": np.round(np.std(values),6), + "mean": np.round(np.mean(values),6), + "weight": np.round(float(len(values))/len(data), 6) + } statistic = [] for key, value in stats.items(): @@ -2002,8 +2010,11 @@ def calcStatisticsInteractions(data, **kwargs): LOGGER.info(" Average [Ang.]: {}".format(value['mean'])) LOGGER.info(" Standard deviation [Ang.]: {0}".format(value['stddev'])) LOGGER.info(" Weight: {0}".format(value['weight'])) - LOGGER.info(" Energy [kcal/mol]: {0}".format(value['energy'])) - statistic.append([key, value['weight'], value['mean'], value['stddev'], value['energy']]) + try: + LOGGER.info(" Energy [kcal/mol]: {0}".format(value['energy'])) + statistic.append([key, value['weight'], value['mean'], value['stddev'], value['energy']]) + except: + statistic.append([key, value['weight'], value['mean'], value['stddev']]) else: pass statistic.sort(key=lambda x: x[1], reverse=True) From 86714f4a7ca0f8bb6adb4a0c483a2f69ce63d7d7 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Wed, 4 Sep 2024 13:38:57 +0200 Subject: [PATCH 42/68] HIS/HSD/HSP added to tabulated_energies.txt; bug fix in get_energy() --- prody/proteins/interactions.py | 12 ++- prody/proteins/tabulated_energies.txt | 117 ++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 4 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 8ec8a2476..b7e4eaad9 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -163,14 +163,13 @@ def get_energy(pair, source): try: # Python 3 with pkg_resources.path('prody.proteins', 'tabulated_energies.txt') as file_path: - data = np.loadtxt(file_path, skiprows=1, dtype=str) + data = np.loadtxt(file_path, dtype=str) except: # Python 2.7 import pkg_resources file_path = pkg_resources.resource_filename('prody.proteins', 'tabulated_energies.txt') with open(file_path) as f: - data = np.loadtxt(f, skiprows=1, dtype=str) - + data = np.loadtxt(f, dtype=str) sources = ["IB_nosolv", "IB_solv", "CS"] aa_pairs = [] @@ -180,7 +179,12 @@ def get_energy(pair, source): lookup = pair[0]+pair[1] - return data[np.where(np.array(aa_pairs)==lookup)[0]][0][2:][np.where(np.array(sources)==source)][0] + try: + data_results = data[np.where(np.array(aa_pairs)==lookup)[0]][0][2:][np.where(np.array(sources)==source)][0] + except ImportError: + raise ImportError('Please replace non-standard names of residues with standard names.') + + return data_results def showPairEnergy(data, **kwargs): diff --git a/prody/proteins/tabulated_energies.txt b/prody/proteins/tabulated_energies.txt index 009c8c1b5..af530f206 100644 --- a/prody/proteins/tabulated_energies.txt +++ b/prody/proteins/tabulated_energies.txt @@ -398,3 +398,120 @@ PRO LYS 0.3 -0.5 0.0 PRO ARG -0.17 -2.43 0.0 PRO HIS 0.33 -1.8 0.0 PRO PRO -0.03 -0.83 0.0 +GLY HSE 0.01 -2.47 0.0 +ALA HSE 0.01 -3.29 0.0 +VAL HSE -0.23 -4.14 -1.1 +ILE HSE -0.02 -4.55 -1.1 +LEU HSE 0.25 -4.85 -1.1 +CYS HSE -0.64 -4.79 -0.8 +MET HSE -0.17 -4.47 -0.5 +PHE HSE 0.79 -3.82 -0.6 +TYR HSE 0.34 -3.78 -1.1 +TRP HSE -0.05 -4.5 -1.7 +SER HSE -0.38 -3.12 -0.5 +THR HSE -0.05 -2.73 -0.5 +ASP HSE 0.0 -2.93 -0.4 +ASN HSE -0.52 -3.05 -1.2 +GLU HSE -0.1 -3.15 -0.4 +GLN HSE -0.31 -4.2 -1.2 +LYS HSE -0.01 -2.14 0.0 +ARG HSE 0.35 -3.24 -0.4 +HSE GLY 0.01 -2.47 0.0 +HSE ALA 0.01 -3.29 0.0 +HSE VAL -0.23 -4.14 -1.1 +HSE ILE -0.02 -4.55 -1.1 +HSE LEU 0.25 -4.85 -1.1 +HSE CYS -0.64 -4.79 -0.8 +HSE MET -0.17 -4.47 -0.5 +HSE PHE 0.79 -3.82 -0.6 +HSE TYR 0.34 -3.78 -1.1 +HSE TRP -0.05 -4.5 -1.7 +HSE SER -0.38 -3.12 -0.5 +HSE THR -0.05 -2.73 -0.5 +HSE ASP 0.0 -2.93 -0.4 +HSE ASN -0.52 -3.05 -1.2 +HSE GLU -0.1 -3.15 -0.4 +HSE GLN -0.31 -4.2 -1.2 +HSE LYS -0.01 -2.14 0.0 +HSE ARG 0.35 -3.24 -0.4 +HSE HSE 0.38 -3.08 -0.5 +HSE PRO 0.33 -1.8 0.0 +PRO HSE 0.33 -1.8 0.0 +GLY HSD 0.01 -2.47 0.0 +ALA HSD 0.01 -3.29 0.0 +VAL HSD -0.23 -4.14 -1.1 +ILE HSD -0.02 -4.55 -1.1 +LEU HSD 0.25 -4.85 -1.1 +CYS HSD -0.64 -4.79 -0.8 +MET HSD -0.17 -4.47 -0.5 +PHE HSD 0.79 -3.82 -0.6 +TYR HSD 0.34 -3.78 -1.1 +TRP HSD -0.05 -4.5 -1.7 +SER HSD -0.38 -3.12 -0.5 +THR HSD -0.05 -2.73 -0.5 +ASP HSD 0.0 -2.93 -0.4 +ASN HSD -0.52 -3.05 -1.2 +GLU HSD -0.1 -3.15 -0.4 +GLN HSD -0.31 -4.2 -1.2 +LYS HSD -0.01 -2.14 0.0 +ARG HSD 0.35 -3.24 -0.4 +HSD GLY 0.01 -2.47 0.0 +HSD ALA 0.01 -3.29 0.0 +HSD VAL -0.23 -4.14 -1.1 +HSD ILE -0.02 -4.55 -1.1 +HSD LEU 0.25 -4.85 -1.1 +HSD CYS -0.64 -4.79 -0.8 +HSD MET -0.17 -4.47 -0.5 +HSD PHE 0.79 -3.82 -0.6 +HSD TYR 0.34 -3.78 -1.1 +HSD TRP -0.05 -4.5 -1.7 +HSD SER -0.38 -3.12 -0.5 +HSD THR -0.05 -2.73 -0.5 +HSD ASP 0.0 -2.93 -0.4 +HSD ASN -0.52 -3.05 -1.2 +HSD GLU -0.1 -3.15 -0.4 +HSD GLN -0.31 -4.2 -1.2 +HSD LYS -0.01 -2.14 0.0 +HSD ARG 0.35 -3.24 -0.4 +HSD HSD 0.38 -3.08 -0.5 +HSD PRO 0.33 -1.8 0.0 +PRO HSD 0.33 -1.8 0.0 +GLY HSP 0.01 -2.47 0.0 +ALA HSP 0.01 -3.29 0.0 +VAL HSP -0.23 -4.14 -1.1 +ILE HSP -0.02 -4.55 -1.1 +LEU HSP 0.25 -4.85 -1.1 +CYS HSP -0.64 -4.79 -0.8 +MET HSP -0.17 -4.47 -0.5 +PHE HSP 0.79 -3.82 -0.6 +TYR HSP 0.34 -3.78 -1.1 +TRP HSP -0.05 -4.5 -1.7 +SER HSP -0.38 -3.12 -0.5 +THR HSP -0.05 -2.73 -0.5 +ASP HSP 0.0 -2.93 -0.4 +ASN HSP -0.52 -3.05 -1.2 +GLU HSP -0.1 -3.15 -0.4 +GLN HSP -0.31 -4.2 -1.2 +LYS HSP -0.01 -2.14 0.0 +ARG HSP 0.35 -3.24 -0.4 +HSP GLY 0.01 -2.47 0.0 +HSP ALA 0.01 -3.29 0.0 +HSP VAL -0.23 -4.14 -1.1 +HSP ILE -0.02 -4.55 -1.1 +HSP LEU 0.25 -4.85 -1.1 +HSP CYS -0.64 -4.79 -0.8 +HSP MET -0.17 -4.47 -0.5 +HSP PHE 0.79 -3.82 -0.6 +HSP TYR 0.34 -3.78 -1.1 +HSP TRP -0.05 -4.5 -1.7 +HSP SER -0.38 -3.12 -0.5 +HSP THR -0.05 -2.73 -0.5 +HSP ASP 0.0 -2.93 -0.4 +HSP ASN -0.52 -3.05 -1.2 +HSP GLU -0.1 -3.15 -0.4 +HSP GLN -0.31 -4.2 -1.2 +HSP LYS -0.01 -2.14 0.0 +HSP ARG 0.35 -3.24 -0.4 +HSP HSP 0.38 -3.08 -0.5 +HSP PRO 0.33 -1.8 0.0 +PRO HSP 0.33 -1.8 0.0 From 3c7fde93d19e7912ef5bf18a99fa8cd60283ecd9 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Wed, 4 Sep 2024 13:59:47 +0200 Subject: [PATCH 43/68] reference/energy added [InSty] --- prody/proteins/interactions.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index b7e4eaad9..6f15148fa 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -190,8 +190,8 @@ def get_energy(pair, source): def showPairEnergy(data, **kwargs): """Return energies when a list of interactions is given. Energies will be added to each pair of residues at the last position in the list. Energy is based on the residue types and not on the distances. - The unit of energy is kcal/mol. The energies defined as 'IB_nosolv', 'IB_solv' are taken from XX and - 'CS' from YY. + The unit of energy is kcal/mol. The energies defined as 'IB_nosolv', 'IB_solv' are taken from [OK98]_ and + 'CS' from InSty paper. :arg data: list with interactions from calcHydrogenBonds() or other types :type data: list @@ -199,6 +199,12 @@ def showPairEnergy(data, **kwargs): :arg energy_list_type: name of the list with energies default is 'IB_solv' :type energy_list_type: 'IB_nosolv', 'IB_solv', 'CS' + + + .. [OK98] Keskin O., Bahar I., Badretdinov A.Y., Ptitsyn O.B., Jernigan R.L., + Empirical solvet-mediated potentials hold for both intra-molecular and + inter-molecular inter-residues interactions, + *Protein Science* **1998** 7: 2578–2586. """ if not isinstance(data, list): From 1e16368d5d99ae27fa0881072edb9dbc0a194cff Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Wed, 4 Sep 2024 22:14:49 +0200 Subject: [PATCH 44/68] HSE/HSD/HSP removed from tabulated_energies.txt and get_energy() is modified --- prody/proteins/interactions.py | 50 ++++++++++- prody/proteins/tabulated_energies.txt | 117 -------------------------- 2 files changed, 49 insertions(+), 118 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 6f15148fa..18f076b53 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -160,6 +160,53 @@ def get_energy(pair, source): import numpy as np import importlib.resources as pkg_resources + aa_correction = { + # Histidine (His) + 'HSD': 'HIS', # Protonated at ND1 (HID in AMBER) + 'HSE': 'HIS', # Protonated at NE2 (HIE in AMBER) + 'HSP': 'HIS', # Doubly protonated (HIP in AMBER) + 'HID': 'HIS', # AMBER name, protonated at ND1 + 'HIE': 'HIS', # AMBER name, protonated at NE2 + 'HIP': 'HIS', # AMBER name, doubly protonated + 'HISD': 'HIS', # GROMACS: protonated at ND1 + 'HISE': 'HIS', # GROMACS: protonated at NE2 + 'HISP': 'HIS', # GROMACS: doubly protonated + + # Cysteine (Cys) + 'CYX': 'CYS', # Cystine (disulfide bridge) + 'CYM': 'CYS', # Deprotonated cysteine, anion (GROMACS) + + # Aspartic acid (Asp) + 'ASH': 'ASP', # Deprotonated Asp (GROMACS: ASH, AMBER: AS4) + + # Glutamic acid (Glu) + 'GLH': 'GLU', # Deprotonated Glu (GROMACS: GLH, AMBER: GL4) + + # Lysine (Lys) + 'LYN': 'LYS', # Deprotonated lysine (GROMACS: LYN, AMBER: LYP) + + # Arginine (Arg) + 'ARN': 'ARG', # Deprotonated arginine (rare, GROMACS) + + # Tyrosine (Tyr) + 'TYM': 'TYR', # Deprotonated tyrosine (GROMACS: TYM) + + # Serine (Ser) + 'SEP': 'SER', # Phosphorylated serine (GROMACS/AMBER) + + # Threonine (Thr) + 'TPO': 'THR', # Phosphorylated threonine (GROMACS/AMBER) + + # Tyrosine (Tyr) + 'PTR': 'TYR', # Phosphorylated tyrosine (GROMACS/AMBER) + + # Non-standard names for aspartic and glutamic acids in low pH environments + 'ASH': 'ASP', # Protonated Asp + 'GLH': 'GLU', # Protonated Glu + } + + pair = [aa_correction.get(aa, aa) for aa in pair] + try: # Python 3 with pkg_resources.path('prody.proteins', 'tabulated_energies.txt') as file_path: @@ -191,7 +238,7 @@ def showPairEnergy(data, **kwargs): """Return energies when a list of interactions is given. Energies will be added to each pair of residues at the last position in the list. Energy is based on the residue types and not on the distances. The unit of energy is kcal/mol. The energies defined as 'IB_nosolv', 'IB_solv' are taken from [OK98]_ and - 'CS' from InSty paper. + 'CS' from InSty paper (under preparation). :arg data: list with interactions from calcHydrogenBonds() or other types :type data: list @@ -2007,6 +2054,7 @@ def calcStatisticsInteractions(data, **kwargs): "energy": get_energy([element.split('-')[0][:3], element.split('-')[1][:3]], energy_list_type) } except: + LOGGER.warn('energy information is not available for ', element.split('-')[0][:3], element.split('-')[1][:3]) stats[element] = { "stddev": np.round(np.std(values),6), "mean": np.round(np.mean(values),6), diff --git a/prody/proteins/tabulated_energies.txt b/prody/proteins/tabulated_energies.txt index af530f206..009c8c1b5 100644 --- a/prody/proteins/tabulated_energies.txt +++ b/prody/proteins/tabulated_energies.txt @@ -398,120 +398,3 @@ PRO LYS 0.3 -0.5 0.0 PRO ARG -0.17 -2.43 0.0 PRO HIS 0.33 -1.8 0.0 PRO PRO -0.03 -0.83 0.0 -GLY HSE 0.01 -2.47 0.0 -ALA HSE 0.01 -3.29 0.0 -VAL HSE -0.23 -4.14 -1.1 -ILE HSE -0.02 -4.55 -1.1 -LEU HSE 0.25 -4.85 -1.1 -CYS HSE -0.64 -4.79 -0.8 -MET HSE -0.17 -4.47 -0.5 -PHE HSE 0.79 -3.82 -0.6 -TYR HSE 0.34 -3.78 -1.1 -TRP HSE -0.05 -4.5 -1.7 -SER HSE -0.38 -3.12 -0.5 -THR HSE -0.05 -2.73 -0.5 -ASP HSE 0.0 -2.93 -0.4 -ASN HSE -0.52 -3.05 -1.2 -GLU HSE -0.1 -3.15 -0.4 -GLN HSE -0.31 -4.2 -1.2 -LYS HSE -0.01 -2.14 0.0 -ARG HSE 0.35 -3.24 -0.4 -HSE GLY 0.01 -2.47 0.0 -HSE ALA 0.01 -3.29 0.0 -HSE VAL -0.23 -4.14 -1.1 -HSE ILE -0.02 -4.55 -1.1 -HSE LEU 0.25 -4.85 -1.1 -HSE CYS -0.64 -4.79 -0.8 -HSE MET -0.17 -4.47 -0.5 -HSE PHE 0.79 -3.82 -0.6 -HSE TYR 0.34 -3.78 -1.1 -HSE TRP -0.05 -4.5 -1.7 -HSE SER -0.38 -3.12 -0.5 -HSE THR -0.05 -2.73 -0.5 -HSE ASP 0.0 -2.93 -0.4 -HSE ASN -0.52 -3.05 -1.2 -HSE GLU -0.1 -3.15 -0.4 -HSE GLN -0.31 -4.2 -1.2 -HSE LYS -0.01 -2.14 0.0 -HSE ARG 0.35 -3.24 -0.4 -HSE HSE 0.38 -3.08 -0.5 -HSE PRO 0.33 -1.8 0.0 -PRO HSE 0.33 -1.8 0.0 -GLY HSD 0.01 -2.47 0.0 -ALA HSD 0.01 -3.29 0.0 -VAL HSD -0.23 -4.14 -1.1 -ILE HSD -0.02 -4.55 -1.1 -LEU HSD 0.25 -4.85 -1.1 -CYS HSD -0.64 -4.79 -0.8 -MET HSD -0.17 -4.47 -0.5 -PHE HSD 0.79 -3.82 -0.6 -TYR HSD 0.34 -3.78 -1.1 -TRP HSD -0.05 -4.5 -1.7 -SER HSD -0.38 -3.12 -0.5 -THR HSD -0.05 -2.73 -0.5 -ASP HSD 0.0 -2.93 -0.4 -ASN HSD -0.52 -3.05 -1.2 -GLU HSD -0.1 -3.15 -0.4 -GLN HSD -0.31 -4.2 -1.2 -LYS HSD -0.01 -2.14 0.0 -ARG HSD 0.35 -3.24 -0.4 -HSD GLY 0.01 -2.47 0.0 -HSD ALA 0.01 -3.29 0.0 -HSD VAL -0.23 -4.14 -1.1 -HSD ILE -0.02 -4.55 -1.1 -HSD LEU 0.25 -4.85 -1.1 -HSD CYS -0.64 -4.79 -0.8 -HSD MET -0.17 -4.47 -0.5 -HSD PHE 0.79 -3.82 -0.6 -HSD TYR 0.34 -3.78 -1.1 -HSD TRP -0.05 -4.5 -1.7 -HSD SER -0.38 -3.12 -0.5 -HSD THR -0.05 -2.73 -0.5 -HSD ASP 0.0 -2.93 -0.4 -HSD ASN -0.52 -3.05 -1.2 -HSD GLU -0.1 -3.15 -0.4 -HSD GLN -0.31 -4.2 -1.2 -HSD LYS -0.01 -2.14 0.0 -HSD ARG 0.35 -3.24 -0.4 -HSD HSD 0.38 -3.08 -0.5 -HSD PRO 0.33 -1.8 0.0 -PRO HSD 0.33 -1.8 0.0 -GLY HSP 0.01 -2.47 0.0 -ALA HSP 0.01 -3.29 0.0 -VAL HSP -0.23 -4.14 -1.1 -ILE HSP -0.02 -4.55 -1.1 -LEU HSP 0.25 -4.85 -1.1 -CYS HSP -0.64 -4.79 -0.8 -MET HSP -0.17 -4.47 -0.5 -PHE HSP 0.79 -3.82 -0.6 -TYR HSP 0.34 -3.78 -1.1 -TRP HSP -0.05 -4.5 -1.7 -SER HSP -0.38 -3.12 -0.5 -THR HSP -0.05 -2.73 -0.5 -ASP HSP 0.0 -2.93 -0.4 -ASN HSP -0.52 -3.05 -1.2 -GLU HSP -0.1 -3.15 -0.4 -GLN HSP -0.31 -4.2 -1.2 -LYS HSP -0.01 -2.14 0.0 -ARG HSP 0.35 -3.24 -0.4 -HSP GLY 0.01 -2.47 0.0 -HSP ALA 0.01 -3.29 0.0 -HSP VAL -0.23 -4.14 -1.1 -HSP ILE -0.02 -4.55 -1.1 -HSP LEU 0.25 -4.85 -1.1 -HSP CYS -0.64 -4.79 -0.8 -HSP MET -0.17 -4.47 -0.5 -HSP PHE 0.79 -3.82 -0.6 -HSP TYR 0.34 -3.78 -1.1 -HSP TRP -0.05 -4.5 -1.7 -HSP SER -0.38 -3.12 -0.5 -HSP THR -0.05 -2.73 -0.5 -HSP ASP 0.0 -2.93 -0.4 -HSP ASN -0.52 -3.05 -1.2 -HSP GLU -0.1 -3.15 -0.4 -HSP GLN -0.31 -4.2 -1.2 -HSP LYS -0.01 -2.14 0.0 -HSP ARG 0.35 -3.24 -0.4 -HSP HSP 0.38 -3.08 -0.5 -HSP PRO 0.33 -1.8 0.0 -PRO HSP 0.33 -1.8 0.0 From d5c64c2f0a5256bf986aca223464aad1954793d6 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Wed, 4 Sep 2024 22:42:53 +0200 Subject: [PATCH 45/68] new function - checkNonstandardResidues() --- prody/proteins/interactions.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 18f076b53..79d909bf9 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -46,7 +46,7 @@ 'calcHydrogenBondsTrajectory', 'calcHydrophobicOverlapingAreas', 'Interactions', 'InteractionsTrajectory', 'LigandInteractionsTrajectory', 'calcSminaBindingAffinity', 'calcSminaPerAtomInteractions', 'calcSminaTermValues', - 'showSminaTermValues', 'showPairEnergy'] + 'showSminaTermValues', 'showPairEnergy', 'checkNonstandardResidues'] def cleanNumbers(listContacts): @@ -234,6 +234,25 @@ def get_energy(pair, source): return data_results +def checkNonstandardResidues(atoms): + """Check whether the aromic structure contain non-standard residues and inform to replace the name + to the standard one to be that non-standard residues are treated in a correct way while computing + interactions.""" + + amino_acids = ["ALA", "ARG", "ASN", "ASP", "CYS", "GLU", "GLN", "GLY", "HIS", "ILE", + "LEU", "LYS", "MET", "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL"] + aa_list = atoms.select('name CA').getResnames() + nonstandard = [] + + for i in aa_list: + if i not in amino_acids: + nonstandard.append(i) + + LOGGER.info('There are several non-standard residues in the structure.') + LOGGER.info('Replace the non-standard name in the PDB file with the equivalent name from the standard one if you want to include them in the interactions.') + LOGGER.info("Residues: {0}.".format(' '.join(nonstandard))) + + def showPairEnergy(data, **kwargs): """Return energies when a list of interactions is given. Energies will be added to each pair of residues at the last position in the list. Energy is based on the residue types and not on the distances. From 0263b04b947de0a939c4e1e31644be7828e7628f Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Wed, 4 Sep 2024 22:47:11 +0200 Subject: [PATCH 46/68] check for checkNonstandardResidues() --- prody/proteins/interactions.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 79d909bf9..d5d4423f5 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -235,12 +235,27 @@ def get_energy(pair, source): def checkNonstandardResidues(atoms): - """Check whether the aromic structure contain non-standard residues and inform to replace the name + """Check whether the atomic structure contain non-standard residues and inform to replace the name to the standard one to be that non-standard residues are treated in a correct way while computing - interactions.""" + interactions. + + :arg atoms: an Atomic object from which residues are selected + :type atoms: :class:`.Atomic` + """ + + try: + coords = (atoms._getCoords() if hasattr(atoms, '_getCoords') else + atoms.getCoords()) + except AttributeError: + try: + checkCoords(coords) + except TypeError: + raise TypeError('coords must be an object ' + 'with `getCoords` method') amino_acids = ["ALA", "ARG", "ASN", "ASP", "CYS", "GLU", "GLN", "GLY", "HIS", "ILE", "LEU", "LYS", "MET", "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL"] + aa_list = atoms.select('name CA').getResnames() nonstandard = [] From e22ff3de60fe207383bad0d4e58afc6d09e46924 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Thu, 5 Sep 2024 08:55:09 +0200 Subject: [PATCH 47/68] More info in docs about energies --- prody/proteins/interactions.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index d5d4423f5..46c57355a 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -271,8 +271,8 @@ def checkNonstandardResidues(atoms): def showPairEnergy(data, **kwargs): """Return energies when a list of interactions is given. Energies will be added to each pair of residues at the last position in the list. Energy is based on the residue types and not on the distances. - The unit of energy is kcal/mol. The energies defined as 'IB_nosolv', 'IB_solv' are taken from [OK98]_ and - 'CS' from InSty paper (under preparation). + The unit of energy is kcal/mol. The energies defined as 'IB_nosolv' (non-solvent-mediated), 'IB_solv' (solvent-mediated) + are taken from [OK98]_ and 'CS' from InSty paper (under preparation). :arg data: list with interactions from calcHydrogenBonds() or other types :type data: list @@ -2040,8 +2040,12 @@ def showInteractionsGraph(statistics, **kwargs): def calcStatisticsInteractions(data, **kwargs): """Return the statistics of interactions from PDB Ensemble or trajectory including: (1) the weight for each residue pair: corresponds to the number of counts divided by the - number of frames (values >1 are obtained when residue pair creates multiple contacts); - (2) average distance of interactions for each pair [in Ang] and (3) standard deviation [Ang.]. + number of frames (values >1 are obtained when the residue pair creates multiple contacts); + (2) average distance of interactions for each pair [in Ang], (3) standard deviation [Ang.], + (4) Energy [in kcal/mol] that is not distance dependent. Energy by default is solvent-mediated + from [OK98]_ ('IB_solv'). To use non-solvent-mediated entries ('IB_nosolv') from [OK98]_ or + solvent-mediated values obtained for InSty paper ('CS', under preparation) change + `energy_list_type` parameter. :arg data: list with interactions from calcHydrogenBondsTrajectory() or other types :type data: list From 75fbd58624365f7ea970df20b2e0a751d089dbd2 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Thu, 5 Sep 2024 09:05:02 +0200 Subject: [PATCH 48/68] more info in docs InSty --- prody/proteins/interactions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 46c57355a..6a1cdb94d 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -273,6 +273,8 @@ def showPairEnergy(data, **kwargs): at the last position in the list. Energy is based on the residue types and not on the distances. The unit of energy is kcal/mol. The energies defined as 'IB_nosolv' (non-solvent-mediated), 'IB_solv' (solvent-mediated) are taken from [OK98]_ and 'CS' from InSty paper (under preparation). + Protonation of resiudues is not distinguished. The protonation of residues is not distinguished. + Known residues such as HSD, HSE, HIE, and HID (used in MD simulations) are treated as HIS. :arg data: list with interactions from calcHydrogenBonds() or other types :type data: list From 1e15ef97572b875b628e83b0703f83de77acd0f3 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Thu, 5 Sep 2024 09:39:09 +0200 Subject: [PATCH 49/68] improvement in the non-standard residues in get_energy --- prody/proteins/interactions.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 6a1cdb94d..02b662094 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -162,9 +162,9 @@ def get_energy(pair, source): aa_correction = { # Histidine (His) - 'HSD': 'HIS', # Protonated at ND1 (HID in AMBER) - 'HSE': 'HIS', # Protonated at NE2 (HIE in AMBER) - 'HSP': 'HIS', # Doubly protonated (HIP in AMBER) + 'HSD': 'HIS', # NAMD, protonated at ND1 (HID in AMBER) + 'HSE': 'HIS', # NAMD, protonated at NE2 (HIE in AMBER) + 'HSP': 'HIS', # NAMD, doubly protonated (HIP in AMBER) 'HID': 'HIS', # AMBER name, protonated at ND1 'HIE': 'HIS', # AMBER name, protonated at NE2 'HIP': 'HIS', # AMBER name, doubly protonated @@ -174,22 +174,24 @@ def get_energy(pair, source): # Cysteine (Cys) 'CYX': 'CYS', # Cystine (disulfide bridge) - 'CYM': 'CYS', # Deprotonated cysteine, anion (GROMACS) + 'CYM': 'CYS', # Deprotonated cysteine, anion # Aspartic acid (Asp) - 'ASH': 'ASP', # Deprotonated Asp (GROMACS: ASH, AMBER: AS4) + 'ASH': 'ASP', # Protonated Asp + 'ASPP': 'ASP', # Glutamic acid (Glu) - 'GLH': 'GLU', # Deprotonated Glu (GROMACS: GLH, AMBER: GL4) + 'GLH': 'GLU', # Protonated Glu + 'GLUP': 'GLU', # Protonated Glu # Lysine (Lys) - 'LYN': 'LYS', # Deprotonated lysine (GROMACS: LYN, AMBER: LYP) + 'LYN': 'LYS', # Deprotonated lysine (nautral) # Arginine (Arg) 'ARN': 'ARG', # Deprotonated arginine (rare, GROMACS) # Tyrosine (Tyr) - 'TYM': 'TYR', # Deprotonated tyrosine (GROMACS: TYM) + 'TYM': 'TYR', # Deprotonated tyrosine (GROMACS) # Serine (Ser) 'SEP': 'SER', # Phosphorylated serine (GROMACS/AMBER) From 9f2484b218ea8491e7975997ffcb97b0d391d892 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Sat, 7 Sep 2024 09:21:21 +0200 Subject: [PATCH 50/68] new function saveInteractionsAsDummyAtoms() is added --- prody/proteins/interactions.py | 77 +++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 02b662094..5fee3b88b 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -46,7 +46,8 @@ 'calcHydrogenBondsTrajectory', 'calcHydrophobicOverlapingAreas', 'Interactions', 'InteractionsTrajectory', 'LigandInteractionsTrajectory', 'calcSminaBindingAffinity', 'calcSminaPerAtomInteractions', 'calcSminaTermValues', - 'showSminaTermValues', 'showPairEnergy', 'checkNonstandardResidues'] + 'showSminaTermValues', 'showPairEnergy', 'checkNonstandardResidues', + 'saveInteractionsAsDummyAtoms'] def cleanNumbers(listContacts): @@ -2198,6 +2199,80 @@ def calcDistribution(interactions, residue1, residue2=None, **kwargs): LOGGER.info(i) +def saveInteractionsAsDummyAtoms(atoms, interactions, filename, *kwargs): + '''Creates a PDB file which will contain protein structure and dummy atoms that will be placed between pairs + of interacting residues. + + :arg atoms: an Atomic object from which residues are selected + :type atoms: :class:`.Atomic` + + :arg interactions: list of interactions + :type interactions: list + + :arg filename: name of the PDB file which will contain dummy atoms and protein structure + :type filename: str + + :arg RESNAME_dummy: resname of the dummy atom, use 3-letter name + be default is 'DUM' + :type RESNAME_dummy: str ''' + + + try: + coords = (atoms._getCoords() if hasattr(atoms, '_getCoords') else + atoms.getCoords()) + except AttributeError: + try: + checkCoords(coords) + except TypeError: + raise TypeError('coords must be an object ' + 'with `getCoords` method') + + RESNAME_dummy = kwargs.pop('RESNAME_dummy', 'DUM') + + def putDUMatom(coord1, coord2): + midpoint = [ + (coord1[0] + coord2[0]) / 2, + (coord1[1] + coord2[1]) / 2, + (coord1[2] + coord2[2]) / 2 + ] + return midpoint + + all_DUMs = [] + atoms_ = atoms.copy() + + for i in interactions: + if len(i[1].split('_')) <= 3: + res1_name = 'chain '+i[2]+' resname '+i[0][:3]+' and resid '+i[0][3:]+' and index '+' '.join(i[1].split('_')[1:]) + res1_coords = calcCenter(atoms.select(res1_name)) + + if len(i[1].split('_')) > 3: + res1_name = 'chain '+i[2]+' resname '+i[0][:3]+' and resid '+i[0][3:]+' and index '+' '.join(i[1].split('_')) + res1_coords = calcCenter(atoms.select(res1_name)) + + if len(i[4].split('_')) <= 3: + res2_name = 'chain '+i[5]+' resname '+i[3][:3]+' and resid '+i[3][3:]+' and index '+' '.join(i[4].split('_')[1:]) + res2_coords = calcCenter(atoms.select(res2_name)) + + if len(i[4].split('_')) > 3: + res2_name = 'chain '+i[5]+' resname '+i[3][:3]+' and resid '+i[3][3:]+' and index '+' '.join(i[4].split('_')) + res2_coords = calcCenter(atoms.select(res2_name)) + + all_DUMs.append(putDUMatom(res1_coords, res2_coords)) + + if all_DUMs == []: + LOGGER.info('Lack of interactions') + else: + LOGGER.info('Creating file with dummy atoms') + dummyAtoms = AtomGroup() + coords = array([all_DUMs], dtype=float) + dummyAtoms.setCoords(coords) + dummyAtoms.setNames([RESNAME_dummy]*len(dummyAtoms)) + dummyAtoms.setResnums(range(1, len(dummyAtoms)+1)) + dummyAtoms.setResnames([RESNAME_dummy]*len(dummyAtoms)) + + writePDB(filename, atoms_+dummyAtoms) + + def listLigandInteractions(PLIP_output, **kwargs): """Create a list of interactions from PLIP output created using calcLigandInteractions(). Results can be displayed in VMD. From def37bbb6892f32d0788463fb95f585d58d81f19 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Sun, 8 Sep 2024 22:00:40 +0200 Subject: [PATCH 51/68] saveInteractionsAsDummyAtoms fix with kwargs --- prody/proteins/interactions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 5fee3b88b..0de0a8aef 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -2199,7 +2199,7 @@ def calcDistribution(interactions, residue1, residue2=None, **kwargs): LOGGER.info(i) -def saveInteractionsAsDummyAtoms(atoms, interactions, filename, *kwargs): +def saveInteractionsAsDummyAtoms(atoms, interactions, filename, **kwargs): '''Creates a PDB file which will contain protein structure and dummy atoms that will be placed between pairs of interacting residues. @@ -2226,9 +2226,9 @@ def saveInteractionsAsDummyAtoms(atoms, interactions, filename, *kwargs): except TypeError: raise TypeError('coords must be an object ' 'with `getCoords` method') - + RESNAME_dummy = kwargs.pop('RESNAME_dummy', 'DUM') - + def putDUMatom(coord1, coord2): midpoint = [ (coord1[0] + coord2[0]) / 2, From 6277f1dad3814b30e526758c00c212a2f11951ea Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Mon, 9 Sep 2024 21:44:01 +0200 Subject: [PATCH 52/68] improvements of checkNonstandardResidues() --- prody/proteins/interactions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 0de0a8aef..d7f561507 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -260,11 +260,12 @@ def checkNonstandardResidues(atoms): "LEU", "LYS", "MET", "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL"] aa_list = atoms.select('name CA').getResnames() + aa_list_nr = atoms.select('name CA').getResnums() nonstandard = [] - for i in aa_list: + for nr_i,i in enumerate(aa_list): if i not in amino_acids: - nonstandard.append(i) + nonstandard.append(aa_list[nr_i] + str(aa_list_nr[nr_i])) LOGGER.info('There are several non-standard residues in the structure.') LOGGER.info('Replace the non-standard name in the PDB file with the equivalent name from the standard one if you want to include them in the interactions.') From 286ceb8f208af5ba843bbe4c315cd8a4fbad0e77 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Tue, 10 Sep 2024 11:23:04 +0200 Subject: [PATCH 53/68] getInteractions - replace option for trajectory --- prody/proteins/interactions.py | 46 +++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index d7f561507..6b5bf777d 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -28,7 +28,7 @@ from prody.proteins import writePDB, parsePDB from collections import Counter -from prody.trajectory import TrajBase, Trajectory +from prody.trajectory import TrajBase, Trajectory, Frame from prody.ensemble import Ensemble import multiprocessing @@ -3025,14 +3025,26 @@ def getInteractions(self, **kwargs): :arg selection2: selection string :type selection2: str + :arg replace: Used with selection criteria to set the new one + If set to True the selection will be replaced by the new one + :type replace: True or False + by default is False + Selection: If we want to select interactions for the particular residue or group of residues: selection='chain A and resid 1 to 50' If we want to study chain-chain interactions: selection='chain A', selection2='chain B' """ - + + replace = kwargs.pop('replace', False) + if len(kwargs) != 0: results = [filterInteractions(j, self._atoms, **kwargs) for j in self._interactions] + + if replace == True: + self._interactions = results + LOGGER.info('New interactions are set') + else: results = self._interactions @@ -3917,19 +3929,47 @@ def getInteractions(self, **kwargs): :arg selection2: selection string :type selection2: str + + :arg replace: Used with selection criteria to set the new one + If set to True the selection will be replaced by the new one + :type replace: True or False + by default is False Selection: If we want to select interactions for the particular residue or group of residues: selection='chain A and resid 1 to 50' If we want to study chain-chain interactions: selection='chain A', selection2='chain B' """ - + + replace = kwargs.pop('replace', False) + if len(kwargs) != 0: sele_inter = [] for i in self._interactions_traj: for nr_j,j in enumerate(i): sele_inter.append(filterInteractions(i[nr_j], self._atoms, **kwargs)) + + if replace == True: + try: + trajectory = self._traj + numFrames = trajectory._n_csets + except: + # If we analyze previously saved PKL file we doesn't have dcd information + # We have seven type of interactions. It will give number of frames. + numFrames = int(len(sele_inter)/7) + + self._interactions_traj = sele_inter + self._hbs_traj = sele_inter[0:numFrames] + self._sbs_traj = sele_inter[numFrames:2*numFrames] + self._rib_traj = sele_inter[2*numFrames:3*numFrames] + self._piStack_traj = sele_inter[3*numFrames:4*numFrames] + self._piCat_traj = sele_inter[4*numFrames:5*numFrames] + self._hps_traj = sele_inter[5*numFrames:6*numFrames] + self._dibs_traj = sele_inter[6*numFrames:7*numFrames] + LOGGER.info('New interactions are set') + results = sele_inter + else: results = self._interactions_traj From 3a06083e3de079c9766d18a2091cf6b81be1475e Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Tue, 10 Sep 2024 11:35:27 +0200 Subject: [PATCH 54/68] getInteractions - replace for a single PDB interactions --- prody/proteins/interactions.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 6b5bf777d..1e2d2fe46 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -3042,8 +3042,15 @@ def getInteractions(self, **kwargs): results = [filterInteractions(j, self._atoms, **kwargs) for j in self._interactions] if replace == True: - self._interactions = results LOGGER.info('New interactions are set') + self._interactions = results + self._hbs = results[0] + self._sbs = results[1] + self._rib = results[2] + self._piStack = results[3] + self._piCat = results[4] + self._hps = results[5] + self._dibs = results[6] else: results = self._interactions From d86f7b8af9a7dbe18e6f1847fdfb0b6ad2d8b0f6 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Tue, 10 Sep 2024 14:24:54 +0200 Subject: [PATCH 55/68] getTimeInteractions() improvement to include selection replacement --- prody/proteins/interactions.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 1e2d2fe46..bca2349a9 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -3974,7 +3974,20 @@ def getInteractions(self, **kwargs): self._hps_traj = sele_inter[5*numFrames:6*numFrames] self._dibs_traj = sele_inter[6*numFrames:7*numFrames] LOGGER.info('New interactions are set') - + + self._interactions_nb_traj = None + self._interactions_matrix_traj = None + + new_interactions_nb_traj = [] + new_interactions_nb_traj.append([ len(i) for i in self._hbs_traj ]) + new_interactions_nb_traj.append([ len(i) for i in self._sbs_traj ]) + new_interactions_nb_traj.append([ len(i) for i in self._rib_traj ]) + new_interactions_nb_traj.append([ len(i) for i in self._piStack_traj ]) + new_interactions_nb_traj.append([ len(i) for i in self._piCat_traj ]) + new_interactions_nb_traj.append([ len(i) for i in self._hps_traj ]) + new_interactions_nb_traj.append([ len(i) for i in self._dibs_traj ]) + self._interactions_nb_traj = new_interactions_nb_traj + results = sele_inter else: From 4b5d687c358182e9ed3b974f9a61798f2c0dfd47 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Tue, 10 Sep 2024 22:48:39 +0200 Subject: [PATCH 56/68] showFrequentInteractors() [InSty] improvement - return dict with residues --- prody/proteins/interactions.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index bca2349a9..c0a07bfc2 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -3583,18 +3583,22 @@ def showFrequentInteractors(self, cutoff=5, **kwargs): y.append(all_y[nr_ii]) if SETTINGS['auto_show']: - matplotlib.rcParams['font.size'] = '20' - fig = plt.figure(num=None, figsize=(12,6), facecolor='w') + matplotlib.rcParams['font.size'] = '12' + fig = plt.figure(num=None, figsize=(16,5), facecolor='w') y_pos = np.arange(len(y)) show = plt.bar(y_pos, x, align='center', alpha=0.5, color='blue') - plt.xticks(y_pos, y, rotation=45, fontsize=20) - plt.ylabel('Number of interactions') + plt.xticks(y_pos, y, rotation=45, fontsize=16) + plt.ylabel('Number of interactions', fontsize=16) plt.tight_layout() if SETTINGS['auto_show']: showFigure() - return show + + dict_counts = dict(zip(y, x)) + dict_counts_sorted = dict(sorted(dict_counts.items(), key=lambda item: item[1], reverse=True)) + + return dict_counts_sorted def showCumulativeInteractionTypes(self, **kwargs): From d5de489dd4e9ace1e0713f04bd63ed3e9ab81178 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Wed, 11 Sep 2024 21:39:16 +0200 Subject: [PATCH 57/68] addMissingAtoms() [fixer.py] - keep_ids added --- prody/proteins/fixer.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/prody/proteins/fixer.py b/prody/proteins/fixer.py index ad30aa731..d78882d7a 100644 --- a/prody/proteins/fixer.py +++ b/prody/proteins/fixer.py @@ -28,7 +28,7 @@ def addMissingAtoms(infile, method='openbabel', pH=7.0, outfile=None, **kwargs): or PDBFixer with OpenMM. There are also options whether to *model_residues* (default False), *remove_heterogens* - (default False), *keep_waters* (default True), *overwrite* (default False). + (default False), *keep_waters* (default True), *overwrite* (default False), *keep_ids* (default True). :arg infile: PDB file name :type infile: str @@ -44,6 +44,14 @@ def addMissingAtoms(infile, method='openbabel', pH=7.0, outfile=None, **kwargs): :arg pH: pH value applyed only for PDBfixer. :type pH: int, float + :arg model_residues: add all missing atoms from residues, applyed only for PDBfixer. + default is False + :type model_residues: bool + + :arg keep_ids: keep the oryginal residue number, applyed only for PDBfixer. + default is True + :type keep_ids: bool + Instalation of Openbabel: conda install -c conda-forge openbabel @@ -58,6 +66,7 @@ def addMissingAtoms(infile, method='openbabel', pH=7.0, outfile=None, **kwargs): remove_heterogens = kwargs.get("remove_heterogens", False) keep_water = kwargs.get("keep_water", True) overwrite = kwargs.get("overwrite", False) + keep_ids = kwargs.get("keep_ids", True) import os @@ -70,6 +79,9 @@ def addMissingAtoms(infile, method='openbabel', pH=7.0, outfile=None, **kwargs): if not isinstance(keep_water, bool): raise TypeError('keep_water should be True or False') + if not isinstance(keep_Ids, bool): + raise TypeError('keep_Ids should be True or False') + if not isinstance(overwrite, bool): raise TypeError('overwrite should be True or False') @@ -136,7 +148,7 @@ def addMissingAtoms(infile, method='openbabel', pH=7.0, outfile=None, **kwargs): fixer.findMissingAtoms() fixer.addMissingAtoms() fixer.addMissingHydrogens(pH) - PDBFile.writeFile(fixer.topology, fixer.positions, open(outfile, 'w')) + PDBFile.writeFile(fixer.topology, fixer.positions, open(outfile, 'w'), keepIds=keep_ids) LOGGER.info("Hydrogens were added to the structure. New structure is saved as {0}.".format(outfile)) except ImportError: @@ -165,6 +177,14 @@ def fixStructuresMissingAtoms(infiles, method='openbabel', pH=7.0, outfiles=None 'pdbfixer': PDBFixer and OpenMM default is 'openbabel' :type method: str + + :arg model_residues: add all missing atoms from residues, applyed only for PDBfixer. + default is False + :type model_residues: bool + + :arg keep_ids: keep the oryginal residue number, applyed only for PDBfixer. + default is True + :type keep_ids: bool :arg pH: pH value applyed only for PDBfixer. :type pH: int, float From 6c10c4647ae06eee4c5c73b59afed47c7db0e941 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Wed, 11 Sep 2024 21:51:49 +0200 Subject: [PATCH 58/68] typo in addMissingAtoms --- prody/proteins/fixer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prody/proteins/fixer.py b/prody/proteins/fixer.py index d78882d7a..1aa97acb4 100644 --- a/prody/proteins/fixer.py +++ b/prody/proteins/fixer.py @@ -79,8 +79,8 @@ def addMissingAtoms(infile, method='openbabel', pH=7.0, outfile=None, **kwargs): if not isinstance(keep_water, bool): raise TypeError('keep_water should be True or False') - if not isinstance(keep_Ids, bool): - raise TypeError('keep_Ids should be True or False') + if not isinstance(keep_ids, bool): + raise TypeError('keep_ids should be True or False') if not isinstance(overwrite, bool): raise TypeError('overwrite should be True or False') From cf86d944bca13dadccfcbbb6d232dade2e654d67 Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Wed, 11 Sep 2024 22:36:20 +0200 Subject: [PATCH 59/68] typo found by James --- prody/proteins/interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index c0a07bfc2..e996427da 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -3965,7 +3965,7 @@ def getInteractions(self, **kwargs): trajectory = self._traj numFrames = trajectory._n_csets except: - # If we analyze previously saved PKL file we doesn't have dcd information + # If we analyze previously saved PKL file it doesn't have dcd information # We have seven type of interactions. It will give number of frames. numFrames = int(len(sele_inter)/7) From 11738ad78d64e84ba1e7b9b2bb14bda6a59e66ba Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Wed, 11 Sep 2024 22:46:55 +0200 Subject: [PATCH 60/68] InSty - typos and TypeError fixed [James comments] --- prody/proteins/interactions.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index e996427da..cbe700d87 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -231,8 +231,8 @@ def get_energy(pair, source): try: data_results = data[np.where(np.array(aa_pairs)==lookup)[0]][0][2:][np.where(np.array(sources)==source)][0] - except ImportError: - raise ImportError('Please replace non-standard names of residues with standard names.') + except TypeError: + raise TypeError('Please replace non-standard names of residues with standard names.') return data_results @@ -277,7 +277,7 @@ def showPairEnergy(data, **kwargs): at the last position in the list. Energy is based on the residue types and not on the distances. The unit of energy is kcal/mol. The energies defined as 'IB_nosolv' (non-solvent-mediated), 'IB_solv' (solvent-mediated) are taken from [OK98]_ and 'CS' from InSty paper (under preparation). - Protonation of resiudues is not distinguished. The protonation of residues is not distinguished. + Protonation of residues is not distinguished. The protonation of residues is not distinguished. Known residues such as HSD, HSE, HIE, and HID (used in MD simulations) are treated as HIS. :arg data: list with interactions from calcHydrogenBonds() or other types @@ -2047,7 +2047,8 @@ def calcStatisticsInteractions(data, **kwargs): """Return the statistics of interactions from PDB Ensemble or trajectory including: (1) the weight for each residue pair: corresponds to the number of counts divided by the number of frames (values >1 are obtained when the residue pair creates multiple contacts); - (2) average distance of interactions for each pair [in Ang], (3) standard deviation [Ang.], + (2) average distance of interactions for each pair [in Ang], + (3) standard deviation [Ang.], (4) Energy [in kcal/mol] that is not distance dependent. Energy by default is solvent-mediated from [OK98]_ ('IB_solv'). To use non-solvent-mediated entries ('IB_nosolv') from [OK98]_ or solvent-mediated values obtained for InSty paper ('CS', under preparation) change From 95a9a0d4fa5c6ac4ea912e62b5a022b69c2dfcde Mon Sep 17 00:00:00 2001 From: karolamik13 Date: Thu, 12 Sep 2024 08:43:10 +0200 Subject: [PATCH 61/68] InSty [docs and checks improvements] --- prody/proteins/interactions.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index cbe700d87..5c7cd53a4 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -2053,6 +2053,8 @@ def calcStatisticsInteractions(data, **kwargs): from [OK98]_ ('IB_solv'). To use non-solvent-mediated entries ('IB_nosolv') from [OK98]_ or solvent-mediated values obtained for InSty paper ('CS', under preparation) change `energy_list_type` parameter. + If energy information is not available, please check whether the pair of residues is listed in + the "tabulated_energies.txt" file, which is localized in the ProDy directory. :arg data: list with interactions from calcHydrogenBondsTrajectory() or other types :type data: list @@ -3445,17 +3447,20 @@ def saveInteractionsPDB(self, **kwargs): :arg energy: sum of the energy between residues default is False - :type energy: True, False + :type energy: bool """ + energy = kwargs.pop('energy', False) + if not hasattr(self, '_interactions_matrix') or self._interactions_matrix is None: raise ValueError('Please calculate interactions matrix first.') + + if not isinstance(energy, bool): + raise TypeError('energy should be True or False') import numpy as np from collections import Counter - energy = kwargs.pop('energy', False) - atoms = self._atoms interaction_matrix = self._interactions_matrix interaction_matrix_en = self._interactions_matrix_en @@ -3629,7 +3634,7 @@ def showCumulativeInteractionTypes(self, **kwargs): :arg energy: sum of the energy between residues default is False - :type energy: True, False + :type energy: bool """ import numpy as np @@ -3644,13 +3649,15 @@ def showCumulativeInteractionTypes(self, **kwargs): atoms = self._atoms energy = kwargs.pop('energy', False) - + + if not isinstance(energy, bool): + raise TypeError('energy should be True or False') + ResNumb = atoms.select('protein and name CA').getResnums() ResName = atoms.select('protein and name CA').getResnames() ResChid = atoms.select('protein and name CA').getChids() ResList = [ i[0]+str(i[1])+i[2] for i in list(zip([ aa_dic[i] for i in ResName ], ResNumb, ResChid)) ] - if energy == True: matrix_en = self._interactions_matrix_en matrix_en_sum = np.sum(matrix_en, axis=0) @@ -3668,7 +3675,6 @@ def showCumulativeInteractionTypes(self, **kwargs): plt.show() return matrix_en_sum - else: replace_matrix = kwargs.get('replace_matrix', False) From 860c7b3d2acef2e3d1310a918629f8b19db6dc96 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 12 Sep 2024 14:49:01 +0200 Subject: [PATCH 62/68] fix typos --- prody/proteins/fixer.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/prody/proteins/fixer.py b/prody/proteins/fixer.py index 1aa97acb4..ccd49aef3 100644 --- a/prody/proteins/fixer.py +++ b/prody/proteins/fixer.py @@ -41,14 +41,14 @@ def addMissingAtoms(infile, method='openbabel', pH=7.0, outfile=None, **kwargs): default is 'openbabel' :type method: str - :arg pH: pH value applyed only for PDBfixer. + :arg pH: pH value applied only for PDBfixer. :type pH: int, float - :arg model_residues: add all missing atoms from residues, applyed only for PDBfixer. + :arg model_residues: add all missing atoms from residues, applied only for PDBfixer. default is False :type model_residues: bool - :arg keep_ids: keep the oryginal residue number, applyed only for PDBfixer. + :arg keep_ids: keep the original residue number, applied only for PDBfixer. default is True :type keep_ids: bool @@ -178,15 +178,15 @@ def fixStructuresMissingAtoms(infiles, method='openbabel', pH=7.0, outfiles=None default is 'openbabel' :type method: str - :arg model_residues: add all missing atoms from residues, applyed only for PDBfixer. + :arg model_residues: add all missing atoms from residues, applied only for PDBfixer. default is False :type model_residues: bool - :arg keep_ids: keep the oryginal residue number, applyed only for PDBfixer. + :arg keep_ids: keep the original residue number, applied only for PDBfixer. default is True :type keep_ids: bool - :arg pH: pH value applyed only for PDBfixer. + :arg pH: pH value applied only for PDBfixer. :type pH: int, float Instalation of Openbabel: From 0ffa953f8ffbe28c6bd32f05b15714644163c112 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 12 Sep 2024 15:07:28 +0200 Subject: [PATCH 63/68] fix replace type --- prody/proteins/interactions.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 5c7cd53a4..88e6403f8 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -3029,10 +3029,10 @@ def getInteractions(self, **kwargs): :type selection2: str :arg replace: Used with selection criteria to set the new one - If set to True the selection will be replaced by the new one - :type replace: True or False - by default is False - + If set to **True** the selection will be replaced by the new one. + Default is **False** + :type replace: bool + Selection: If we want to select interactions for the particular residue or group of residues: selection='chain A and resid 1 to 50' @@ -3949,10 +3949,10 @@ def getInteractions(self, **kwargs): :type selection2: str :arg replace: Used with selection criteria to set the new one - If set to True the selection will be replaced by the new one - :type replace: True or False - by default is False - + If set to **True** the selection will be replaced by the new one. + Default is **False** + :type replace: bool + Selection: If we want to select interactions for the particular residue or group of residues: selection='chain A and resid 1 to 50' From e1f4c6ff52832f19e6ec0493b70d6377a1b0017a Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 12 Sep 2024 15:17:10 +0200 Subject: [PATCH 64/68] fix pkg_resources for PY3K --- prody/proteins/interactions.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 88e6403f8..3b6a75386 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -210,16 +210,13 @@ def get_energy(pair, source): pair = [aa_correction.get(aa, aa) for aa in pair] - try: - # Python 3 - with pkg_resources.path('prody.proteins', 'tabulated_energies.txt') as file_path: - data = np.loadtxt(file_path, dtype=str) - except: - # Python 2.7 - import pkg_resources + if PY3K: + file_path = pkg_resources.path('prody.proteins', 'tabulated_energies.txt') + else: file_path = pkg_resources.resource_filename('prody.proteins', 'tabulated_energies.txt') - with open(file_path) as f: - data = np.loadtxt(f, dtype=str) + + with open(file_path) as f: + data = np.loadtxt(f, dtype=str) sources = ["IB_nosolv", "IB_solv", "CS"] aa_pairs = [] From 370e5612b9f1f338173ab6fdbe345caefd0fe4dd Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 12 Sep 2024 15:25:29 +0200 Subject: [PATCH 65/68] fix checkNonstandardResidues --- prody/proteins/interactions.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 3b6a75386..b27a00fc4 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -235,8 +235,8 @@ def get_energy(pair, source): def checkNonstandardResidues(atoms): - """Check whether the atomic structure contain non-standard residues and inform to replace the name - to the standard one to be that non-standard residues are treated in a correct way while computing + """Check whether the atomic structure contains non-standard residues and inform to replace the name + to the standard one so that non-standard residues are treated in a correct way while computing interactions. :arg atoms: an Atomic object from which residues are selected @@ -264,9 +264,13 @@ def checkNonstandardResidues(atoms): if i not in amino_acids: nonstandard.append(aa_list[nr_i] + str(aa_list_nr[nr_i])) - LOGGER.info('There are several non-standard residues in the structure.') - LOGGER.info('Replace the non-standard name in the PDB file with the equivalent name from the standard one if you want to include them in the interactions.') - LOGGER.info("Residues: {0}.".format(' '.join(nonstandard))) + if len(nonstandard) > 0: + LOGGER.info('There are several non-standard residues in the structure.') + LOGGER.info('Replace the non-standard name in the PDB file with the equivalent name from the standard one if you want to include them in the interactions.') + LOGGER.info("Residues: {0}.".format(' '.join(nonstandard))) + return True + + return False def showPairEnergy(data, **kwargs): From e0f4d102e7eab703fe2d9ca956b9aafc96a40f04 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 12 Sep 2024 15:26:32 +0200 Subject: [PATCH 66/68] rename putDUMatom --- prody/proteins/interactions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index b27a00fc4..35a9cfc4a 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -2234,7 +2234,7 @@ def saveInteractionsAsDummyAtoms(atoms, interactions, filename, **kwargs): RESNAME_dummy = kwargs.pop('RESNAME_dummy', 'DUM') - def putDUMatom(coord1, coord2): + def calcDUMposition(coord1, coord2): midpoint = [ (coord1[0] + coord2[0]) / 2, (coord1[1] + coord2[1]) / 2, @@ -2262,7 +2262,7 @@ def putDUMatom(coord1, coord2): res2_name = 'chain '+i[5]+' resname '+i[3][:3]+' and resid '+i[3][3:]+' and index '+' '.join(i[4].split('_')) res2_coords = calcCenter(atoms.select(res2_name)) - all_DUMs.append(putDUMatom(res1_coords, res2_coords)) + all_DUMs.append(calcDUMposition(res1_coords, res2_coords)) if all_DUMs == []: LOGGER.info('Lack of interactions') From 670db545a7948b9a0797c00648ab33f4ad7e1531 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 12 Sep 2024 15:28:00 +0200 Subject: [PATCH 67/68] add and for readability --- prody/proteins/interactions.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index 35a9cfc4a..a35cf87ae 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -2247,19 +2247,19 @@ def calcDUMposition(coord1, coord2): for i in interactions: if len(i[1].split('_')) <= 3: - res1_name = 'chain '+i[2]+' resname '+i[0][:3]+' and resid '+i[0][3:]+' and index '+' '.join(i[1].split('_')[1:]) + res1_name = 'chain '+i[2]+' and resname '+i[0][:3]+' and resid '+i[0][3:]+' and index '+' '.join(i[1].split('_')[1:]) res1_coords = calcCenter(atoms.select(res1_name)) if len(i[1].split('_')) > 3: - res1_name = 'chain '+i[2]+' resname '+i[0][:3]+' and resid '+i[0][3:]+' and index '+' '.join(i[1].split('_')) + res1_name = 'chain '+i[2]+' and resname '+i[0][:3]+' and resid '+i[0][3:]+' and index '+' '.join(i[1].split('_')) res1_coords = calcCenter(atoms.select(res1_name)) if len(i[4].split('_')) <= 3: - res2_name = 'chain '+i[5]+' resname '+i[3][:3]+' and resid '+i[3][3:]+' and index '+' '.join(i[4].split('_')[1:]) + res2_name = 'chain '+i[5]+' and resname '+i[3][:3]+' and resid '+i[3][3:]+' and index '+' '.join(i[4].split('_')[1:]) res2_coords = calcCenter(atoms.select(res2_name)) if len(i[4].split('_')) > 3: - res2_name = 'chain '+i[5]+' resname '+i[3][:3]+' and resid '+i[3][3:]+' and index '+' '.join(i[4].split('_')) + res2_name = 'chain '+i[5]+' and resname '+i[3][:3]+' and resid '+i[3][3:]+' and index '+' '.join(i[4].split('_')) res2_coords = calcCenter(atoms.select(res2_name)) all_DUMs.append(calcDUMposition(res1_coords, res2_coords)) From 2db6ea99ffa9a05f92bece582b4417905ca8aa81 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 12 Sep 2024 16:06:51 +0200 Subject: [PATCH 68/68] another typo fix --- prody/proteins/interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prody/proteins/interactions.py b/prody/proteins/interactions.py index a35cf87ae..7c49cc4c0 100644 --- a/prody/proteins/interactions.py +++ b/prody/proteins/interactions.py @@ -186,7 +186,7 @@ def get_energy(pair, source): 'GLUP': 'GLU', # Protonated Glu # Lysine (Lys) - 'LYN': 'LYS', # Deprotonated lysine (nautral) + 'LYN': 'LYS', # Deprotonated lysine (neutral) # Arginine (Arg) 'ARN': 'ARG', # Deprotonated arginine (rare, GROMACS)