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

Source Code for Module Bio.PDB.PDBIO'

  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  """Output of PDB files.""" 
  7   
  8  from Bio._py3k import basestring 
  9   
 10  from Bio.PDB.StructureBuilder import StructureBuilder # To allow saving of chains, residues, etc.. 
 11  from Bio.Data.IUPACData import atom_weights # Allowed Elements 
 12   
 13  __docformat__ = "restructuredtext en" 
 14   
 15  _ATOM_FORMAT_STRING="%s%5i %-4s%c%3s %c%4i%c   %8.3f%8.3f%8.3f%s%6.2f      %4s%2s%2s\n" 
 16   
 17   
18 -class Select(object):
19 """Select everything fo PDB output (for use as a bas class). 20 21 Default selection (everything) during writing - can be used as base class 22 to implement selective output. This selects which entities will be written out. 23 """ 24
25 - def __repr__(self):
26 return "<Select all>"
27
28 - def accept_model(self, model):
29 """Overload this to reject models for output.""" 30 return 1
31
32 - def accept_chain(self, chain):
33 """Overload this to reject chains for output.""" 34 return 1
35
36 - def accept_residue(self, residue):
37 """Overload this to reject residues for output.""" 38 return 1
39
40 - def accept_atom(self, atom):
41 """Overload this to reject atoms for output.""" 42 return 1
43 44
45 -class PDBIO(object):
46 """Write a Structure object (or a subset of a Structure object) as a PDB file. 47 48 Example: 49 50 >>> p=PDBParser() 51 >>> s=p.get_structure("1fat", "1fat.pdb") 52 >>> io=PDBIO() 53 >>> io.set_structure(s) 54 >>> io.save("out.pdb") 55 """
56 - def __init__(self, use_model_flag=0):
57 """Creat the PDBIO object. 58 59 @param use_model_flag: if 1, force use of the MODEL record in output. 60 @type use_model_flag: int 61 """ 62 self.use_model_flag=use_model_flag
63 64 # private mathods 65
66 - def _get_atom_line(self, atom, hetfield, segid, atom_number, resname, 67 resseq, icode, chain_id, charge=" "):
68 """Returns an ATOM PDB string (PRIVATE).""" 69 if hetfield!=" ": 70 record_type="HETATM" 71 else: 72 record_type="ATOM " 73 if atom.element: 74 element = atom.element.strip().upper() 75 if element.capitalize() not in atom_weights: 76 raise ValueError("Unrecognised element %r" % atom.element) 77 element = element.rjust(2) 78 else: 79 element = " " 80 name=atom.get_fullname() 81 altloc=atom.get_altloc() 82 x, y, z=atom.get_coord() 83 bfactor=atom.get_bfactor() 84 occupancy=atom.get_occupancy() 85 try: 86 occupancy_str = "%6.2f" % occupancy 87 except TypeError: 88 if occupancy is None: 89 occupancy_str = " " * 6 90 import warnings 91 from Bio import BiopythonWarning 92 warnings.warn("Missing occupancy in atom %s written as blank" % 93 repr(atom.get_full_id()), BiopythonWarning) 94 else: 95 raise TypeError("Invalid occupancy %r in atom %r" 96 % (occupancy, atom.get_full_id())) 97 pass 98 args=(record_type, atom_number, name, altloc, resname, chain_id, 99 resseq, icode, x, y, z, occupancy_str, bfactor, segid, 100 element, charge) 101 return _ATOM_FORMAT_STRING % args
102 103 # Public methods 104
105 - def set_structure(self, pdb_object):
106 # Check what the user is providing and build a structure appropriately 107 if pdb_object.level == "S": 108 structure = pdb_object 109 else: 110 sb = StructureBuilder() 111 sb.init_structure('pdb') 112 sb.init_seg(' ') 113 # Build parts as necessary 114 if pdb_object.level == "M": 115 sb.structure.add(pdb_object) 116 self.structure = sb.structure 117 else: 118 sb.init_model(0) 119 if pdb_object.level == "C": 120 sb.structure[0].add(pdb_object) 121 else: 122 sb.init_chain('A') 123 if pdb_object.level == "R": 124 try: 125 parent_id = pdb_object.parent.id 126 sb.structure[0]['A'].id = parent_id 127 except Exception: 128 pass 129 sb.structure[0]['A'].add(pdb_object) 130 else: 131 # Atom 132 sb.init_residue('DUM', ' ', 1, ' ') 133 try: 134 parent_id = pdb_object.parent.parent.id 135 sb.structure[0]['A'].id = parent_id 136 except Exception: 137 pass 138 sb.structure[0]['A'].child_list[0].add(pdb_object) 139 140 # Return structure 141 structure = sb.structure 142 self.structure=structure
143
144 - def save(self, file, select=Select(), write_end=True):
145 """ 146 @param file: output file 147 @type file: string or filehandle 148 149 @param select: selects which entities will be written. 150 @type select: object 151 152 Typically select is a subclass of L{Select}, it should 153 have the following methods: 154 155 - accept_model(model) 156 - accept_chain(chain) 157 - accept_residue(residue) 158 - accept_atom(atom) 159 160 These methods should return 1 if the entity is to be 161 written out, 0 otherwise. 162 163 Typically select is a subclass of L{Select}. 164 """ 165 get_atom_line=self._get_atom_line 166 if isinstance(file, basestring): 167 fp=open(file, "w") 168 close_file=1 169 else: 170 # filehandle, I hope :-) 171 fp=file 172 close_file=0 173 # multiple models? 174 if len(self.structure)>1 or self.use_model_flag: 175 model_flag=1 176 else: 177 model_flag=0 178 for model in self.structure.get_list(): 179 if not select.accept_model(model): 180 continue 181 # necessary for ENDMDL 182 # do not write ENDMDL if no residues were written 183 # for this model 184 model_residues_written=0 185 atom_number=1 186 if model_flag: 187 fp.write("MODEL %s\n" % model.serial_num) 188 for chain in model.get_list(): 189 if not select.accept_chain(chain): 190 continue 191 chain_id=chain.get_id() 192 # necessary for TER 193 # do not write TER if no residues were written 194 # for this chain 195 chain_residues_written=0 196 for residue in chain.get_unpacked_list(): 197 if not select.accept_residue(residue): 198 continue 199 hetfield, resseq, icode=residue.get_id() 200 resname=residue.get_resname() 201 segid=residue.get_segid() 202 for atom in residue.get_unpacked_list(): 203 if select.accept_atom(atom): 204 chain_residues_written=1 205 model_residues_written=1 206 s=get_atom_line(atom, hetfield, segid, atom_number, resname, 207 resseq, icode, chain_id) 208 fp.write(s) 209 atom_number=atom_number+1 210 if chain_residues_written: 211 fp.write("TER\n") 212 if model_flag and model_residues_written: 213 fp.write("ENDMDL\n") 214 if write_end: 215 fp.write('END\n') 216 if close_file: 217 fp.close()
218 219 if __name__=="__main__": 220 221 from Bio.PDB.PDBParser import PDBParser 222 223 import sys 224 225 p=PDBParser(PERMISSIVE=True) 226 227 s=p.get_structure("test", sys.argv[1]) 228 229 io=PDBIO() 230 io.set_structure(s) 231 io.save("out1.pdb") 232 233 with open("out2.pdb", "w") as fp: 234 s1=p.get_structure("test1", sys.argv[1]) 235 s2=p.get_structure("test2", sys.argv[2]) 236 io=PDBIO(1) 237 io.set_structure(s1) 238 io.save(fp) 239 io.set_structure(s2) 240 io.save(fp, write_end=1) 241