1
2
3
4
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
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 \
21 PDBConstructionException, PDBConstructionWarning
22
23
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 """
30 self.line_counter=0
31 self.header={}
32
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
43
46
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
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
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
91 """Flag a change in segid.
92
93 Arguments:
94 o segid - string
95 """
96 self.segid=segid
97
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
112 field="H_"+resname
113 res_id=(field, resseq, icode)
114 if field==" ":
115 if self.chain.has_id(res_id):
116
117
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
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,
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
176
177 if residue is None:
178 return
179
180
181
182
183
184 if residue.has_id(name):
185 duplicate_atom=residue[name]
186
187 duplicate_fullname=duplicate_atom.get_fullname()
188 if duplicate_fullname!=fullname:
189
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
200 if residue.has_id(name):
201
202 duplicate_atom=residue[name]
203 if duplicate_atom.is_disordered()==2:
204 duplicate_atom.disordered_add(atom)
205 else:
206
207
208
209
210
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
223
224 disordered_atom=DisorderedAtom(name)
225 residue.add(disordered_atom)
226
227
228 disordered_atom.disordered_add(atom)
229 residue.flag_disordered()
230 else:
231
232 residue.add(atom)
233
235 "Set anisotropic B factor of current Atom."
236 self.atom.set_anisou(anisou_array)
237
239 "Set standard deviation of anisotropic B factor of current Atom."
240 self.atom.set_siguij(siguij_array)
241
243 "Set standard deviation of atom position of current Atom."
244 self.atom.set_sigatm(sigatm_array)
245
253
256