Package Bio :: Package PDB :: Module StructureBuilder
[hide private]
[frames] | no frames]

Source Code for Module Bio.PDB.StructureBuilder

  1  # Copyright (C) 2002, Thomas Hamelryck (thamelry@binf.ku.dk) 
  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  """Consumer class that builds a Structure object. 
  7   
  8  This is used by the PDBParser and MMCIFparser classes. 
  9  """ 
 10   
 11  import warnings 
 12   
 13  # SMCRA hierarchy 
 14  from Bio.PDB.Structure import Structure 
 15  from Bio.PDB.Model import Model 
 16  from Bio.PDB.Chain import Chain 
 17  from Bio.PDB.Residue import Residue, DisorderedResidue 
 18  from Bio.PDB.Atom import Atom, DisorderedAtom 
 19   
 20  from Bio.PDB.PDBExceptions import PDBConstructionException 
 21  from Bio.PDB.PDBExceptions import PDBConstructionWarning 
 22   
 23   
24 -class StructureBuilder(object):
25 """ 26 Deals with contructing the Structure object. The StructureBuilder class is used 27 by the PDBParser classes to translate a file to a Structure object. 28 """
29 - def __init__(self):
30 self.line_counter=0 31 self.header={}
32
33 - def _is_completely_disordered(self, residue):
34 "Return 1 if all atoms in the residue have a non blank altloc." 35 atom_list=residue.get_unpacked_list() 36 for atom in atom_list: 37 altloc=atom.get_altloc() 38 if altloc==" ": 39 return 0 40 return 1
41 42 # Public methods called by the Parser classes 43
44 - def set_header(self, header):
45 self.header=header
46
47 - def set_line_counter(self, line_counter):
48 """ 49 The line counter keeps track of the line in the PDB file that 50 is being parsed. 51 52 Arguments: 53 o line_counter - int 54 """ 55 self.line_counter=line_counter
56
57 - def init_structure(self, structure_id):
58 """Initiate a new Structure object with given id. 59 60 Arguments: 61 o id - string 62 """ 63 self.structure=Structure(structure_id)
64
65 - def init_model(self, model_id, serial_num = None):
66 """Initiate a new Model object with given id. 67 68 Arguments: 69 o id - int 70 o serial_num - int 71 """ 72 self.model=Model(model_id, serial_num) 73 self.structure.add(self.model)
74
75 - def init_chain(self, chain_id):
76 """Initiate a new Chain object with given id. 77 78 Arguments: 79 o chain_id - string 80 """ 81 if self.model.has_id(chain_id): 82 self.chain=self.model[chain_id] 83 warnings.warn("WARNING: Chain %s is discontinuous at line %i." 84 % (chain_id, self.line_counter), 85 PDBConstructionWarning) 86 else: 87 self.chain=Chain(chain_id) 88 self.model.add(self.chain)
89
90 - def init_seg(self, segid):
91 """Flag a change in segid. 92 93 Arguments: 94 o segid - string 95 """ 96 self.segid=segid
97
98 - def init_residue(self, resname, field, resseq, icode):
99 """ 100 Initiate a new Residue object. 101 102 Arguments: 103 o resname - string, e.g. "ASN" 104 o field - hetero flag, "W" for waters, "H" for 105 hetero residues, otherwise blank. 106 o resseq - int, sequence identifier 107 o icode - string, insertion code 108 """ 109 if field!=" ": 110 if field=="H": 111 # The hetero field consists of H_ + the residue name (e.g. H_FUC) 112 field="H_"+resname 113 res_id=(field, resseq, icode) 114 if field==" ": 115 if self.chain.has_id(res_id): 116 # There already is a residue with the id (field, resseq, icode). 117 # This only makes sense in the case of a point mutation. 118 warnings.warn("WARNING: Residue ('%s', %i, '%s') " 119 "redefined at line %i." 120 % (field, resseq, icode, self.line_counter), 121 PDBConstructionWarning) 122 duplicate_residue=self.chain[res_id] 123 if duplicate_residue.is_disordered()==2: 124 # The residue in the chain is a DisorderedResidue object. 125 # So just add the last Residue object. 126 if duplicate_residue.disordered_has_id(resname): 127 # The residue was already made 128 self.residue=duplicate_residue 129 duplicate_residue.disordered_select(resname) 130 else: 131 # Make a new residue and add it to the already 132 # present DisorderedResidue 133 new_residue=Residue(res_id, resname, self.segid) 134 duplicate_residue.disordered_add(new_residue) 135 self.residue=duplicate_residue 136 return 137 else: 138 # Make a new DisorderedResidue object and put all 139 # the Residue objects with the id (field, resseq, icode) in it. 140 # These residues each should have non-blank altlocs for all their atoms. 141 # If not, the PDB file probably contains an error. 142 if not self._is_completely_disordered(duplicate_residue): 143 # if this exception is ignored, a residue will be missing 144 self.residue=None 145 raise PDBConstructionException( 146 "Blank altlocs in duplicate residue %s ('%s', %i, '%s')" 147 % (resname, field, resseq, icode)) 148 self.chain.detach_child(res_id) 149 new_residue=Residue(res_id, resname, self.segid) 150 disordered_residue=DisorderedResidue(res_id) 151 self.chain.add(disordered_residue) 152 disordered_residue.disordered_add(duplicate_residue) 153 disordered_residue.disordered_add(new_residue) 154 self.residue=disordered_residue 155 return 156 residue=Residue(res_id, resname, self.segid) 157 self.chain.add(residue) 158 self.residue=residue
159
160 - def init_atom(self, name, coord, b_factor, occupancy, altloc, fullname, 161 serial_number=None, element=None):
162 """ 163 Initiate a new Atom object. 164 165 Arguments: 166 o name - string, atom name, e.g. CA, spaces should be stripped 167 o coord - Numeric array (Float0, size 3), atomic coordinates 168 o b_factor - float, B factor 169 o occupancy - float 170 o altloc - string, alternative location specifier 171 o fullname - string, atom name including spaces, e.g. " CA " 172 o element - string, upper case, e.g. "HG" for mercury 173 """ 174 residue=self.residue 175 # if residue is None, an exception was generated during 176 # the construction of the residue 177 if residue is None: 178 return 179 # First check if this atom is already present in the residue. 180 # If it is, it might be due to the fact that the two atoms have atom 181 # names that differ only in spaces (e.g. "CA.." and ".CA.", 182 # where the dots are spaces). If that is so, use all spaces 183 # in the atom name of the current atom. 184 if residue.has_id(name): 185 duplicate_atom=residue[name] 186 # atom name with spaces of duplicate atom 187 duplicate_fullname=duplicate_atom.get_fullname() 188 if duplicate_fullname!=fullname: 189 # name of current atom now includes spaces 190 name=fullname 191 warnings.warn("Atom names %r and %r differ " 192 "only in spaces at line %i." 193 % (duplicate_fullname, fullname, 194 self.line_counter), 195 PDBConstructionWarning) 196 atom=self.atom=Atom(name, coord, b_factor, occupancy, altloc, 197 fullname, serial_number, element) 198 if altloc!=" ": 199 # The atom is disordered 200 if residue.has_id(name): 201 # Residue already contains this atom 202 duplicate_atom=residue[name] 203 if duplicate_atom.is_disordered()==2: 204 duplicate_atom.disordered_add(atom) 205 else: 206 # This is an error in the PDB file: 207 # a disordered atom is found with a blank altloc 208 # Detach the duplicate atom, and put it in a 209 # DisorderedAtom object together with the current 210 # atom. 211 residue.detach_child(name) 212 disordered_atom=DisorderedAtom(name) 213 residue.add(disordered_atom) 214 disordered_atom.disordered_add(atom) 215 disordered_atom.disordered_add(duplicate_atom) 216 residue.flag_disordered() 217 warnings.warn("WARNING: disordered atom found " 218 "with blank altloc before line %i.\n" 219 % self.line_counter, 220 PDBConstructionWarning) 221 else: 222 # The residue does not contain this disordered atom 223 # so we create a new one. 224 disordered_atom=DisorderedAtom(name) 225 residue.add(disordered_atom) 226 # Add the real atom to the disordered atom, and the 227 # disordered atom to the residue 228 disordered_atom.disordered_add(atom) 229 residue.flag_disordered() 230 else: 231 # The atom is not disordered 232 residue.add(atom)
233
234 - def set_anisou(self, anisou_array):
235 "Set anisotropic B factor of current Atom." 236 self.atom.set_anisou(anisou_array)
237
238 - def set_siguij(self, siguij_array):
239 "Set standard deviation of anisotropic B factor of current Atom." 240 self.atom.set_siguij(siguij_array)
241
242 - def set_sigatm(self, sigatm_array):
243 "Set standard deviation of atom position of current Atom." 244 self.atom.set_sigatm(sigatm_array)
245
246 - def get_structure(self):
247 "Return the structure." 248 # first sort everything 249 # self.structure.sort() 250 # Add the header dict 251 self.structure.header=self.header 252 return self.structure
253
254 - def set_symmetry(self, spacegroup, cell):
255 pass
256