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