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

Source Code for Module user_functions.interatom

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2013 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 = "pipe", 
138      py_type = "str", 
139      desc_short = "alternative data pipe", 
140      desc = "The data pipe to create the interatomic data container for.  This defaults to the current data pipe if not supplied.", 
141      wiz_element_type = 'combo', 
142      wiz_combo_iter = pipes.pipe_names, 
143      wiz_read_only = True, 
144      can_be_none = True 
145  ) 
146  # Description. 
147  uf.desc.append(Desc_container()) 
148  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.") 
149  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.") 
150  # Prompt examples. 
151  uf.desc.append(Desc_container("Prompt examples")) 
152  uf.desc[-1].add_paragraph("To connect the spins ':1@N' to ':1@H', type one of:") 
153  uf.desc[-1].add_prompt("relax> interatom.define(':1@N', ':1@H')") 
154  uf.desc[-1].add_prompt("relax> interatom.define(spin_id1=':1@N', spin_id2=':1@H')") 
155  uf.desc[-1].add_paragraph("To define the protein 15N heteronuclear relaxation mechanism for a model-free analysis, type one of the following:") 
156  uf.desc[-1].add_prompt("relax> interatom.define('@N', '@H', True)") 
157  uf.desc[-1].add_prompt("relax> interatom.define(spin_id1='@N', spin_id2='@H', direct_bond=True)") 
158  uf.backend = interatomic.define 
159  uf.menu_text = "&define" 
160  uf.gui_icon = "oxygen.actions.list-add-relax-blue" 
161  uf.wizard_height_desc = 350 
162  uf.wizard_size = (900, 700) 
163  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
164   
165   
166  # The interatom.read_dist user function. 
167  uf = uf_info.add_uf('interatom.read_dist') 
168  uf.title = "Read inter-spin distances from a file." 
169  uf.title_short = "Interatomic distance reading." 
170  uf.add_keyarg( 
171      name = "file", 
172      py_type = "str", 
173      arg_type = "file sel", 
174      desc_short = "file name", 
175      desc = "The name of the file containing the averaged distance data.", 
176      wiz_filesel_style = FD_OPEN 
177  ) 
178  uf.add_keyarg( 
179      name = "dir", 
180      py_type = "str", 
181      arg_type = "dir", 
182      desc_short = "directory name", 
183      desc = "The directory where the file is located.", 
184      can_be_none = True 
185  ) 
186  uf.add_keyarg( 
187      name = "unit", 
188      default = "meter", 
189      py_type = "str", 
190      desc_short = "distance unit", 
191      desc = "The unit of distance.  The default is meter, but Angstrom can also be specified.", 
192      wiz_element_type = "combo", 
193      wiz_combo_choices = ["meter", "Angstrom"], 
194      wiz_read_only = True 
195  ) 
196  uf.add_keyarg( 
197      name = "spin_id1_col", 
198      default = 1, 
199      py_type = "int", 
200      min = 1, 
201      desc_short = "first spin ID column", 
202      desc = "The spin ID string column for the first spin." 
203  ) 
204  uf.add_keyarg( 
205      name = "spin_id2_col", 
206      default = 2, 
207      py_type = "int", 
208      min = 1, 
209      desc_short = "second spin ID column", 
210      desc = "The spin ID string column for the second spin." 
211  ) 
212  uf.add_keyarg( 
213      name = "data_col", 
214      default = 3, 
215      py_type = "int", 
216      min = 1, 
217      desc_short = "data column", 
218      desc = "The distance data column." 
219  ) 
220  uf.add_keyarg( 
221      name = "sep", 
222      py_type = "str", 
223      desc_short = "column separator", 
224      desc = "The column separator (the default is white space).", 
225      wiz_element_type = "combo", 
226      wiz_combo_choices = ["white space", ",", ";", ":"], 
227      wiz_combo_data = [None, ",", ";", ":"], 
228      wiz_read_only = False, 
229      can_be_none = True 
230  ) 
231  # Description. 
232  uf.desc.append(Desc_container()) 
233  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.") 
234  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.") 
235  # Prompt examples. 
236  uf.desc.append(Desc_container("Prompt examples")) 
237  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:") 
238  uf.desc[-1].add_prompt("relax> interatom.read_dist('distances', 1, 2, 5)") 
239  uf.desc[-1].add_prompt("relax> interatom.read_dist(file='distances', unit='meter', spin_id1_col=1, spin_id2_col=2, data_col=5)") 
240  uf.backend = interatomic.read_dist 
241  uf.menu_text = "&read_dist" 
242  uf.gui_icon = "oxygen.actions.document-open" 
243  uf.wizard_height_desc = 350 
244  uf.wizard_size = (900, 700) 
245  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
246   
247   
248  # The interatom.set_dist user function. 
249  uf = uf_info.add_uf('interatom.set_dist') 
250  uf.title = "Set the inter-spin distances." 
251  uf.title_short = "Interatomic distance setup." 
252  uf.add_keyarg( 
253      name = "spin_id1", 
254      default = "@N", 
255      py_type = "str", 
256      arg_type = "spin ID", 
257      desc_short = "first spin ID string", 
258      desc = "The spin identification string for the first spin of the dipole pair." 
259  ) 
260  uf.add_keyarg( 
261      name = "spin_id2", 
262      default = "@H", 
263      py_type = "str", 
264      arg_type = "spin ID", 
265      desc_short = "second spin ID string", 
266      desc = "The spin identification string for the second spin of the dipole pair." 
267  ) 
268  uf.add_keyarg( 
269      name = "ave_dist", 
270      default = NH_BOND_LENGTH, 
271      py_type = "float", 
272      desc_short = "averaged interatomic distance", 
273      desc = "The r^-3 averaged distance between the two spins to be used in the magnetic dipole constant, defaulting to meters." 
274  ) 
275  uf.add_keyarg( 
276      name = "unit", 
277      default = "meter", 
278      py_type = "str", 
279      desc_short = "distance unit", 
280      desc = "The unit of distance (the default is 'meter').", 
281      wiz_element_type = "combo", 
282      wiz_combo_choices = ["meter", "Angstrom"], 
283      wiz_read_only = True 
284  ) 
285  # Description. 
286  uf.desc.append(Desc_container()) 
287  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.") 
288  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.") 
289  # Prompt examples. 
290  uf.desc.append(Desc_container("Prompt examples")) 
291  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:") 
292  uf.desc[-1].add_prompt("relax> interatom.set_dist('@N', '@H', 1.02 * 1e-10)") 
293  uf.desc[-1].add_prompt("relax> interatom.set_dist(spin_id1='@N', spin_id2='@H', ave_dist=1.02 * 1e-10, unit='meter')") 
294  uf.desc[-1].add_prompt("relax> interatom.set_dist(spin_id1='@N', spin_id2='@H', ave_dist=1.02, unit='Angstrom')") 
295  uf.backend = interatomic.set_dist 
296  uf.menu_text = "&set_dist" 
297  uf.gui_icon = "oxygen.actions.edit-rename" 
298  uf.wizard_height_desc = 350 
299  uf.wizard_size = (900, 700) 
300  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
301   
302   
303  # The interatom.unit_vectors user function. 
304  uf = uf_info.add_uf('interatom.unit_vectors') 
305  uf.title = "Calculate the unit vectors for all interatomic interactions." 
306  uf.title_short = "Interatomic unit vector calculation." 
307  uf.add_keyarg( 
308      name = "ave", 
309      default = True, 
310      py_type = "bool", 
311      desc_short = "average vector flag", 
312      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." 
313  ) 
314  # Description. 
315  uf.desc.append(Desc_container()) 
316  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.") 
317  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.") 
318  # Prompt examples. 
319  uf.desc.append(Desc_container("Prompt examples")) 
320  uf.desc[-1].add_paragraph("To calculate the unit vectors prior to a model-free analysis, type one of the following:") 
321  uf.desc[-1].add_prompt("relax> interatom.unit_vectors(True)") 
322  uf.desc[-1].add_prompt("relax> interatom.unit_vectors(ave=True)") 
323  uf.backend = interatomic.unit_vectors 
324  uf.menu_text = "&unit_vectors" 
325  uf.wizard_height_desc = 400 
326  uf.wizard_size = (900, 600) 
327  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
328