1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """The frame_order user function definitions."""
24
25
26 from graphics import WIZARD_IMAGE_PATH
27 from lib.frame_order.variables import MODEL_DOUBLE_ROTOR, MODEL_FREE_ROTOR, MODEL_ISO_CONE, MODEL_ISO_CONE_FREE_ROTOR, MODEL_ISO_CONE_TORSIONLESS, MODEL_PSEUDO_ELLIPSE, MODEL_PSEUDO_ELLIPSE_FREE_ROTOR, MODEL_PSEUDO_ELLIPSE_TORSIONLESS, MODEL_RIGID, MODEL_ROTOR
28 from specific_analyses.frame_order.optimisation import count_sobol_points
29 from specific_analyses.frame_order.uf import decompose, distribute, sobol_setup, pdb_model, permute_axes, pivot, quad_int, ref_domain, select_model, simulate
30 from user_functions.data import Uf_info; uf_info = Uf_info()
31 from user_functions.data import Uf_tables; uf_tables = Uf_tables()
32 from user_functions.objects import Desc_container
33 from user_functions.wildcards import WILDCARD_STRUCT_PDB_ALL
34
35
36
37 uf_class = uf_info.add_class('frame_order')
38 uf_class.title = "Class containing the user functions of the Frame Order theories."
39 uf_class.menu_text = "&frame_order"
40 uf_class.gui_icon = "relax.frame_order"
41
42
43
44 uf = uf_info.add_uf('frame_order.count_sobol_points')
45 uf.title = "Count the number of Sobol' points used for the current parameter values."
46 uf.title_short = "Used Sobol' point count."
47
48 uf.desc.append(Desc_container())
49 uf.desc[-1].add_paragraph("This allows the number of Sobol' integration points used during the Frame Order target function optimisation to be counted. This uses the current parameter values to determine how many are used for the PCS calculation compared to the total number.")
50 uf.backend = count_sobol_points
51 uf.menu_text = "&count_sobol_points"
52 uf.gui_icon = "oxygen.categories.applications-education"
53 uf.wizard_size = (800, 400)
54 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
55
56
57
58 uf = uf_info.add_uf('frame_order.decompose')
59 uf.title = "Structural representation of the individual frame order motional components."
60 uf.title_short = "Frame order motional components."
61 uf.add_keyarg(
62 name = "root",
63 default = "decomposed",
64 basic_types = ["str"],
65 desc_short = "PDB file root",
66 desc = "The file root for the PDB files created. Each motional component will be represented by a different PDB file appended with '_mode1.pdb', '_mode2.pdb', '_mode3.pdb', etc.",
67 can_be_none = True
68 )
69 uf.add_keyarg(
70 name = "dir",
71 arg_type = "dir",
72 desc_short = "directory name",
73 desc = "The directory where the files are to be saved.",
74 can_be_none = True
75 )
76 uf.add_keyarg(
77 name = "atom_id",
78 basic_types = ["str"],
79 desc_short = "atom identification string",
80 desc = "The atom identification string to allow the representation to be applied to a subset of all atoms.",
81 can_be_none = True
82 )
83 uf.add_keyarg(
84 name = "model",
85 default = 1,
86 min = 1,
87 basic_types = ["int"],
88 desc_short = "original structural model",
89 desc = "Only one model from an analysed ensemble of structures can be used for the representation, as the decomposition PDB files consist of one model per state.",
90 wiz_element_type = "spin"
91 )
92 uf.add_keyarg(
93 name = "total",
94 default = None,
95 basic_types = ["int"],
96 desc_short = "total number of structures",
97 desc = "The total number of structures to distribute along the motional modes. This overrides the fixed angle value.",
98 wiz_element_type = "spin",
99 can_be_none = True
100 )
101 uf.add_keyarg(
102 name = "reverse",
103 default = False,
104 basic_types = ["bool"],
105 container_types = ["list"],
106 dim = [(), (None,)],
107 desc_short = "reversal of distributed models",
108 desc = "Set this to reverse the ordering of the models distributed along the motional mode."
109 )
110 uf.add_keyarg(
111 name = "mirror",
112 default = False,
113 basic_types = ["bool"],
114 desc_short = "mirror the distribution",
115 desc = "Set this to have the models distributed along the motional mode shift from the negative angle to positive angle, and then return to the negative angle."
116 )
117 uf.add_keyarg(
118 name = "force",
119 default = False,
120 basic_types = ["bool"],
121 desc_short = "force flag",
122 desc = "A flag which, if set to True, will overwrite the any pre-existing file."
123 )
124
125 uf.desc.append(Desc_container())
126 uf.desc[-1].add_paragraph("An alternative way to visualise the frame order motions is to decompose the motions and visualise each mode separately. This user function will create a uniform distribution of structures shifted from the original position and rotated around the eigenvector for that motional mode. Each distribution will be output to a PDB file appended with '_modeX.pdb', where X are the discrete motional modes ordered from largest to smallest. The curved line of positions will extend over the full distribution of structures.")
127 uf.backend = decompose
128 uf.menu_text = "&decompose"
129 uf.gui_icon = "oxygen.actions.document-save"
130 uf.wizard_height_desc = 420
131 uf.wizard_size = (900, 600)
132 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
133
134
135
136 uf = uf_info.add_uf('frame_order.distribute')
137 uf.title = "Structural distribution of the frame order motions."
138 uf.title_short = "Frame order motional distribution."
139 uf.add_keyarg(
140 name = "file",
141 default = "distribution.pdb.gz",
142 arg_type = "file sel read",
143 desc_short = "distribution file",
144 desc = "The PDB file for storing the frame order motional distribution. The compression is determined automatically by the file extensions '*.pdb', '*.pdb.gz', and '*.pdb.bz2'.",
145 wiz_filesel_wildcard = WILDCARD_STRUCT_PDB_ALL,
146 wiz_filesel_preview = False
147 )
148 uf.add_keyarg(
149 name = "dir",
150 arg_type = "dir",
151 desc_short = "directory name",
152 desc = "The directory where the files are to be located.",
153 can_be_none = True
154 )
155 uf.add_keyarg(
156 name = "atom_id",
157 basic_types = ["str"],
158 desc_short = "atom identification string",
159 desc = "The atom identification string to allow the distribution to be a subset of all atoms.",
160 can_be_none = True
161 )
162 uf.add_keyarg(
163 name = "total",
164 default = 1000,
165 min = 1,
166 max = 1000000,
167 basic_types = ["int"],
168 desc_short = "total number of structures",
169 desc = "The total number of structures to include in the uniform distribution.",
170 wiz_element_type = "spin"
171 )
172 uf.add_keyarg(
173 name = "max_rotations",
174 default = 100000,
175 min = 1,
176 max = 100000000,
177 basic_types = ["int"],
178 desc_short = "maximum number of rotations",
179 desc = "The maximum number of rotations to generate the distribution from. This prevents the user function from executing for an infinite amount of time. This occurs whenever a frame order amplitude parameter (cone opening angle or torsion angle) is zero so that the subset of all rotations within the motional distribution is also zero.",
180 wiz_element_type = "spin"
181 )
182 uf.add_keyarg(
183 name = "model",
184 default = 1,
185 min = 1,
186 basic_types = ["int"],
187 desc_short = "original structural model",
188 desc = "Only one model from an analysed ensemble of structures can be used for the distribution, as the distribution PDB file consists of one model per state.",
189 wiz_element_type = "spin"
190 )
191 uf.add_keyarg(
192 name = "force",
193 default = False,
194 basic_types = ["bool"],
195 desc_short = "force flag",
196 desc = "A flag which, if set to True, will overwrite the any pre-existing file."
197 )
198
199 uf.desc.append(Desc_container())
200 uf.desc[-1].add_paragraph("To visualise the frame order motions, this user function generates a distribution of structures randomly within the bounds of the uniform distribution of the frame order model. The original structure is rotated randomly and only accepted for the distribution if it is within the bounds. This is a more faithful representation of the dynamics than the pseudo-Brownian simulation user function.")
201 uf.desc[-1].add_paragraph("Note that the RDC and PCS data does not contain information about all parts of the real distribution of structures. Therefore the structures in this distribution only represent the components of the distribution present in the data, as modelled by the frame order models.")
202 uf.desc[-1].add_paragraph("As the distribution consists of one model per state, if an ensemble of structures has been analysed, only one model from the ensemble can be used for the representation.")
203 uf.backend = distribute
204 uf.menu_text = "&distribute"
205 uf.gui_icon = "oxygen.actions.document-save"
206 uf.wizard_height_desc = 420
207 uf.wizard_size = (900, 600)
208 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
209
210
211
212 uf = uf_info.add_uf('frame_order.pdb_model')
213 uf.title = "Create a PDB file representation of the frame order dynamics."
214 uf.title_short = "Frame order dynamics PDB representation."
215 uf.add_keyarg(
216 name = "ave_pos",
217 default = "ave_pos",
218 basic_types = ["str"],
219 desc_short = "average structure file root",
220 desc = "The file root of the 3D structure PDB file for the molecular structure with the moving domains shifted to the average position.",
221 can_be_none = True
222 )
223 uf.add_keyarg(
224 name = "rep",
225 default = "frame_order",
226 basic_types = ["str"],
227 desc_short = "PDB representation file root",
228 desc = "The file root of the PDB file for the geometric object representation of the frame order dynamics.",
229 can_be_none = True
230 )
231 uf.add_keyarg(
232 name = "dir",
233 arg_type = "dir",
234 desc_short = "directory name",
235 desc = "The directory where the files are to be located.",
236 can_be_none = True
237 )
238 uf.add_keyarg(
239 name = "compress_type",
240 default = 0,
241 basic_types = ["int"],
242 desc_short = "file compression",
243 desc = "The type of compression to use when creating the files.",
244 wiz_element_type = "combo",
245 wiz_combo_choices = [
246 "No compression",
247 "bzip2 compression",
248 "gzip compression"
249 ],
250 wiz_combo_data = [
251 0,
252 1,
253 2
254 ],
255 wiz_read_only = True
256 )
257 uf.add_keyarg(
258 name = "size",
259 default = 30.0,
260 basic_types = ["number"],
261 desc_short = "geometric object size",
262 desc = "The size of the geometric object in Angstroms."
263 )
264 uf.add_keyarg(
265 name = "inc",
266 default = 36,
267 basic_types = ["int"],
268 desc_short = "increment number",
269 desc = "The number of increments used to create the geometric object.",
270 wiz_element_type = "spin"
271 )
272 uf.add_keyarg(
273 name = "model",
274 default = 1,
275 min = 1,
276 basic_types = ["int"],
277 desc_short = "structural model",
278 desc = "Only one model from an analysed ensemble can be used for the PDB representation of the Monte Carlo simulations of the average domain position, as these consists of one model per simulation.",
279 wiz_element_type = "spin"
280 )
281 uf.add_keyarg(
282 name = "force",
283 default = False,
284 basic_types = ["bool"],
285 desc_short = "force flag",
286 desc = "A flag which, if set to True, will overwrite the any pre-existing files."
287 )
288
289 uf.desc.append(Desc_container())
290 uf.desc[-1].add_paragraph("This function creates a set of PDB files for representing the frame order cone models. This includes a file for the average position of the molecule and a file containing a geometric representation of the frame order motions.")
291 uf.desc[-1].add_paragraph("The three files are specified via the file root whereby the extensions '.pdb', '.pdb.gz', etc. should not be provided. This is important for the geometric representation whereby different files are created for the positive and negative representations (due to symmetry in the NMR data, these cannot be differentiated), and for the Monte Carlo simulations. For example if the file root is 'frame_order', the positive and negative representations will be placed in the 'frame_order_pos.pdb.gz' and 'frame_order_neg.pdb.gz' files and the Monte Carlo simulations in the 'frame_order_sim_pos.pdb.gz' and 'frame_order_sim_neg.pdb.gz' files. For models where there is no difference in representation between the positive and negative directions, the files 'frame_order.pdb.gz' and 'frame_order_sim.pdb.gz' will be produced.")
292 uf.desc[-1].add_paragraph("There are four different types of residue within the PDB. The pivot point is represented as as a single carbon atom of the residue 'PIV'. The cone consists of numerous H atoms of the residue 'CON'. The cone axis vector is presented as the residue 'AXE' with one carbon atom positioned at the pivot and the other x Angstroms away on the cone axis (set by the geometric object size). Finally, if Monte Carlo have been performed, there will be multiple 'MCC' residues representing the cone for each simulation, and multiple 'MCA' residues representing the multiple cone axes.")
293 uf.desc[-1].add_paragraph("To create the diffusion in a cone PDB representation, a uniform distribution of vectors on a sphere is generated using spherical coordinates with the polar angle defined by the cone axis. 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 are all placed into the PDB file as 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 representing the filled cone.")
294 uf.desc[-1].add_paragraph("The PDB representation of the Monte Carlo simulations consists of one model per simulation. Therefore if an ensemble of structures has been analysed, only one model from the ensemble can be used for the representation. This defaults to model number 1, but this can be changed.")
295 uf.backend = pdb_model
296 uf.menu_text = "pdb_&model"
297 uf.gui_icon = "oxygen.actions.document-save"
298 uf.wizard_height_desc = 400
299 uf.wizard_size = (1000, 750)
300 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
301
302
303
304 uf = uf_info.add_uf('frame_order.permute_axes')
305 uf.title = "Permute the axes of the motional eigenframe to switch between local minima."
306 uf.title_short = "Eigenframe axis permutation."
307 uf.add_keyarg(
308 name = "permutation",
309 default = "A",
310 basic_types = ["str"],
311 desc_short = "permutation",
312 desc = "Which of the two permutations 'A' or 'B' to create. Three permutations are possible, and 'A' and 'B' select those which are not the starting combination.",
313 wiz_element_type = "combo",
314 wiz_combo_choices = [
315 "A",
316 "B"
317 ],
318 wiz_read_only = True
319 )
320
321 uf.desc.append(Desc_container())
322 uf.desc[-1].add_paragraph("The isotropic and pseudo-elliptic cone frame order models consist of multiple solutions as the optimisation space contains multiple local minima. Because of the constraint cone_theta_x <= cone_theta_y in the pseudo-ellipse model, there are exactly three local minima (out of 6 possible permutations). However the cone_theta_x == cone_theta_y condition of the isotropic cone collapses this to two minima. The multiple minima correspond to permutations of the motional system - the eigenframe x, y and z-axes as well as the cone opening angles cone_theta_x, cone_theta_y, and cone_sigma_max associated with these axes. But as the mechanics of the cone angles is not identical to that of the torsion angle, only one of the three local minima is the global minimum.")
323 uf.desc[-1].add_paragraph("When optimising the pseudo-elliptic models, specifically the '%s' and '%s' model, any of the three local minima can be found. Convergence to the global minimum is not guaranteed. Therefore this user function can be used to permute the motional system to jump from one local minimum to the other. Optimisation will be required as the permuted parameters will not be exactly at the minimum." % (MODEL_PSEUDO_ELLIPSE, MODEL_PSEUDO_ELLIPSE_TORSIONLESS))
324 table = uf_tables.add_table(label="table: frame_order.permute_axes combinations", caption="The motional eigenframe axis permutations for the frame order models.", caption_short="The frame order axis permutations.")
325 table.add_headings(["Condition", "Permutation name", "Cone angles", "Axes"])
326 table.add_row(["x < y < z", "Self", "[x, y, z]", "[x, y, z]"])
327 table.add_row([" ", " A ", "[x, z, y]", "[-z, y, x]"])
328 table.add_row([" ", " B ", "[y, z, x]", "[z, x, y]"])
329 table.add_row(["x < z < y", "Self", "[x, y, z]", "[x, y, z]"])
330 table.add_row([" ", " A ", "[x, z, y]", "[-z, y, x]"])
331 table.add_row([" ", " B ", "[z, y, x]", "[x, -z, y]"])
332 table.add_row(["z < x < y", "Self", "[x, y, z]", "[x, y, z]"])
333 table.add_row([" ", " A ", "[z, x, y]", "[y, z, x]"])
334 table.add_row([" ", " B ", "[z, y, x]", "[x, -z, y]"])
335 uf.desc[-1].add_table(table.label)
336 uf.desc[-1].add_paragraph("In this table, the condition and cone angle values [x, y, z] correspond to cone_theta_x, cone_theta_y, and cone_sigma_max.")
337
338 uf.desc.append(Desc_container("Prompt examples"))
339 uf.desc[-1].add_paragraph("For combination 'A', simply type:")
340 uf.desc[-1].add_prompt("relax> frame_order.permute_axes('A')")
341 uf.backend = permute_axes
342 uf.menu_text = "per&mute_axes"
343 uf.wizard_height_desc = 580
344 uf.wizard_size = (1000, 750)
345 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
346
347
348
349 uf = uf_info.add_uf('frame_order.pivot')
350 uf.title = "Set the pivot points for the two body motion in the structural coordinate system."
351 uf.title_short = "Pivot point setting."
352 uf.add_keyarg(
353 name = "pivot",
354 basic_types = ["number"],
355 container_types = ["number array"],
356 dim = (3,),
357 desc_short = "pivot point",
358 desc = "The pivot point for the motion (e.g. the position between the 2 domains in PDB coordinates).",
359 can_be_none = True
360 )
361 uf.add_keyarg(
362 name = "order",
363 default = 1,
364 min = 1,
365 max = 100,
366 basic_types = ["int"],
367 desc_short = "pivot point number",
368 desc = "The ordinal number of the pivot point. The value of 1 is for the first pivot point, the value of 2 for the second pivot point, and so on.",
369 wiz_element_type = "spin"
370 )
371 uf.add_keyarg(
372 name = "fix",
373 basic_types = ["bool"],
374 default = False,
375 desc_short = "fixed flag",
376 desc = "A flag specifying if the pivot point should be fixed during optimisation."
377 )
378
379 uf.desc.append(Desc_container())
380 uf.desc[-1].add_paragraph("This will set the pivot points for the two domain system within the PDB coordinate system. This is required for interpreting PCS data as well as for the generation of cone or other PDB representations of the domain motions.")
381 uf.desc[-1].add_paragraph("This user function can also be used to change the optimisation status of an already set pivot point. By simply providing the fixed flag and not the pivot point values, the pivot can be changed to be either fixed during optimisation or that it will be optimised.")
382
383 uf.desc.append(Desc_container("Prompt examples"))
384 uf.desc[-1].add_paragraph("To set the pivot point, type one of:")
385 uf.desc[-1].add_prompt("relax> frame_order.pivot([12.067, 14.313, -3.2675])")
386 uf.desc[-1].add_prompt("relax> frame_order.pivot(pivot=[12.067, 14.313, -3.2675])")
387 uf.desc[-1].add_paragraph("To change an already set and fixed pivot point so that it can now be optimised, type:")
388 uf.desc[-1].add_prompt("relax> frame_order.pivot(fix=False)")
389 uf.backend = pivot
390 uf.menu_text = "&pivot"
391 uf.wizard_size = (900, 600)
392 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
393
394
395
396 uf = uf_info.add_uf('frame_order.quad_int')
397 uf.title = "Turn the high precision quadratic integration on or off."
398 uf.title_short = "Quadratic integration."
399 uf.add_keyarg(
400 name = "flag",
401 default = True,
402 basic_types = ["bool"],
403 desc_short = "flag",
404 desc = "The flag with if True will perform high precision numerical integration via the scipy.integrate quad(), dblquad() and tplquad() integration methods rather than the rough quasi-random numerical integration."
405 )
406
407 uf.desc.append(Desc_container())
408 uf.desc[-1].add_paragraph("This allows the high precision numerical integration of the Scipy quad() and related functions to be used instead of the lower precision quasi-random Sobol' sequence integration. This is for the optimisation of the Frame Order target functions. The quadratic integration is orders of magnitude slower than the Sobol' sequence integration, but the precision is much higher.")
409 uf.backend = quad_int
410 uf.menu_text = "&quad_int"
411 uf.gui_icon = "oxygen.actions.edit-rename"
412 uf.wizard_size = (900, 500)
413 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
414
415
416
417 uf = uf_info.add_uf('frame_order.ref_domain')
418 uf.title = "Set the reference non-moving domain for the 2-domain frame order theories."
419 uf.title_short = "Reference non-moving domain set up."
420 uf.add_keyarg(
421 name = "ref",
422 basic_types = ["str"],
423 desc_short = "non-moving reference domain",
424 desc = "The non-moving domain which will act as the frame of reference."
425 )
426
427 uf.desc.append(Desc_container())
428 uf.desc[-1].add_paragraph("Prior to optimisation of the frame order model, the frame of reference non-moving domain must be specified. This is essential for determining which spins will be used in the analysis, which will be shifted to the average position, etc.")
429
430 uf.desc.append(Desc_container("Prompt examples"))
431 uf.desc[-1].add_paragraph("To set up the isotropic cone frame order model with 'centre' domain being the frame of reference, type:")
432 uf.desc[-1].add_prompt("relax> frame_order.ref_domain(ref='centre')")
433 uf.backend = ref_domain
434 uf.menu_text = "&ref_domain"
435 uf.gui_icon = "oxygen.actions.edit-rename"
436 uf.wizard_size = (900, 500)
437 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
438
439
440
441 uf = uf_info.add_uf('frame_order.select_model')
442 uf.title = "Select and set up the Frame Order model."
443 uf.title_short = "Model choice."
444 uf.add_keyarg(
445 name = "model",
446 basic_types = ["str"],
447 desc_short = "Frame Order model",
448 desc = "The name of the preset Frame Order model.",
449 wiz_element_type = "combo",
450 wiz_combo_choices = [
451 "Rigid model",
452 "Rotor model",
453 "Free rotor model",
454 "Torsionless isotropic cone",
455 "Isotropic cone",
456 "Free rotor isotropic cone",
457 "Torsionless pseudo-ellipse",
458 "Pseudo-ellipse",
459 "Free rotor pseudo-ellipse",
460 "Double rotor"
461 ],
462 wiz_combo_data = [
463 MODEL_RIGID,
464 MODEL_ROTOR,
465 MODEL_FREE_ROTOR,
466 MODEL_ISO_CONE_TORSIONLESS,
467 MODEL_ISO_CONE,
468 MODEL_ISO_CONE_FREE_ROTOR,
469 MODEL_PSEUDO_ELLIPSE_TORSIONLESS,
470 MODEL_PSEUDO_ELLIPSE,
471 MODEL_PSEUDO_ELLIPSE_FREE_ROTOR,
472 MODEL_DOUBLE_ROTOR
473 ],
474 wiz_read_only = True,
475 )
476
477 uf.desc.append(Desc_container())
478 uf.desc[-1].add_paragraph("Prior to optimisation, the Frame Order model should be selected. These models consist of three parameter categories:")
479 uf.desc[-1].add_list_element("The average domain position. This includes the parameters ave_pos_alpha, ave_pos_beta, and ave_pos_gamma. These Euler angles rotate the tensors from the arbitrary PDB frame of the moving domain to the average domain position.")
480 uf.desc[-1].add_list_element("The frame order eigenframe. This includes the parameters eigen_alpha, eigen_beta, and eigen_gamma. These Euler angles define the major modes of motion. The cone central axis is defined as the z-axis. The pseudo-elliptic cone x and y-axes are defined as the x and y-axes of the eigenframe.")
481 uf.desc[-1].add_list_element("The cone parameters. These are defined as the tilt-torsion angles cone_theta_x, cone_theta_y, and cone_sigma_max. The cone_theta_x and cone_theta_y parameters define the two cone opening angles of the pseudo-ellipse. The amount of domain torsion is defined as the average domain position, plus and minus cone_sigma_max. The isotropic cones are defined by setting cone_theta_x = cone_theta_y and converting the single parameter into a 2nd rank order parameter.")
482 uf.desc[-1].add_paragraph("The list of available models are:")
483 uf.desc[-1].add_item_list_element(repr(MODEL_PSEUDO_ELLIPSE), "The pseudo-elliptic cone model. This is the full model consisting of the parameters ave_pos_alpha, ave_pos_beta, ave_pos_gamma, eigen_alpha, eigen_beta, eigen_gamma, cone_theta_x, cone_theta_y, and cone_sigma_max.")
484 uf.desc[-1].add_item_list_element(repr(MODEL_PSEUDO_ELLIPSE_TORSIONLESS), "The pseudo-elliptic cone with the torsion angle cone_sigma_max set to zero.")
485 uf.desc[-1].add_item_list_element(repr(MODEL_PSEUDO_ELLIPSE_FREE_ROTOR), "The pseudo-elliptic cone with no torsion angle restriction.")
486 uf.desc[-1].add_item_list_element(repr(MODEL_ISO_CONE), "The isotropic cone model. The cone is defined by a single order parameter s1 which is related to the single cone opening angle cone_theta_x = cone_theta_y. Due to rotational symmetry about the cone axis, the average position alpha Euler angle ave_pos_alpha is dropped from the model. The symmetry also collapses the eigenframe to a single z-axis defined by the parameters axis_theta and axis_phi.")
487 uf.desc[-1].add_item_list_element(repr(MODEL_ISO_CONE_TORSIONLESS), "The isotropic cone model with the torsion angle cone_sigma_max set to zero.")
488 uf.desc[-1].add_item_list_element(repr(MODEL_ISO_CONE_FREE_ROTOR), "The isotropic cone model with no torsion angle restriction.")
489 uf.desc[-1].add_item_list_element(repr(MODEL_ROTOR), "The only motion is a rotation about the cone axis restricted by the torsion angle cone_sigma_max.")
490 uf.desc[-1].add_item_list_element(repr(MODEL_RIGID), "No domain motions.")
491 uf.desc[-1].add_item_list_element(repr(MODEL_FREE_ROTOR), "The only motion is free rotation about the cone axis.")
492 uf.desc[-1].add_item_list_element(repr(MODEL_DOUBLE_ROTOR), "Restricted motions about two independent but orthogonal rotor axes. The first rotation is about the y-axis and the second is about the x-axis.")
493
494 uf.desc.append(Desc_container("Prompt examples"))
495 uf.desc[-1].add_paragraph("To select the isotropic cone model, type:")
496 uf.desc[-1].add_prompt("relax> frame_order.select_model(model='%s')" % MODEL_ISO_CONE)
497 uf.backend = select_model
498 uf.menu_text = "&select_model"
499 uf.gui_icon = "oxygen.actions.list-add"
500 uf.wizard_height_desc = 560
501 uf.wizard_size = (1000, 750)
502 uf.wizard_apply_button = False
503 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
504
505
506
507 uf = uf_info.add_uf('frame_order.simulate')
508 uf.title = "Pseudo-Brownian dynamics simulation of the frame order motions."
509 uf.title_short = "Frame order pseudo-Brownian dynamics simulation."
510 uf.add_keyarg(
511 name = "file",
512 default = "simulation.pdb.gz",
513 arg_type = "file sel read",
514 desc_short = "simulation file",
515 desc = "The PDB file for storing the frame order pseudo-Brownian dynamics simulation. The compression is determined automatically by the file extensions '*.pdb', '*.pdb.gz', and '*.pdb.bz2'.",
516 wiz_filesel_wildcard = WILDCARD_STRUCT_PDB_ALL,
517 wiz_filesel_preview = False
518 )
519 uf.add_keyarg(
520 name = "dir",
521 arg_type = "dir",
522 desc_short = "directory name",
523 desc = "The directory where the files are to be located.",
524 can_be_none = True
525 )
526 uf.add_keyarg(
527 name = "step_size",
528 default = 2.0,
529 basic_types = ["float"],
530 desc_short = "angle of rotation",
531 desc = "The rotation will be of a random direction but with this fixed angle. The value is in degrees."
532 )
533 uf.add_keyarg(
534 name = "snapshot",
535 default = 10,
536 min = 1,
537 max = 1000000,
538 basic_types = ["int"],
539 desc_short = "number of steps per snapshot",
540 desc = "The number of steps in the simulation when snapshots will be taken."
541 )
542 uf.add_keyarg(
543 name = "total",
544 default = 1000,
545 min = 1,
546 max = 1000000,
547 basic_types = ["int"],
548 desc_short = "total number of snapshots",
549 desc = "The total number of snapshots to take before stopping the simulation.",
550 wiz_element_type = "spin"
551 )
552 uf.add_keyarg(
553 name = "model",
554 default = 1,
555 min = 1,
556 basic_types = ["int"],
557 desc_short = "original structural model",
558 desc = "Only one model from an analysed ensemble of structures can be used for the pseudo-Brownian simulation, as the simulation and corresponding PDB file consists of one model per simulation.",
559 wiz_element_type = "spin"
560 )
561 uf.add_keyarg(
562 name = "force",
563 default = False,
564 basic_types = ["bool"],
565 desc_short = "force flag",
566 desc = "A flag which, if set to True, will overwrite the any pre-existing file."
567 )
568
569 uf.desc.append(Desc_container())
570 uf.desc[-1].add_paragraph("To visualise the frame order motions, this user function performs a type of simulation whereby structures are randomly rotated by a fixed angle within the bounds of the uniform distribution of the frame order model. This can be thought of as a pseudo-Brownian dynamics simulation. It is in no way a real molecular or Brownian dynamics simulation.")
571 uf.desc[-1].add_paragraph("Note that the RDC and PCS data does not contain information about all parts of the real distribution of structures. Therefore the snapshots in this simulation only represent the components of the distribution present in the data, as modelled by the frame order models.")
572 uf.desc[-1].add_paragraph("The simulation algorithm is as follows. The current state is initially defined as the identity matrix I. The maximum opening angle theta or the torsion angle sigma are defined by the parameter values of the frame order model. The algorithm for one step of the simulation is:")
573 uf.desc[-1].add_item_list_element("1", "Generate a random vector in 3D.")
574 uf.desc[-1].add_item_list_element("2", "Construct a rotation matrix from the random vector and the fixed rotation angle.")
575 uf.desc[-1].add_item_list_element("3", "Pre-multiply the current state by the rotation matrix.")
576 uf.desc[-1].add_item_list_element("4", "Decompose the new state into the torsion-tilt angles.")
577 uf.desc[-1].add_item_list_element("5", "If theta or sigma are greater than model parameter values, set them to these maximum values.")
578 uf.desc[-1].add_item_list_element("6", "Back convert the modified torsion-tilt angles to a rotation matrix - this is the current state.")
579 uf.desc[-1].add_item_list_element("7", "Store a snapshot if the correct number of iterations has been reached. This consists of rotating a new model about the pivot(s), as defined by the frame order model.")
580 uf.desc[-1].add_item_list_element("8", "Terminate the loop if the maximum number of snapshots has been reached.")
581 uf.desc[-1].add_paragraph("The setting of the steps outside of the distribution to the maximum parameter values is specifically to allow for models with parameter values close to zero. Without this, the simulation would take a huge amount of time to complete.")
582 uf.desc[-1].add_paragraph("As the simulation consists of one model per snapshot, if an ensemble of structures has been analysed, only one model from the ensemble can be used for the representation. This defaults to model number 1, but this can be changed.")
583 uf.backend = simulate
584 uf.menu_text = "simula&te"
585 uf.gui_icon = "oxygen.actions.document-save"
586 uf.wizard_height_desc = 420
587 uf.wizard_size = (1000, 750)
588 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
589
590
591
592 uf = uf_info.add_uf('frame_order.sobol_setup')
593 uf.title = "Set up the quasi-random Sobol' sequence points for numerical PCS integration."
594 uf.title_short = "Set up the quasi-random Sobol' sequence."
595 uf.add_keyarg(
596 name = "max_num",
597 default = 200,
598 min = 3,
599 max = 10000000,
600 basic_types = ["int"],
601 desc_short = "maximum number of Sobol' points",
602 desc = "The maximum number of integration points to use in the Sobol' sequence during optimisation. This can be considered as the number of molecular structures in an ensemble used form a uniform distribution of the dynamics.",
603 wiz_element_type = "spin"
604 )
605 uf.add_keyarg(
606 name = "oversample",
607 default = 1,
608 min = 1,
609 max = 100000,
610 basic_types = ["int"],
611 desc_short = "oversampling factor",
612 desc = "The generation of the Sobol' sequence oversamples as N * Ov * 10**M, where N is the maximum number of points, Ov is the oversamling value, and M is the number of dimensions or torsion-tilt angles used in the system.",
613 wiz_element_type = "spin"
614 )
615
616 uf.desc.append(Desc_container())
617 uf.desc[-1].add_paragraph("This allows the maximum number of integration points N used during the frame order target function optimisation to be specified. This is used in the quasi-random Sobol' sequence for the numerical integration of the PCS. The formula used to find the total number of Sobol' points is:")
618 uf.desc[-1].add_verbatim("""
619 total_num = N * Ov * 10**M,
620 """)
621 uf.desc[-1].add_paragraph("where:")
622 uf.desc[-1].add_list_element("N is the maximum number of Sobol' integration points,")
623 uf.desc[-1].add_list_element("Ov is the oversampling factor.")
624 uf.desc[-1].add_list_element("M is the number of dimensions or torsion-tilt angles used in the system.")
625 uf.desc[-1].add_paragraph("The aim of the oversampling is to try to reach the maximum number of points. However if the system is not very dynamic, the maximum number of points may not be reached. In this case, simply increase the oversampling factor. The algorithm used for uniformly sampling the motional space is:")
626 uf.desc[-1].add_list_element("Generate the Sobol' sequence for the total number of points.")
627 uf.desc[-1].add_list_element("Convert all points to the torsion-tilt angle system.")
628 uf.desc[-1].add_list_element("Skip all Sobol' points with angles greater than the current parameter values.")
629 uf.desc[-1].add_list_element("Terminate the loop over the Sobol' points once the maximum number of points has been reached.")
630 uf.backend = sobol_setup
631 uf.menu_text = "&sobol_setup"
632 uf.gui_icon = "oxygen.actions.edit-rename"
633 uf.wizard_height_desc = 500
634 uf.wizard_size = (1000, 700)
635 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
636