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 from os import sep
27
28
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
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
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
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
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 = "©"
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
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
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
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
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
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
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
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
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
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
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
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
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