From 825a2bfe4c48bf289b6a7b525c41c9bf734ff693 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Tue, 9 Apr 2024 10:08:07 +0200 Subject: [PATCH 01/34] split pqr coords --- prody/proteins/pdbfile.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/prody/proteins/pdbfile.py b/prody/proteins/pdbfile.py index 127aae19a..75851066f 100644 --- a/prody/proteins/pdbfile.py +++ b/prody/proteins/pdbfile.py @@ -539,12 +539,16 @@ def _parsePDBLines(atomgroup, lines, split, model, chain, subset, line = lines[i] if not isPDB: fields = line.split() - if len(fields) == 10: + if fields[5].find('.') != -1: + # coords too early as no chid fields.insert(4, '') - elif len(fields) != 11: - LOGGER.warn('wrong number of fields for PQR format at line %d'%i) - i += 1 - continue + if len(fields) != 11: + try: + fields = fields[:6] + [line[30:38].strip(), line[38:46].strip(), line[46:54].strip()] + line[54:].split() + except: + LOGGER.warn('wrong number of fields for PQR format at line %d'%i) + i += 1 + continue if isPDB: startswith = line[0:6].strip() From 894806356d7f0ee77d4a09b4ab9a9689d3df372b Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 17 Apr 2024 15:49:44 +0200 Subject: [PATCH 02/34] 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 03/34] 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 04/34] 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 05/34] 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 06/34] 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 c33a1b92728d5b43a2309209203f147eae60d47b Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 15 May 2024 19:18:06 +0200 Subject: [PATCH 07/34] move fields fix to ATOM or HETATM block --- prody/proteins/pdbfile.py | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/prody/proteins/pdbfile.py b/prody/proteins/pdbfile.py index 75851066f..9ec4fa75f 100644 --- a/prody/proteins/pdbfile.py +++ b/prody/proteins/pdbfile.py @@ -537,23 +537,7 @@ def _parsePDBLines(atomgroup, lines, split, model, chain, subset, dec = True while i < stop: line = lines[i] - if not isPDB: - fields = line.split() - if fields[5].find('.') != -1: - # coords too early as no chid - fields.insert(4, '') - if len(fields) != 11: - try: - fields = fields[:6] + [line[30:38].strip(), line[38:46].strip(), line[46:54].strip()] + line[54:].split() - except: - LOGGER.warn('wrong number of fields for PQR format at line %d'%i) - i += 1 - continue - - if isPDB: - startswith = line[0:6].strip() - else: - startswith = fields[0] + startswith = line[0:6].strip() if startswith == 'ATOM' or startswith == 'HETATM': if isPDB: @@ -564,6 +548,17 @@ def _parsePDBLines(atomgroup, lines, split, model, chain, subset, else: resname = line[17:20].strip() else: + fields = line.split() + if fields[5].find('.') != -1: + # coords too early as no chid + fields.insert(4, '') + if len(fields) != 11: + try: + fields = fields[:6] + [line[30:38].strip(), line[38:46].strip(), line[46:54].strip()] + line[54:].split() + except: + LOGGER.warn('wrong number of fields for PQR format at line %d'%i) + i += 1 + continue atomname= fields[2] resname = fields[3] From cb11724450cf30acc4dea2372224b4f53b14f3e0 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 15 May 2024 19:20:22 +0200 Subject: [PATCH 08/34] ssa no calphas fix --- prody/proteins/pdbfile.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/prody/proteins/pdbfile.py b/prody/proteins/pdbfile.py index 9ec4fa75f..c03489139 100644 --- a/prody/proteins/pdbfile.py +++ b/prody/proteins/pdbfile.py @@ -1688,7 +1688,10 @@ def writePQRStream(stream, atoms, **kwargs): write = stream.write calphas = atoms.ca - ssa = calphas.getSecstrs() + if calphas is not None: + ssa = calphas.getSecstrs() + else: + ssa = None helix = [] sheet = [] if ssa is not None: From ccbde645243df63ec665f5fc10912cc84edf8e10 Mon Sep 17 00:00:00 2001 From: exx Date: Fri, 7 Jun 2024 16:21:06 -0400 Subject: [PATCH 09/34] 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 d30fd6d33c746b16448236c2ed9db9f2a9401413 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Sat, 29 Jun 2024 13:08:08 +0200 Subject: [PATCH 10/34] redo parsePDBLigand for cif --- prody/compounds/pdbligands.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/prody/compounds/pdbligands.py b/prody/compounds/pdbligands.py index 8d2e795c1..b62a917c4 100644 --- a/prody/compounds/pdbligands.py +++ b/prody/compounds/pdbligands.py @@ -8,6 +8,7 @@ from prody import LOGGER, SETTINGS, getPackagePath, PY3K from prody.atomic import AtomGroup, ATOMIC_FIELDS from prody.utilities import openFile, makePath, openURL +from .ccd import parseCCD __all__ = ['PDBLigandRecord', 'fetchPDBLigand', 'parsePDBLigand'] @@ -18,7 +19,11 @@ def __init__(self, data): self._rawdata = data def getCanonicalSMILES(self): - return self._rawdata['CACTVS_SMILES_CANONICAL'] + canonical = None + for row in self._rawdata[2].data: + if row['_pdbx_chem_comp_descriptor.type'] == 'SMILES_CANONICAL': + canonical = row['_pdbx_chem_comp_descriptor.descriptor'] + return canonical def fetchPDBLigand(cci, filename=None): @@ -233,8 +238,8 @@ def fetchPDBLigand(cci, filename=None): return dict_ -def parsePDBLigand(cci, filename=None): +def parsePDBLigand(cci): """See :func:`.fetchPDBLigand`""" - lig_dict = fetchPDBLigand(cci, filename) + lig_dict = parseCCD(cci) return PDBLigandRecord(lig_dict) From c4dfe00be74f2fff420ead3608ccd4343c8af23a Mon Sep 17 00:00:00 2001 From: James Krieger Date: Sat, 29 Jun 2024 13:14:28 +0200 Subject: [PATCH 11/34] handle fetchPDBLigand in docs --- prody/compounds/pdbligands.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/prody/compounds/pdbligands.py b/prody/compounds/pdbligands.py index b62a917c4..de72a193b 100644 --- a/prody/compounds/pdbligands.py +++ b/prody/compounds/pdbligands.py @@ -27,9 +27,12 @@ def getCanonicalSMILES(self): def fetchPDBLigand(cci, filename=None): - """Fetch PDB ligand data from PDB_ for chemical component *cci*. + """Handle PDB ligand data from PDB_ for chemical component *cci*. *cci* may be 3-letter chemical component identifier or a valid XML - filename. If *filename* is given, XML file will be saved with that name. + filename. If *filename* is given, XML file will be saved with that name. + + This function may not work as _PDB is not hosting ligand XML files anymore. + It is kept for use with existing ligand XML files. If you query ligand data frequently, you may configure ProDy to save XML files in your computer. Set ``ligand_xml_save`` option **True**, i.e. From f05b688fc7900d89dcaddc1e744381fd93554bf5 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 17 Apr 2024 18:02:00 +0200 Subject: [PATCH 12/34] suppress problems with ligands --- prody/compounds/pdbligands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/prody/compounds/pdbligands.py b/prody/compounds/pdbligands.py index de72a193b..31e2f2d90 100644 --- a/prody/compounds/pdbligands.py +++ b/prody/compounds/pdbligands.py @@ -58,6 +58,7 @@ def fetchPDBLigand(cci, filename=None): ideal (energy minimized) coordinate sets: .. ipython:: python + :okexcept: from prody import * ligand_data = fetchPDBLigand('STI') From 42718b40be485c1c82663ea65236f3b7b49d39c9 Mon Sep 17 00:00:00 2001 From: exx Date: Mon, 5 Aug 2024 09:33:58 -0400 Subject: [PATCH 13/34] 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 14/34] 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 15/34] 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 0b88f43df771ea94fb56dbd91e82696348c219cc Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 14 Aug 2024 13:32:40 +0100 Subject: [PATCH 16/34] fix pqr anisou not defined --- prody/proteins/pdbfile.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/prody/proteins/pdbfile.py b/prody/proteins/pdbfile.py index c03489139..a8127e72f 100644 --- a/prody/proteins/pdbfile.py +++ b/prody/proteins/pdbfile.py @@ -490,11 +490,10 @@ def _parsePDBLines(atomgroup, lines, split, model, chain, subset, elements = np.zeros(asize, dtype=ATOMIC_FIELDS['element'].dtype) bfactors = np.zeros(asize, dtype=ATOMIC_FIELDS['beta'].dtype) occupancies = np.zeros(asize, dtype=ATOMIC_FIELDS['occupancy'].dtype) - anisou = None siguij = None else: radii = np.zeros(asize, dtype=ATOMIC_FIELDS['radius'].dtype) - + anisou = None asize = 2000 # increase array length by this much when needed start = split From dde1beaa03265b4efdcc3eb3e88fc60f0a12f566 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Wed, 14 Aug 2024 13:37:33 +0100 Subject: [PATCH 17/34] add pqr tests --- prody/tests/datafiles/__init__.py | 20 +++ prody/tests/datafiles/pqr_snippet1.pqr | 5 + .../datafiles/pqr_snippet2_transcomp.pqr | 5 + .../tests/datafiles/pqr_snippet3_fpocket.pqr | 5 + prody/tests/datafiles/pqr_snippet4_pymol.pqr | 5 + prody/tests/proteins/test_pdbfile.py | 12 +- prody/tests/proteins/test_pqrfile.py | 146 ++++++++++++++++++ 7 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 prody/tests/datafiles/pqr_snippet1.pqr create mode 100644 prody/tests/datafiles/pqr_snippet2_transcomp.pqr create mode 100644 prody/tests/datafiles/pqr_snippet3_fpocket.pqr create mode 100644 prody/tests/datafiles/pqr_snippet4_pymol.pqr create mode 100644 prody/tests/proteins/test_pqrfile.py diff --git a/prody/tests/datafiles/__init__.py b/prody/tests/datafiles/__init__.py index 1f621f95c..54f7c00de 100644 --- a/prody/tests/datafiles/__init__.py +++ b/prody/tests/datafiles/__init__.py @@ -381,6 +381,26 @@ 'file': 'pdb7pbl.pdb', 'atoms': 31396, 'nucleoside': 252 + }, + 'pqrUnknown': { + 'file': 'pqr_snippet1.pqr', + 'atoms': 5, + 'models': 1 + }, + 'pqrTranscomp': { + 'file': 'pqr_snippet2_transcomp.pqr', + 'atoms': 5, + 'models': 1 + }, + 'pqrFpocket': { + 'file': 'pqr_snippet3_fpocket.pqr', + 'atoms': 5, + 'models': 1 + }, + 'pqrPymol': { + 'file': 'pqr_snippet4_pymol.pqr', + 'atoms': 5, + 'models': 1 } } diff --git a/prody/tests/datafiles/pqr_snippet1.pqr b/prody/tests/datafiles/pqr_snippet1.pqr new file mode 100644 index 000000000..15058186a --- /dev/null +++ b/prody/tests/datafiles/pqr_snippet1.pqr @@ -0,0 +1,5 @@ +ATOM 1 C STP 1 -26.417 62.269-123.283 0.00 3.30 +ATOM 2 O STP 1 -30.495 65.669-122.669 0.00 3.08 +ATOM 3 O STP 1 -25.792 61.516-124.085 0.00 3.32 +ATOM 4 O STP 1 -25.262 61.506-124.230 0.00 3.05 +ATOM 5 O STP 1 -30.521 65.070-122.439 0.00 3.05 \ No newline at end of file diff --git a/prody/tests/datafiles/pqr_snippet2_transcomp.pqr b/prody/tests/datafiles/pqr_snippet2_transcomp.pqr new file mode 100644 index 000000000..843ab19d7 --- /dev/null +++ b/prody/tests/datafiles/pqr_snippet2_transcomp.pqr @@ -0,0 +1,5 @@ +ATOM 1 N VAL 1 16.783 48.812 26.447 0.0577 1.550 +ATOM 2 H1 VAL 1 15.848 48.422 26.463 0.2272 1.200 +ATOM 3 H2 VAL 1 16.734 49.803 26.251 0.2272 1.200 +ATOM 4 H3 VAL 1 17.195 48.663 27.359 0.2272 1.200 +ATOM 5 CA VAL 1 17.591 48.101 25.416 -0.0054 1.700 \ No newline at end of file diff --git a/prody/tests/datafiles/pqr_snippet3_fpocket.pqr b/prody/tests/datafiles/pqr_snippet3_fpocket.pqr new file mode 100644 index 000000000..15058186a --- /dev/null +++ b/prody/tests/datafiles/pqr_snippet3_fpocket.pqr @@ -0,0 +1,5 @@ +ATOM 1 C STP 1 -26.417 62.269-123.283 0.00 3.30 +ATOM 2 O STP 1 -30.495 65.669-122.669 0.00 3.08 +ATOM 3 O STP 1 -25.792 61.516-124.085 0.00 3.32 +ATOM 4 O STP 1 -25.262 61.506-124.230 0.00 3.05 +ATOM 5 O STP 1 -30.521 65.070-122.439 0.00 3.05 \ No newline at end of file diff --git a/prody/tests/datafiles/pqr_snippet4_pymol.pqr b/prody/tests/datafiles/pqr_snippet4_pymol.pqr new file mode 100644 index 000000000..7c1719e6f --- /dev/null +++ b/prody/tests/datafiles/pqr_snippet4_pymol.pqr @@ -0,0 +1,5 @@ +ATOM 29 P G 11 -17.189 -6.642 -23.827 0.00000000 0.000 +ATOM 30 C5' G 11 -15.744 -5.986 -25.911 0.00000000 0.000 +ATOM 31 O5' G 11 -16.783 -5.642 -25.005 0.00000000 0.000 +ATOM 32 C4' G 11 -15.722 -5.012 -27.074 0.00000000 0.000 +ATOM 33 O4' G 11 -16.947 -5.133 -27.838 0.00000000 0.000 \ No newline at end of file diff --git a/prody/tests/proteins/test_pdbfile.py b/prody/tests/proteins/test_pdbfile.py index c802dbd66..9d89e2b44 100644 --- a/prody/tests/proteins/test_pdbfile.py +++ b/prody/tests/proteins/test_pdbfile.py @@ -19,7 +19,7 @@ class TestParsePDB(unittest.TestCase): def setUp(self): - """Set PDB file data and parse the PDB file.""" + """Set PDB file data.""" self.pdb = DATA_FILES['multi_model_truncated'] self.one = DATA_FILES['oneatom'] @@ -108,14 +108,22 @@ def testSubsetArgument(self): 'failed to parse correct number of "bb" atoms') def testAgArgument(self): - """Test outcome of valid and invalid *ag* arguments.""" + """Test outcome of 2 invalid and 2 valid *ag* arguments.""" path = pathDatafile(self.pdb['file']) self.assertRaises(TypeError, parsePDB, path, ag='AtomGroup') + ag = prody.AtomGroup('One atom') ag.setCoords(np.array([[0., 0., 0.]])) self.assertRaises(ValueError, parsePDB, path, ag=ag) + + ag = prody.AtomGroup('Test') + self.assertEqual(parsePDB(path, ag=ag).numAtoms(), + self.pdb['atoms'], + 'parsePDB failed to parse correct number of atoms') + ag = prody.AtomGroup('Test') + ag.setCoords(np.array([[0., 0., 0.]]*self.pdb['atoms'])) self.assertEqual(parsePDB(path, ag=ag).numAtoms(), self.pdb['atoms'], 'parsePDB failed to parse correct number of atoms') diff --git a/prody/tests/proteins/test_pqrfile.py b/prody/tests/proteins/test_pqrfile.py new file mode 100644 index 000000000..2e69dfd75 --- /dev/null +++ b/prody/tests/proteins/test_pqrfile.py @@ -0,0 +1,146 @@ +"""This module contains unit tests for :mod:`~prody.proteins`.""" + +import os + +import numpy as np +from numpy.testing import * + +from prody.utilities import importDec +dec = importDec() + +from prody import * +from prody import LOGGER +from prody.utilities import which +from prody.tests import TEMPDIR, unittest +from prody.tests.datafiles import * + +LOGGER.verbosity = 'none' + +class TestParsePRQ(unittest.TestCase): + + def setUp(self): + """Set PQR file data.""" + + self.pqr1 = DATA_FILES['pqrUnknown'] + self.pqr2 = DATA_FILES['pqrTranscomp'] + self.pqr3 = DATA_FILES['pqrFpocket'] + self.pqr4 = DATA_FILES['pqrPymol'] + + def testExamplePQR(self): + """Test the outcome of a simple parsing scenario with example 1 (unnamed).""" + + path = pathDatafile(self.pqr1['file']) + ag = parsePQR(path) + + self.assertIsInstance(ag, prody.AtomGroup, + 'parsePQR failed to return an AtomGroup instance') + + self.assertEqual(ag.numAtoms(), self.pqr1['atoms'], + 'parsePQR failed to parse correct number of atoms') + + self.assertEqual(ag.numCoordsets(), self.pqr1['models'], + 'parsePQR failed to parse correct number of coordinate sets ' + '(models)') + + self.assertEqual(ag.getTitle(), + os.path.splitext(self.pqr1['file'])[0], + 'failed to set AtomGroup title based on filename') + + def testTranscompPQR(self): + """Test the outcome of a simple parsing scenario with transcomp example.""" + + path = pathDatafile(self.pqr2['file']) + ag = parsePQR(path) + + self.assertIsInstance(ag, prody.AtomGroup, + 'parsePQR failed to return an AtomGroup instance') + + self.assertEqual(ag.numAtoms(), self.pqr2['atoms'], + 'parsePQR failed to parse correct number of atoms') + + self.assertEqual(ag.numCoordsets(), self.pqr2['models'], + 'parsePQR failed to parse correct number of coordinate sets ' + '(models)') + + self.assertEqual(ag.getTitle(), + os.path.splitext(self.pqr2['file'])[0], + 'failed to set AtomGroup title based on filename') + + def testFpocketPQR(self): + """Test the outcome of a simple parsing scenario with example 1 (unnamed).""" + + path = pathDatafile(self.pqr3['file']) + ag = parsePQR(path) + + self.assertIsInstance(ag, prody.AtomGroup, + 'parsePQR failed to return an AtomGroup instance') + + self.assertEqual(ag.numAtoms(), self.pqr3['atoms'], + 'parsePQR failed to parse correct number of atoms') + + self.assertEqual(ag.numCoordsets(), self.pqr3['models'], + 'parsePQR failed to parse correct number of coordinate sets ' + '(models)') + + self.assertEqual(ag.getTitle(), + os.path.splitext(self.pqr3['file'])[0], + 'failed to set AtomGroup title based on filename') + + def testPymolPQR(self): + """Test the outcome of a simple parsing scenario with example 1 (unnamed).""" + + path = pathDatafile(self.pqr4['file']) + ag = parsePQR(path) + + self.assertIsInstance(ag, prody.AtomGroup, + 'parsePQR failed to return an AtomGroup instance') + + self.assertEqual(ag.numAtoms(), self.pqr4['atoms'], + 'parsePQR failed to parse correct number of atoms') + + self.assertEqual(ag.numCoordsets(), self.pqr4['models'], + 'parsePQR failed to parse correct number of coordinate sets ' + '(models)') + + self.assertEqual(ag.getTitle(), + os.path.splitext(self.pqr4['file'])[0], + 'failed to set AtomGroup title based on filename') + + def testTitleArgument(self): + """Test outcome of *title* argument.""" + + path = pathDatafile(self.pqr1['file']) + title = 'small protein' + self.assertEqual(parsePQR(path, title=title).getTitle(), + title, 'parsePQR failed to set user given title') + + def testSubsetArgument(self): + """Test outcome of valid and invalid *subset* arguments.""" + + path = pathDatafile(self.pqr2['file']) + self.assertRaises(TypeError, parsePQR, path, subset=['A']) + self.assertEqual(parsePQR(path, subset='ca').numAtoms(), 1, + 'failed to parse correct number of "ca" atoms') + self.assertEqual(parsePQR(path, subset='bb').numAtoms(), 2, + 'failed to parse correct number of "bb" atoms') + + def testAgArgument(self): + """Test outcome of 2 invalid and 2 valid *ag* arguments.""" + + path = pathDatafile(self.pqr1['file']) + self.assertRaises(TypeError, parsePQR, path, ag='AtomGroup') + + ag = prody.AtomGroup('One atom') + ag.setCoords(np.array([[0., 0., 0.]])) + self.assertRaises(ValueError, parsePQR, path, ag=ag) + + ag = prody.AtomGroup('Test') + self.assertEqual(parsePQR(path, ag=ag).numAtoms(), + self.pqr1['atoms'], + 'parsePQR failed to parse correct number of atoms') + + ag = prody.AtomGroup('Test') + ag.setCoords(np.array([[0., 0., 0.]]*5)) + self.assertEqual(parsePQR(path, ag=ag).numAtoms(), + self.pqr1['atoms'], + 'parsePQR failed to parse correct number of atoms') \ No newline at end of file From b770882436ac859217aa9f5ef0f90066f68a8ed3 Mon Sep 17 00:00:00 2001 From: exx Date: Thu, 15 Aug 2024 15:51:25 -0400 Subject: [PATCH 18/34] 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 19/34] 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 20/34] 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 21/34] 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 22/34] 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 23/34] 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 24/34] 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 efab53944010d879b7e5d766d7f1cf581addd818 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 12:05:47 +0200 Subject: [PATCH 25/34] update website except build website docs --- CONTRIBUTING.md | 2 +- PKG-INFO | 14 +++++++------- docs/apps/prody/index.rst | 2 +- docs/conf.py | 6 +++--- docs/index.rst | 2 +- prody/ensemble/functions.py | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd33301d1..5da7b11be 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -This is a first draft, which is based on the ProDy website page http://prody.csb.pitt.edu/manual/devel/develop.html. Please see that page for updates. +This is a first draft, which is based on the ProDy website page http://www.bahargroup.org/prody/manual/devel/develop.html. Please see that page for updates. Install Git and a GUI diff --git a/PKG-INFO b/PKG-INFO index 047dc0d48..bf2690a89 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -32,23 +32,23 @@ Description: .. image:: https://secure.travis-ci.org/prody/ProDy.png?branch=mast You can run ProDy on all major platforms. For download and installation instructions see: - * http://prody.csb.pitt.edu/downloads + * http://www.bahargroup.org/prody/downloads DOCUMENTATION ------------- - * Homepage: http://prody.csb.pitt.edu/ + * Homepage: http://www.bahargroup.org/prody/ - * Tutorials: http://prody.csb.pitt.edu/tutorials + * Tutorials: http://www.bahargroup.org/prody/tutorials - * Reference: http://prody.csb.pitt.edu/manual + * Reference: http://www.bahargroup.org/prody/manual - * Applications: http://prody.csb.pitt.edu/manual/apps + * Applications: http://www.bahargroup.org/prody/manual/apps - * NMWiz GUI: http://prody.csb.pitt.edu/nmwiz + * NMWiz GUI: http://www.bahargroup.org/prody/nmwiz - * Changes: http://prody.csb.pitt.edu/manual/release + * Changes: http://www.bahargroup.org/prody/manual/release SOURCE CODE diff --git a/docs/apps/prody/index.rst b/docs/apps/prody/index.rst index 477f661b1..32958c34b 100644 --- a/docs/apps/prody/index.rst +++ b/docs/apps/prody/index.rst @@ -40,4 +40,4 @@ the output files are prefixed with :file:`p38_anm`:: The output file :file:`p38_anm.nmd` can be visualized using `NMWiz`_. -.. _NMWiz: http://prody.csb.pitt.edu/nmwiz/ +.. _NMWiz: http://www.bahargroup.org/prody/nmwiz/ diff --git a/docs/conf.py b/docs/conf.py index b5880a85c..4588b0003 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -158,13 +158,13 @@ 'numpy': ('http://docs.scipy.org/doc/numpy/', None), 'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None), 'matplotlib': ('http://matplotlib.sourceforge.net/', None), - 'prodywebsite': ('http://prody.csb.pitt.edu/', None), + 'prodywebsite': ('http://www.bahargroup.org/prody/', None), } rst_epilog = u""" -.. _ProDy: http://prody.csb.pitt.edu -.. _Tutorials: http://prody.csb.pitt.edu/tutorials +.. _ProDy: http://www.bahargroup.org/prody +.. _Tutorials: http://www.bahargroup.org/prody/tutorials .. _NMWiz: http://csb.pitt.edu/NMWiz .. _VMD: http://www.ks.uiuc.edu/Research/vmd .. _PDB: http://www.pdb.org diff --git a/docs/index.rst b/docs/index.rst index 4aad2ed6d..aa56b17e4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,7 +11,7 @@ ProDy Manual .. only:: rtd and html This is a partial copy of ProDy documentation. Please visit - `ProDy Homepage `_ for complete + `ProDy Homepage `_ for complete documentation with tutorials. diff --git a/prody/ensemble/functions.py b/prody/ensemble/functions.py index c09cd844e..be7bd1688 100644 --- a/prody/ensemble/functions.py +++ b/prody/ensemble/functions.py @@ -411,7 +411,7 @@ def buildPDBEnsemble(atomics, ref=None, title='Unknown', labels=None, atommaps=N if 'mapping_func' in kwargs: raise DeprecationWarning('mapping_func is deprecated. Please see release notes for ' - 'more details: http://prody.csb.pitt.edu/manual/release/v1.11_series.html') + 'more details: http://www.bahargroup.org/prody/manual/release/v1.11_series.html') start = time.time() if not isListLike(atomics): From a93f2f65ac4aea44df33ef90c5a06c9332235ee2 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 13:50:23 +0200 Subject: [PATCH 26/34] 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 27/34] 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 28/34] 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 29/34] 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 30/34] 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 31/34] 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 c29b609f8593f17d0bc47b8199bc20db6d3f9ba8 Mon Sep 17 00:00:00 2001 From: James Krieger Date: Thu, 22 Aug 2024 17:18:55 +0200 Subject: [PATCH 32/34] fix max_proc 1 multi-model atoms --- prody/proteins/waterbridges.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prody/proteins/waterbridges.py b/prody/proteins/waterbridges.py index 500d85ce9..a247e07b5 100644 --- a/prody/proteins/waterbridges.py +++ b/prody/proteins/waterbridges.py @@ -638,9 +638,9 @@ def analyseFrame(i, interactions_all): if max_proc == 1: interactions_all = [] - for j0, frame0 in enumerate(traj, start=start_frame): + for i in range(len(atoms.getCoordsets()[start_frame:stop_frame])): interactions_all.append([]) - analyseFrame(j0, start_frame, frame0, interactions_all) + analyseFrame(i, interactions_all) else: with mp.Manager() as manager: interactions_all = manager.list() From 27f2a3b78f52b8423a967fa65e8ed2e3bf1cc6cf Mon Sep 17 00:00:00 2001 From: exx Date: Thu, 22 Aug 2024 12:07:15 -0400 Subject: [PATCH 33/34] 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 34/34] 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