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