1
2
3
4
5
6 import sys
7
8
9 __doc__="""
10 Consumer class that builds a Structure object. This is used by
11 the PDBParser and MMCIFparser classes.
12 """
13
14
15
16
17 from Structure import Structure
18 from Model import Model
19 from Chain import Chain
20 from Residue import Residue, DisorderedResidue
21 from Atom import Atom, DisorderedAtom
22
23 from PDBExceptions import PDBConstructionException
24
25
27 """
28 Deals with contructing the Structure object. The StructureBuilder class is used
29 by the PDBParser classes to translate a file to a Structure object.
30 """
32 self.line_counter=0
33 self.header={}
34
36 "Return 1 if all atoms in the residue have a non blanc altloc."
37 atom_list=residue.get_unpacked_list()
38 for atom in atom_list:
39 altloc=atom.get_altloc()
40 if altloc==" ":
41 return 0
42 return 1
43
44
45
48
50 """
51 The line counter keeps track of the line in the PDB file that
52 is being parsed.
53
54 Arguments:
55 o line_counter - int
56 """
57 self.line_counter=line_counter
58
60 """Initiate a new Structure object with given id.
61
62 Arguments:
63 o id - string
64 """
65 self.structure=Structure(structure_id)
66
68 """Initiate a new Model object with given id.
69
70 Arguments:
71 o id - int
72 """
73 self.model=Model(model_id)
74 self.structure.add(self.model)
75
77 """Initiate a new Chain object with given id.
78
79 Arguments:
80 o chain_id - string
81 """
82 if self.model.has_id(chain_id):
83 self.chain=self.model[chain_id]
84 if __debug__:
85 sys.stderr.write("WARNING: Chain %s is discontinuous at line %i.\n"
86 % (chain_id, self.line_counter))
87 else:
88 self.chain=Chain(chain_id)
89 self.model.add(self.chain)
90
92 """Flag a change in segid.
93
94 Arguments:
95 o segid - string
96 """
97 self.segid=segid
98
100 """
101 Initiate a new Residue object.
102
103 Arguments:
104 o resname - string, e.g. "ASN"
105 o field - hetero flag, "W" for waters, "H" for
106 hetero residues, otherwise blanc.
107 o resseq - int, sequence identifier
108 o icode - string, insertion code
109 """
110 if field!=" ":
111 if field=="H":
112
113 field="H_"+resname
114 res_id=(field, resseq, icode)
115 if field==" ":
116 if self.chain.has_id(res_id):
117
118
119 if __debug__:
120 sys.stderr.write("WARNING: Residue ('%s', %i, '%s') redefined at line %i.\n"
121 % (field, resseq, icode, self.line_counter))
122 duplicate_residue=self.chain[res_id]
123 if duplicate_residue.is_disordered()==2:
124
125
126 if duplicate_residue.disordered_has_id(resname):
127
128 self.residue=duplicate_residue
129 duplicate_residue.disordered_select(resname)
130 else:
131
132
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
139
140
141
142 if not self._is_completely_disordered(duplicate_residue):
143
144 self.residue=None
145 raise PDBConstructionException, "Blank altlocs in duplicate residue %s ('%s', %i, '%s')" % (resname, field, resseq, icode)
146 self.chain.detach_child(res_id)
147 new_residue=Residue(res_id, resname, self.segid)
148 disordered_residue=DisorderedResidue(res_id)
149 self.chain.add(disordered_residue)
150 disordered_residue.disordered_add(duplicate_residue)
151 disordered_residue.disordered_add(new_residue)
152 self.residue=disordered_residue
153 return
154 residue=Residue(res_id, resname, self.segid)
155 self.chain.add(residue)
156 self.residue=residue
157
158 - def init_atom(self, name, coord, b_factor, occupancy, altloc, fullname, serial_number=None):
159 """
160 Initiate a new Atom object.
161
162 Arguments:
163 o name - string, atom name, e.g. CA, spaces should be stripped
164 o coord - Numeric array (Float0, size 3), atomic coordinates
165 o b_factor - float, B factor
166 o occupancy - float
167 o altloc - string, alternative location specifier
168 o fullname - string, atom name including spaces, e.g. " CA "
169 """
170 residue=self.residue
171
172
173 if residue is None:
174 return
175
176
177
178
179
180 if residue.has_id(name):
181 duplicate_atom=residue[name]
182
183 duplicate_fullname=duplicate_atom.get_fullname()
184 if duplicate_fullname!=fullname:
185
186 name=fullname
187 if __debug__:
188 sys.stderr.write("WARNING: atom names %s and %s differ only in spaces at line %i.\n"
189 % (duplicate_fullname, fullname, self.line_counter))
190 atom=self.atom=Atom(name, coord, b_factor, occupancy, altloc, fullname, serial_number)
191 if altloc!=" ":
192
193 if residue.has_id(name):
194
195 duplicate_atom=residue[name]
196 if duplicate_atom.is_disordered()==2:
197 duplicate_atom.disordered_add(atom)
198 else:
199
200
201
202
203
204 residue.detach_child(name)
205 disordered_atom=DisorderedAtom(name)
206 residue.add(disordered_atom)
207 disordered_atom.disordered_add(atom)
208 disordered_atom.disordered_add(duplicate_atom)
209 residue.flag_disordered()
210 if __debug__:
211 sys.stderr.write("WARNING: disordered atom found with blanc altloc before line %i.\n"
212 % self.line_counter)
213 else:
214
215
216 disordered_atom=DisorderedAtom(name)
217 residue.add(disordered_atom)
218
219
220 disordered_atom.disordered_add(atom)
221 residue.flag_disordered()
222 else:
223
224 residue.add(atom)
225
227 "Set anisotropic B factor of current Atom."
228 self.atom.set_anisou(anisou_array)
229
231 "Set standard deviation of anisotropic B factor of current Atom."
232 self.atom.set_siguij(siguij_array)
233
235 "Set standard deviation of atom position of current Atom."
236 self.atom.set_sigatm(sigatm_array)
237
245
248