Package user_functions :: Module frame_order
[hide private]
[frames] | no frames]

Source Code for Module user_functions.frame_order

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2009-2015 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """The frame_order user function definitions.""" 
 24   
 25  # Python module imports. 
 26  import dep_check 
 27  if dep_check.wx_module: 
 28      from wx import FD_OPEN 
 29  else: 
 30      FD_OPEN = -1 
 31   
 32  # relax module imports. 
 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  # The user function class. 
 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  # The frame_order.count_sobol_points user function. 
 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  # Description. 
 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  # The frame_order.distribute user function. 
 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  # Description. 
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  # The frame_order.pdb_model user function. 
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  # Description. 
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  # The frame_order.permute_axes user function. 
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  # Description. 
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  # Prompt examples. 
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  # The frame_order.pivot user function. 
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  # Description. 
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  # Prompt examples. 
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  # The frame_order.quad_int user function. 
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  # Description. 
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  # The frame_order.ref_domain user function. 
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  # Description. 
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  # Prompt examples. 
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  # The frame_order.select_model user function. 
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  # Description. 
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  # Prompt examples. 
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  # The frame_order.simulate user function. 
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  # Description. 
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  # The frame_order.sobol_setup user function. 
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  # Description. 
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