-
Notifications
You must be signed in to change notification settings - Fork 805
/
pdb.py
104 lines (96 loc) · 3.18 KB
/
pdb.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/python
# -*- coding: ISO-8859-1 -*-
"""
Simple parser for reading atoms from a PDB file.
Copyright (C) 2016 Martti Louhivuori
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
"""
import re
from numpy import array, zeros
class Atom:
"""
Container for atom coordinates with the possibility to store additional
information (element and chain ID).
self.x -- X coordinate
self.y -- Y coordinate
self.z -- Z coordinate
self.element -- atom type
self.chain -- chain ID of the atom
"""
def __init__(self, x, y, z, element=None, chain=None):
self.x = float(x)
self.y = float(y)
self.z = float(z)
self.element = element or None
self.chain = chain or None
def tolist(self):
return [self.x, self.y, self.z]
def toarray(self):
return array(self.tolist())
def __repr__(self):
element = self.element or 'None'
return 'Atom(%f, %f, %f, element=%s)' % \
(self.x, self.y, self.z, element)
def __str__(self):
if self.element:
return self.element + ': ' + str(self.tolist())
else:
return str(self.tolist())
class PDB:
"""
Read atom coordinates from a PDB file.
self.atoms -- List of Atom() objects containing all ATOM records
self.coordinates -- NumPy array of atom coordinates
Example usage:
from pdb import PDB
pdb = PDB('5ire.pdb')
print pdb.coordinates
for atom in pdb:
print atom
"""
def __init__(self, filename):
self.__ro_atom__ = re.compile('^ATOM ')
self.read(filename)
def read(self, filename):
"""
Parse a PDB file and store all ATOM records.
"""
self.filename = filename
file = open(filename)
self.atoms = []
for line in file:
if not self.__ro_atom__.match(line):
continue
x = line[30:38].strip()
y = line[38:46].strip()
z = line[46:54].strip()
e = line[76:78].strip()
c = line[21]
self.atoms.append(Atom(x, y, z, element=e, chain=c))
file.close()
self.__prep_coords__()
def __prep_coords__(self):
self.coordinates = zeros((len(self.atoms), 3), float)
for i, atom in enumerate(self.atoms):
self.coordinates[i] = atom.toarray()
def __iter__(self):
for atom in self.atoms:
yield atom
def __getitem__(self, key):
if type(key) is int and key < len(self.atoms):
return self.atoms[key]
else:
raise KeyError('Invalid chain ID')
def __len__(self):
return len(self.atoms)
def __repr__(self):
return 'PDB(%s)' % self.filename
def __str__(self):
txt = '%d atoms from %s\n' % (len(self.atoms), self.filename)
txt += '---\n'
for atom in self.atoms:
txt += str(atom) + '\n'
return txt