Back to index

python-biopython  1.60
__init__.py
Go to the documentation of this file.
00001 # Copyright 2002 by Katharine Lindner.  All rights reserved.
00002 # This code is part of the Biopython distribution and governed by its
00003 # license.  Please see the LICENSE file that should have been included
00004 # as part of this package.
00005 
00006 """
00007 Module to represent the NDB Atlas structure (a minimal subset of PDB format).
00008 
00009 Hetero, Crystal and Chain exist to represent the NDB Atlas structure.  Atlas
00010 is a minimal subset of the PDB format.  Heteo supports a 3 alphameric code.
00011 The NDB web interface is located at http://ndbserver.rutgers.edu/NDB/index.html
00012 """
00013 
00014 import copy
00015 
00016 class CrystalError(Exception):
00017     pass
00018 
00019 def wrap_line(line):
00020     output = ''
00021     for i in range(0, len(line), 80):
00022         output = output + '%s\n' % line[ i: i + 80 ]
00023     return output
00024 
00025 def validate_key(key):
00026     if type(key) != type(''):
00027         raise CrystalError('chain requires a string label')
00028     if len(key) != 1:
00029         raise CrystalError('chain label should contain one letter')
00030 
00031 class Hetero(object):
00032     """
00033     This class exists to support the PDB hetero codes.
00034 
00035     Supports only the 3 alphameric code.
00036     The annotation is available from http://alpha2.bmc.uu.se/hicup/
00037     """
00038     def __init__(self, data):
00039         # Enforce string storage
00040         if type(data) != type(""):
00041             raise CrystalError('Hetero data must be an alphameric string')
00042         if data.isalnum() == 0:
00043             raise CrystalError('Hetero data must be an alphameric string')
00044         if len(data) > 3:
00045             raise CrystalError('Hetero data may contain up to 3 characters')
00046         if len(data) < 1:
00047             raise CrystalError('Hetero data must not be empty')
00048 
00049         self.data = data[:].lower()
00050 
00051     def __eq__(self, other):
00052         return self.data == other.data
00053 
00054     def __ne__(self, other):
00055         """Returns true iff self is not equal to other."""
00056         return not self.__eq__(other)
00057 
00058     def __repr__(self):
00059         return "%s" % self.data
00060 
00061     def __str__(self):
00062         return "%s" % self.data
00063 
00064     def __len__(self): return len(self.data)
00065 
00066 class Chain(object):
00067     def __init__(self, residues = ''):
00068         self.data = []
00069         if type(residues) == type(''):
00070             residues = residues.replace('*', ' ')
00071             residues = residues.strip()
00072             elements = residues.split()
00073             self.data = map(Hetero, elements)
00074         elif type(residues) == type([]):
00075             for element in residues:
00076                 if not isinstance(element, Hetero):
00077                     raise CrystalError('Text must be a string')
00078             for residue in residues:
00079                 self.data.append(residue)
00080         elif isinstance(residues, Chain):
00081             for residue in residues:
00082                 self.data.append(residue)
00083         self.validate()
00084 
00085     def validate(self):
00086         data = self.data
00087         for element in data:
00088             self.validate_element(element)
00089 
00090     def validate_element(self, element):
00091         if not isinstance(element, Hetero):
00092             raise TypeError
00093 
00094     def __str__(self):
00095         output = ''
00096         i = 0
00097         for element in self.data:
00098             output = output + '%s ' % element
00099         output = output.strip()
00100         output = wrap_line(output)
00101         return output
00102 
00103 
00104     def __eq__(self, other):
00105         if len(self.data) != len(other.data):
00106             return 0
00107         ok = reduce(lambda x, y: x and y, map(lambda x, y: x == y, self.data, other.data))
00108         return ok
00109 
00110     def __ne__(self, other):
00111         """Returns true iff self is not equal to other."""
00112         return not self.__eq__(other)
00113 
00114     def __len__(self): return len(self.data)
00115 
00116     def __getitem__(self, index):
00117         if isinstance(index, int):
00118             return self.data[index]
00119         elif isinstance(index, slice):
00120             return self.__class__(self.data[index])
00121         else:
00122             raise TypeError
00123             
00124     def __setitem__(self, index, value):
00125         if isinstance(index, int):
00126             try:
00127                 self.validate_element(value)
00128             except TypeError:
00129                 value = Hetero(value.lower())
00130             self.data[index] = value
00131         elif isinstance(index, slice):
00132             if isinstance(value, Chain):
00133                 self.data[index] = value.data
00134             elif isinstance(value, type(self.data)):
00135                 self.data[index] = value
00136             elif isinstance(value, basestring):
00137                 self.data[index] = Chain(value).data
00138             else:
00139                 raise TypeError
00140         else:
00141             raise TypeError
00142     
00143     def __delitem__(self, index):
00144         del self.data[index]
00145 
00146     def __contains__(self, item):
00147         try:
00148             self.validate_element(item)
00149         except TypeError:
00150             item = Hetero(item.lower())
00151         return item in self.data
00152 
00153     def append(self, item):
00154         try:
00155             self.validate_element(item)
00156         except TypeError:
00157             item = Hetero(item.lower())
00158         self.data.append(item)
00159 
00160     def insert(self, i, item):
00161         try:
00162             self.validate_element(item)
00163         except TypeError:
00164             item = Hetero(item.lower())
00165         self.data.insert(i, item)
00166 
00167     def remove(self, item):
00168         item = Hetero(item.lower())
00169         self.data.remove(item)
00170 
00171     def count(self, item):
00172         try:
00173             self.validate_element(item)
00174         except TypeError:
00175             item = Hetero(item.lower())
00176         return self.data.count(item)
00177 
00178     def index(self, item):
00179         try:
00180             self.validate_element(item)
00181         except TypeError:
00182             item = Hetero(item.lower())
00183         return self.data.index(item)
00184 
00185     def __add__(self, other):
00186         if isinstance(other, Chain):
00187             return self.__class__(self.data + other.data)
00188         elif type(other) == type(''):
00189             return self.__class__(self.data + Chain(other).data)
00190         else:
00191             raise TypeError
00192 
00193     def __radd__(self, other):
00194         if isinstance(other, Chain):
00195             return self.__class__(other.data + self.data)
00196         elif type(other) == type(''):
00197             return self.__class__(Chain(other).data + self.data)
00198         else:
00199             raise TypeError
00200 
00201     def __iadd__(self, other):
00202         if isinstance(other, Chain):
00203             self.data += other.data
00204         elif type(other) == type(''):
00205             self.data += Chain(other).data
00206         else:
00207             raise TypeError
00208         return self
00209 
00210 class Crystal(object):
00211     def __init__(self, data = {}):
00212         # Enforcestorage
00213         if type(data) != type({}):
00214             raise CrystalError('Crystal must be a dictionary')
00215         self.data = data
00216         self.fix()
00217 
00218     def fix(self):
00219         data = self.data
00220         for key in data:
00221             element = data[key]
00222             if isinstance(element, Chain):
00223                 pass
00224             elif type(element) == type(''):
00225                 data[key] = Chain(element)
00226             else:
00227                 raise TypeError
00228 
00229     def __repr__(self):
00230         output = ''
00231         keys = self.data.keys()
00232         keys.sort()
00233         for key in keys:
00234             output = output +  '%s : %s\n' % (key, self.data[ key ])
00235         return output
00236 
00237     def __str__(self):
00238         output = ''
00239         keys = self.data.keys()
00240         keys.sort()
00241         for key in keys:
00242             output = output +  '%s : %s\n' % (key, self.data[ key ])
00243         return output
00244 
00245     def tostring(self):
00246         return self.data
00247 
00248     def __len__(self): return len(self.data)
00249     def __getitem__(self, key): return self.data[key]
00250     def __setitem__(self, key, item):
00251         if isinstance(item, Chain):
00252             self.data[key] = item
00253         elif type(item) == type(''):
00254             self.data[ key ] = Chain(item)
00255         else:
00256             raise TypeError
00257 
00258     def __delitem__(self, key): del self.data[key]
00259     def clear(self): self.data.clear()
00260     def copy(self):
00261         return copy.copy(self)
00262     def keys(self): return self.data.keys()
00263     def items(self): return self.data.items()
00264     def values(self): return self.data.values()
00265     def __contains__(self, value): return value in self.data
00266     def has_key(self, key): return key in self.data
00267     def get(self, key, failobj=None):
00268         return self.data.get(key, failobj)
00269     def setdefault(self, key, failobj=None):
00270         if key not in self.data:
00271             self.data[key] = failobj
00272         return self.data[key]
00273     def popitem(self):
00274         return self.data.popitem()