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 import dep_check
27 if dep_check.wx_module:
28 from wx import FD_OPEN
29 else:
30 FD_OPEN = -1
31
32
33 from graphics import WIZARD_IMAGE_PATH
34 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
35 from specific_analyses.frame_order.optimisation import count_sobol_points
36 from specific_analyses.frame_order.uf import distribute, sobol_setup, pdb_model, permute_axes, pivot, quad_int, ref_domain, select_model, simulate
37 from user_functions.data import Uf_info; uf_info = Uf_info()
38 from user_functions.data import Uf_tables; uf_tables = Uf_tables()
39 from user_functions.objects import Desc_container
40 from user_functions.wildcards import WILDCARD_STRUCT_PDB_ALL
41
42
43
44 uf_class = uf_info.add_class('frame_order')
45 uf_class.title = "Class containing the user functions of the Frame Order theories."
46 uf_class.menu_text = "&frame_order"
47 uf_class.gui_icon = "relax.frame_order"
48
49
50
51 uf = uf_info.add_uf('frame_order.count_sobol_points')
52 uf.title = "Count the number of Sobol' points used for the current parameter values."
53 uf.title_short = "Used Sobol' point count."
54
55 uf.desc.append(Desc_container())
56 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.")
57 uf.backend = count_sobol_points
58 uf.menu_text = "&count_sobol_points"
59 uf.gui_icon = "oxygen.categories.applications-education"
60 uf.wizard_size = (800, 400)
61 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
62
63
64
65 uf = uf_info.add_uf('frame_order.distribute')
66 uf.title = "Structural distribution of the frame order motions."
67 uf.title_short = "Frame order motional distribution."
68 uf.add_keyarg(
69 name = "file",
70 default = "distribution.pdb.gz",
71 py_type = "str",
72 arg_type = "file sel",
73 desc_short = "distribution file",
74 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'.",
75 wiz_filesel_wildcard = WILDCARD_STRUCT_PDB_ALL,
76 wiz_filesel_style = FD_OPEN,
77 wiz_filesel_preview = False
78 )
79 uf.add_keyarg(
80 name = "dir",
81 py_type = "str",
82 arg_type = "dir",
83 desc_short = "directory name",
84 desc = "The directory where the files are to be located.",
85 can_be_none = True
86 )
87 uf.add_keyarg(
88 name = "atom_id",
89 py_type = "str",
90 desc_short = "atom identification string",
91 desc = "The atom identification string to allow the distribution to be a subset of all atoms.",
92 can_be_none = True
93 )
94 uf.add_keyarg(
95 name = "total",
96 default = 1000,
97 min = 1,
98 max = 1000000,
99 py_type = "int",
100 desc_short = "total number of structures",
101 desc = "The total number of structures to include in the uniform distribution.",
102 wiz_element_type = "spin"
103 )
104 uf.add_keyarg(
105 name = "max_rotations",
106 default = 100000,
107 min = 1,
108 max = 100000000,
109 py_type = "int",
110 desc_short = "maximum number of rotations",
111 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.",
112 wiz_element_type = "spin"
113 )
114 uf.add_keyarg(
115 name = "model",
116 default = 1,
117 min = 1,
118 py_type = "int",
119 desc_short = "original structural model",
120 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.",
121 wiz_element_type = "spin"
122 )
123 uf.add_keyarg(
124 name = "force",
125 default = False,
126 py_type = "bool",
127 desc_short = "force flag",
128 desc = "A flag which, if set to True, will overwrite the any pre-existing file."
129 )
130
131 uf.desc.append(Desc_container())
132 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.")
133 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.")
134 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.")
135 uf.backend = distribute
136 uf.menu_text = "&distribute"
137 uf.gui_icon = "oxygen.actions.document-save"
138 uf.wizard_height_desc = 420
139 uf.wizard_size = (900, 600)
140 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
141
142
143
144 uf = uf_info.add_uf('frame_order.pdb_model')
145 uf.title = "Create a PDB file representation of the frame order dynamics."
146 uf.title_short = "Frame order dynamics PDB representation."
147 uf.add_keyarg(
148 name = "ave_pos",
149 default = "ave_pos",
150 py_type = "str",
151 arg_type = "str",
152 desc_short = "average structure file root",
153 desc = "The file root of the 3D structure PDB file for the molecular structure with the moving domains shifted to the average position.",
154 can_be_none = True
155 )
156 uf.add_keyarg(
157 name = "rep",
158 default = "frame_order",
159 py_type = "str",
160 arg_type = "str",
161 desc_short = "PDB representation file root",
162 desc = "The file root of the PDB file for the geometric object representation of the frame order dynamics.",
163 can_be_none = True
164 )
165 uf.add_keyarg(
166 name = "dir",
167 py_type = "str",
168 arg_type = "dir",
169 desc_short = "directory name",
170 desc = "The directory where the files are to be located.",
171 can_be_none = True
172 )
173 uf.add_keyarg(
174 name = "compress_type",
175 default = 0,
176 py_type = "int",
177 desc_short = "file compression",
178 desc = "The type of compression to use when creating the files.",
179 wiz_element_type = "combo",
180 wiz_combo_choices = [
181 "No compression",
182 "bzip2 compression",
183 "gzip compression"
184 ],
185 wiz_combo_data = [
186 0,
187 1,
188 2
189 ],
190 wiz_read_only = True
191 )
192 uf.add_keyarg(
193 name = "size",
194 default = 30.0,
195 py_type = "num",
196 desc_short = "geometric object size",
197 desc = "The size of the geometric object in Angstroms."
198 )
199 uf.add_keyarg(
200 name = "inc",
201 default = 36,
202 py_type = "int",
203 desc_short = "increment number",
204 desc = "The number of increments used to create the geometric object.",
205 wiz_element_type = "spin"
206 )
207 uf.add_keyarg(
208 name = "model",
209 default = 1,
210 min = 1,
211 py_type = "int",
212 desc_short = "structural model",
213 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.",
214 wiz_element_type = "spin"
215 )
216 uf.add_keyarg(
217 name = "force",
218 default = False,
219 py_type = "bool",
220 desc_short = "force flag",
221 desc = "A flag which, if set to True, will overwrite the any pre-existing files."
222 )
223
224 uf.desc.append(Desc_container())
225 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.")
226 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.")
227 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.")
228 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.")
229 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.")
230 uf.backend = pdb_model
231 uf.menu_text = "pdb_&model"
232 uf.gui_icon = "oxygen.actions.document-save"
233 uf.wizard_height_desc = 400
234 uf.wizard_size = (1000, 750)
235 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
236
237
238
239 uf = uf_info.add_uf('frame_order.permute_axes')
240 uf.title = "Permute the axes of the motional eigenframe to switch between local minima."
241 uf.title_short = "Eigenframe axis permutation."
242 uf.add_keyarg(
243 name = "permutation",
244 default = "A",
245 py_type = "str",
246 desc_short = "permutation",
247 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.",
248 wiz_element_type = "combo",
249 wiz_combo_choices = [
250 "A",
251 "B"
252 ],
253 wiz_read_only = True
254 )
255
256 uf.desc.append(Desc_container())
257 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.")
258 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))
259 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.")
260 table.add_headings(["Condition", "Permutation name", "Cone angles", "Axes"])
261 table.add_row(["x < y < z", "Self", "[x, y, z]", "[x, y, z]"])
262 table.add_row([" ", " A ", "[x, z, y]", "[-z, y, x]"])
263 table.add_row([" ", " B ", "[y, z, x]", "[z, x, y]"])
264 table.add_row(["x < z < y", "Self", "[x, y, z]", "[x, y, z]"])
265 table.add_row([" ", " A ", "[x, z, y]", "[-z, y, x]"])
266 table.add_row([" ", " B ", "[z, y, x]", "[x, -z, y]"])
267 table.add_row(["z < x < y", "Self", "[x, y, z]", "[x, y, z]"])
268 table.add_row([" ", " A ", "[z, x, y]", "[y, z, x]"])
269 table.add_row([" ", " B ", "[z, y, x]", "[x, -z, y]"])
270 uf.desc[-1].add_table(table.label)
271 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.")
272
273 uf.desc.append(Desc_container("Prompt examples"))
274 uf.desc[-1].add_paragraph("For combination 'A', simply type:")
275 uf.desc[-1].add_prompt("relax> frame_order.permute_axes('A')")
276 uf.backend = permute_axes
277 uf.menu_text = "per&mute_axes"
278 uf.wizard_height_desc = 580
279 uf.wizard_size = (1000, 750)
280 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
281
282
283
284 uf = uf_info.add_uf('frame_order.pivot')
285 uf.title = "Set the pivot points for the two body motion in the structural coordinate system."
286 uf.title_short = "Pivot point setting."
287 uf.add_keyarg(
288 name = "pivot",
289 py_type = "num_list",
290 dim = 3,
291 desc_short = "pivot point",
292 desc = "The pivot point for the motion (e.g. the position between the 2 domains in PDB coordinates).",
293 can_be_none = True
294 )
295 uf.add_keyarg(
296 name = "order",
297 default = 1,
298 min = 1,
299 max = 100,
300 py_type = "int",
301 desc_short = "pivot point number",
302 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.",
303 wiz_element_type = "spin"
304 )
305 uf.add_keyarg(
306 name = "fix",
307 py_type = "bool",
308 default = False,
309 desc_short = "fixed flag",
310 desc = "A flag specifying if the pivot point should be fixed during optimisation."
311 )
312
313 uf.desc.append(Desc_container())
314 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.")
315 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.")
316
317 uf.desc.append(Desc_container("Prompt examples"))
318 uf.desc[-1].add_paragraph("To set the pivot point, type one of:")
319 uf.desc[-1].add_prompt("relax> frame_order.pivot([12.067, 14.313, -3.2675])")
320 uf.desc[-1].add_prompt("relax> frame_order.pivot(pivot=[12.067, 14.313, -3.2675])")
321 uf.desc[-1].add_paragraph("To change an already set and fixed pivot point so that it can now be optimised, type:")
322 uf.desc[-1].add_prompt("relax> frame_order.pivot(fix=False)")
323 uf.backend = pivot
324 uf.menu_text = "&pivot"
325 uf.wizard_size = (900, 600)
326 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
327
328
329
330 uf = uf_info.add_uf('frame_order.quad_int')
331 uf.title = "Turn the high precision quadratic integration on or off."
332 uf.title_short = "Quadratic integration."
333 uf.add_keyarg(
334 name = "flag",
335 default = True,
336 py_type = "bool",
337 desc_short = "flag",
338 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."
339 )
340
341 uf.desc.append(Desc_container())
342 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.")
343 uf.backend = quad_int
344 uf.menu_text = "&quad_int"
345 uf.gui_icon = "oxygen.actions.edit-rename"
346 uf.wizard_size = (900, 500)
347 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
348
349
350
351 uf = uf_info.add_uf('frame_order.ref_domain')
352 uf.title = "Set the reference non-moving domain for the 2-domain frame order theories."
353 uf.title_short = "Reference non-moving domain set up."
354 uf.add_keyarg(
355 name = "ref",
356 py_type = "str",
357 desc_short = "non-moving reference domain",
358 desc = "The non-moving domain which will act as the frame of reference."
359 )
360
361 uf.desc.append(Desc_container())
362 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.")
363
364 uf.desc.append(Desc_container("Prompt examples"))
365 uf.desc[-1].add_paragraph("To set up the isotropic cone frame order model with 'centre' domain being the frame of reference, type:")
366 uf.desc[-1].add_prompt("relax> frame_order.ref_domain(ref='centre')")
367 uf.backend = ref_domain
368 uf.menu_text = "&ref_domain"
369 uf.gui_icon = "oxygen.actions.edit-rename"
370 uf.wizard_size = (900, 500)
371 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
372
373
374
375 uf = uf_info.add_uf('frame_order.select_model')
376 uf.title = "Select and set up the Frame Order model."
377 uf.title_short = "Model choice."
378 uf.add_keyarg(
379 name = "model",
380 py_type = "str",
381 desc_short = "Frame Order model",
382 desc = "The name of the preset Frame Order model.",
383 wiz_element_type = "combo",
384 wiz_combo_choices = [
385 "Rigid model",
386 "Rotor model",
387 "Free rotor model",
388 "Torsionless isotropic cone",
389 "Isotropic cone",
390 "Free rotor isotropic cone",
391 "Torsionless pseudo-ellipse",
392 "Pseudo-ellipse",
393 "Free rotor pseudo-ellipse",
394 "Double rotor"
395 ],
396 wiz_combo_data = [
397 MODEL_RIGID,
398 MODEL_ROTOR,
399 MODEL_FREE_ROTOR,
400 MODEL_ISO_CONE_TORSIONLESS,
401 MODEL_ISO_CONE,
402 MODEL_ISO_CONE_FREE_ROTOR,
403 MODEL_PSEUDO_ELLIPSE_TORSIONLESS,
404 MODEL_PSEUDO_ELLIPSE,
405 MODEL_PSEUDO_ELLIPSE_FREE_ROTOR,
406 MODEL_DOUBLE_ROTOR
407 ],
408 wiz_read_only = True,
409 )
410
411 uf.desc.append(Desc_container())
412 uf.desc[-1].add_paragraph("Prior to optimisation, the Frame Order model should be selected. These models consist of three parameter categories:")
413 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.")
414 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.")
415 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.")
416 uf.desc[-1].add_paragraph("The list of available models are:")
417 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.")
418 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.")
419 uf.desc[-1].add_item_list_element(repr(MODEL_PSEUDO_ELLIPSE_FREE_ROTOR), "The pseudo-elliptic cone with no torsion angle restriction.")
420 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.")
421 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.")
422 uf.desc[-1].add_item_list_element(repr(MODEL_ISO_CONE_FREE_ROTOR), "The isotropic cone model with no torsion angle restriction.")
423 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.")
424 uf.desc[-1].add_item_list_element(repr(MODEL_RIGID), "No domain motions.")
425 uf.desc[-1].add_item_list_element(repr(MODEL_FREE_ROTOR), "The only motion is free rotation about the cone axis.")
426 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.")
427
428 uf.desc.append(Desc_container("Prompt examples"))
429 uf.desc[-1].add_paragraph("To select the isotropic cone model, type:")
430 uf.desc[-1].add_prompt("relax> frame_order.select_model(model='%s')" % MODEL_ISO_CONE)
431 uf.backend = select_model
432 uf.menu_text = "&select_model"
433 uf.gui_icon = "oxygen.actions.list-add"
434 uf.wizard_height_desc = 560
435 uf.wizard_size = (1000, 750)
436 uf.wizard_apply_button = False
437 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
438
439
440
441 uf = uf_info.add_uf('frame_order.simulate')
442 uf.title = "Pseudo-Brownian dynamics simulation of the frame order motions."
443 uf.title_short = "Frame order pseudo-Brownian dynamics simulation."
444 uf.add_keyarg(
445 name = "file",
446 default = "simulation.pdb.gz",
447 py_type = "str",
448 arg_type = "file sel",
449 desc_short = "simulation file",
450 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'.",
451 wiz_filesel_wildcard = WILDCARD_STRUCT_PDB_ALL,
452 wiz_filesel_style = FD_OPEN,
453 wiz_filesel_preview = False
454 )
455 uf.add_keyarg(
456 name = "dir",
457 py_type = "str",
458 arg_type = "dir",
459 desc_short = "directory name",
460 desc = "The directory where the files are to be located.",
461 can_be_none = True
462 )
463 uf.add_keyarg(
464 name = "step_size",
465 default = 2.0,
466 py_type = "float",
467 desc_short = "angle of rotation",
468 desc = "The rotation will be of a random direction but with this fixed angle. The value is in degrees."
469 )
470 uf.add_keyarg(
471 name = "snapshot",
472 default = 10,
473 min = 1,
474 max = 1000000,
475 py_type = "int",
476 desc_short = "number of steps per snapshot",
477 desc = "The number of steps in the simulation when snapshots will be taken."
478 )
479 uf.add_keyarg(
480 name = "total",
481 default = 1000,
482 min = 1,
483 max = 1000000,
484 py_type = "int",
485 desc_short = "total number of snapshots",
486 desc = "The total number of snapshots to take before stopping the simulation.",
487 wiz_element_type = "spin"
488 )
489 uf.add_keyarg(
490 name = "model",
491 default = 1,
492 min = 1,
493 py_type = "int",
494 desc_short = "original structural model",
495 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.",
496 wiz_element_type = "spin"
497 )
498 uf.add_keyarg(
499 name = "force",
500 default = False,
501 py_type = "bool",
502 desc_short = "force flag",
503 desc = "A flag which, if set to True, will overwrite the any pre-existing file."
504 )
505
506 uf.desc.append(Desc_container())
507 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.")
508 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.")
509 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:")
510 uf.desc[-1].add_item_list_element("1", "Generate a random vector in 3D.")
511 uf.desc[-1].add_item_list_element("2", "Construct a rotation matrix from the random vector and the fixed rotation angle.")
512 uf.desc[-1].add_item_list_element("3", "Pre-multiply the current state by the rotation matrix.")
513 uf.desc[-1].add_item_list_element("4", "Decompose the new state into the torsion-tilt angles.")
514 uf.desc[-1].add_item_list_element("5", "If theta or sigma are greater than model parameter values, set them to these maximum values.")
515 uf.desc[-1].add_item_list_element("6", "Back convert the modified torsion-tilt angles to a rotation matrix - this is the current state.")
516 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.")
517 uf.desc[-1].add_item_list_element("8", "Terminate the loop if the maximum number of snapshots has been reached.")
518 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.")
519 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.")
520 uf.backend = simulate
521 uf.menu_text = "simula&te"
522 uf.gui_icon = "oxygen.actions.document-save"
523 uf.wizard_height_desc = 420
524 uf.wizard_size = (1000, 750)
525 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
526
527
528
529 uf = uf_info.add_uf('frame_order.sobol_setup')
530 uf.title = "Set up the quasi-random Sobol' sequence points for numerical PCS integration."
531 uf.title_short = "Set up the quasi-random Sobol' sequence."
532 uf.add_keyarg(
533 name = "max_num",
534 default = 200,
535 min = 3,
536 max = 10000000,
537 py_type = "int",
538 desc_short = "maximum number of Sobol' points",
539 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.",
540 wiz_element_type = "spin"
541 )
542 uf.add_keyarg(
543 name = "oversample",
544 default = 1,
545 min = 1,
546 max = 100000,
547 py_type = "int",
548 desc_short = "oversampling factor",
549 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.",
550 wiz_element_type = "spin"
551 )
552
553 uf.desc.append(Desc_container())
554 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:")
555 uf.desc[-1].add_verbatim("""
556 total_num = N * Ov * 10**M,
557 """)
558 uf.desc[-1].add_paragraph("where:")
559 uf.desc[-1].add_list_element("N is the maximum number of Sobol' integration points,")
560 uf.desc[-1].add_list_element("Ov is the oversampling factor.")
561 uf.desc[-1].add_list_element("M is the number of dimensions or torsion-tilt angles used in the system.")
562 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:")
563 uf.desc[-1].add_list_element("Generate the Sobol' sequence for the total number of points.")
564 uf.desc[-1].add_list_element("Convert all points to the torsion-tilt angle system.")
565 uf.desc[-1].add_list_element("Skip all Sobol' points with angles greater than the current parameter values.")
566 uf.desc[-1].add_list_element("Terminate the loop over the Sobol' points once the maximum number of points has been reached.")
567 uf.backend = sobol_setup
568 uf.menu_text = "&sobol_setup"
569 uf.gui_icon = "oxygen.actions.edit-rename"
570 uf.wizard_height_desc = 500
571 uf.wizard_size = (1000, 700)
572 uf.wizard_image = WIZARD_IMAGE_PATH + 'frame_order.png'
573