protinspect 0.1.0__py3-none-any.whl
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.
- protinspect/__init__.py +0 -0
- protinspect/analyzer.py +140 -0
- protinspect/cli.py +73 -0
- protinspect/parser.py +12 -0
- protinspect/utils.py +101 -0
- protinspect-0.1.0.dist-info/METADATA +59 -0
- protinspect-0.1.0.dist-info/RECORD +9 -0
- protinspect-0.1.0.dist-info/WHEEL +4 -0
- protinspect-0.1.0.dist-info/entry_points.txt +3 -0
protinspect/__init__.py
ADDED
|
File without changes
|
protinspect/analyzer.py
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
from .parser import load_structure
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def count_chains(file_path):
|
|
5
|
+
"""
|
|
6
|
+
Count number of chains.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
structure = load_structure(file_path)
|
|
10
|
+
|
|
11
|
+
chains = list(structure.get_chains())
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
"chain_count": len(chains),
|
|
15
|
+
"chain_ids": [c.id for c in chains]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_resolution(file_path):
|
|
20
|
+
"""
|
|
21
|
+
Get experimental resolution.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
structure = load_structure(file_path)
|
|
25
|
+
|
|
26
|
+
resolution = structure.header.get(
|
|
27
|
+
"resolution"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
return resolution
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def detect_ligands(file_path):
|
|
34
|
+
"""
|
|
35
|
+
Detect ligands in structure.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
structure = load_structure(file_path)
|
|
39
|
+
|
|
40
|
+
ligands = []
|
|
41
|
+
|
|
42
|
+
excluded = [
|
|
43
|
+
"HOH",
|
|
44
|
+
"WAT"
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
for model in structure:
|
|
48
|
+
for chain in model:
|
|
49
|
+
for residue in chain:
|
|
50
|
+
|
|
51
|
+
if residue.id[0] != " ":
|
|
52
|
+
|
|
53
|
+
ligand_name = residue.resname
|
|
54
|
+
|
|
55
|
+
if ligand_name not in excluded:
|
|
56
|
+
ligands.append(
|
|
57
|
+
ligand_name
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
unique_ligands = list(
|
|
61
|
+
set(ligands)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
"ligand_present":
|
|
66
|
+
len(unique_ligands) > 0,
|
|
67
|
+
|
|
68
|
+
"ligands":
|
|
69
|
+
unique_ligands
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_ligand_ids(file_path):
|
|
74
|
+
"""
|
|
75
|
+
Return ligand IDs with chain and position.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
structure = load_structure(file_path)
|
|
79
|
+
|
|
80
|
+
ligand_data = []
|
|
81
|
+
|
|
82
|
+
excluded = [
|
|
83
|
+
"HOH",
|
|
84
|
+
"WAT"
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
for model in structure:
|
|
88
|
+
for chain in model:
|
|
89
|
+
for residue in chain:
|
|
90
|
+
|
|
91
|
+
if residue.id[0] != " ":
|
|
92
|
+
|
|
93
|
+
ligand = residue.resname
|
|
94
|
+
|
|
95
|
+
if ligand not in excluded:
|
|
96
|
+
|
|
97
|
+
ligand_data.append({
|
|
98
|
+
"id": ligand,
|
|
99
|
+
"chain": chain.id,
|
|
100
|
+
"position":
|
|
101
|
+
residue.id[1]
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
return ligand_data
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def get_missing_residues(file_path):
|
|
108
|
+
"""
|
|
109
|
+
Parse REMARK 465 section.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
missing_residues = []
|
|
113
|
+
|
|
114
|
+
with open(file_path, "r") as file:
|
|
115
|
+
|
|
116
|
+
lines = file.readlines()
|
|
117
|
+
|
|
118
|
+
for line in lines:
|
|
119
|
+
|
|
120
|
+
if line.startswith("REMARK 465"):
|
|
121
|
+
|
|
122
|
+
parts = line.split()
|
|
123
|
+
|
|
124
|
+
if len(parts) >= 5:
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
residue = parts[2]
|
|
128
|
+
chain = parts[3]
|
|
129
|
+
position = int(parts[4])
|
|
130
|
+
|
|
131
|
+
missing_residues.append({
|
|
132
|
+
"residue": residue,
|
|
133
|
+
"chain": chain,
|
|
134
|
+
"position": position
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
except:
|
|
138
|
+
continue
|
|
139
|
+
|
|
140
|
+
return missing_residues
|
protinspect/cli.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
|
|
3
|
+
from .analyzer import (
|
|
4
|
+
count_chains,
|
|
5
|
+
get_resolution,
|
|
6
|
+
detect_ligands,
|
|
7
|
+
get_missing_residues
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from .utils import (
|
|
11
|
+
show_chain_table,
|
|
12
|
+
show_resolution,
|
|
13
|
+
show_ligands,
|
|
14
|
+
show_missing_residues
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
app = typer.Typer()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@app.command()
|
|
21
|
+
def chains(file: str):
|
|
22
|
+
|
|
23
|
+
data = count_chains(file)
|
|
24
|
+
|
|
25
|
+
show_chain_table(data)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@app.command()
|
|
29
|
+
def resolution(file: str):
|
|
30
|
+
|
|
31
|
+
data = get_resolution(file)
|
|
32
|
+
|
|
33
|
+
show_resolution(data)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@app.command()
|
|
37
|
+
def ligands(file: str):
|
|
38
|
+
|
|
39
|
+
data = detect_ligands(file)
|
|
40
|
+
|
|
41
|
+
show_ligands(data)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@app.command()
|
|
45
|
+
def missing(file: str):
|
|
46
|
+
|
|
47
|
+
data = get_missing_residues(file)
|
|
48
|
+
|
|
49
|
+
show_missing_residues(data)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@app.command()
|
|
53
|
+
def all(file: str):
|
|
54
|
+
|
|
55
|
+
show_chain_table(
|
|
56
|
+
count_chains(file)
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
show_resolution(
|
|
60
|
+
get_resolution(file)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
show_ligands(
|
|
64
|
+
detect_ligands(file)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
show_missing_residues(
|
|
68
|
+
get_missing_residues(file)
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
app()
|
protinspect/parser.py
ADDED
protinspect/utils.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from rich.console import Console
|
|
2
|
+
from rich.table import Table
|
|
3
|
+
|
|
4
|
+
console = Console()
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def show_chain_table(data):
|
|
8
|
+
|
|
9
|
+
table = Table(
|
|
10
|
+
title="Chain Information"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
table.add_column(
|
|
14
|
+
"Chain Count",
|
|
15
|
+
justify="center"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
table.add_column(
|
|
19
|
+
"Chain IDs",
|
|
20
|
+
justify="center"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
table.add_row(
|
|
24
|
+
str(data["chain_count"]),
|
|
25
|
+
", ".join(data["chain_ids"])
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
console.print(table)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def show_resolution(resolution):
|
|
32
|
+
|
|
33
|
+
table = Table(
|
|
34
|
+
title="Resolution"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
table.add_column(
|
|
38
|
+
"Resolution (Å)",
|
|
39
|
+
justify="center"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
table.add_row(
|
|
43
|
+
str(resolution)
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
console.print(table)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def show_ligands(data):
|
|
50
|
+
|
|
51
|
+
table = Table(
|
|
52
|
+
title="Ligands"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
table.add_column(
|
|
56
|
+
"Ligand Present"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
table.add_column(
|
|
60
|
+
"Ligand IDs"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
ligands = ", ".join(
|
|
64
|
+
data["ligands"]
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
table.add_row(
|
|
68
|
+
str(data["ligand_present"]),
|
|
69
|
+
ligands
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
console.print(table)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def show_missing_residues(data):
|
|
76
|
+
|
|
77
|
+
table = Table(
|
|
78
|
+
title="Missing Residues"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
table.add_column(
|
|
82
|
+
"Residue"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
table.add_column(
|
|
86
|
+
"Chain"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
table.add_column(
|
|
90
|
+
"Position"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
for item in data:
|
|
94
|
+
|
|
95
|
+
table.add_row(
|
|
96
|
+
item["residue"],
|
|
97
|
+
item["chain"],
|
|
98
|
+
str(item["position"])
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
console.print(table)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: protinspect
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary:
|
|
5
|
+
Author: rkarishma27
|
|
6
|
+
Author-email: anukarishma.27@gmail.com
|
|
7
|
+
Requires-Python: >=3.13
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
11
|
+
Requires-Dist: biopython (>=1.87,<2.0)
|
|
12
|
+
Requires-Dist: rich (>=15.0.0,<16.0.0)
|
|
13
|
+
Requires-Dist: typer (>=0.25.1,<0.26.0)
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# ProtInspect
|
|
17
|
+
|
|
18
|
+
ProtInspect is a Python package for protein structure analysis using PDB files.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Detect missing residues
|
|
23
|
+
- Count protein chains
|
|
24
|
+
- Find experimental resolution
|
|
25
|
+
- Detect ligands
|
|
26
|
+
- Return ligand IDs
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install protinspect
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
Analyze a protein structure:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
protinspect all path/to/file.pdb
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Example:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
protinspect all examples/1crn.pdb
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Tech Stack
|
|
49
|
+
|
|
50
|
+
- Python
|
|
51
|
+
- Poetry
|
|
52
|
+
- Biopython
|
|
53
|
+
- Typer
|
|
54
|
+
- Rich
|
|
55
|
+
- Pytest
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
protinspect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
protinspect/analyzer.py,sha256=dO_TYMKVyIgrrSt_O9i-U7Aa8VeoZqVtzJ4d6KhALCw,2831
|
|
3
|
+
protinspect/cli.py,sha256=ToWC80E0FYt0Eynq5mRohir5Kmd0j6B-qoy6gM-xYs0,1052
|
|
4
|
+
protinspect/parser.py,sha256=0vYuIDp-jomrM3iHMldFlvWSPyVlcpubdPI6pGfZ9ek,212
|
|
5
|
+
protinspect/utils.py,sha256=J5PE5nESEI7stPwvyBLirztSzNUNNVvZ7wltj_22QtE,1540
|
|
6
|
+
protinspect-0.1.0.dist-info/entry_points.txt,sha256=IEIE9-z5V9gxZqYxYryiVDaN8NFmj_DkbyEw-gWYnJs,51
|
|
7
|
+
protinspect-0.1.0.dist-info/METADATA,sha256=xxY1W1BjNOJaQEdz9L1Q8vSWV8YrpyS90C6hf7fxErk,967
|
|
8
|
+
protinspect-0.1.0.dist-info/WHEEL,sha256=EGEvSphFYqXKs23-kQBeyNoJP1nrT8ZJKQoi5p5DYL8,88
|
|
9
|
+
protinspect-0.1.0.dist-info/RECORD,,
|