Package Bio :: Package Crystal
[hide private]
[frames] | no frames]

Source Code for Package Bio.Crystal

  1  # Copyright 2002 by Katharine Lindner.  All rights reserved. 
  2  # This code is part of the Biopython distribution and governed by its 
  3  # license.  Please see the LICENSE file that should have been included 
  4  # as part of this package. 
  5   
  6  """ 
  7  Module to represent the NDB Atlas structure (a minimal subset of PDB format). 
  8   
  9  Hetero, Crystal and Chain exist to represent the NDB Atlas structure.  Atlas 
 10  is a minimal subset of the PDB format.  Heteo supports a 3 alphameric code. 
 11  The NDB web interface is located at http://ndbserver.rutgers.edu/NDB/index.html 
 12  """ 
 13   
 14  import copy 
 15  from functools import reduce 
 16   
 17  from Bio._py3k import map 
 18  from Bio._py3k import basestring 
 19   
 20   
21 -class CrystalError(Exception):
22 pass
23 24
25 -def wrap_line(line):
26 output = '' 27 for i in range(0, len(line), 80): 28 output = output + '%s\n' % line[ i: i + 80 ] 29 return output
30 31
32 -def validate_key(key):
33 if not isinstance(key, str): 34 raise CrystalError('chain requires a string label') 35 if len(key) != 1: 36 raise CrystalError('chain label should contain one letter')
37 38
39 -class Hetero(object):
40 """ 41 This class exists to support the PDB hetero codes. 42 43 Supports only the 3 alphameric code. 44 The annotation is available from http://alpha2.bmc.uu.se/hicup/ 45 """
46 - def __init__(self, data):
47 # Enforce string storage 48 if not isinstance(data, str): 49 raise CrystalError('Hetero data must be an alphameric string') 50 if data.isalnum() == 0: 51 raise CrystalError('Hetero data must be an alphameric string') 52 if len(data) > 3: 53 raise CrystalError('Hetero data may contain up to 3 characters') 54 if len(data) < 1: 55 raise CrystalError('Hetero data must not be empty') 56 57 self.data = data[:].lower()
58
59 - def __eq__(self, other):
60 return self.data == other.data
61
62 - def __ne__(self, other):
63 """Returns true iff self is not equal to other.""" 64 return not self.__eq__(other)
65
66 - def __repr__(self):
67 return "%s" % self.data
68
69 - def __str__(self):
70 return "%s" % self.data
71
72 - def __len__(self):
73 return len(self.data)
74 75
76 -class Chain(object):
77 """This class represents a sequence of Hetero elements.""" 78
79 - def __init__(self, residues = ''):
80 self.data = [] 81 if isinstance(residues, str): 82 residues = residues.replace('*', ' ') 83 residues = residues.strip() 84 elements = residues.split() 85 self.data = [Hetero(x) for x in elements] 86 elif isinstance(residues, list): 87 for element in residues: 88 if not isinstance(element, Hetero): 89 raise CrystalError('Text must be a string') 90 for residue in residues: 91 self.data.append(residue) 92 elif isinstance(residues, Chain): 93 for residue in residues: 94 self.data.append(residue) 95 self.validate()
96
97 - def validate(self):
98 data = self.data 99 for element in data: 100 self.validate_element(element)
101
102 - def validate_element(self, element):
103 if not isinstance(element, Hetero): 104 raise TypeError
105
106 - def __str__(self):
107 output = '' 108 for element in self.data: 109 output = output + '%s ' % element 110 output = output.strip() 111 output = wrap_line(output) 112 return output
113
114 - def __eq__(self, other):
115 if len(self.data) != len(other.data): 116 return 0 117 ok = reduce(lambda x, y: x and y, map(lambda x, y: x == y, self.data, other.data)) 118 return ok
119
120 - def __ne__(self, other):
121 """Returns true iff self is not equal to other.""" 122 return not self.__eq__(other)
123
124 - def __len__(self):
125 return len(self.data)
126
127 - def __getitem__(self, index):
128 if isinstance(index, int): 129 return self.data[index] 130 elif isinstance(index, slice): 131 return self.__class__(self.data[index]) 132 else: 133 raise TypeError
134
135 - def __setitem__(self, index, value):
136 if isinstance(index, int): 137 try: 138 self.validate_element(value) 139 except TypeError: 140 value = Hetero(value.lower()) 141 self.data[index] = value 142 elif isinstance(index, slice): 143 if isinstance(value, Chain): 144 self.data[index] = value.data 145 elif isinstance(value, type(self.data)): 146 self.data[index] = value 147 elif isinstance(value, basestring): 148 self.data[index] = Chain(value).data 149 else: 150 raise TypeError 151 else: 152 raise TypeError
153
154 - def __delitem__(self, index):
155 del self.data[index]
156
157 - def __contains__(self, item):
158 try: 159 self.validate_element(item) 160 except TypeError: 161 item = Hetero(item.lower()) 162 return item in self.data
163
164 - def append(self, item):
165 try: 166 self.validate_element(item) 167 except TypeError: 168 item = Hetero(item.lower()) 169 self.data.append(item)
170
171 - def insert(self, i, item):
172 try: 173 self.validate_element(item) 174 except TypeError: 175 item = Hetero(item.lower()) 176 self.data.insert(i, item)
177
178 - def remove(self, item):
179 item = Hetero(item.lower()) 180 self.data.remove(item)
181
182 - def count(self, item):
183 try: 184 self.validate_element(item) 185 except TypeError: 186 item = Hetero(item.lower()) 187 return self.data.count(item)
188
189 - def index(self, item):
190 try: 191 self.validate_element(item) 192 except TypeError: 193 item = Hetero(item.lower()) 194 return self.data.index(item)
195
196 - def __add__(self, other):
197 if isinstance(other, Chain): 198 return self.__class__(self.data + other.data) 199 elif isinstance(other, str): 200 return self.__class__(self.data + Chain(other).data) 201 else: 202 raise TypeError
203
204 - def __radd__(self, other):
205 if isinstance(other, Chain): 206 return self.__class__(other.data + self.data) 207 elif isinstance(other, str): 208 return self.__class__(Chain(other).data + self.data) 209 else: 210 raise TypeError
211
212 - def __iadd__(self, other):
213 if isinstance(other, Chain): 214 self.data += other.data 215 elif isinstance(other, str): 216 self.data += Chain(other).data 217 else: 218 raise TypeError 219 return self
220 221
222 -class Crystal(object):
223 """This class represents a dictionary of labeled chains from the 224 same structure""" 225
226 - def __init__(self, data = {}):
227 # Enforcestorage 228 if not isinstance(data, dict): 229 raise CrystalError('Crystal must be a dictionary') 230 self.data = data 231 self.fix()
232
233 - def fix(self):
234 data = self.data 235 for key in data: 236 element = data[key] 237 if isinstance(element, Chain): 238 pass 239 elif isinstance(element, str): 240 data[key] = Chain(element) 241 else: 242 raise TypeError
243
244 - def __repr__(self):
245 output = '' 246 for key in sorted(self.data): 247 output += '%s : %s\n' % (key, self.data[key]) 248 return output
249
250 - def __str__(self):
251 output = '' 252 for key in sorted(self.data): 253 output += '%s : %s\n' % (key, self.data[key]) 254 return output
255
256 - def tostring(self):
257 return self.data
258
259 - def __len__(self):
260 return len(self.data)
261
262 - def __getitem__(self, key):
263 return self.data[key]
264
265 - def __setitem__(self, key, item):
266 if isinstance(item, Chain): 267 self.data[key] = item 268 elif isinstance(item, str): 269 self.data[key] = Chain(item) 270 else: 271 raise TypeError
272
273 - def __delitem__(self, key):
274 del self.data[key]
275
276 - def clear(self):
277 self.data.clear()
278
279 - def copy(self):
280 return copy.copy(self)
281
282 - def keys(self):
283 return self.data.keys()
284
285 - def items(self):
286 return self.data.items()
287
288 - def values(self):
289 return self.data.values()
290
291 - def __contains__(self, value):
292 return value in self.data
293
294 - def has_key(self, key):
295 return key in self.data
296
297 - def get(self, key, failobj=None):
298 return self.data.get(key, failobj)
299
300 - def setdefault(self, key, failobj=None):
301 if key not in self.data: 302 self.data[key] = failobj 303 return self.data[key]
304
305 - def popitem(self):
306 return self.data.popitem()
307