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

Source Code for Module user_functions.interatom

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2002-2004,2007-2010,2012-2014,2019 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  from os import sep 
 27   
 28  # relax module imports. 
 29  from graphics import WIZARD_IMAGE_PATH 
 30  from lib.physical_constants import NH_BOND_LENGTH 
 31  from pipe_control.mol_res_spin import get_spin_ids 
 32  from pipe_control import pipes, interatomic 
 33  from user_functions.data import Uf_info; uf_info = Uf_info() 
 34  from user_functions.objects import Desc_container 
 35   
 36   
 37  # The user function class. 
 38  uf_class = uf_info.add_class('interatom') 
 39  uf_class.title = "Class for manipulating magnetic dipole-dipole interactions." 
 40  uf_class.menu_text = "&interatom" 
 41  uf_class.gui_icon = "relax.dipole_pair" 
 42   
 43   
 44  # The interatom.copy user function. 
 45  uf = uf_info.add_uf('interatom.copy') 
 46  uf.title = "Copy all data associated with a interatomic data container." 
 47  uf.title_short = "Interatomic interaction copying." 
 48  uf.display = True 
 49  uf.add_keyarg( 
 50      name = "pipe_from", 
 51      basic_types = ["str"], 
 52      desc_short = "source data pipe", 
 53      desc = "The data pipe containing the interatomic data container from which the data will be copied.  This defaults to the current data pipe.", 
 54      wiz_element_type = 'combo', 
 55      wiz_combo_iter = pipes.pipe_names, 
 56      wiz_read_only = True, 
 57      can_be_none = True 
 58  ) 
 59  uf.add_keyarg( 
 60      name = "pipe_to", 
 61      basic_types = ["str"], 
 62      desc_short = "destination data pipe", 
 63      desc = "The data pipe to copy the interatomic data container to.  This defaults to the current data pipe.", 
 64      wiz_element_type = 'combo', 
 65      wiz_combo_iter = pipes.pipe_names, 
 66      wiz_read_only = True, 
 67      can_be_none = True 
 68  ) 
 69  uf.add_keyarg( 
 70      name = "spin_id1", 
 71      arg_type = "spin ID", 
 72      desc_short = "first spin ID", 
 73      desc = "The spin ID of the first spin.", 
 74      wiz_combo_iter = get_spin_ids, 
 75      can_be_none = True 
 76  ) 
 77  uf.add_keyarg( 
 78      name = "spin_id2", 
 79      arg_type = "spin ID", 
 80      desc_short = "second spin ID", 
 81      desc = "The spin ID of the first spin.", 
 82      wiz_combo_iter = get_spin_ids, 
 83      can_be_none = True 
 84  ) 
 85  # Description. 
 86  uf.desc.append(Desc_container()) 
 87  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.") 
 88  # Prompt examples. 
 89  uf.desc.append(Desc_container("Prompt examples")) 
 90  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:") 
 91  uf.desc[-1].add_prompt("relax> interatom.copy('orig', spin_id1=':2@C', spin_id2=':2@H')") 
 92  uf.desc[-1].add_prompt("relax> interatom.copy(pipe_from='orig', spin_id1=':2@C', spin_id2=':2@H')") 
 93  uf.backend = interatomic.copy 
 94  uf.menu_text = "&copy" 
 95  uf.gui_icon = "oxygen.actions.list-add" 
 96  uf.wizard_size = (700, 600) 
 97  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
 98   
 99   
100  # The interatom.define user function. 
101  uf = uf_info.add_uf('interatom.define') 
102  uf.title = "Define interatomic interactions between pairs of spins." 
103  uf.title_short = "Interatomic interaction setup." 
104  uf.add_keyarg( 
105      name = "spin_id1", 
106      default = "@N", 
107      arg_type = "spin ID", 
108      desc_short = "first spin ID string", 
109      desc = "The spin ID string for the first spin of the interatomic interaction.", 
110      can_be_none = True 
111  ) 
112  uf.add_keyarg( 
113      name = "spin_id2", 
114      default = "@H", 
115      arg_type = "spin ID", 
116      desc_short = "second spin ID string", 
117      desc = "The spin ID string for the second spin of the interatomic interaction.", 
118      can_be_none = True 
119  ) 
120  uf.add_keyarg( 
121      name = "direct_bond", 
122      default = True, 
123      basic_types = ["bool"], 
124      desc_short = "directly bonded atoms flag", 
125      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." 
126  ) 
127  uf.add_keyarg( 
128      name = "spin_selection", 
129      default = True, 
130      basic_types = ["bool"], 
131      desc_short = "selection from the spins", 
132      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." 
133  ) 
134  uf.add_keyarg( 
135      name = "pipe", 
136      basic_types = ["str"], 
137      desc_short = "alternative data pipe", 
138      desc = "The data pipe to create the interatomic data container for.  This defaults to the current data pipe if not supplied.", 
139      wiz_element_type = 'combo', 
140      wiz_combo_iter = pipes.pipe_names, 
141      wiz_read_only = True, 
142      can_be_none = True 
143  ) 
144  # Description. 
145  uf.desc.append(Desc_container()) 
146  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.") 
147  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.") 
148  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.") 
149  # Prompt examples. 
150  uf.desc.append(Desc_container("Prompt examples")) 
151  uf.desc[-1].add_paragraph("To connect the spins ':1@N' to ':1@H', type one of:") 
152  uf.desc[-1].add_prompt("relax> interatom.define(':1@N', ':1@H')") 
153  uf.desc[-1].add_prompt("relax> interatom.define(spin_id1=':1@N', spin_id2=':1@H')") 
154  uf.desc[-1].add_paragraph("To define the protein 15N heteronuclear relaxation mechanism for a model-free analysis, type one of the following:") 
155  uf.desc[-1].add_prompt("relax> interatom.define('@N', '@H', True)") 
156  uf.desc[-1].add_prompt("relax> interatom.define(spin_id1='@N', spin_id2='@H', direct_bond=True)") 
157  uf.backend = interatomic.define_dipole_pair 
158  uf.menu_text = "&define" 
159  uf.gui_icon = "oxygen.actions.list-add-relax-blue" 
160  uf.wizard_height_desc = 380 
161  uf.wizard_size = (950, 700) 
162  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
163   
164   
165  # The interatom.read_dist user function. 
166  uf = uf_info.add_uf('interatom.read_dist') 
167  uf.title = "Read inter-spin distances from a file." 
168  uf.title_short = "Interatomic distance reading." 
169  uf.add_keyarg( 
170      name = "file", 
171      arg_type = "file sel read", 
172      desc_short = "file name", 
173      desc = "The name of the file containing the averaged distance data.", 
174  ) 
175  uf.add_keyarg( 
176      name = "dir", 
177      arg_type = "dir", 
178      desc_short = "directory name", 
179      desc = "The directory where the file is located.", 
180      can_be_none = True 
181  ) 
182  uf.add_keyarg( 
183      name = "unit", 
184      default = "meter", 
185      basic_types = ["str"], 
186      desc_short = "distance unit", 
187      desc = "The unit of distance.  The default is meter, but Angstrom can also be specified.", 
188      wiz_element_type = "combo", 
189      wiz_combo_choices = ["meter", "Angstrom"], 
190      wiz_read_only = True 
191  ) 
192  uf.add_keyarg( 
193      name = "spin_id1_col", 
194      default = 1, 
195      basic_types = ["int"], 
196      min = 1, 
197      desc_short = "first spin ID column", 
198      desc = "The spin ID string column for the first spin." 
199  ) 
200  uf.add_keyarg( 
201      name = "spin_id2_col", 
202      default = 2, 
203      basic_types = ["int"], 
204      min = 1, 
205      desc_short = "second spin ID column", 
206      desc = "The spin ID string column for the second spin." 
207  ) 
208  uf.add_keyarg( 
209      name = "data_col", 
210      default = 3, 
211      basic_types = ["int"], 
212      min = 1, 
213      desc_short = "data column", 
214      desc = "The distance data column." 
215  ) 
216  uf.add_keyarg( 
217      name = "sep", 
218      basic_types = ["str"], 
219      desc_short = "column separator", 
220      desc = "The column separator (the default is white space).", 
221      wiz_element_type = "combo", 
222      wiz_combo_choices = ["white space", ",", ";", ":"], 
223      wiz_combo_data = [None, ",", ";", ":"], 
224      wiz_read_only = False, 
225      can_be_none = True 
226  ) 
227  # Description. 
228  uf.desc.append(Desc_container()) 
229  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.") 
230  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.") 
231  # Prompt examples. 
232  uf.desc.append(Desc_container("Prompt examples")) 
233  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:") 
234  uf.desc[-1].add_prompt("relax> interatom.read_dist('distances', 1, 2, 5)") 
235  uf.desc[-1].add_prompt("relax> interatom.read_dist(file='distances', unit='meter', spin_id1_col=1, spin_id2_col=2, data_col=5)") 
236  uf.backend = interatomic.read_dist 
237  uf.menu_text = "&read_dist" 
238  uf.gui_icon = "oxygen.actions.document-open" 
239  uf.wizard_height_desc = 350 
240  uf.wizard_size = (900, 700) 
241  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
242   
243   
244  # The interatom.set_dist user function. 
245  uf = uf_info.add_uf('interatom.set_dist') 
246  uf.title = "Set the inter-spin distances." 
247  uf.title_short = "Interatomic distance setup." 
248  uf.add_keyarg( 
249      name = "spin_id1", 
250      default = "@N", 
251      arg_type = "spin ID", 
252      desc_short = "first spin ID string", 
253      desc = "The spin identification string for the first spin of the dipole pair." 
254  ) 
255  uf.add_keyarg( 
256      name = "spin_id2", 
257      default = "@H", 
258      arg_type = "spin ID", 
259      desc_short = "second spin ID string", 
260      desc = "The spin identification string for the second spin of the dipole pair." 
261  ) 
262  uf.add_keyarg( 
263      name = "ave_dist", 
264      default = NH_BOND_LENGTH, 
265      basic_types = ["float"], 
266      desc_short = "averaged interatomic distance", 
267      desc = "The r^-3 averaged distance between the two spins to be used in the magnetic dipole constant, defaulting to meters." 
268  ) 
269  uf.add_keyarg( 
270      name = "unit", 
271      default = "meter", 
272      basic_types = ["str"], 
273      desc_short = "distance unit", 
274      desc = "The unit of distance (the default is 'meter').", 
275      wiz_element_type = "combo", 
276      wiz_combo_choices = ["meter", "Angstrom"], 
277      wiz_read_only = True 
278  ) 
279  # Description. 
280  uf.desc.append(Desc_container()) 
281  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.") 
282  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.") 
283  # Prompt examples. 
284  uf.desc.append(Desc_container("Prompt examples")) 
285  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:") 
286  uf.desc[-1].add_prompt("relax> interatom.set_dist('@N', '@H', 1.02 * 1e-10)") 
287  uf.desc[-1].add_prompt("relax> interatom.set_dist(spin_id1='@N', spin_id2='@H', ave_dist=1.02 * 1e-10, unit='meter')") 
288  uf.desc[-1].add_prompt("relax> interatom.set_dist(spin_id1='@N', spin_id2='@H', ave_dist=1.02, unit='Angstrom')") 
289  uf.backend = interatomic.set_dist 
290  uf.menu_text = "&set_dist" 
291  uf.gui_icon = "oxygen.actions.edit-rename" 
292  uf.wizard_height_desc = 350 
293  uf.wizard_size = (900, 700) 
294  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
295   
296   
297  # The interatom.unit_vectors user function. 
298  uf = uf_info.add_uf('interatom.unit_vectors') 
299  uf.title = "Calculate the unit vectors for all interatomic interactions." 
300  uf.title_short = "Interatomic unit vector calculation." 
301  uf.add_keyarg( 
302      name = "ave", 
303      default = True, 
304      basic_types = ["bool"], 
305      desc_short = "average vector flag", 
306      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." 
307  ) 
308  # Description. 
309  uf.desc.append(Desc_container()) 
310  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.") 
311  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.") 
312  # Prompt examples. 
313  uf.desc.append(Desc_container("Prompt examples")) 
314  uf.desc[-1].add_paragraph("To calculate the unit vectors prior to a model-free analysis, type one of the following:") 
315  uf.desc[-1].add_prompt("relax> interatom.unit_vectors(True)") 
316  uf.desc[-1].add_prompt("relax> interatom.unit_vectors(ave=True)") 
317  uf.backend = interatomic.unit_vectors 
318  uf.menu_text = "&unit_vectors" 
319  uf.wizard_height_desc = 400 
320  uf.wizard_size = (900, 600) 
321  uf.wizard_image = WIZARD_IMAGE_PATH + 'dipole_pair' + sep + 'NH_dipole_pair.png' 
322