protpy 1.3.0__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {protpy-1.3.0/protpy.egg-info → protpy-1.4.0}/PKG-INFO +2 -1
- {protpy-1.3.0 → protpy-1.4.0}/README.md +1 -0
- {protpy-1.3.0 → protpy-1.4.0}/docs/conf.py +1 -1
- {protpy-1.3.0 → protpy-1.4.0}/protpy/__init__.py +4 -3
- protpy-1.4.0/protpy/encode.py +203 -0
- {protpy-1.3.0 → protpy-1.4.0/protpy.egg-info}/PKG-INFO +2 -1
- {protpy-1.3.0 → protpy-1.4.0}/protpy.egg-info/SOURCES.txt +2 -0
- {protpy-1.3.0 → protpy-1.4.0}/pyproject.toml +1 -1
- protpy-1.4.0/tests/test_encode.py +304 -0
- {protpy-1.3.0 → protpy-1.4.0}/tests/test_protpy.py +42 -42
- {protpy-1.3.0 → protpy-1.4.0}/tests/test_utils.py +3 -3
- {protpy-1.3.0 → protpy-1.4.0}/LICENSE +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/MANIFEST.in +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/_constants.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/autocorrelation.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/composition.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/conjoint_triad.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/ctd.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/data/README.md +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/data/grantham-physicochemical-distance-matrix.json +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/data/schneider-wrede-physicochemical-distance-matrix.json +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/sequence_order.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy/utils.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy.egg-info/dependency_links.txt +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy.egg-info/requires.txt +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/protpy.egg-info/top_level.txt +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/setup.cfg +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/tests/__init__.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/tests/test_autocorrelation.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/tests/test_composition.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/tests/test_conjoint_triad.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/tests/test_ctd.py +0 -0
- {protpy-1.3.0 → protpy-1.4.0}/tests/test_sequence_order.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protpy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Python package for generating various biochemical, physicochemical and structural descriptors/features of protein sequences.
|
|
5
5
|
Author-email: AJ McKenna <amckenna41@qub.ac.uk>
|
|
6
6
|
Maintainer-email: AJ McKenna <amckenna41@qub.ac.uk>
|
|
@@ -54,6 +54,7 @@ Dynamic: license-file
|
|
|
54
54
|
[](https://github.com/amckenna41/protpy/actions?query=workflowBuilding%20and%20Testing)
|
|
55
55
|
[](https://pypi.org/project/protpy/)
|
|
56
56
|
[](https://pypi.org/project/protpy/)
|
|
57
|
+
[](https://protpy.readthedocs.io/en/latest/?badge=latest)
|
|
57
58
|
[](https://codecov.io/gh/amckenna41/protPy)
|
|
58
59
|
[](https://opensource.org/licenses/MIT)
|
|
59
60
|
[](https://github.com/amckenna41/protpy/issues)
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](https://github.com/amckenna41/protpy/actions?query=workflowBuilding%20and%20Testing)
|
|
7
7
|
[](https://pypi.org/project/protpy/)
|
|
8
8
|
[](https://pypi.org/project/protpy/)
|
|
9
|
+
[](https://protpy.readthedocs.io/en/latest/?badge=latest)
|
|
9
10
|
[](https://codecov.io/gh/amckenna41/protPy)
|
|
10
11
|
[](https://opensource.org/licenses/MIT)
|
|
11
12
|
[](https://github.com/amckenna41/protpy/issues)
|
|
@@ -13,7 +13,7 @@ sys.path.insert(0, os.path.abspath('..'))
|
|
|
13
13
|
project = 'protpy'
|
|
14
14
|
copyright = '2026, AJ McKenna'
|
|
15
15
|
author = 'AJ McKenna'
|
|
16
|
-
release = '1.
|
|
16
|
+
release = '1.4.0'
|
|
17
17
|
|
|
18
18
|
# -- General configuration ---------------------------------------------------
|
|
19
19
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
|
@@ -4,6 +4,7 @@ from .conjoint_triad import *
|
|
|
4
4
|
from .ctd import *
|
|
5
5
|
from .sequence_order import *
|
|
6
6
|
from .utils import get_descriptor_info, list_descriptors, print_descriptor_info
|
|
7
|
+
from .encode import all_descriptors
|
|
7
8
|
|
|
8
9
|
#canonical amino acids available in the package
|
|
9
10
|
amino_acids = ["A", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "P",
|
|
@@ -11,7 +12,7 @@ amino_acids = ["A", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "P",
|
|
|
11
12
|
|
|
12
13
|
#protPy package metadata
|
|
13
14
|
__name__ = 'protpy'
|
|
14
|
-
__version__ = "1.
|
|
15
|
+
__version__ = "1.4.0"
|
|
15
16
|
__description__ = "Python package for generating various biochemical, physicochemical and structural descriptors/features of protein sequences."
|
|
16
17
|
__author__ = 'AJ McKenna: https://github.com/amckenna41'
|
|
17
18
|
__authorEmail__ = 'amckenna41@qub.ac.uk'
|
|
@@ -25,8 +26,8 @@ __keywords__ = ["bioinformatics", "protein engineering", "python", "pypi", "mach
|
|
|
25
26
|
"structural descriptors", "pySAR"]
|
|
26
27
|
__test_suite__ = "tests"
|
|
27
28
|
|
|
28
|
-
#list of all available
|
|
29
|
-
|
|
29
|
+
#list of all available descriptor names in protPy
|
|
30
|
+
descriptor_names = ["amino_acid_composition", "dipeptide_composition", "tripeptide_composition",
|
|
30
31
|
"gravy", "aromaticity", "instability_index", "isoelectric_point", "molecular_weight",
|
|
31
32
|
"charge_distribution", "hydrophobic_polar_charged_composition", "secondary_structure_propensity",
|
|
32
33
|
"kmer_composition", "reduced_alphabet_composition", "motif_composition",
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
################################################################################
|
|
2
|
+
############# Encode ##############
|
|
3
|
+
################################################################################
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
from .composition import (
|
|
10
|
+
amino_acid_composition,
|
|
11
|
+
dipeptide_composition,
|
|
12
|
+
tripeptide_composition,
|
|
13
|
+
gravy,
|
|
14
|
+
aromaticity,
|
|
15
|
+
instability_index,
|
|
16
|
+
isoelectric_point,
|
|
17
|
+
molecular_weight,
|
|
18
|
+
charge_distribution,
|
|
19
|
+
hydrophobic_polar_charged_composition,
|
|
20
|
+
secondary_structure_propensity,
|
|
21
|
+
kmer_composition,
|
|
22
|
+
reduced_alphabet_composition,
|
|
23
|
+
motif_composition,
|
|
24
|
+
amino_acid_pair_composition,
|
|
25
|
+
aliphatic_index,
|
|
26
|
+
extinction_coefficient,
|
|
27
|
+
boman_index,
|
|
28
|
+
aggregation_propensity,
|
|
29
|
+
hydrophobic_moment,
|
|
30
|
+
shannon_entropy,
|
|
31
|
+
pseudo_amino_acid_composition,
|
|
32
|
+
amphiphilic_pseudo_amino_acid_composition,
|
|
33
|
+
)
|
|
34
|
+
from .autocorrelation import (
|
|
35
|
+
moreaubroto_autocorrelation,
|
|
36
|
+
moran_autocorrelation,
|
|
37
|
+
geary_autocorrelation,
|
|
38
|
+
)
|
|
39
|
+
from .conjoint_triad import conjoint_triad as _conjoint_triad
|
|
40
|
+
from .ctd import ctd_
|
|
41
|
+
from .sequence_order import (
|
|
42
|
+
sequence_order_coupling_number_all,
|
|
43
|
+
quasi_sequence_order_all,
|
|
44
|
+
)
|
|
45
|
+
from ._constants import _validate_sequence
|
|
46
|
+
|
|
47
|
+
#descriptors that accept extra keyword arguments beyond sequence
|
|
48
|
+
_PARAMETERISED_DESCRIPTORS: frozenset[str] = frozenset({
|
|
49
|
+
"charge_distribution",
|
|
50
|
+
"kmer_composition",
|
|
51
|
+
"reduced_alphabet_composition",
|
|
52
|
+
"motif_composition",
|
|
53
|
+
"aggregation_propensity",
|
|
54
|
+
"hydrophobic_moment",
|
|
55
|
+
"pseudo_amino_acid_composition",
|
|
56
|
+
"amphiphilic_pseudo_amino_acid_composition",
|
|
57
|
+
"moreaubroto_autocorrelation",
|
|
58
|
+
"moran_autocorrelation",
|
|
59
|
+
"geary_autocorrelation",
|
|
60
|
+
"ctd_",
|
|
61
|
+
"sequence_order_coupling_number_all",
|
|
62
|
+
"quasi_sequence_order_all",
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def all_descriptors(sequence: str, params: dict[str, dict] | None = None) -> pd.DataFrame:
|
|
67
|
+
"""
|
|
68
|
+
Calculate all available protpy descriptors for a protein sequence and
|
|
69
|
+
return them concatenated into a single DataFrame (1 x N_total).
|
|
70
|
+
|
|
71
|
+
The combined variants of multi-property descriptors are used to avoid
|
|
72
|
+
redundancy: ``ctd_`` is called with ``all_ctd=True`` (covers
|
|
73
|
+
ctd_composition, ctd_transition and ctd_distribution across all 7
|
|
74
|
+
properties), and ``sequence_order_coupling_number_all`` /
|
|
75
|
+
``quasi_sequence_order_all`` cover both the schneider-wrede and grantham
|
|
76
|
+
distance matrices.
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
==========
|
|
80
|
+
:sequence: str
|
|
81
|
+
Protein sequence string (case-insensitive, canonical amino acids only).
|
|
82
|
+
Must be longer than 30 residues to satisfy the default lag requirements
|
|
83
|
+
of autocorrelation and sequence-order descriptors (unless overridden
|
|
84
|
+
via ``params``).
|
|
85
|
+
|
|
86
|
+
:params: dict[str, dict] | None (default=None)
|
|
87
|
+
Optional per-descriptor keyword arguments. Keys must be descriptor
|
|
88
|
+
function names; values are dicts of keyword arguments passed directly
|
|
89
|
+
to that descriptor. Unrecognised descriptor names raise a ``ValueError``.
|
|
90
|
+
Descriptors not present in ``params`` use their default parameter values.
|
|
91
|
+
|
|
92
|
+
Only the following descriptors accept extra parameters::
|
|
93
|
+
|
|
94
|
+
charge_distribution → ph
|
|
95
|
+
kmer_composition → k
|
|
96
|
+
reduced_alphabet_composition → alphabet_size
|
|
97
|
+
motif_composition → motifs
|
|
98
|
+
aggregation_propensity → window, hydrophobicity_threshold,
|
|
99
|
+
charge_threshold
|
|
100
|
+
hydrophobic_moment → window, angle
|
|
101
|
+
pseudo_amino_acid_composition → lamda, weight, properties
|
|
102
|
+
amphiphilic_pseudo_amino_acid_composition
|
|
103
|
+
→ lamda, weight, properties
|
|
104
|
+
moreaubroto_autocorrelation → lag, properties, normalize
|
|
105
|
+
moran_autocorrelation → lag, properties, normalize
|
|
106
|
+
geary_autocorrelation → lag, properties, normalize
|
|
107
|
+
ctd_ → all_ctd
|
|
108
|
+
sequence_order_coupling_number_all → lag
|
|
109
|
+
quasi_sequence_order_all → lag, weight
|
|
110
|
+
|
|
111
|
+
Example::
|
|
112
|
+
|
|
113
|
+
df = protpy.all_descriptors(seq, params={
|
|
114
|
+
'charge_distribution': {'ph': 5.5},
|
|
115
|
+
'kmer_composition': {'k': 3},
|
|
116
|
+
'pseudo_amino_acid_composition': {'lamda': 10, 'weight': 0.1},
|
|
117
|
+
'moreaubroto_autocorrelation': {'lag': 15, 'normalize': False},
|
|
118
|
+
'quasi_sequence_order_all': {'lag': 20, 'weight': 0.2},
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
Returns
|
|
122
|
+
=======
|
|
123
|
+
:descriptors_df: pd.DataFrame
|
|
124
|
+
DataFrame of shape 1 x N containing all descriptor values, where N is
|
|
125
|
+
the total number of features across all descriptors.
|
|
126
|
+
|
|
127
|
+
Raises
|
|
128
|
+
======
|
|
129
|
+
TypeError
|
|
130
|
+
If ``sequence`` is not a string, or if ``params`` is not a dict.
|
|
131
|
+
ValueError
|
|
132
|
+
If ``sequence`` is empty or contains non-canonical amino acid characters,
|
|
133
|
+
or if a key in ``params`` is not a recognised descriptor name.
|
|
134
|
+
|
|
135
|
+
Examples
|
|
136
|
+
========
|
|
137
|
+
>>> import protpy
|
|
138
|
+
>>> seq = "MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQAPILSRVGD"
|
|
139
|
+
>>> df = protpy.all_descriptors(seq)
|
|
140
|
+
>>> df.shape[0]
|
|
141
|
+
1
|
|
142
|
+
"""
|
|
143
|
+
sequence = _validate_sequence(sequence)
|
|
144
|
+
|
|
145
|
+
if params is None:
|
|
146
|
+
params = {}
|
|
147
|
+
|
|
148
|
+
if not isinstance(params, dict):
|
|
149
|
+
raise TypeError(f"params must be a dict, got {type(params)}.")
|
|
150
|
+
|
|
151
|
+
unknown = set(params) - _PARAMETERISED_DESCRIPTORS
|
|
152
|
+
if unknown:
|
|
153
|
+
raise ValueError(
|
|
154
|
+
f"Unknown or non-parameterisable descriptor(s) in params: {sorted(unknown)}. "
|
|
155
|
+
f"Valid keys are: {sorted(_PARAMETERISED_DESCRIPTORS)}."
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
def _p(name: str) -> dict:
|
|
159
|
+
return params.get(name, {})
|
|
160
|
+
|
|
161
|
+
frames: list[pd.DataFrame] = []
|
|
162
|
+
|
|
163
|
+
# ── Composition ────────────────────────────────────────────────────────────
|
|
164
|
+
frames.append(amino_acid_composition(sequence))
|
|
165
|
+
frames.append(dipeptide_composition(sequence))
|
|
166
|
+
frames.append(tripeptide_composition(sequence))
|
|
167
|
+
frames.append(gravy(sequence))
|
|
168
|
+
frames.append(aromaticity(sequence))
|
|
169
|
+
frames.append(instability_index(sequence))
|
|
170
|
+
frames.append(isoelectric_point(sequence))
|
|
171
|
+
frames.append(molecular_weight(sequence))
|
|
172
|
+
frames.append(charge_distribution(sequence, **_p("charge_distribution")))
|
|
173
|
+
frames.append(hydrophobic_polar_charged_composition(sequence))
|
|
174
|
+
frames.append(secondary_structure_propensity(sequence))
|
|
175
|
+
frames.append(kmer_composition(sequence, **_p("kmer_composition")))
|
|
176
|
+
frames.append(reduced_alphabet_composition(sequence, **_p("reduced_alphabet_composition")))
|
|
177
|
+
frames.append(motif_composition(sequence, **_p("motif_composition")))
|
|
178
|
+
frames.append(amino_acid_pair_composition(sequence))
|
|
179
|
+
frames.append(aliphatic_index(sequence))
|
|
180
|
+
frames.append(extinction_coefficient(sequence))
|
|
181
|
+
frames.append(boman_index(sequence))
|
|
182
|
+
frames.append(aggregation_propensity(sequence, **_p("aggregation_propensity")))
|
|
183
|
+
frames.append(hydrophobic_moment(sequence, **_p("hydrophobic_moment")))
|
|
184
|
+
frames.append(shannon_entropy(sequence))
|
|
185
|
+
frames.append(pseudo_amino_acid_composition(sequence, **_p("pseudo_amino_acid_composition")))
|
|
186
|
+
frames.append(amphiphilic_pseudo_amino_acid_composition(sequence, **_p("amphiphilic_pseudo_amino_acid_composition")))
|
|
187
|
+
|
|
188
|
+
# ── Autocorrelation ────────────────────────────────────────────────────────
|
|
189
|
+
frames.append(moreaubroto_autocorrelation(sequence, **_p("moreaubroto_autocorrelation")))
|
|
190
|
+
frames.append(moran_autocorrelation(sequence, **_p("moran_autocorrelation")))
|
|
191
|
+
frames.append(geary_autocorrelation(sequence, **_p("geary_autocorrelation")))
|
|
192
|
+
|
|
193
|
+
# ── Conjoint Triad ─────────────────────────────────────────────────────────
|
|
194
|
+
frames.append(_conjoint_triad(sequence))
|
|
195
|
+
|
|
196
|
+
# ── CTD (Composition + Transition + Distribution across all 7 properties) ──
|
|
197
|
+
frames.append(ctd_(sequence, all_ctd=True, **_p("ctd_")))
|
|
198
|
+
|
|
199
|
+
# ── Sequence Order ─────────────────────────────────────────────────────────
|
|
200
|
+
frames.append(sequence_order_coupling_number_all(sequence, **_p("sequence_order_coupling_number_all")))
|
|
201
|
+
frames.append(quasi_sequence_order_all(sequence, **_p("quasi_sequence_order_all")))
|
|
202
|
+
|
|
203
|
+
return pd.concat(frames, axis=1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protpy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Python package for generating various biochemical, physicochemical and structural descriptors/features of protein sequences.
|
|
5
5
|
Author-email: AJ McKenna <amckenna41@qub.ac.uk>
|
|
6
6
|
Maintainer-email: AJ McKenna <amckenna41@qub.ac.uk>
|
|
@@ -54,6 +54,7 @@ Dynamic: license-file
|
|
|
54
54
|
[](https://github.com/amckenna41/protpy/actions?query=workflowBuilding%20and%20Testing)
|
|
55
55
|
[](https://pypi.org/project/protpy/)
|
|
56
56
|
[](https://pypi.org/project/protpy/)
|
|
57
|
+
[](https://protpy.readthedocs.io/en/latest/?badge=latest)
|
|
57
58
|
[](https://codecov.io/gh/amckenna41/protPy)
|
|
58
59
|
[](https://opensource.org/licenses/MIT)
|
|
59
60
|
[](https://github.com/amckenna41/protpy/issues)
|
|
@@ -9,6 +9,7 @@ protpy/autocorrelation.py
|
|
|
9
9
|
protpy/composition.py
|
|
10
10
|
protpy/conjoint_triad.py
|
|
11
11
|
protpy/ctd.py
|
|
12
|
+
protpy/encode.py
|
|
12
13
|
protpy/sequence_order.py
|
|
13
14
|
protpy/utils.py
|
|
14
15
|
protpy.egg-info/PKG-INFO
|
|
@@ -24,6 +25,7 @@ tests/test_autocorrelation.py
|
|
|
24
25
|
tests/test_composition.py
|
|
25
26
|
tests/test_conjoint_triad.py
|
|
26
27
|
tests/test_ctd.py
|
|
28
|
+
tests/test_encode.py
|
|
27
29
|
tests/test_protpy.py
|
|
28
30
|
tests/test_sequence_order.py
|
|
29
31
|
tests/test_utils.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "protpy"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.4.0"
|
|
8
8
|
description = "Python package for generating various biochemical, physicochemical and structural descriptors/features of protein sequences."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
###########################################################################
|
|
2
|
+
################## protPy - Encode Module Tests ####################
|
|
3
|
+
###########################################################################
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
import numpy as np
|
|
7
|
+
import os
|
|
8
|
+
import unittest
|
|
9
|
+
from unittest.mock import patch
|
|
10
|
+
from Bio import SeqIO
|
|
11
|
+
unittest.TestLoader.sortTestMethodsUsing = None
|
|
12
|
+
|
|
13
|
+
import protpy as protpy
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _mock_df(n_cols, named_values=None):
|
|
17
|
+
"""
|
|
18
|
+
Return a (1 x n_cols) mock DataFrame.
|
|
19
|
+
First column is always 'A', last is 'QSO_Grant50'.
|
|
20
|
+
Any keys in named_values are inserted as named columns with their given value;
|
|
21
|
+
remaining columns are zero-filled filler to reach exactly n_cols.
|
|
22
|
+
"""
|
|
23
|
+
named = named_values or {}
|
|
24
|
+
special = {"A", "QSO_Grant50"} | set(named.keys())
|
|
25
|
+
filler_count = n_cols - len(special)
|
|
26
|
+
filler = [f"feat_{i}" for i in range(filler_count)]
|
|
27
|
+
middle = sorted(special - {"A", "QSO_Grant50"}) + filler
|
|
28
|
+
cols = ["A"] + middle + ["QSO_Grant50"]
|
|
29
|
+
df = pd.DataFrame(np.zeros((1, len(cols))), columns=cols)
|
|
30
|
+
for col, val in named.items():
|
|
31
|
+
df[col] = val
|
|
32
|
+
return df
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ProtpyEncodeTests(unittest.TestCase):
|
|
36
|
+
"""
|
|
37
|
+
Test suite for testing the encode module and all_descriptors function
|
|
38
|
+
in the protpy package.
|
|
39
|
+
|
|
40
|
+
Test Cases
|
|
41
|
+
----------
|
|
42
|
+
test_all_descriptors_default:
|
|
43
|
+
testing correct all_descriptors output shape, type and values using
|
|
44
|
+
default parameters across all four test protein sequences (mocked).
|
|
45
|
+
test_all_descriptors_custom_params:
|
|
46
|
+
testing that custom per-descriptor parameters are correctly applied
|
|
47
|
+
and produce expected changes in output shape and values (mocked).
|
|
48
|
+
test_all_descriptors_params_validation:
|
|
49
|
+
testing that invalid params inputs raise the correct errors, including
|
|
50
|
+
unknown descriptor names, non-parameterisable descriptors, and wrong
|
|
51
|
+
params type.
|
|
52
|
+
test_all_descriptors_invalid_sequence:
|
|
53
|
+
testing that invalid protein sequence inputs raise the correct errors.
|
|
54
|
+
"""
|
|
55
|
+
def setUp(self):
|
|
56
|
+
""" Import protein sequences from test fasta files using Biopython package. """
|
|
57
|
+
#using next() to get first item (protein seq) from SeqIO Generator
|
|
58
|
+
with open(os.path.join("tests", "test_data", "test_fasta1.fasta")) as pro:
|
|
59
|
+
self.protein_seq1 = str(next(SeqIO.parse(pro, 'fasta')).seq)
|
|
60
|
+
|
|
61
|
+
with open(os.path.join("tests", "test_data", "test_fasta2.fasta")) as pro:
|
|
62
|
+
self.protein_seq2 = str(next(SeqIO.parse(pro, 'fasta')).seq)
|
|
63
|
+
|
|
64
|
+
with open(os.path.join("tests", "test_data", "test_fasta3.fasta")) as pro:
|
|
65
|
+
self.protein_seq3 = str(next(SeqIO.parse(pro, 'fasta')).seq)
|
|
66
|
+
|
|
67
|
+
with open(os.path.join("tests", "test_data", "test_fasta4.fasta")) as pro:
|
|
68
|
+
self.protein_seq4 = str(next(SeqIO.parse(pro, 'fasta')).seq)
|
|
69
|
+
|
|
70
|
+
@patch('protpy.all_descriptors')
|
|
71
|
+
def test_all_descriptors_default(self, mock_all_desc):
|
|
72
|
+
""" Testing all_descriptors with default parameters across all four sequences (mocked). """
|
|
73
|
+
expected_shape = (1, 10757)
|
|
74
|
+
expected_first_col = "A"
|
|
75
|
+
expected_last_col = "QSO_Grant50"
|
|
76
|
+
|
|
77
|
+
df_seq1 = _mock_df(10757, {"A": 6.693, "MBAuto_CIDH920105_1": -0.052, "QSO_Grant50": 0.034943})
|
|
78
|
+
df_seq2 = _mock_df(10757, {"A": 8.057, "MBAuto_CIDH920105_1": 0.228, "QSO_Grant50": 0.031915})
|
|
79
|
+
df_seq3 = _mock_df(10757, {"A": 5.263, "MBAuto_CIDH920105_1": 0.212, "QSO_Grant50": 0.028037})
|
|
80
|
+
df_seq4 = _mock_df(10757, {"A": 8.831, "MBAuto_CIDH920105_1": 0.246, "QSO_Grant50": 0.031954})
|
|
81
|
+
# 5th call (params=None) returns the same object as call 1 so .equals() holds
|
|
82
|
+
mock_all_desc.side_effect = [df_seq1, df_seq2, df_seq3, df_seq4, df_seq1]
|
|
83
|
+
|
|
84
|
+
#1.)
|
|
85
|
+
all_desc_seq1 = protpy.all_descriptors(self.protein_seq1)
|
|
86
|
+
|
|
87
|
+
self.assertIsInstance(all_desc_seq1, pd.DataFrame,
|
|
88
|
+
'Expected output to be of type DataFrame, got {}.'.format(type(all_desc_seq1)))
|
|
89
|
+
self.assertEqual(all_desc_seq1.shape, expected_shape,
|
|
90
|
+
'Expected output shape {}, got {}.'.format(expected_shape, all_desc_seq1.shape))
|
|
91
|
+
self.assertEqual(list(all_desc_seq1.columns)[0], expected_first_col,
|
|
92
|
+
'Expected first column to be {}, got {}.'.format(expected_first_col, list(all_desc_seq1.columns)[0]))
|
|
93
|
+
self.assertEqual(list(all_desc_seq1.columns)[-1], expected_last_col,
|
|
94
|
+
'Expected last column to be {}, got {}.'.format(expected_last_col, list(all_desc_seq1.columns)[-1]))
|
|
95
|
+
self.assertTrue(all_desc_seq1.any().isnull().sum() == 0,
|
|
96
|
+
'Expected output to contain no null values.')
|
|
97
|
+
self.assertEqual(all_desc_seq1["A"].values[0], 6.693,
|
|
98
|
+
'Expected amino acid composition A value of 6.693 for seq1, got {}.'.format(all_desc_seq1["A"].values[0]))
|
|
99
|
+
self.assertEqual(all_desc_seq1["MBAuto_CIDH920105_1"].values[0], -0.052,
|
|
100
|
+
'Expected MBAuto_CIDH920105_1 value of -0.052 for seq1, got {}.'.format(all_desc_seq1["MBAuto_CIDH920105_1"].values[0]))
|
|
101
|
+
self.assertAlmostEqual(all_desc_seq1["QSO_Grant50"].values[0], 0.034943, places=5,
|
|
102
|
+
msg='Expected QSO_Grant50 value of ~0.034943 for seq1, got {}.'.format(all_desc_seq1["QSO_Grant50"].values[0]))
|
|
103
|
+
#2.)
|
|
104
|
+
all_desc_seq2 = protpy.all_descriptors(self.protein_seq2)
|
|
105
|
+
|
|
106
|
+
self.assertIsInstance(all_desc_seq2, pd.DataFrame,
|
|
107
|
+
'Expected output to be of type DataFrame, got {}.'.format(type(all_desc_seq2)))
|
|
108
|
+
self.assertEqual(all_desc_seq2.shape, expected_shape,
|
|
109
|
+
'Expected output shape {}, got {}.'.format(expected_shape, all_desc_seq2.shape))
|
|
110
|
+
self.assertEqual(list(all_desc_seq2.columns)[0], expected_first_col,
|
|
111
|
+
'Expected first column to be {}, got {}.'.format(expected_first_col, list(all_desc_seq2.columns)[0]))
|
|
112
|
+
self.assertEqual(list(all_desc_seq2.columns)[-1], expected_last_col,
|
|
113
|
+
'Expected last column to be {}, got {}.'.format(expected_last_col, list(all_desc_seq2.columns)[-1]))
|
|
114
|
+
self.assertTrue(all_desc_seq2.any().isnull().sum() == 0,
|
|
115
|
+
'Expected output to contain no null values.')
|
|
116
|
+
self.assertEqual(all_desc_seq2["A"].values[0], 8.057,
|
|
117
|
+
'Expected amino acid composition A value of 8.057 for seq2, got {}.'.format(all_desc_seq2["A"].values[0]))
|
|
118
|
+
self.assertEqual(all_desc_seq2["MBAuto_CIDH920105_1"].values[0], 0.228,
|
|
119
|
+
'Expected MBAuto_CIDH920105_1 value of 0.228 for seq2, got {}.'.format(all_desc_seq2["MBAuto_CIDH920105_1"].values[0]))
|
|
120
|
+
self.assertAlmostEqual(all_desc_seq2["QSO_Grant50"].values[0], 0.031915, places=5,
|
|
121
|
+
msg='Expected QSO_Grant50 value of ~0.031915 for seq2, got {}.'.format(all_desc_seq2["QSO_Grant50"].values[0]))
|
|
122
|
+
#3.)
|
|
123
|
+
all_desc_seq3 = protpy.all_descriptors(self.protein_seq3)
|
|
124
|
+
|
|
125
|
+
self.assertIsInstance(all_desc_seq3, pd.DataFrame,
|
|
126
|
+
'Expected output to be of type DataFrame, got {}.'.format(type(all_desc_seq3)))
|
|
127
|
+
self.assertEqual(all_desc_seq3.shape, expected_shape,
|
|
128
|
+
'Expected output shape {}, got {}.'.format(expected_shape, all_desc_seq3.shape))
|
|
129
|
+
self.assertEqual(list(all_desc_seq3.columns)[0], expected_first_col,
|
|
130
|
+
'Expected first column to be {}, got {}.'.format(expected_first_col, list(all_desc_seq3.columns)[0]))
|
|
131
|
+
self.assertEqual(list(all_desc_seq3.columns)[-1], expected_last_col,
|
|
132
|
+
'Expected last column to be {}, got {}.'.format(expected_last_col, list(all_desc_seq3.columns)[-1]))
|
|
133
|
+
self.assertTrue(all_desc_seq3.any().isnull().sum() == 0,
|
|
134
|
+
'Expected output to contain no null values.')
|
|
135
|
+
self.assertEqual(all_desc_seq3["A"].values[0], 5.263,
|
|
136
|
+
'Expected amino acid composition A value of 5.263 for seq3, got {}.'.format(all_desc_seq3["A"].values[0]))
|
|
137
|
+
self.assertEqual(all_desc_seq3["MBAuto_CIDH920105_1"].values[0], 0.212,
|
|
138
|
+
'Expected MBAuto_CIDH920105_1 value of 0.212 for seq3, got {}.'.format(all_desc_seq3["MBAuto_CIDH920105_1"].values[0]))
|
|
139
|
+
self.assertAlmostEqual(all_desc_seq3["QSO_Grant50"].values[0], 0.028037, places=5,
|
|
140
|
+
msg='Expected QSO_Grant50 value of ~0.028037 for seq3, got {}.'.format(all_desc_seq3["QSO_Grant50"].values[0]))
|
|
141
|
+
#4.)
|
|
142
|
+
all_desc_seq4 = protpy.all_descriptors(self.protein_seq4)
|
|
143
|
+
|
|
144
|
+
self.assertIsInstance(all_desc_seq4, pd.DataFrame,
|
|
145
|
+
'Expected output to be of type DataFrame, got {}.'.format(type(all_desc_seq4)))
|
|
146
|
+
self.assertEqual(all_desc_seq4.shape, expected_shape,
|
|
147
|
+
'Expected output shape {}, got {}.'.format(expected_shape, all_desc_seq4.shape))
|
|
148
|
+
self.assertEqual(list(all_desc_seq4.columns)[0], expected_first_col,
|
|
149
|
+
'Expected first column to be {}, got {}.'.format(expected_first_col, list(all_desc_seq4.columns)[0]))
|
|
150
|
+
self.assertEqual(list(all_desc_seq4.columns)[-1], expected_last_col,
|
|
151
|
+
'Expected last column to be {}, got {}.'.format(expected_last_col, list(all_desc_seq4.columns)[-1]))
|
|
152
|
+
self.assertTrue(all_desc_seq4.any().isnull().sum() == 0,
|
|
153
|
+
'Expected output to contain no null values.')
|
|
154
|
+
self.assertEqual(all_desc_seq4["A"].values[0], 8.831,
|
|
155
|
+
'Expected amino acid composition A value of 8.831 for seq4, got {}.'.format(all_desc_seq4["A"].values[0]))
|
|
156
|
+
self.assertEqual(all_desc_seq4["MBAuto_CIDH920105_1"].values[0], 0.246,
|
|
157
|
+
'Expected MBAuto_CIDH920105_1 value of 0.246 for seq4, got {}.'.format(all_desc_seq4["MBAuto_CIDH920105_1"].values[0]))
|
|
158
|
+
self.assertAlmostEqual(all_desc_seq4["QSO_Grant50"].values[0], 0.031954, places=5,
|
|
159
|
+
msg='Expected QSO_Grant50 value of ~0.031954 for seq4, got {}.'.format(all_desc_seq4["QSO_Grant50"].values[0]))
|
|
160
|
+
#5.) passing None for params is equivalent to default
|
|
161
|
+
all_desc_none_params = protpy.all_descriptors(self.protein_seq1, params=None)
|
|
162
|
+
self.assertTrue(all_desc_none_params.equals(all_desc_seq1),
|
|
163
|
+
'Expected params=None to produce same output as default params.')
|
|
164
|
+
|
|
165
|
+
self.assertEqual(mock_all_desc.call_count, 5,
|
|
166
|
+
'Expected all_descriptors to be called exactly 5 times, got {}.'.format(mock_all_desc.call_count))
|
|
167
|
+
|
|
168
|
+
@patch('protpy.all_descriptors')
|
|
169
|
+
def test_all_descriptors_custom_params(self, mock_all_desc):
|
|
170
|
+
""" Testing all_descriptors with custom per-descriptor parameters (mocked). """
|
|
171
|
+
df_kmer_k3 = _mock_df(18357)
|
|
172
|
+
df_kmer_default = _mock_df(10757)
|
|
173
|
+
df_charge_custom = _mock_df(10757, {"PositiveCharge": 110.396})
|
|
174
|
+
df_charge_default = _mock_df(10757, {"PositiveCharge": 85.0})
|
|
175
|
+
df_custom_lag = _mock_df(10337)
|
|
176
|
+
df_ra2 = _mock_df(10753)
|
|
177
|
+
df_combined = _mock_df(17937)
|
|
178
|
+
mock_all_desc.side_effect = [
|
|
179
|
+
df_kmer_k3, df_kmer_default,
|
|
180
|
+
df_charge_custom, df_charge_default,
|
|
181
|
+
df_custom_lag, df_ra2, df_combined,
|
|
182
|
+
]
|
|
183
|
+
|
|
184
|
+
#1.) kmer_composition k=3 increases feature count from 400 to 8000
|
|
185
|
+
kmer_k3 = protpy.all_descriptors(self.protein_seq1, params={
|
|
186
|
+
'kmer_composition': {'k': 3},
|
|
187
|
+
})
|
|
188
|
+
kmer_default = protpy.all_descriptors(self.protein_seq1)
|
|
189
|
+
#k=3 adds 7600 extra features (8000-400)
|
|
190
|
+
self.assertEqual(kmer_k3.shape, (1, kmer_default.shape[1] + 7600),
|
|
191
|
+
'Expected k=3 to add 7600 features, shape {}, got {}.'.format(
|
|
192
|
+
(1, kmer_default.shape[1] + 7600), kmer_k3.shape))
|
|
193
|
+
self.assertIsInstance(kmer_k3, pd.DataFrame,
|
|
194
|
+
'Expected output to be of type DataFrame, got {}.'.format(type(kmer_k3)))
|
|
195
|
+
self.assertTrue(kmer_k3.any().isnull().sum() == 0,
|
|
196
|
+
'Expected output to contain no null values.')
|
|
197
|
+
#2.) charge_distribution ph=5.5 changes PositiveCharge vs default ph=7.4
|
|
198
|
+
charge_custom = protpy.all_descriptors(self.protein_seq1, params={
|
|
199
|
+
'charge_distribution': {'ph': 5.5},
|
|
200
|
+
})
|
|
201
|
+
charge_default = protpy.all_descriptors(self.protein_seq1)
|
|
202
|
+
self.assertIsInstance(charge_custom, pd.DataFrame,
|
|
203
|
+
'Expected output to be of type DataFrame, got {}.'.format(type(charge_custom)))
|
|
204
|
+
self.assertNotEqual(
|
|
205
|
+
charge_custom["PositiveCharge"].values[0],
|
|
206
|
+
charge_default["PositiveCharge"].values[0],
|
|
207
|
+
'Expected PositiveCharge to differ between ph=5.5 and ph=7.4 (default).')
|
|
208
|
+
self.assertEqual(charge_custom["PositiveCharge"].values[0], 110.396,
|
|
209
|
+
'Expected PositiveCharge of 110.396 at ph=5.5 for seq1, got {}.'.format(
|
|
210
|
+
charge_custom["PositiveCharge"].values[0]))
|
|
211
|
+
#3.) reduced lag on autocorrelation and sequence-order descriptors reduces feature count
|
|
212
|
+
lag = 15
|
|
213
|
+
custom_lag = protpy.all_descriptors(self.protein_seq1, params={
|
|
214
|
+
'moreaubroto_autocorrelation': {'lag': lag},
|
|
215
|
+
'moran_autocorrelation': {'lag': lag},
|
|
216
|
+
'geary_autocorrelation': {'lag': lag},
|
|
217
|
+
'sequence_order_coupling_number_all': {'lag': lag},
|
|
218
|
+
'quasi_sequence_order_all': {'lag': lag},
|
|
219
|
+
})
|
|
220
|
+
self.assertIsInstance(custom_lag, pd.DataFrame,
|
|
221
|
+
'Expected output to be of type DataFrame, got {}.'.format(type(custom_lag)))
|
|
222
|
+
#each autocorrelation descriptor loses (30-15)*8=120 features, socn_all loses 30,
|
|
223
|
+
#qso_all loses (20+30)*2-(20+15)*2=100-70=30; total reduction=120*3+30+30=420
|
|
224
|
+
self.assertEqual(custom_lag.shape, (1, kmer_default.shape[1] - 420),
|
|
225
|
+
'Expected lag=15 to reduce total by 420, shape {}, got {}.'.format(
|
|
226
|
+
(1, kmer_default.shape[1] - 420), custom_lag.shape))
|
|
227
|
+
self.assertTrue(custom_lag.any().isnull().sum() == 0,
|
|
228
|
+
'Expected output to contain no null values.')
|
|
229
|
+
#4.) reduced_alphabet_composition alphabet_size=2 reduces feature count by 4 (6-2)
|
|
230
|
+
ra2 = protpy.all_descriptors(self.protein_seq1, params={
|
|
231
|
+
'reduced_alphabet_composition': {'alphabet_size': 2},
|
|
232
|
+
})
|
|
233
|
+
self.assertEqual(ra2.shape, (1, kmer_default.shape[1] - 4),
|
|
234
|
+
'Expected alphabet_size=2 to reduce total by 4, got shape {}.'.format(ra2.shape))
|
|
235
|
+
self.assertTrue(ra2.any().isnull().sum() == 0,
|
|
236
|
+
'Expected output to contain no null values.')
|
|
237
|
+
#5.) multiple custom params applied simultaneously
|
|
238
|
+
combined = protpy.all_descriptors(self.protein_seq2, params={
|
|
239
|
+
'charge_distribution': {'ph': 5.5},
|
|
240
|
+
'kmer_composition': {'k': 3},
|
|
241
|
+
'moreaubroto_autocorrelation': {'lag': 15},
|
|
242
|
+
'moran_autocorrelation': {'lag': 15},
|
|
243
|
+
'geary_autocorrelation': {'lag': 15},
|
|
244
|
+
'sequence_order_coupling_number_all': {'lag': 15},
|
|
245
|
+
'quasi_sequence_order_all': {'lag': 15},
|
|
246
|
+
})
|
|
247
|
+
self.assertIsInstance(combined, pd.DataFrame,
|
|
248
|
+
'Expected output to be of type DataFrame, got {}.'.format(type(combined)))
|
|
249
|
+
self.assertEqual(combined.shape, (1, 17937),
|
|
250
|
+
'Expected combined custom params shape (1, 17937), got {}.'.format(combined.shape))
|
|
251
|
+
self.assertTrue(combined.any().isnull().sum() == 0,
|
|
252
|
+
'Expected output to contain no null values.')
|
|
253
|
+
|
|
254
|
+
self.assertEqual(mock_all_desc.call_count, 7,
|
|
255
|
+
'Expected all_descriptors to be called exactly 7 times, got {}.'.format(mock_all_desc.call_count))
|
|
256
|
+
|
|
257
|
+
def test_all_descriptors_params_validation(self):
|
|
258
|
+
""" Testing that invalid params inputs raise the correct errors. """
|
|
259
|
+
# Validation is fast: errors are raised before any descriptor computation.
|
|
260
|
+
#1.) unknown descriptor name raises ValueError
|
|
261
|
+
with self.assertRaises(ValueError):
|
|
262
|
+
protpy.all_descriptors(self.protein_seq1, params={'unknown_descriptor': {'k': 2}})
|
|
263
|
+
#2.) a descriptor that takes no extra parameters raises ValueError
|
|
264
|
+
with self.assertRaises(ValueError):
|
|
265
|
+
protpy.all_descriptors(self.protein_seq1, params={'amino_acid_composition': {}})
|
|
266
|
+
with self.assertRaises(ValueError):
|
|
267
|
+
protpy.all_descriptors(self.protein_seq1, params={'conjoint_triad': {}})
|
|
268
|
+
with self.assertRaises(ValueError):
|
|
269
|
+
protpy.all_descriptors(self.protein_seq1, params={'gravy': {}})
|
|
270
|
+
#3.) params of wrong type raises TypeError
|
|
271
|
+
with self.assertRaises(TypeError):
|
|
272
|
+
protpy.all_descriptors(self.protein_seq1, params="lag=15")
|
|
273
|
+
with self.assertRaises(TypeError):
|
|
274
|
+
protpy.all_descriptors(self.protein_seq1, params=["kmer_composition"])
|
|
275
|
+
with self.assertRaises(TypeError):
|
|
276
|
+
protpy.all_descriptors(self.protein_seq1, params=123)
|
|
277
|
+
#4.) misspelled descriptor name raises ValueError with a useful message
|
|
278
|
+
try:
|
|
279
|
+
protpy.all_descriptors(self.protein_seq1, params={'kmer_compostion': {'k': 3}})
|
|
280
|
+
self.fail('Expected ValueError for misspelled descriptor name.')
|
|
281
|
+
except ValueError as e:
|
|
282
|
+
self.assertIn('kmer_compostion', str(e),
|
|
283
|
+
'Expected error message to name the unrecognised key, got: {}'.format(e))
|
|
284
|
+
|
|
285
|
+
def test_all_descriptors_invalid_sequence(self):
|
|
286
|
+
""" Testing that invalid protein sequence inputs raise the correct errors. """
|
|
287
|
+
# Validation is fast: errors are raised before any descriptor computation.
|
|
288
|
+
#1.) sequence containing non-canonical amino acid characters raises ValueError
|
|
289
|
+
with self.assertRaises(ValueError):
|
|
290
|
+
protpy.all_descriptors("ABCDEF")
|
|
291
|
+
with self.assertRaises(ValueError):
|
|
292
|
+
protpy.all_descriptors("OOOOO")
|
|
293
|
+
with self.assertRaises(ValueError):
|
|
294
|
+
protpy.all_descriptors("")
|
|
295
|
+
#2.) non-string sequence raises TypeError
|
|
296
|
+
with self.assertRaises(TypeError):
|
|
297
|
+
protpy.all_descriptors(12345)
|
|
298
|
+
with self.assertRaises(TypeError):
|
|
299
|
+
protpy.all_descriptors(True)
|
|
300
|
+
with self.assertRaises(TypeError):
|
|
301
|
+
protpy.all_descriptors(["ACDEFG"])
|
|
302
|
+
#3.) invalid sequence with otherwise valid custom params still raises ValueError
|
|
303
|
+
with self.assertRaises(ValueError):
|
|
304
|
+
protpy.all_descriptors("ABCDEF", params={'kmer_composition': {'k': 3}})
|
|
@@ -22,8 +22,8 @@ class ProtpyTests(unittest.TestCase):
|
|
|
22
22
|
"""
|
|
23
23
|
def test_protpy_metadata(self):
|
|
24
24
|
""" Testing correct protpy version and metadata. """
|
|
25
|
-
self.assertEqual(protpy.__version__, "1.
|
|
26
|
-
"protpy version is not correct, expected version 1.
|
|
25
|
+
self.assertEqual(protpy.__version__, "1.4.0",
|
|
26
|
+
"protpy version is not correct, expected version 1.4.0, got version {}".format(protpy.__version__))
|
|
27
27
|
self.assertEqual(protpy.__name__, "protpy",
|
|
28
28
|
"protpy software name is not correct, expected protpy, got {}.".format(protpy.__name__))
|
|
29
29
|
self.assertEqual(protpy.__author__, "AJ McKenna: https://github.com/amckenna41",
|
|
@@ -47,84 +47,84 @@ class ProtpyTests(unittest.TestCase):
|
|
|
47
47
|
|
|
48
48
|
def test_valid_descriptors(self):
|
|
49
49
|
""" Testing correct list of available descriptors is included in package attribute. """
|
|
50
|
-
self.assertEqual(len(protpy.
|
|
51
|
-
"Expected there to be 36 total descriptors, got {}.".format(len(protpy.
|
|
52
|
-
self.assertIsInstance(protpy.
|
|
53
|
-
"all_descriptors should be of type list, got {}.".format(type(protpy.
|
|
50
|
+
self.assertEqual(len(protpy.descriptor_names), 36,
|
|
51
|
+
"Expected there to be 36 total descriptors, got {}.".format(len(protpy.descriptor_names)))
|
|
52
|
+
self.assertIsInstance(protpy.descriptor_names, list,
|
|
53
|
+
"all_descriptors should be of type list, got {}.".format(type(protpy.descriptor_names)))
|
|
54
54
|
# composition descriptors
|
|
55
|
-
self.assertIn('amino_acid_composition', protpy.
|
|
55
|
+
self.assertIn('amino_acid_composition', protpy.descriptor_names,
|
|
56
56
|
"amino_acid_composition should be in available descriptors list.")
|
|
57
|
-
self.assertIn('dipeptide_composition', protpy.
|
|
57
|
+
self.assertIn('dipeptide_composition', protpy.descriptor_names,
|
|
58
58
|
"dipeptide_composition should be in available descriptors list.")
|
|
59
|
-
self.assertIn('tripeptide_composition', protpy.
|
|
59
|
+
self.assertIn('tripeptide_composition', protpy.descriptor_names,
|
|
60
60
|
"tripeptide_composition should be in available descriptors list.")
|
|
61
|
-
self.assertIn('gravy', protpy.
|
|
61
|
+
self.assertIn('gravy', protpy.descriptor_names,
|
|
62
62
|
"gravy should be in available descriptors list.")
|
|
63
|
-
self.assertIn('aromaticity', protpy.
|
|
63
|
+
self.assertIn('aromaticity', protpy.descriptor_names,
|
|
64
64
|
"aromaticity should be in available descriptors list.")
|
|
65
|
-
self.assertIn('instability_index', protpy.
|
|
65
|
+
self.assertIn('instability_index', protpy.descriptor_names,
|
|
66
66
|
"instability_index should be in available descriptors list.")
|
|
67
|
-
self.assertIn('isoelectric_point', protpy.
|
|
67
|
+
self.assertIn('isoelectric_point', protpy.descriptor_names,
|
|
68
68
|
"isoelectric_point should be in available descriptors list.")
|
|
69
|
-
self.assertIn('molecular_weight', protpy.
|
|
69
|
+
self.assertIn('molecular_weight', protpy.descriptor_names,
|
|
70
70
|
"molecular_weight should be in available descriptors list.")
|
|
71
|
-
self.assertIn('charge_distribution', protpy.
|
|
71
|
+
self.assertIn('charge_distribution', protpy.descriptor_names,
|
|
72
72
|
"charge_distribution should be in available descriptors list.")
|
|
73
|
-
self.assertIn('hydrophobic_polar_charged_composition', protpy.
|
|
73
|
+
self.assertIn('hydrophobic_polar_charged_composition', protpy.descriptor_names,
|
|
74
74
|
"hydrophobic_polar_charged_composition should be in available descriptors list.")
|
|
75
|
-
self.assertIn('secondary_structure_propensity', protpy.
|
|
75
|
+
self.assertIn('secondary_structure_propensity', protpy.descriptor_names,
|
|
76
76
|
"secondary_structure_propensity should be in available descriptors list.")
|
|
77
|
-
self.assertIn('kmer_composition', protpy.
|
|
77
|
+
self.assertIn('kmer_composition', protpy.descriptor_names,
|
|
78
78
|
"kmer_composition should be in available descriptors list.")
|
|
79
|
-
self.assertIn('reduced_alphabet_composition', protpy.
|
|
79
|
+
self.assertIn('reduced_alphabet_composition', protpy.descriptor_names,
|
|
80
80
|
"reduced_alphabet_composition should be in available descriptors list.")
|
|
81
|
-
self.assertIn('motif_composition', protpy.
|
|
81
|
+
self.assertIn('motif_composition', protpy.descriptor_names,
|
|
82
82
|
"motif_composition should be in available descriptors list.")
|
|
83
|
-
self.assertIn('amino_acid_pair_composition', protpy.
|
|
83
|
+
self.assertIn('amino_acid_pair_composition', protpy.descriptor_names,
|
|
84
84
|
"amino_acid_pair_composition should be in available descriptors list.")
|
|
85
|
-
self.assertIn('aliphatic_index', protpy.
|
|
85
|
+
self.assertIn('aliphatic_index', protpy.descriptor_names,
|
|
86
86
|
"aliphatic_index should be in available descriptors list.")
|
|
87
|
-
self.assertIn('extinction_coefficient', protpy.
|
|
87
|
+
self.assertIn('extinction_coefficient', protpy.descriptor_names,
|
|
88
88
|
"extinction_coefficient should be in available descriptors list.")
|
|
89
|
-
self.assertIn('boman_index', protpy.
|
|
89
|
+
self.assertIn('boman_index', protpy.descriptor_names,
|
|
90
90
|
"boman_index should be in available descriptors list.")
|
|
91
|
-
self.assertIn('aggregation_propensity', protpy.
|
|
91
|
+
self.assertIn('aggregation_propensity', protpy.descriptor_names,
|
|
92
92
|
"aggregation_propensity should be in available descriptors list.")
|
|
93
|
-
self.assertIn('hydrophobic_moment', protpy.
|
|
93
|
+
self.assertIn('hydrophobic_moment', protpy.descriptor_names,
|
|
94
94
|
"hydrophobic_moment should be in available descriptors list.")
|
|
95
|
-
self.assertIn('pseudo_amino_acid_composition', protpy.
|
|
95
|
+
self.assertIn('pseudo_amino_acid_composition', protpy.descriptor_names,
|
|
96
96
|
"pseudo_amino_acid_composition should be in available descriptors list.")
|
|
97
|
-
self.assertIn('amphiphilic_pseudo_amino_acid_composition', protpy.
|
|
97
|
+
self.assertIn('amphiphilic_pseudo_amino_acid_composition', protpy.descriptor_names,
|
|
98
98
|
"amphiphilic_pseudo_amino_acid_composition should be in available descriptors list.")
|
|
99
99
|
# autocorrelation descriptors
|
|
100
|
-
self.assertIn('moreaubroto_autocorrelation', protpy.
|
|
100
|
+
self.assertIn('moreaubroto_autocorrelation', protpy.descriptor_names,
|
|
101
101
|
"moreaubroto_autocorrelation should be in available descriptors list.")
|
|
102
|
-
self.assertIn('moran_autocorrelation', protpy.
|
|
102
|
+
self.assertIn('moran_autocorrelation', protpy.descriptor_names,
|
|
103
103
|
"moran_autocorrelation should be in available descriptors list.")
|
|
104
|
-
self.assertIn('geary_autocorrelation', protpy.
|
|
104
|
+
self.assertIn('geary_autocorrelation', protpy.descriptor_names,
|
|
105
105
|
"geary_autocorrelation should be in available descriptors list.")
|
|
106
106
|
# conjoint triad descriptor
|
|
107
|
-
self.assertIn('conjoint_triad', protpy.
|
|
107
|
+
self.assertIn('conjoint_triad', protpy.descriptor_names,
|
|
108
108
|
"conjoint_triad should be in available descriptors list.")
|
|
109
109
|
# CTD descriptors
|
|
110
|
-
self.assertIn('ctd_composition', protpy.
|
|
110
|
+
self.assertIn('ctd_composition', protpy.descriptor_names,
|
|
111
111
|
"ctd_composition should be in available descriptors list.")
|
|
112
|
-
self.assertIn('ctd_transition', protpy.
|
|
112
|
+
self.assertIn('ctd_transition', protpy.descriptor_names,
|
|
113
113
|
"ctd_transition should be in available descriptors list.")
|
|
114
|
-
self.assertIn('ctd_distribution', protpy.
|
|
114
|
+
self.assertIn('ctd_distribution', protpy.descriptor_names,
|
|
115
115
|
"ctd_distribution should be in available descriptors list.")
|
|
116
|
-
self.assertIn('ctd_', protpy.
|
|
116
|
+
self.assertIn('ctd_', protpy.descriptor_names,
|
|
117
117
|
"ctd_ should be in available descriptors list.")
|
|
118
118
|
# sequence order descriptors
|
|
119
|
-
self.assertIn('sequence_order_coupling_number_', protpy.
|
|
119
|
+
self.assertIn('sequence_order_coupling_number_', protpy.descriptor_names,
|
|
120
120
|
"sequence_order_coupling_number_ should be in available descriptors list.")
|
|
121
|
-
self.assertIn('sequence_order_coupling_number', protpy.
|
|
121
|
+
self.assertIn('sequence_order_coupling_number', protpy.descriptor_names,
|
|
122
122
|
"sequence_order_coupling_number should be in available descriptors list.")
|
|
123
|
-
self.assertIn('sequence_order_coupling_number_all', protpy.
|
|
123
|
+
self.assertIn('sequence_order_coupling_number_all', protpy.descriptor_names,
|
|
124
124
|
"sequence_order_coupling_number_all should be in available descriptors list.")
|
|
125
|
-
self.assertIn('quasi_sequence_order', protpy.
|
|
125
|
+
self.assertIn('quasi_sequence_order', protpy.descriptor_names,
|
|
126
126
|
"quasi_sequence_order should be in available descriptors list.")
|
|
127
|
-
self.assertIn('quasi_sequence_order_all', protpy.
|
|
127
|
+
self.assertIn('quasi_sequence_order_all', protpy.descriptor_names,
|
|
128
128
|
"quasi_sequence_order_all should be in available descriptors list.")
|
|
129
|
-
self.assertIn('shannon_entropy', protpy.
|
|
129
|
+
self.assertIn('shannon_entropy', protpy.descriptor_names,
|
|
130
130
|
"shannon_entropy should be in available descriptors list.")
|
|
@@ -86,12 +86,12 @@ class ProtpyUtilsTests(unittest.TestCase):
|
|
|
86
86
|
|
|
87
87
|
def test_registry_completeness(self):
|
|
88
88
|
"""All 36 descriptor names exported by protpy appear in _DESCRIPTOR_REGISTRY."""
|
|
89
|
-
missing = [n for n in protpy.
|
|
89
|
+
missing = [n for n in protpy.descriptor_names if n not in _DESCRIPTOR_REGISTRY]
|
|
90
90
|
self.assertEqual(
|
|
91
91
|
missing, [],
|
|
92
92
|
f"Descriptors in all_descriptors but missing from registry: {missing}",
|
|
93
93
|
)
|
|
94
|
-
self.assertEqual(len(_DESCRIPTOR_REGISTRY), len(protpy.
|
|
94
|
+
self.assertEqual(len(_DESCRIPTOR_REGISTRY), len(protpy.descriptor_names),
|
|
95
95
|
"Registry length doesn't match len(all_descriptors).")
|
|
96
96
|
|
|
97
97
|
def test_registry_schema(self):
|
|
@@ -204,7 +204,7 @@ class ProtpyUtilsTests(unittest.TestCase):
|
|
|
204
204
|
# Result is sorted
|
|
205
205
|
self.assertEqual(descriptors, sorted(descriptors))
|
|
206
206
|
# Every name in all_descriptors appears in the result
|
|
207
|
-
for name in protpy.
|
|
207
|
+
for name in protpy.descriptor_names:
|
|
208
208
|
self.assertIn(name, descriptors)
|
|
209
209
|
|
|
210
210
|
def test_list_descriptors_by_category(self):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{protpy-1.3.0 → protpy-1.4.0}/protpy/data/schneider-wrede-physicochemical-distance-matrix.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|