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

Source Code for Module user_functions.interatom

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2014 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 interatom user function definitions.""" 
 24   
 25  # Python module imports. 
 26  import dep_check 
 27  from os import sep 
 28  if dep_check.wx_module: 
 29      from wx import FD_OPEN 
 30  else: 
 31      FD_OPEN = -1 
 32   
 33  # relax module imports. 
 34  from graphics import WIZARD_IMAGE_PATH 
 35  from lib.physical_constants import NH_BOND_LENGTH 
 36  from pipe_control.mol_res_spin import get_spin_ids 
 37  from pipe_control import pipes, interatomic 
 38  from user_functions.data import Uf_info; uf_info = Uf_info() 
 39  from user_functions.objects import Desc_container 
 40   
 41   
 42  # The user function class. 
 43  uf_class = uf_info.add_class('interatom') 
 44  uf_class.title = "Class for manipulating magnetic dipole-dipole interactions." 
 45  uf_class.menu_text = "&interatom" 
 46  uf_class.gui_icon = "relax.dipole_pair" 
 47   
 48   
 49  # The interatom.copy user function. 
 50  uf = uf_info.add_uf('interatom.copy') 
 51  uf.title = "Copy all data associated with a interatomic data container." 
 52  uf.title_short = "Interatomic interaction copying." 
 53  uf.display = True 
 54  uf.add_keyarg( 
 55      name = "pipe_from", 
 56      py_type = "str", 
 57      desc_short = "source data pipe", 
 58      desc = "The data pipe containing the interatomic data container from which the data will be copied.  This defaults to the current data pipe.", 
 59      wiz_element_type = 'combo', 
 60      wiz_combo_iter = pipes.pipe_names, 
 61      wiz_read_only = True, 
 62      can_be_none = True 
 63  ) 
 64  uf.add_keyarg( 
 65      name = "pipe_to", 
 66      py_type = "str", 
 67      desc_short = "destination data pipe", 
 68      desc = "The data pipe to copy the interatomic data container to.  This defaults to the current data pipe.", 
 69      wiz_element_type = 'combo', 
 70      wiz_combo_iter = pipes.pipe_names, 
 71      wiz_read_only = True, 
 72      can_be_none = True 
 73  ) 
 74  uf.add_keyarg( 
 75      name = "spin_id1", 
 76      py_type = "str", 
 77      arg_type = "spin ID", 
 78      desc_short = "first spin ID", 
 79      desc = "The spin ID of the first spin.", 
 80      wiz_combo_iter = get_spin_ids, 
 81      can_be_none = True 
 82  ) 
 83  uf.add_keyarg( 
 84      name = "spin_id2", 
 85      py_type = "str", 
 86      arg_type = "spin ID", 
 87      desc_short = "second spin ID", 
 88      desc = "The spin ID of the first spin.", 
 89      wiz_combo_iter = get_spin_ids, 
 90      can_be_none = True 
 91  ) 
 92  # Description. 
 93  uf.desc.append(Desc_container()) 
 94  uf.desc[-1].add_paragraph("This will copy all the data associated with the identified interatomic data container to a different data pipe.  The new interatomic data container must not already exist.") 
 95  # Prompt examples. 
 96  uf.desc.append(Desc_container("Prompt examples")) 
 97  uf.desc[-1].add_paragraph("To copy the interatomic data container between ':2@C' and ':2@H', from the 'orig' data pipe to the current data pipe, type one of:") 
 98  uf.desc[-1].add_prompt("relax> interatom.copy('orig', spin_id1=':2@C', spin_id2=':2@H')") 
 99  uf.desc[-1].add_prompt("relax> interatom.copy(pipe_from='orig', spin_id1=':2@C', spin_id2=':2@H')") 
100  uf.backend = interatomic.copy 
101  uf.menu_text = "&copy" 
102  uf.gui_icon = "oxygen.actions.list-add" 
103  uf.wizard_size = (700, 600) 
104  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
105   
106   
107  # The interatom.define user function. 
108  uf = uf_info.add_uf('interatom.define') 
109  uf.title = "Define interatomic interactions between pairs of spins." 
110  uf.title_short = "Interatomic interaction setup." 
111  uf.add_keyarg( 
112      name = "spin_id1", 
113      default = "@N", 
114      py_type = "str", 
115      arg_type = "spin ID", 
116      desc_short = "first spin ID string", 
117      desc = "The spin ID string for the first spin of the interatomic interaction.", 
118      can_be_none = True 
119  ) 
120  uf.add_keyarg( 
121      name = "spin_id2", 
122      default = "@H", 
123      py_type = "str", 
124      arg_type = "spin ID", 
125      desc_short = "second spin ID string", 
126      desc = "The spin ID string for the second spin of the interatomic interaction.", 
127      can_be_none = True 
128  ) 
129  uf.add_keyarg( 
130      name = "direct_bond", 
131      default = True, 
132      py_type = "bool", 
133      desc_short = "directly bonded atoms flag", 
134      desc = "This is a flag which if True means that the two spins are directly bonded.  This flag is useful to simplify the set up of the main heteronuclear relaxation mechanism or one-bond residual dipolar couplings." 
135  ) 
136  uf.add_keyarg( 
137      name = "spin_selection", 
138      default = True, 
139      py_type = "bool", 
140      desc_short = "selection from the spins", 
141      desc = "Define the interatomic data container selection based on the spin selection.  If either spin is deselected, the interatomic container will also be deselected.  Otherwise the container will be selected." 
142  ) 
143  uf.add_keyarg( 
144      name = "pipe", 
145      py_type = "str", 
146      desc_short = "alternative data pipe", 
147      desc = "The data pipe to create the interatomic data container for.  This defaults to the current data pipe if not supplied.", 
148      wiz_element_type = 'combo', 
149      wiz_combo_iter = pipes.pipe_names, 
150      wiz_read_only = True, 
151      can_be_none = True 
152  ) 
153  # Description. 
154  uf.desc.append(Desc_container()) 
155  uf.desc[-1].add_paragraph("To analyse relaxation or residual dipolar coupling (RDC) data, for example, pairs of spins which are coupled need to be defined.  This can be via the magnetic dipole-dipole interaction or scalar coupling interaction.  This function will create an interatomic data object connecting two existing spins.  This data container will be used to store all information about the interactomic interaction including interatomic vectors and distances.") 
156  uf.desc[-1].add_paragraph("For analyses which use relaxation data, simply defining the interatomic interaction will indicate that there is a dipolar relaxation mechanism operating between the two spins.  Note that for model-free analyses or reduced spectral density mapping, only a single relaxation mechanism can be handled.  For RDC dependent analyses, the presence of the interatomic interaction indicates that dipolar coupling is expected between the two spins.") 
157  uf.desc[-1].add_paragraph("If the spin selection flag is set, then the newly created interatomic data container will be selected based on the current selection status of the two spins defining the interaction.  If either of the spins are deselected, then the new interatomic data container will also be deselected.  If both spins are selected, then the interatomic data container will also be selected.") 
158  # Prompt examples. 
159  uf.desc.append(Desc_container("Prompt examples")) 
160  uf.desc[-1].add_paragraph("To connect the spins ':1@N' to ':1@H', type one of:") 
161  uf.desc[-1].add_prompt("relax> interatom.define(':1@N', ':1@H')") 
162  uf.desc[-1].add_prompt("relax> interatom.define(spin_id1=':1@N', spin_id2=':1@H')") 
163  uf.desc[-1].add_paragraph("To define the protein 15N heteronuclear relaxation mechanism for a model-free analysis, type one of the following:") 
164  uf.desc[-1].add_prompt("relax> interatom.define('@N', '@H', True)") 
165  uf.desc[-1].add_prompt("relax> interatom.define(spin_id1='@N', spin_id2='@H', direct_bond=True)") 
166  uf.backend = interatomic.define 
167  uf.menu_text = "&define" 
168  uf.gui_icon = "oxygen.actions.list-add-relax-blue" 
169  uf.wizard_height_desc = 380 
170  uf.wizard_size = (950, 700) 
171  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
172   
173   
174  # The interatom.read_dist user function. 
175  uf = uf_info.add_uf('interatom.read_dist') 
176  uf.title = "Read inter-spin distances from a file." 
177  uf.title_short = "Interatomic distance reading." 
178  uf.add_keyarg( 
179      name = "file", 
180      py_type = "str", 
181      arg_type = "file sel", 
182      desc_short = "file name", 
183      desc = "The name of the file containing the averaged distance data.", 
184      wiz_filesel_style = FD_OPEN 
185  ) 
186  uf.add_keyarg( 
187      name = "dir", 
188      py_type = "str", 
189      arg_type = "dir", 
190      desc_short = "directory name", 
191      desc = "The directory where the file is located.", 
192      can_be_none = True 
193  ) 
194  uf.add_keyarg( 
195      name = "unit", 
196      default = "meter", 
197      py_type = "str", 
198      desc_short = "distance unit", 
199      desc = "The unit of distance.  The default is meter, but Angstrom can also be specified.", 
200      wiz_element_type = "combo", 
201      wiz_combo_choices = ["meter", "Angstrom"], 
202      wiz_read_only = True 
203  ) 
204  uf.add_keyarg( 
205      name = "spin_id1_col", 
206      default = 1, 
207      py_type = "int", 
208      min = 1, 
209      desc_short = "first spin ID column", 
210      desc = "The spin ID string column for the first spin." 
211  ) 
212  uf.add_keyarg( 
213      name = "spin_id2_col", 
214      default = 2, 
215      py_type = "int", 
216      min = 1, 
217      desc_short = "second spin ID column", 
218      desc = "The spin ID string column for the second spin." 
219  ) 
220  uf.add_keyarg( 
221      name = "data_col", 
222      default = 3, 
223      py_type = "int", 
224      min = 1, 
225      desc_short = "data column", 
226      desc = "The distance data column." 
227  ) 
228  uf.add_keyarg( 
229      name = "sep", 
230      py_type = "str", 
231      desc_short = "column separator", 
232      desc = "The column separator (the default is white space).", 
233      wiz_element_type = "combo", 
234      wiz_combo_choices = ["white space", ",", ";", ":"], 
235      wiz_combo_data = [None, ",", ";", ":"], 
236      wiz_read_only = False, 
237      can_be_none = True 
238  ) 
239  # Description. 
240  uf.desc.append(Desc_container()) 
241  uf.desc[-1].add_paragraph("This allows interatomic distances to be read from a file.  This is useful in the case when the distances vary, avoiding having to tediously use the interatom.set_dist user function for each spin-pair separately.  The format of the file should be columnar, with the two spin ID strings in two separate columns and the distances in any other.  The default measurement unit is meter but this can be changed to Angstrom.") 
242  uf.desc[-1].add_paragraph("For RDC and relaxation based analyses, as the magnetic dipole-dipole interaction is averaged in NMR over the interatomic distance to the inverse third power, the interatomic distances within a 3D structural file are of no use for defining the interaction.  Therefore these r^-3 average distances must be explicitly defined.") 
243  # Prompt examples. 
244  uf.desc.append(Desc_container("Prompt examples")) 
245  uf.desc[-1].add_paragraph("To load the distances in meters from the fifth column of the 'distances' file, and where the spin IDs are in the first and second columns, type one of the following:") 
246  uf.desc[-1].add_prompt("relax> interatom.read_dist('distances', 1, 2, 5)") 
247  uf.desc[-1].add_prompt("relax> interatom.read_dist(file='distances', unit='meter', spin_id1_col=1, spin_id2_col=2, data_col=5)") 
248  uf.backend = interatomic.read_dist 
249  uf.menu_text = "&read_dist" 
250  uf.gui_icon = "oxygen.actions.document-open" 
251  uf.wizard_height_desc = 350 
252  uf.wizard_size = (900, 700) 
253  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
254   
255   
256  # The interatom.set_dist user function. 
257  uf = uf_info.add_uf('interatom.set_dist') 
258  uf.title = "Set the inter-spin distances." 
259  uf.title_short = "Interatomic distance setup." 
260  uf.add_keyarg( 
261      name = "spin_id1", 
262      default = "@N", 
263      py_type = "str", 
264      arg_type = "spin ID", 
265      desc_short = "first spin ID string", 
266      desc = "The spin identification string for the first spin of the dipole pair." 
267  ) 
268  uf.add_keyarg( 
269      name = "spin_id2", 
270      default = "@H", 
271      py_type = "str", 
272      arg_type = "spin ID", 
273      desc_short = "second spin ID string", 
274      desc = "The spin identification string for the second spin of the dipole pair." 
275  ) 
276  uf.add_keyarg( 
277      name = "ave_dist", 
278      default = NH_BOND_LENGTH, 
279      py_type = "float", 
280      desc_short = "averaged interatomic distance", 
281      desc = "The r^-3 averaged distance between the two spins to be used in the magnetic dipole constant, defaulting to meters." 
282  ) 
283  uf.add_keyarg( 
284      name = "unit", 
285      default = "meter", 
286      py_type = "str", 
287      desc_short = "distance unit", 
288      desc = "The unit of distance (the default is 'meter').", 
289      wiz_element_type = "combo", 
290      wiz_combo_choices = ["meter", "Angstrom"], 
291      wiz_read_only = True 
292  ) 
293  # Description. 
294  uf.desc.append(Desc_container()) 
295  uf.desc[-1].add_paragraph("For many NMR interactions, the distance between the spin of interest and another spin or atom must be defined.  This information can be extracted from a 3D structure but, in many cases, these distances are not of interest.  For example the empirical or fixed distance calculation of proton positions in X-ray crystallographic structures will often not correspond to the real interatomic distances.") 
296  uf.desc[-1].add_paragraph("Another example is the magnetic dipole-dipole interaction which is averaged over the interatomic distance to the inverse third power.  In this case, the interatomic distances from any 3D structural file can be of no use for defining the interaction.  The average distances must be explicitly supplied.  This user function allows these distances to be set up.  The default measurement unit is meter but this can be changed to Angstrom.  Alternatively the distances can be read from a file using other user functions in this class.") 
297  # Prompt examples. 
298  uf.desc.append(Desc_container("Prompt examples")) 
299  uf.desc[-1].add_paragraph("To set the N-H distance for protein the 15N heteronuclear relaxation mechanism to 1.02 Angstrom, type one of the following:") 
300  uf.desc[-1].add_prompt("relax> interatom.set_dist('@N', '@H', 1.02 * 1e-10)") 
301  uf.desc[-1].add_prompt("relax> interatom.set_dist(spin_id1='@N', spin_id2='@H', ave_dist=1.02 * 1e-10, unit='meter')") 
302  uf.desc[-1].add_prompt("relax> interatom.set_dist(spin_id1='@N', spin_id2='@H', ave_dist=1.02, unit='Angstrom')") 
303  uf.backend = interatomic.set_dist 
304  uf.menu_text = "&set_dist" 
305  uf.gui_icon = "oxygen.actions.edit-rename" 
306  uf.wizard_height_desc = 350 
307  uf.wizard_size = (900, 700) 
308  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
309   
310   
311  # The interatom.unit_vectors user function. 
312  uf = uf_info.add_uf('interatom.unit_vectors') 
313  uf.title = "Calculate the unit vectors for all interatomic interactions." 
314  uf.title_short = "Interatomic unit vector calculation." 
315  uf.add_keyarg( 
316      name = "ave", 
317      default = True, 
318      py_type = "bool", 
319      desc_short = "average vector flag", 
320      desc = "A flag which if True will cause the bond vectors from all models to be averaged.  If vectors from only one model is extracted, this will have no effect." 
321  ) 
322  # Description. 
323  uf.desc.append(Desc_container()) 
324  uf.desc[-1].add_paragraph("For an orientational dependent analysis, such as model-free analysis with the spheroidal and ellipsoidal global diffusion tensors or any analysis using RDCs, the unit vectors between the two dipoles must be calculated prior to starting the analysis.  For the unit vector extraction, the two interacting spins should already possess positional information and the dipole-dipole interaction should already be defined via the interatom.define user function.  This information will be used to calculate unit vectors between the two spins.  Without positional information from a 3D structure, no vectors can be calculated and an orientational dependent analysis will not be possible.") 
325  uf.desc[-1].add_paragraph("The number of unit vectors per interaction will be defined by the number of positions each spin possesses together with the averaging flag.  If both spins have N and M positions loaded, the number of positions for both must match (N=M).  In this case, as well as when one spin has N positions and the other a single position, then N unit vectors will be calculated.  This is unless the averaging flag is set in which case an averaged vector of unit length will be calculated.") 
326  # Prompt examples. 
327  uf.desc.append(Desc_container("Prompt examples")) 
328  uf.desc[-1].add_paragraph("To calculate the unit vectors prior to a model-free analysis, type one of the following:") 
329  uf.desc[-1].add_prompt("relax> interatom.unit_vectors(True)") 
330  uf.desc[-1].add_prompt("relax> interatom.unit_vectors(ave=True)") 
331  uf.backend = interatomic.unit_vectors 
332  uf.menu_text = "&unit_vectors" 
333  uf.wizard_height_desc = 400 
334  uf.wizard_size = (900, 600) 
335  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
336