/usr/share/pyshared/Bio/PDB/FragmentMapper.py is in python-biopython 1.58-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | # Copyright (C) 2002, Thomas Hamelryck (thamelry@binf.ku.dk)
# This code is part of the Biopython distribution and governed by its
# license. Please see the LICENSE file that should have been included
# as part of this package.
"""Classify protein backbone structure according to Kolodny et al's fragment
libraries.
It can be regarded as a form of objective secondary structure classification.
Only fragments of length 5 or 7 are supported (ie. there is a 'central'
residue).
Full reference:
Kolodny R, Koehl P, Guibas L, Levitt M.
Small libraries of protein fragments model native protein structures accurately.
J Mol Biol. 2002 323(2):297-307.
The definition files of the fragments can be obtained from:
U{http://csb.stanford.edu/~rachel/fragments/}
You need these files to use this module.
The following example uses the library with 10 fragments of length 5.
The library files can be found in directory 'fragment_data'.
>>> model = structure[0]
>>> fm = FragmentMapper(model, lsize=10, flength=5, dir="fragment_data")
>>> fragment = fm[residue]
"""
import numpy
from Bio.SVDSuperimposer import SVDSuperimposer
from Bio.PDB import Selection
from Bio.PDB.PDBExceptions import PDBException
from Bio.PDB.PDBParser import PDBParser
from Bio.PDB.Polypeptide import PPBuilder
# fragment file (lib_SIZE_z_LENGTH.txt)
# SIZE=number of fragments
# LENGTH=length of fragment (4,5,6,7)
_FRAGMENT_FILE="lib_%s_z_%s.txt"
def _read_fragments(size, length, dir="."):
"""
Read a fragment spec file (available from
U{http://csb.stanford.edu/rachel/fragments/}
and return a list of Fragment objects.
@param size: number of fragments in the library
@type size: int
@param length: length of the fragments
@type length: int
@param dir: directory where the fragment spec files can be found
@type dir: string
"""
filename=(dir+"/"+_FRAGMENT_FILE) % (size, length)
fp=open(filename, "r")
flist=[]
# ID of fragment=rank in spec file
fid=0
for l in fp.readlines():
# skip comment and blank lines
if l[0]=="*" or l[0]=="\n":
continue
sl=l.split()
if sl[1]=="------":
# Start of fragment definition
f=Fragment(length, fid)
flist.append(f)
# increase fragment id (rank)
fid+=1
continue
# Add CA coord to Fragment
coord=numpy.array(map(float, sl[0:3]))
# XXX= dummy residue name
f.add_residue("XXX", coord)
fp.close()
return flist
class Fragment(object):
"""
Represent a polypeptide C-alpha fragment.
"""
def __init__(self, length, fid):
"""
@param length: length of the fragment
@type length: int
@param fid: id for the fragment
@type fid: int
"""
# nr of residues in fragment
self.length=length
# nr of residues added
self.counter=0
self.resname_list=[]
# CA coordinate matrix
self.coords_ca=numpy.zeros((length, 3), "d")
self.fid=fid
def get_resname_list(self):
"""
@return: the residue names
@rtype: [string, string,...]
"""
return self.resname_list
def get_id(self):
"""
@return: id for the fragment
@rtype: int
"""
return self.fid
def get_coords(self):
"""
@return: the CA coords in the fragment
@rtype: Numeric (Nx3) array
"""
return self.coords_ca
def add_residue(self, resname, ca_coord):
"""
@param resname: residue name (eg. GLY).
@type resname: string
@param ca_coord: the c-alpha coorinates of the residues
@type ca_coord: Numeric array with length 3
"""
if self.counter>=self.length:
raise PDBException("Fragment boundary exceeded.")
self.resname_list.append(resname)
self.coords_ca[self.counter]=ca_coord
self.counter=self.counter+1
def __len__(self):
"""
@return: length of fragment
@rtype: int
"""
return self.length
def __sub__(self, other):
"""
Return rmsd between two fragments.
Example:
>>> rmsd=fragment1-fragment2
@return: rmsd between fragments
@rtype: float
"""
sup=SVDSuperimposer()
sup.set(self.coords_ca, other.coords_ca)
sup.run()
return sup.get_rms()
def __repr__(self):
"""
Returns <Fragment length=L id=ID> where L=length of fragment
and ID the identifier (rank in the library).
"""
return "<Fragment length=%i id=%i>" % (self.length, self.fid)
def _make_fragment_list(pp, length):
"""
Dice up a peptide in fragments of length "length".
@param pp: a list of residues (part of one peptide)
@type pp: [L{Residue}, L{Residue}, ...]
@param length: fragment length
@type length: int
"""
frag_list=[]
for i in range(0, len(pp)-length+1):
f=Fragment(length, -1)
for j in range(0, length):
residue=pp[i+j]
resname=residue.get_resname()
if residue.has_id("CA"):
ca=residue["CA"]
else:
raise PDBException("CHAINBREAK")
if ca.is_disordered():
raise PDBException("CHAINBREAK")
ca_coord=ca.get_coord()
f.add_residue(resname, ca_coord)
frag_list.append(f)
return frag_list
def _map_fragment_list(flist, reflist):
"""
Map all frgaments in flist to the closest
(in RMSD) fragment in reflist.
Returns a list of reflist indices.
@param flist: list of protein fragments
@type flist: [L{Fragment}, L{Fragment}, ...]
@param reflist: list of reference (ie. library) fragments
@type reflist: [L{Fragment}, L{Fragment}, ...]
"""
mapped=[]
for f in flist:
rank=[]
for i in range(0, len(reflist)):
rf=reflist[i]
rms=f-rf
rank.append((rms, rf))
rank.sort()
fragment=rank[0][1]
mapped.append(fragment)
return mapped
class FragmentMapper(object):
"""
Map polypeptides in a model to lists of representative fragments.
"""
def __init__(self, model, lsize=20, flength=5, fdir="."):
"""
@param model: the model that will be mapped
@type model: L{Model}
@param lsize: number of fragments in the library
@type lsize: int
@param flength: length of fragments in the library
@type flength: int
@param fdir: directory where the definition files are
found (default=".")
@type fdir: string
"""
if flength==5:
self.edge=2
elif flength==7:
self.edge=3
else:
raise PDBException("Fragment length should be 5 or 7.")
self.flength=flength
self.lsize=lsize
self.reflist=_read_fragments(lsize, flength, fdir)
self.model=model
self.fd=self._map(self.model)
def _map(self, model):
"""
@param model: the model that will be mapped
@type model: L{Model}
"""
ppb=PPBuilder()
ppl=ppb.build_peptides(model)
fd={}
for pp in ppl:
try:
# make fragments
flist=_make_fragment_list(pp, self.flength)
# classify fragments
mflist=_map_fragment_list(flist, self.reflist)
for i in range(0, len(pp)):
res=pp[i]
if i<self.edge:
# start residues
continue
elif i>=(len(pp)-self.edge):
# end residues
continue
else:
# fragment
index=i-self.edge
assert(index>=0)
fd[res]=mflist[index]
except PDBException, why:
if why == 'CHAINBREAK':
# Funny polypeptide - skip
pass
else:
raise PDBException(why)
return fd
def has_key(self, res):
"""(Obsolete)
@type res: L{Residue}
"""
import warnings
warnings.warn("has_key is obsolete; use 'res in object' instead", PendingDeprecationWarning)
return (res in self)
def __contains__(self, res):
"""True if the given residue is in any of the mapped fragments.
@type res: L{Residue}
"""
return (res in self.fd)
def __getitem__(self, res):
"""
@type res: L{Residue}
@return: fragment classification
@rtype: L{Fragment}
"""
return self.fd[res]
if __name__=="__main__":
import sys
p=PDBParser()
s=p.get_structure("X", sys.argv[1])
m=s[0]
fm=FragmentMapper(m, 10, 5, "levitt_data")
for r in Selection.unfold_entities(m, "R"):
print r,
if r in fm:
print fm[r]
else:
print
|