1
|
|
|
#!/usr/bin/env python |
2
|
|
|
# -*- coding: utf-8 -*- |
3
|
|
|
""" |
4
|
|
|
|
5
|
|
|
""" |
6
|
|
|
from __future__ import print_function |
7
|
|
|
import argparse |
8
|
|
|
from icecream import ic |
9
|
|
|
import sys |
10
|
|
|
ic.configureOutput(outputFunction=lambda *a: print(*a, file=sys.stderr)) |
11
|
|
|
ic.configureOutput(prefix='> ') |
12
|
|
|
|
13
|
|
|
from Bio.PDB import PDBParser, Superimposer |
14
|
|
|
import numpy as np |
15
|
|
|
|
16
|
|
|
# Function to parse a structure from a PDB file |
17
|
|
|
def parse_structure(file_path): |
18
|
|
|
parser = PDBParser() |
19
|
|
|
return parser.get_structure('protein', file_path) |
20
|
|
|
|
21
|
|
|
# Function to calculate GDT |
22
|
|
|
def calculate_gdt(structure1, structure2, thresholds): |
23
|
|
|
# Superimpose structures |
24
|
|
|
ref_atoms = list(structure1.get_atoms()) |
25
|
|
|
sample_atoms = list(structure2.get_atoms()) |
26
|
|
|
|
27
|
|
|
# Ensuring both structures have the same number of atoms |
28
|
|
|
if len(ref_atoms) != len(sample_atoms): |
29
|
|
|
raise ValueError("Structures do not have the same number of atoms") |
30
|
|
|
|
31
|
|
|
super_imposer = Superimposer() |
32
|
|
|
super_imposer.set_atoms(ref_atoms, sample_atoms) |
33
|
|
|
super_imposer.apply(sample_atoms) |
34
|
|
|
|
35
|
|
|
# Calculate distances after superimposition |
36
|
|
|
distances = np.array([ref_atom - sample_atom for ref_atom, sample_atom in zip(ref_atoms, sample_atoms)]) |
37
|
|
|
|
38
|
|
|
# Calculate GDT for given thresholds |
39
|
|
|
gdt_scores = {} |
40
|
|
|
for threshold in thresholds: |
41
|
|
|
matches = np.sum(distances < threshold) |
42
|
|
|
gdt_scores[threshold] = (matches / len(ref_atoms)) * 100 # GDT percentage |
43
|
|
|
|
44
|
|
|
return gdt_scores |
45
|
|
|
|
46
|
|
|
|
47
|
|
|
def get_parser(): |
48
|
|
|
parser = argparse.ArgumentParser( |
49
|
|
|
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) |
50
|
|
|
|
51
|
|
|
parser.add_argument('-ha', "--high-accuracy", help="", default="", action="store_true") |
52
|
|
|
parser.add_argument("-v", "--verbose", |
53
|
|
|
action="store_true", help="be verbose") |
54
|
|
|
parser.add_argument("struc1", help="", default="") # nargs='+') |
55
|
|
|
parser.add_argument("struc2", help="", default="") # nargs='+') |
56
|
|
|
return parser |
57
|
|
|
|
58
|
|
|
|
59
|
|
|
if __name__ == '__main__': |
60
|
|
|
parser = get_parser() |
61
|
|
|
args = parser.parse_args() |
62
|
|
|
|
63
|
|
|
# Example usage |
64
|
|
|
structure1 = parse_structure(args.struc1) |
65
|
|
|
structure2 = parse_structure(args.struc2) |
66
|
|
|
thresholds = [1, 2, 4, 8] # Thresholds in Angstroms |
67
|
|
|
if args.high_accuracy: |
68
|
|
|
thresholds = [0.5, 1, 2, 4] |
69
|
|
|
gdt_scores = calculate_gdt(structure1, structure2, thresholds) |
70
|
|
|
print("GDT Scores:", gdt_scores) |
71
|
|
|
|