1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """The structure user function definitions."""
25
26
27 from numpy import eye
28 from os import sep
29 import wx
30
31
32 import generic_fns.structure.geometric
33 import generic_fns.structure.main
34 from graphics import WIZARD_IMAGE_PATH
35 from user_functions.data import Uf_info; uf_info = Uf_info()
36 from user_functions.data import Uf_tables; uf_tables = Uf_tables()
37 from user_functions.objects import Desc_container
38
39
40
41 uf_class = uf_info.add_class('structure')
42 uf_class.title = "Class containing the structural related functions."
43 uf_class.menu_text = "&structure"
44 uf_class.gui_icon = "relax.structure"
45
46
47
48 uf = uf_info.add_uf('structure.add_atom')
49 uf.title = "Add an atom."
50 uf.title_short = "Atom creation."
51 uf.add_keyarg(
52 name = "atom_name",
53 py_type = "str",
54 desc_short = "atom name",
55 desc = "The atom name."
56 )
57 uf.add_keyarg(
58 name = "res_name",
59 py_type = "str",
60 desc_short = "residue name",
61 desc = "The residue name."
62 )
63 uf.add_keyarg(
64 name = "res_num",
65 py_type = "int",
66 min = -10000,
67 max = 10000,
68 desc_short = "residue number",
69 desc = "The residue number."
70 )
71 uf.add_keyarg(
72 name = "pos",
73 default = [None, None, None],
74 py_type = "float_array",
75 dim = 3,
76 desc_short = "atomic position",
77 desc = "The atomic coordinates."
78 )
79 uf.add_keyarg(
80 name = "element",
81 py_type = "str",
82 desc_short = "element",
83 desc = "The element name.",
84 wiz_element_type = "combo",
85 wiz_combo_choices = ["N", "C", "H", "O", "P"],
86 can_be_none = True
87 )
88 uf.add_keyarg(
89 name = "atom_num",
90 py_type = "int",
91 desc_short = "atom number",
92 desc = "The optional atom number.",
93 can_be_none = True
94 )
95 uf.add_keyarg(
96 name = "chain_id",
97 py_type = "str",
98 desc_short = "optional chain ID",
99 desc = "The optional chain ID string.",
100 can_be_none = True
101 )
102 uf.add_keyarg(
103 name = "segment_id",
104 py_type = "str",
105 desc_short = "optional segment ID",
106 desc = "The optional segment ID string.",
107 can_be_none = True
108 )
109 uf.add_keyarg(
110 name = "pdb_record",
111 py_type = "str",
112 desc_short = "optional PDB record name",
113 desc = "The optional PDB record name, e.g. 'ATOM' or 'HETATM'.",
114 can_be_none = True
115 )
116
117 uf.desc.append(Desc_container())
118 uf.desc[-1].add_paragraph("This allows atoms to be added to the internal structural object.")
119 uf.backend = generic_fns.structure.main.add_atom
120 uf.menu_text = "&add_atom"
121 uf.gui_icon = "oxygen.actions.list-add-relax-blue"
122 uf.wizard_size = (800, 600)
123 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
124
125
126
127 uf = uf_info.add_uf('structure.connect_atom')
128 uf.title = "Connect two atoms."
129 uf.title_short = "Atom connection."
130 uf.add_keyarg(
131 name = "index1",
132 py_type = "int",
133 max = 10000,
134 desc_short = "index 1",
135 desc = "The global index of the first atom."
136 )
137 uf.add_keyarg(
138 name = "index2",
139 py_type = "int",
140 max = 10000,
141 desc_short = "index 2",
142 desc = "The global index of the second atom."
143 )
144
145 uf.desc.append(Desc_container())
146 uf.desc[-1].add_paragraph("This allows atoms to be connected in the internal structural object. The global index is normally equal to the PDB atom number minus 1.")
147 uf.backend = generic_fns.structure.main.connect_atom
148 uf.menu_text = "co&nnect_atom"
149 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
150
151
152
153 uf = uf_info.add_uf('structure.create_diff_tensor_pdb')
154 uf.title = "Create a PDB file to represent the diffusion tensor."
155 uf.title_short = "Diffusion tensor PDB file creation."
156 uf.add_keyarg(
157 name = "scale",
158 default = 1.8e-6,
159 py_type = "num",
160 desc_short = "scaling factor",
161 desc = "Value for scaling the diffusion rates."
162 )
163 uf.add_keyarg(
164 name = "file",
165 default = "tensor.pdb",
166 py_type = "str",
167 arg_type = "file sel",
168 desc_short = "file name",
169 desc = "The name of the PDB file.",
170 wiz_filesel_wildcard = "PDB files (*.pdb)|*.pdb;*.PDB",
171 wiz_filesel_style = wx.FD_SAVE
172 )
173 uf.add_keyarg(
174 name = "dir",
175 py_type = "str",
176 arg_type = "dir",
177 desc_short = "directory name",
178 desc = "The directory to place the file into.",
179 can_be_none = True
180 )
181 uf.add_keyarg(
182 name = "force",
183 default = False,
184 py_type = "bool",
185 desc_short = "force flag",
186 desc = "A flag which, if set to True, will overwrite the any pre-existing file."
187 )
188
189 uf.desc.append(Desc_container())
190 uf.desc[-1].add_paragraph("This creates a PDB file containing an artificial geometric structure to represent the diffusion tensor. A structure must have previously been read into relax. The diffusion tensor is represented by an ellipsoidal, spheroidal, or spherical geometric object with its origin located at the centre of mass (of the selected residues). This diffusion tensor PDB file can subsequently read into any molecular viewer.")
191 uf.desc[-1].add_paragraph("There are four different types of residue within the PDB. The centre of mass of the selected residues is represented as a single carbon atom of the residue 'COM'. The ellipsoidal geometric shape consists of numerous H atoms of the residue 'TNS'. The axes of the tensor, when defined, are presented as the residue 'AXS' and consist of carbon atoms: one at the centre of mass and one at the end of each eigenvector. Finally, if Monte Carlo simulations were run and the diffusion tensor parameters were allowed to vary then there will be multiple 'SIM' residues, one for each simulation. These are essentially the same as the 'AXS' residue, representing the axes of the simulated tensors, and they will appear as a distribution.")
192 uf.desc[-1].add_paragraph("As the Brownian rotational diffusion tensor is a measure of the rate of rotation about different axes - the larger the geometric object, the faster the diffusion of a molecule. For example the diffusion tensor of a water molecule is much larger than that of a macromolecule.")
193 uf.desc[-1].add_paragraph("The effective global correlation time experienced by an XH bond vector, not to be confused with the Lipari and Szabo parameter tau_e, will be approximately proportional to the component of the diffusion tensor parallel to it. The approximation is not exact due to the multiexponential form of the correlation function of Brownian rotational diffusion. If an XH bond vector is parallel to the longest axis of the tensor, it will be unaffected by rotations about that axis, which are the fastest rotations of the molecule, and therefore its effective global correlation time will be maximal.")
194 uf.desc[-1].add_paragraph("To set the size of the diffusion tensor within the PDB frame the unit vectors used to generate the geometric object are first multiplied by the diffusion tensor (which has the units of inverse seconds) then by the scaling factor (which has the units of second Angstroms and has the default value of 1.8e-6 s.Angstrom). Therefore the rotational diffusion rate per Angstrom is equal the inverse of the scale value (which defaults to 5.56e5 s^-1.Angstrom^-1). Using the default scaling value for spherical diffusion, the correspondence between global correlation time, Diso diffusion rate, and the radius of the sphere for a number of discrete cases will be:")
195 table = uf_tables.add_table(label="table: diff tensor PDB scaling", caption="Diffusion tensor PDB representation sizes using the default scaling for different diffusion tensors", caption_short="Diffusion tensor PDB scaling.")
196 table.add_headings(["tm (ns)", "Diso (s^-1)", "Radius (Angstrom)"])
197 table.add_row(["1", "1.67e8", "300"])
198 table.add_row(["3", "5.56e7", "100"])
199 table.add_row(["10", "1.67e7", "30"])
200 table.add_row(["30", "5.56e6", "10"])
201 uf.desc[-1].add_table(table.label)
202 uf.desc[-1].add_paragraph("The scaling value has been fixed to facilitate comparisons within or between publications, but can be changed to vary the size of the tensor geometric object if necessary. Reporting the rotational diffusion rate per Angstrom within figure legends would be useful.")
203 uf.desc[-1].add_paragraph("To create the tensor PDB representation, a number of algorithms are utilised. Firstly the centre of mass is calculated for the selected residues and is represented in the PDB by a C atom. Then the axes of the diffusion are calculated, as unit vectors scaled to the appropriate length (multiplied by the eigenvalue Dx, Dy, Dz, Dpar, Dper, or Diso as well as the scale value), and a C atom placed at the position of this vector plus the centre of mass. Finally a uniform distribution of vectors on a sphere is generated using spherical coordinates. By incrementing the polar angle using an arccos distribution, a radial array of vectors representing latitude are created while incrementing the azimuthal angle evenly creates the longitudinal vectors. These unit vectors, which are distributed within the PDB frame and are of 1 Angstrom in length, are first rotated into the diffusion frame using a rotation matrix (the spherical diffusion tensor is not rotated). Then they are multiplied by the diffusion tensor matrix to extend the vector out to the correct length, and finally multiplied by the scale value so that the vectors reasonably superimpose onto the macromolecular structure. The last set of algorithms place all this information into a PDB file. The distribution of vectors are represented by H atoms and are all connected using PDB CONECT records. Each H atom is connected to its two neighbours on the both the longitude and latitude. This creates a geometric PDB object with longitudinal and latitudinal lines.")
204 uf.backend = generic_fns.structure.geometric.create_diff_tensor_pdb
205 uf.menu_text = "&create_diff_tensor_pdb"
206 uf.gui_icon = "oxygen.actions.list-add-relax-blue"
207 uf.wizard_height_desc = 450
208 uf.wizard_size = (1000, 750)
209 uf.wizard_apply_button = False
210 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + 'create_diff_tensor_pdb.png'
211
212
213
214 uf = uf_info.add_uf('structure.create_vector_dist')
215 uf.title = "Create a PDB file representation of the distribution of XH bond vectors."
216 uf.title_short = "XH vector distribution PDB representation."
217 uf.add_keyarg(
218 name = "length",
219 default = 2e-9,
220 py_type = "num",
221 desc_short = "vector length",
222 desc = "The length of the vectors in the PDB representation (meters)."
223 )
224 uf.add_keyarg(
225 name = "file",
226 default = "XH_dist.pdb",
227 py_type = "str",
228 arg_type = "file sel",
229 desc_short = "file name",
230 desc = "The name of the PDB file.",
231 wiz_filesel_wildcard = "PDB files (*.pdb)|*.pdb;*.PDB",
232 wiz_filesel_style = wx.FD_SAVE
233 )
234 uf.add_keyarg(
235 name = "dir",
236 py_type = "str",
237 arg_type = "dir",
238 desc_short = "directory name",
239 desc = "The directory to place the file into.",
240 can_be_none = True
241 )
242 uf.add_keyarg(
243 name = "symmetry",
244 default = True,
245 py_type = "bool",
246 desc_short = "symmetry flag",
247 desc = "A flag which if True will create a second chain with reversed XH bond orientations."
248 )
249 uf.add_keyarg(
250 name = "force",
251 default = False,
252 py_type = "bool",
253 desc_short = "force flag",
254 desc = "A flag which if True will overwrite the file if it already exists."
255 )
256
257 uf.desc.append(Desc_container())
258 uf.desc[-1].add_paragraph("This creates a PDB file containing an artificial vectors, the length of which default to 20 Angstrom. A structure must have previously been read into relax. The origin of the vector distribution is located at the centre of mass (of the selected residues). This vector distribution PDB file can subsequently be read into any molecular viewer.")
259 uf.desc[-1].add_paragraph("Because of the symmetry of the diffusion tensor reversing the orientation of the XH bond vector has no effect. Therefore by setting the symmetry flag two chains 'A' and 'B' will be added to the PDB file whereby chain 'B' is chain 'A' with the XH bonds reversed.")
260 uf.backend = generic_fns.structure.geometric.create_vector_dist
261 uf.menu_text = "cr&eate_vector_dist"
262 uf.gui_icon = "oxygen.actions.list-add-relax-blue"
263 uf.wizard_height_desc = 400
264 uf.wizard_size = (900, 700)
265 uf.wizard_apply_button = False
266 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + 'create_vector_dist.png'
267
268
269
270 uf = uf_info.add_uf('structure.get_pos')
271 uf.title = "Extract the atomic positions from the loaded structures for the given spins."
272 uf.title_short = "Atomic position extraction."
273 uf.add_keyarg(
274 name = "spin_id",
275 py_type = "str",
276 desc_short = "spin ID string",
277 desc = "The spin identification string.",
278 can_be_none = True
279 )
280 uf.add_keyarg(
281 name = "ave_pos",
282 default = True,
283 py_type = "bool",
284 desc_short = "average position flag",
285 desc = "A flag specifying if the position of the atom is to be averaged across models."
286 )
287
288 uf.desc.append(Desc_container())
289 uf.desc[-1].add_paragraph("This allows the atomic positions of the spins to be extracted from the loaded structures. This is automatically performed by the structure.load_spins() user function, but if the sequence information is generated in other ways, this user function allows the structural information to be obtained.")
290 uf.desc[-1].add_paragraph("If averaging the atomic positions, then average position of all models will be loaded into the spin container. Otherwise the positions from all models will be loaded separately.")
291
292 uf.desc.append(Desc_container("Prompt examples"))
293 uf.desc[-1].add_paragraph("For a model-free backbone amide nitrogen analysis whereby the N spins have already been created, to obtain the backbone N positions from the file '1F3Y.pdb' (which is a single protein), type the following two user functions:")
294 uf.desc[-1].add_prompt("relax> structure.read_pdb('1F3Y.pdb')")
295 uf.desc[-1].add_prompt("relax> structure.get_pos(spin_id='@N')")
296 uf.backend = generic_fns.structure.main.get_pos
297 uf.menu_text = "&get_pos"
298 uf.wizard_height_desc = 300
299 uf.wizard_size = (800, 600)
300 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
301
302
303
304 uf = uf_info.add_uf('structure.delete')
305 uf.title = "Delete all structural information."
306 uf.title_short = "Structure deletion."
307
308 uf.desc.append(Desc_container())
309 uf.desc[-1].add_paragraph("This will delete all the structural information from the current data pipe. All spin and sequence information loaded from these structures will be preserved - this only affects the structural data.")
310
311 uf.desc.append(Desc_container("Prompt examples"))
312 uf.desc[-1].add_paragraph("Simply type:")
313 uf.desc[-1].add_prompt("relax> structure.delete()")
314 uf.backend = generic_fns.structure.main.delete
315 uf.menu_text = "&delete"
316 uf.gui_icon = "oxygen.actions.list-remove"
317 uf.wizard_size = (600, 400)
318 uf.wizard_apply_button = False
319 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
320
321
322
323 uf = uf_info.add_uf('structure.displacement')
324 uf.title = "Determine the rotational and translational displacement between a set of models."
325 uf.title_short = "Rotational and translational displacement."
326 uf.add_keyarg(
327 name = "model_from",
328 py_type = "int",
329 desc_short = "model from",
330 desc = "The optional model number for the starting position of the displacement.",
331 can_be_none = True
332 )
333 uf.add_keyarg(
334 name = "model_to",
335 py_type = "int",
336 desc_short = "model to",
337 desc = "The optional model number for the ending position of the displacement.",
338 can_be_none = True
339 )
340 uf.add_keyarg(
341 name = "atom_id",
342 py_type = "str",
343 desc_short = "atom identification string",
344 desc = "The atom identification string.",
345 can_be_none = True
346 )
347 uf.add_keyarg(
348 name = "centroid",
349 py_type = "float_array",
350 desc_short = "centroid position",
351 desc = "The alternative position of the centroid.",
352 can_be_none = True
353 )
354
355 uf.desc.append(Desc_container())
356 uf.desc[-1].add_paragraph("This user function allows the rotational and translational displacement between two models of the same structure to be calculated. The information will be printed out in various formats and held in the relax data store. This is directional, so there is a starting and ending position for each displacement. If the starting and ending models are not specified, then the displacements in all directions between all models will be calculated.")
357 uf.desc[-1].add_paragraph("The atom ID, which uses the same notation as the spin ID strings, can be used to restrict the displacement calculation to certain molecules, residues, or atoms. This is useful if studying domain motions, secondary structure rearrangements, amino acid side chain rotations, etc.")
358 uf.desc[-1].add_paragraph("By supplying the position of the centroid, an alternative position than the standard rigid body centre is used as the focal point of the motion. The allows, for example, a pivot of a rotational domain motion to be specified. This is not a formally correct algorithm, all translations will be zero, but does give an indication to the amplitude of the pivoting angle.")
359
360 uf.desc.append(Desc_container("Prompt examples"))
361 uf.desc[-1].add_paragraph("To determine the rotational and translational displacements between all sets of models, type:")
362 uf.desc[-1].add_prompt("relax> structure.displacement()")
363 uf.desc[-1].add_paragraph("To determine the displacement from model 5 to all other models, type:")
364 uf.desc[-1].add_prompt("relax> structure.displacement(model_from=5)")
365 uf.desc[-1].add_paragraph("To determine the displacement of all models to model 5, type:")
366 uf.desc[-1].add_prompt("relax> structure.displacement(model_to=5)")
367 uf.desc[-1].add_paragraph("To determine the displacement of model 2 to model 3, type one of:")
368 uf.desc[-1].add_prompt("relax> structure.displacement(2, 3)")
369 uf.desc[-1].add_prompt("relax> structure.displacement(model_from=2, model_to=3)")
370 uf.backend = generic_fns.structure.main.displacement
371 uf.menu_text = "displace&ment"
372 uf.wizard_height_desc = 400
373 uf.wizard_size = (900, 700)
374 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
375
376
377
378 uf = uf_info.add_uf('structure.find_pivot')
379 uf.title = "Find the pivot point of the motion of a set of structures."
380 uf.title_short = "Pivot search."
381 uf.add_keyarg(
382 name = "models",
383 py_type = "int_list",
384 desc_short = "model list",
385 desc = "The list of models to use.",
386 can_be_none = True
387 )
388 uf.add_keyarg(
389 name = "atom_id",
390 py_type = "str",
391 desc_short = "atom ID string",
392 desc = "The atom identification string.",
393 can_be_none = True
394 )
395 uf.add_keyarg(
396 name = "init_pos",
397 py_type = "float_array",
398 desc_short = "initial pivot position",
399 desc = "The initial position of the pivot.",
400 can_be_none = True
401 )
402
403 uf.desc.append(Desc_container())
404 uf.desc[-1].add_paragraph("This is used to find pivot point of motion between a set of structural models. If the list of models is not supplied, then all models will be used.")
405 uf.desc[-1].add_paragraph("The atom ID, which uses the same notation as the spin ID strings, can be used to restrict the search to certain molecules, residues, or atoms. For example to only use backbone heavy atoms in a protein, use the atom ID of '@N,C,CA,O', assuming those are the names of the atoms from the structural file.")
406 uf.desc[-1].add_paragraph("By supplying the position of the centroid, an alternative position than the standard rigid body centre is used as the focal point of the superimposition. The allows, for example, the superimposition about a pivot point.")
407 uf.backend = generic_fns.structure.main.find_pivot
408 uf.menu_text = "&find_pivot"
409 uf.wizard_height_desc = 400
410 uf.wizard_size = (900, 700)
411 uf.wizard_apply_button = False
412 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
413
414
415
416 uf = uf_info.add_uf('structure.load_spins')
417 uf.title = "Load spins from the structure into the relax data store."
418 uf.title_short = "Loading spins from structure."
419 uf.add_keyarg(
420 name = "spin_id",
421 py_type = "str",
422 arg_type = "spin ID",
423 desc_short = "spin ID string",
424 desc = "The spin identification string for the selective loading of certain spins into the relax data store.",
425 can_be_none = True
426 )
427 uf.add_keyarg(
428 name = "ave_pos",
429 default = True,
430 py_type = "bool",
431 desc_short = "average position flag",
432 desc = "A flag specifying if the position of the atom is to be averaged across models."
433 )
434
435 uf.desc.append(Desc_container())
436 uf.desc[-1].add_paragraph("This allows a sequence to be generated within the relax data store using the atomic information from the structure already associated with this data pipe. The spin ID string is used to select which molecules, which residues, and which atoms will be recognised as spin systems within relax. If the spin ID is left unspecified, then all molecules, residues, and atoms will be placed within the data store (and all atoms will be treated as spins).")
437 uf.desc[-1].add_paragraph("If averaging the atomic positions, then average position of all models will be loaded into the spin container. Otherwise the positions from all models will be loaded separately.")
438
439 uf.desc.append(Desc_container("Prompt examples"))
440 uf.desc[-1].add_paragraph("For a model-free backbone amide nitrogen analysis, to load just the backbone N sequence from the file '1F3Y.pdb' (which is a single protein), type the following two user functions:")
441 uf.desc[-1].add_prompt("relax> structure.read_pdb('1F3Y.pdb')")
442 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id='@N')")
443 uf.desc[-1].add_paragraph("For an RNA analysis of adenine C8 and C2, guanine C8 and N1, cytidine C5 and C6, and uracil N3, C5, and C6, type the following series of commands (assuming that the PDB file with this atom naming has already been read):")
444 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=\":A@C8\")")
445 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=\":A@C2\")")
446 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=\":G@C8\")")
447 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=\":G@N1\")")
448 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=\":C@C5\")")
449 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=\":C@C6\")")
450 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=\":U@N3\")")
451 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=\":U@C5\")")
452 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=\":U@C6\")")
453 uf.desc[-1].add_paragraph("Alternatively using some Python programming:")
454 uf.desc[-1].add_prompt("relax> for id in [\":A@C8\", \":A@C2\", \":G@C8\", \":G@N1\", \":C@C5\", \":C@C6\", \":U@N3\", \":U@C5\", \":U@C6\"]:")
455 uf.desc[-1].add_prompt("relax> structure.load_spins(spin_id=id)")
456 uf.backend = generic_fns.structure.main.load_spins
457 uf.menu_text = "&load_spins"
458 uf.gui_icon = "relax.spin"
459 uf.wizard_height_desc = 300
460 uf.wizard_size = (800, 600)
461 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + 'load_spins.png'
462
463
464
465 uf = uf_info.add_uf('structure.read_pdb')
466 uf.title = "Reading structures from PDB files."
467 uf.title_short = "PDB reading."
468 uf.add_keyarg(
469 name = "file",
470 py_type = "str",
471 arg_type = "file sel",
472 desc_short = "file name",
473 desc = "The name of the PDB file.",
474 wiz_filesel_wildcard = "PDB files (*.pdb)|*.pdb;*.PDB",
475 wiz_filesel_style = wx.FD_OPEN
476 )
477 uf.add_keyarg(
478 name = "dir",
479 py_type = "str",
480 arg_type = "dir",
481 desc_short = "directory name",
482 desc = "The directory where the file is located.",
483 can_be_none = True
484 )
485 uf.add_keyarg(
486 name = "read_mol",
487 py_type = "int_or_int_list",
488 desc_short = "read molecule number",
489 desc = "If set, only the given molecule(s) will be read. The molecules are determined differently by the different parsers, but are numbered consecutively from 1. If unset, then all molecules will be loaded. By providing a list of numbers such as [1, 2], multiple molecules will be read.",
490 can_be_none = True
491 )
492 uf.add_keyarg(
493 name = "set_mol_name",
494 py_type = "str_or_str_list",
495 desc_short = "set molecule names",
496 desc = "Set the names of the read molecules. If unset, then the molecules will be automatically labelled based on the file name or other information. This can either be a single name or a list of names.",
497 can_be_none = True
498 )
499 uf.add_keyarg(
500 name = "read_model",
501 py_type = "int_or_int_list",
502 desc_short = "read model",
503 desc = "If set, only the given model number(s) from the PDB file will be read. This can be a single number or list of numbers.",
504 can_be_none = True
505 )
506 uf.add_keyarg(
507 name = "set_model_num",
508 py_type = "int_or_int_list",
509 desc_short = "set model numbers",
510 desc = "Set the model numbers of the loaded molecules. If unset, then the PDB model numbers will be preserved if they exist. This can be a single number or list of numbers.",
511 can_be_none = True
512 )
513 uf.add_keyarg(
514 name = "parser",
515 default = "internal",
516 py_type = "str",
517 desc_short = "PDB parser",
518 desc = "The PDB parser used to read the file.",
519 wiz_element_type = "combo",
520 wiz_combo_choices = ["Fast internal PDB parser", "Scientific Python PDB parser"],
521 wiz_combo_data = ["internal", "scientific"],
522 wiz_read_only = True
523 )
524
525 uf.desc.append(Desc_container())
526 uf.desc[-1].add_paragraph("The reading of PDB files into relax is quite a flexible procedure allowing for both models, defined as an ensemble of the same molecule but with different atomic positions, and different molecules within the same model. One of more molecules can exist in one or more models. The flexibility allows PDB models to be converted into different molecules and different PDB files loaded as the same molecule but as different models.")
527 uf.desc[-1].add_paragraph("A few different PDB parsers can be used to read the structural data. The choice of which to use depends on whether your PDB file is supported by that reader. These are selected by setting the parser to one of:")
528 uf.desc[-1].add_item_list_element("'internal'", "A fast PDB parser built into relax.")
529 uf.desc[-1].add_item_list_element("'scientific'", "The Scientific Python PDB parser.")
530 uf.desc[-1].add_paragraph("In a PDB file, the models are specified by the MODEL PDB record. All the supported PDB readers in relax recognise this. The molecule level is quite different between the Scientific Python and internal readers. For how Scientific Python defines molecules, please see its documentation. The internal reader is far simpler as it defines molecules using the TER PDB record. In both cases, the molecules will be numbered consecutively from 1.")
531 uf.desc[-1].add_paragraph("Setting the molecule name allows the molecule within the PDB (within one model) to have a custom name. If not set, then the molecules will be named after the file name, with the molecule number appended if more than one exists.")
532 uf.desc[-1].add_paragraph("Note that relax will complain if it cannot work out what to do.")
533 uf.desc[-1].add_paragraph("This is able to handle uncompressed, bzip2 compressed files, or gzip compressed files automatically. The full file name including extension can be supplied, however, if the file cannot be found, this function will search for the file name with '.bz2' appended followed by the file name with '.gz' appended.")
534
535 uf.desc.append(Desc_container("Prompt examples"))
536 uf.desc[-1].add_paragraph("To load all structures from the PDB file 'test.pdb' in the directory '~/pdb', including all models and all molecules, type one of:")
537 uf.desc[-1].add_prompt("relax> structure.read_pdb('test.pdb', '~/pdb')")
538 uf.desc[-1].add_prompt("relax> structure.read_pdb(file='test.pdb', dir='pdb')")
539 uf.desc[-1].add_paragraph("To load the 10th model from the file 'test.pdb' using the Scientific Python PDB parser and naming it 'CaM', use one of:")
540 uf.desc[-1].add_prompt("relax> structure.read_pdb('test.pdb', read_model=10, set_mol_name='CaM', parser='scientific')")
541 uf.desc[-1].add_prompt("relax> structure.read_pdb(file='test.pdb', read_model=10, set_mol_name='CaM', parser='scientific')")
542 uf.desc[-1].add_paragraph("To load models 1 and 5 from the file 'test.pdb' as two different structures of the same model, type one of:")
543 uf.desc[-1].add_prompt("relax> structure.read_pdb('test.pdb', read_model=[1, 5], set_model_num=[1, 1])")
544 uf.desc[-1].add_prompt("relax> structure.read_pdb('test.pdb', set_mol_name=['CaM_1', 'CaM_2'], read_model=[1, 5], set_model_num=[1, 1])")
545 uf.desc[-1].add_paragraph("To load the files 'lactose_MCMM4_S1_1.pdb', 'lactose_MCMM4_S1_2.pdb', 'lactose_MCMM4_S1_3.pdb' and 'lactose_MCMM4_S1_4.pdb' as models, type the following sequence of commands:")
546 uf.desc[-1].add_prompt("relax> structure.read_pdb('lactose_MCMM4_S1_1.pdb', set_mol_name='lactose_MCMM4_S1', set_model_num=1)")
547 uf.desc[-1].add_prompt("relax> structure.read_pdb('lactose_MCMM4_S1_2.pdb', set_mol_name='lactose_MCMM4_S1', set_model_num=2)")
548 uf.desc[-1].add_prompt("relax> structure.read_pdb('lactose_MCMM4_S1_3.pdb', set_mol_name='lactose_MCMM4_S1', set_model_num=3)")
549 uf.desc[-1].add_prompt("relax> structure.read_pdb('lactose_MCMM4_S1_4.pdb', set_mol_name='lactose_MCMM4_S1', set_model_num=4)")
550 uf.backend = generic_fns.structure.main.read_pdb
551 uf.menu_text = "read_&pdb"
552 uf.gui_icon = "oxygen.actions.document-open"
553 uf.wizard_height_desc = 400
554 uf.wizard_size = (1000, 750)
555 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + 'read_pdb.png'
556
557
558
559 uf = uf_info.add_uf('structure.read_xyz')
560 uf.title = "Reading structures from XYZ files."
561 uf.title_short = "XYZ reading."
562 uf.add_keyarg(
563 name = "file",
564 py_type = "str",
565 arg_type = "file sel",
566 desc_short = "file name",
567 desc = "The name of the XYZ file.",
568 wiz_filesel_wildcard = "XYZ files (*.xyz)|*.xyz;*.XYZ",
569 wiz_filesel_style = wx.FD_OPEN
570 )
571 uf.add_keyarg(
572 name = "dir",
573 py_type = "str",
574 arg_type = "dir",
575 desc_short = "directory name",
576 desc = "The directory where the file is located.",
577 can_be_none = True
578 )
579 uf.add_keyarg(
580 name = "read_mol",
581 py_type = "int_or_int_list",
582 desc_short = "read molecule number",
583 desc = "If set, only the given molecule(s) will be read. The molecules are determined differently by the different parsers, but are numbered consecutively from 1. If unset, then all molecules will be loaded. By providing a list of numbers such as [1, 2], multiple molecules will be read.",
584 can_be_none = True
585 )
586 uf.add_keyarg(
587 name = "set_mol_name",
588 py_type = "str_or_str_list",
589 desc_short = "set molecule names",
590 desc = "Set the names of the read molecules. If unset, then the molecules will be automatically labelled based on the file name or other information. This can either be a single name or a list of names.",
591 can_be_none = True
592 )
593 uf.add_keyarg(
594 name = "read_model",
595 py_type = "int_or_int_list",
596 desc_short = "read model",
597 desc = "If set, only the given model number(s) from the PDB file will be read. This can be a single number or list of numbers.",
598 can_be_none = True
599 )
600 uf.add_keyarg(
601 name = "set_model_num",
602 py_type = "int_or_int_list",
603 desc_short = "set model numbers",
604 desc = "Set the model numbers of the loaded molecules. If unset, then the PDB model numbers will be preserved if they exist. This can be a single number or list of numbers.",
605 can_be_none = True
606 )
607
608 uf.desc.append(Desc_container())
609 uf.desc[-1].add_paragraph("The XYZ files with different models, which defined as an ensemble of the same molecule but with different atomic positions, can be read into relax. If there are several molecules in one xyz file, please separate them into different files and then load them individually. Loading different models and different molecules is controlled by specifying the molecule number read, setting the molecule names, specifying which model to read, and setting the model numbers.")
610 uf.desc[-1].add_paragraph("The setting of molecule names is used to name the molecules within the XYZ (within one model). If not set, then the molecules will be named after the file name, with the molecule number appended if more than one exists.")
611 uf.desc[-1].add_paragraph("Note that relax will complain if it cannot work out what to do.")
612
613 uf.desc.append(Desc_container("Prompt examples"))
614 uf.desc[-1].add_paragraph("To load all structures from the XYZ file 'test.xyz' in the directory '~/xyz', including all models and all molecules, type one of:")
615 uf.desc[-1].add_prompt("relax> structure.read_xyz('test.xyz', '~/xyz')")
616 uf.desc[-1].add_prompt("relax> structure.read_xyz(file='test.xyz', dir='xyz')")
617 uf.desc[-1].add_paragraph("To load the 10th model from the file 'test.xyz' and naming it 'CaM', use one of:")
618 uf.desc[-1].add_prompt("relax> structure.read_xyz('test.xyz', read_model=10, set_mol_name='CaM')")
619 uf.desc[-1].add_prompt("relax> structure.read_xyz(file='test.xyz', read_model=10, set_mol_name='CaM')")
620 uf.desc[-1].add_paragraph("To load models 1 and 5 from the file 'test.xyz' as two different structures of the same model, type one of:")
621 uf.desc[-1].add_prompt("relax> structure.read_xyz('test.xyz', read_model=[1, 5], set_model_num=[1, 1])")
622 uf.desc[-1].add_prompt("relax> structure.read_xyz('test.xyz', set_mol_name=['CaM_1', 'CaM_2'], read_model=[1, 5], set_model_num=[1, 1])")
623 uf.desc[-1].add_paragraph("To load the files 'test_1.xyz', 'test_2.xyz', 'test_3.xyz' and 'test_4.xyz' as models, type the following sequence of commands:")
624 uf.desc[-1].add_prompt("relax> structure.read_xyz('test_1.xyz', set_mol_name='test_1', set_model_num=1)")
625 uf.desc[-1].add_prompt("relax> structure.read_xyz('test_2.xyz', set_mol_name='test_2', set_model_num=2)")
626 uf.desc[-1].add_prompt("relax> structure.read_xyz('test_3.xyz', set_mol_name='test_3', set_model_num=3)")
627 uf.desc[-1].add_prompt("relax> structure.read_xyz('test_4.xyz', set_mol_name='test_4', set_model_num=4)")
628 uf.backend = generic_fns.structure.main.read_xyz
629 uf.menu_text = "read_&xyz"
630 uf.gui_icon = "oxygen.actions.document-open"
631 uf.wizard_height_desc = 400
632 uf.wizard_size = (900, 700)
633 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + 'read_xyz.png'
634
635
636
637 uf = uf_info.add_uf('structure.rotate')
638 uf.title = "Rotate the internal structural object about the given origin by the rotation matrix."
639 uf.title_short = "Structure rotation."
640 uf.add_keyarg(
641 name = "R",
642 py_type = "float_matrix",
643 default = eye(3),
644 dim = (3, 3),
645 desc_short = "rotation matrix",
646 desc = "The rotation matrix in forwards rotation notation."
647 )
648 uf.add_keyarg(
649 name = "origin",
650 py_type = "float_array",
651 dim = 3,
652 desc_short = "origin of rotation",
653 desc = "The origin or pivot of the rotation.",
654 can_be_none = True
655 )
656 uf.add_keyarg(
657 name = "model",
658 py_type = "int",
659 desc_short = "model",
660 desc = "The model to rotate (which if not set will cause all models to be rotated).",
661 can_be_none = True
662 )
663 uf.add_keyarg(
664 name = "atom_id",
665 py_type = "str",
666 desc_short = "atom ID string",
667 desc = "The atom identification string.",
668 can_be_none = True
669 )
670
671 uf.desc.append(Desc_container())
672 uf.desc[-1].add_paragraph("This is used to rotate the internal structural data by the given rotation matrix. If the origin is supplied, then this will act as the pivot of the rotation. Otherwise, all structural data will be rotated about the point [0, 0, 0]. The rotation can be restricted to one specific model.")
673 uf.backend = generic_fns.structure.main.rotate
674 uf.menu_text = "&rotate"
675 uf.wizard_height_desc = 300
676 uf.wizard_size = (800, 600)
677 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
678
679
680
681 uf = uf_info.add_uf('structure.superimpose')
682 uf.title = "Superimpose a set of models of the same structure."
683 uf.title_short = "Structural superimposition."
684 uf.add_keyarg(
685 name = "models",
686 py_type = "int_list",
687 desc_short = "model list",
688 desc = "The list of models to superimpose.",
689 can_be_none = True
690 )
691 uf.add_keyarg(
692 name = "method",
693 default = "fit to mean",
694 py_type = "str",
695 desc_short = "superimposition method",
696 desc = "The superimposition method.",
697 wiz_element_type = "combo",
698 wiz_combo_choices = ["fit to mean", "fit to first"],
699 wiz_read_only = True
700 )
701 uf.add_keyarg(
702 name = "atom_id",
703 py_type = "str",
704 desc_short = "atom ID string",
705 desc = "The atom identification string.",
706 can_be_none = True
707 )
708 uf.add_keyarg(
709 name = "centroid",
710 py_type = "float_array",
711 desc_short = "centroid position",
712 desc = "The alternative position of the centroid.",
713 can_be_none = True
714 )
715
716 uf.desc.append(Desc_container())
717 uf.desc[-1].add_paragraph("This allows a set of models of the same structure to be superimposed to each other. Two superimposition methods are currently supported:")
718 uf.desc[-1].add_item_list_element("'fit to mean'", "All models are fit to the mean structure. This is the default and most accurate method for an ensemble description. It is an iterative method which first calculates a mean structure and then fits each model to the mean structure using the Kabsch algorithm. This is repeated until convergence.")
719 uf.desc[-1].add_item_list_element("'fit to first'", "This is quicker but is not as accurate for an ensemble description. The Kabsch algorithm is used to rotate and translate each model to be superimposed onto the first model.")
720 uf.desc[-1].add_paragraph("If the list of models is not supplied, then all models will be superimposed.")
721 uf.desc[-1].add_paragraph("The atom ID, which uses the same notation as the spin ID strings, can be used to restrict the superimpose calculation to certain molecules, residues, or atoms. For example to only superimpose backbone heavy atoms in a protein, use the atom ID of '@N,C,CA,O', assuming those are the names of the atoms from the structural file.")
722 uf.desc[-1].add_paragraph("By supplying the position of the centroid, an alternative position than the standard rigid body centre is used as the focal point of the superimposition. The allows, for example, the superimposition about a pivot point.")
723
724 uf.desc.append(Desc_container("Prompt examples"))
725 uf.desc[-1].add_paragraph("To superimpose all sets of models, type one of:")
726 uf.desc[-1].add_prompt("relax> structure.superimpose()")
727 uf.desc[-1].add_prompt("relax> structure.superimpose(method='fit to mean')")
728 uf.desc[-1].add_paragraph("To superimpose the models 1, 2, 3, 5 onto model 4, type:")
729 uf.desc[-1].add_prompt("relax> structure.superimpose(models=[4, 1, 2, 3, 5], method='fit to first')")
730 uf.desc[-1].add_paragraph("To superimpose an ensemble of protein structures using only the backbone heavy atoms, type one of:")
731 uf.desc[-1].add_prompt("relax> structure.superimpose(atom_id='@N,C,CA,O')")
732 uf.desc[-1].add_prompt("relax> structure.superimpose(method='fit to mean', atom_id='@N,C,CA,O')")
733 uf.desc[-1].add_paragraph("To superimpose model 2 onto model 3 using backbone heavy atoms, type one of:")
734 uf.desc[-1].add_prompt("relax> structure.superimpose([3, 2], 'fit to first', '@N,C,CA,O')")
735 uf.desc[-1].add_prompt("relax> structure.superimpose(models=[3, 2], method='fit to first', atom_id='@N,C,CA,O')")
736 uf.backend = generic_fns.structure.main.superimpose
737 uf.menu_text = "&superimpose"
738 uf.wizard_apply_button = False
739 uf.wizard_height_desc = 450
740 uf.wizard_size = (1000, 750)
741 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
742
743
744
745 uf = uf_info.add_uf('structure.translate')
746 uf.title = "Laterally displace the internal structural object by the translation vector."
747 uf.title_short = "Structure translation."
748 uf.add_keyarg(
749 name = "T",
750 py_type = "float_array",
751 dim = 3,
752 desc_short = "translation vector",
753 desc = "The translation vector."
754 )
755 uf.add_keyarg(
756 name = "model",
757 py_type = "int",
758 desc_short = "model",
759 desc = "The model to translate (which if not set will cause all models to be translate).",
760 can_be_none = True
761 )
762 uf.add_keyarg(
763 name = "atom_id",
764 py_type = "str",
765 desc_short = "atom ID string",
766 desc = "The atom identification string.",
767 can_be_none = True
768 )
769
770 uf.desc.append(Desc_container())
771 uf.desc[-1].add_paragraph("This is used to translate the internal structural data by the given translation vector. The translation can be restricted to one specific model.")
772 uf.backend = generic_fns.structure.main.translate
773 uf.menu_text = "&translate"
774 uf.wizard_size = (750, 500)
775 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
776
777
778
779 uf = uf_info.add_uf('structure.vectors')
780 uf.title = "Extract and store the bond vectors from the loaded structures in the spin container."
781 uf.title_short = "Bond vector extraction."
782 uf.add_keyarg(
783 name = "attached",
784 default = "H",
785 py_type = "str",
786 desc_short = "attached atom",
787 desc = "The name of the second atom which attached to the spin of interest. Regular expression is allowed, for example 'H*'."
788 )
789 uf.add_keyarg(
790 name = "spin_id",
791 default = "@N",
792 py_type = "str",
793 arg_type = "spin ID",
794 desc_short = "spin ID string",
795 desc = "The spin identification string for restricting the loading of vectors to certain spins.",
796 can_be_none = True
797 )
798 uf.add_keyarg(
799 name = "model",
800 py_type = "int",
801 desc_short = "model",
802 desc = "The model to extract bond vectors from (which if not set will cause the vectors of all models to be extracted).",
803 can_be_none = True
804 )
805 uf.add_keyarg(
806 name = "verbosity",
807 default = 1,
808 py_type = "int",
809 desc_short = "verbosity level",
810 desc = "The amount of information to print to screen. Zero corresponds to minimal output while higher values increase the amount of output. The default value is 1."
811 )
812 uf.add_keyarg(
813 name = "ave",
814 default = True,
815 py_type = "bool",
816 desc_short = "average vector flag",
817 desc = "A flag which if True will cause the bond vectors from all models to be averaged. If vectors from only one model is extracted, this will have no effect."
818 )
819 uf.add_keyarg(
820 name = "unit",
821 default = True,
822 py_type = "bool",
823 desc_short = "unit vector flag",
824 desc = "A flag which if True will cause the unit vector to calculated rather than the full length bond vector."
825 )
826
827 uf.desc.append(Desc_container())
828 uf.desc[-1].add_paragraph("For a number of types of analysis, bond vectors or unit bond vectors are required for the calculations. This user function allows these vectors to be extracted from the loaded structures. The bond vector will be that from the atom associated with the spin system loaded in relax to the specified attached atom. For example if the attached atom is set to 'H' and the protein backbone amide spins 'N' are loaded, the all 'N-H' vectors will be extracted. But if set to 'CA', all atoms named 'CA' in the structures will be searched for and all 'N-Ca' bond vectors will be extracted.")
829 uf.desc[-1].add_paragraph("The extraction of vectors can occur in a number of ways. For example if an NMR structure with N models is loaded or if multiple molecules, from any source, of the same compound are loaded as different models, there are three options for extracting the bond vector. Firstly the bond vector of a single model can be extracted by setting the model number. Secondly the bond vectors from all models can be extracted if the model number is not set and the average vector flag is not set. Thirdly, if the model number is not set and the average vector flag is set, then a single vector which is the average for all models will be calculated.")
830
831 uf.desc.append(Desc_container("Prompt examples"))
832 uf.desc[-1].add_paragraph("To extract the XH vectors of the backbone amide nitrogens where in the PDB file the backbone nitrogen is called 'N' and the attached atom is called 'H', assuming multiple types of spin have already been loaded, type one of:")
833 uf.desc[-1].add_prompt("relax> structure.vectors(spin_id='@N')")
834 uf.desc[-1].add_prompt("relax> structure.vectors('H', spin_id='@N')")
835 uf.desc[-1].add_prompt("relax> structure.vectors(attached='H', spin_id='@N')")
836 uf.desc[-1].add_paragraph("If the attached atom is called 'HN', type:")
837 uf.desc[-1].add_prompt("relax> structure.vectors(attached='HN', spin_id='@N')")
838 uf.desc[-1].add_paragraph("For the 'CA' spin bonded to the 'HA' proton, type:")
839 uf.desc[-1].add_prompt("relax> structure.vectors(attached='HA', spin_id='@CA')")
840 uf.desc[-1].add_paragraph("If you are working with RNA, you can use the residue name identifier to calculate the vectors for each residue separately. For example to calculate the vectors for all possible spins in the bases, type:")
841 uf.desc[-1].add_prompt("relax> structure.vectors('H2', spin_id=':A')")
842 uf.desc[-1].add_prompt("relax> structure.vectors('H8', spin_id=':A')")
843 uf.desc[-1].add_prompt("relax> structure.vectors('H1', spin_id=':G')")
844 uf.desc[-1].add_prompt("relax> structure.vectors('H8', spin_id=':G')")
845 uf.desc[-1].add_prompt("relax> structure.vectors('H5', spin_id=':C')")
846 uf.desc[-1].add_prompt("relax> structure.vectors('H6', spin_id=':C')")
847 uf.desc[-1].add_prompt("relax> structure.vectors('H3', spin_id=':U')")
848 uf.desc[-1].add_prompt("relax> structure.vectors('H5', spin_id=':U')")
849 uf.desc[-1].add_prompt("relax> structure.vectors('H6', spin_id=':U')")
850 uf.desc[-1].add_paragraph("Alternatively, assuming the desired spins have been loaded, regular expression can be used:")
851 uf.desc[-1].add_prompt("relax> structure.vectors('H*')")
852 uf.backend = generic_fns.structure.main.vectors
853 uf.menu_text = "&vectors"
854 uf.wizard_height_desc = 400
855 uf.wizard_size = (1000, 750)
856 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + '2JK4.png'
857
858
859
860 uf = uf_info.add_uf('structure.write_pdb')
861 uf.title = "Writing structures to a PDB file."
862 uf.title_short = "PDB writing."
863 uf.add_keyarg(
864 name = "file",
865 py_type = "str",
866 arg_type = "file sel",
867 desc_short = "file name",
868 desc = "The name of the PDB file.",
869 wiz_filesel_wildcard = "PDB files (*.pdb)|*.pdb;*.PDB",
870 wiz_filesel_style = wx.FD_SAVE
871 )
872 uf.add_keyarg(
873 name = "dir",
874 py_type = "str",
875 arg_type = "dir",
876 desc_short = "directory name",
877 desc = "The directory where the file is located.",
878 can_be_none = True
879 )
880 uf.add_keyarg(
881 name = "model_num",
882 py_type = "int",
883 desc_short = "model number",
884 desc = "Restrict the writing of structural data to a single model in the PDB file.",
885 can_be_none = True
886 )
887 uf.add_keyarg(
888 name = "compress_type",
889 default = 0,
890 py_type = "int",
891 desc_short = "compression type",
892 desc = "The type of compression to use when creating the file.",
893 wiz_element_type = "combo",
894 wiz_combo_choices = [
895 "No compression",
896 "bzip2 compression",
897 "gzip compression"
898 ],
899 wiz_combo_data = [
900 0,
901 1,
902 2
903 ],
904 wiz_read_only = True
905 )
906 uf.add_keyarg(
907 name = "force",
908 default = False,
909 py_type = "bool",
910 desc_short = "force flag",
911 desc = "A flag which if set to True will cause any pre-existing files to be overwritten."
912 )
913
914 uf.desc.append(Desc_container())
915 uf.desc[-1].add_paragraph("This will write all of the structural data loaded in the current data pipe to be converted to the PDB format and written to file. Specifying the model number allows single models to be output.")
916 uf.desc[-1].add_paragraph("The default behaviour of this function is to not compress the file. The compression can, however, be changed to either bzip2 or gzip compression. If the '.bz2' or '.gz' extension is not included in the file name, it will be added. This behaviour is controlled by the compression type which can be set to")
917 uf.desc[-1].add_item_list_element("0", "No compression (no file extension).")
918 uf.desc[-1].add_item_list_element("1", "bzip2 compression ('.bz2' file extension).")
919 uf.desc[-1].add_item_list_element("2", "gzip compression ('.gz' file extension).")
920
921 uf.desc.append(Desc_container("Prompt examples"))
922 uf.desc[-1].add_paragraph("To write all models and molecules to the PDB file 'ensemble.pdb' within the directory '~/pdb', type one of:")
923 uf.desc[-1].add_prompt("relax> structure.write_pdb('ensemble.pdb', '~/pdb')")
924 uf.desc[-1].add_prompt("relax> structure.write_pdb(file='ensemble.pdb', dir='pdb')")
925 uf.desc[-1].add_paragraph("To write model number 3 into the new file 'test.pdb', use one of:")
926 uf.desc[-1].add_prompt("relax> structure.write_pdb('test.pdb', model_num=3)")
927 uf.desc[-1].add_prompt("relax> structure.write_pdb(file='test.pdb', model_num=3)")
928 uf.backend = generic_fns.structure.main.write_pdb
929 uf.menu_text = "&write_pdb"
930 uf.gui_icon = "oxygen.actions.document-save"
931 uf.wizard_height_desc = 400
932 uf.wizard_size = (900, 700)
933 uf.wizard_apply_button = False
934 uf.wizard_image = WIZARD_IMAGE_PATH + 'structure' + sep + 'write_pdb.png'
935