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 blank 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 blank.
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(\
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, serial_number=None):
161 """
162 Initiate a new Atom object.
163
164 Arguments:
165 o name - string, atom name, e.g. CA, spaces should be stripped
166 o coord - Numeric array (Float0, size 3), atomic coordinates
167 o b_factor - float, B factor
168 o occupancy - float
169 o altloc - string, alternative location specifier
170 o fullname - string, atom name including spaces, e.g. " CA "
171 """
172 residue=self.residue
173
174
175 if residue is None:
176 return
177
178
179
180
181
182 if residue.has_id(name):
183 duplicate_atom=residue[name]
184
185 duplicate_fullname=duplicate_atom.get_fullname()
186 if duplicate_fullname!=fullname:
187
188 name=fullname
189 if __debug__:
190 sys.stderr.write("WARNING: atom names %s and %s differ only in spaces at line %i.\n"
191 % (duplicate_fullname, fullname, self.line_counter))
192 atom=self.atom=Atom(name, coord, b_factor, occupancy, altloc, fullname, serial_number)
193 if altloc!=" ":
194
195 if residue.has_id(name):
196
197 duplicate_atom=residue[name]
198 if duplicate_atom.is_disordered()==2:
199 duplicate_atom.disordered_add(atom)
200 else:
201
202
203
204
205
206 residue.detach_child(name)
207 disordered_atom=DisorderedAtom(name)
208 residue.add(disordered_atom)
209 disordered_atom.disordered_add(atom)
210 disordered_atom.disordered_add(duplicate_atom)
211 residue.flag_disordered()
212 if __debug__:
213 sys.stderr.write("WARNING: disordered atom found with blank altloc before line %i.\n"
214 % self.line_counter)
215 else:
216
217
218 disordered_atom=DisorderedAtom(name)
219 residue.add(disordered_atom)
220
221
222 disordered_atom.disordered_add(atom)
223 residue.flag_disordered()
224 else:
225
226 residue.add(atom)
227
229 "Set anisotropic B factor of current Atom."
230 self.atom.set_anisou(anisou_array)
231
233 "Set standard deviation of anisotropic B factor of current Atom."
234 self.atom.set_siguij(siguij_array)
235
237 "Set standard deviation of atom position of current Atom."
238 self.atom.set_sigatm(sigatm_array)
239
247
250