1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """The interatom user function definitions."""
24
25
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
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
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
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
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
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 = "©"
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
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
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
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
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
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
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
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
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
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
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
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
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