1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 from re import search
26 from warnings import warn
27
28
29 from api_base import API_base
30 from api_common import API_common
31 from generic_fns.mol_res_spin import exists_mol_res_spin_data, return_spin, spin_loop
32 from generic_fns import pipes
33 from maths_fns.consistency_tests import Consistency
34 from physical_constants import N15_CSA, NH_BOND_LENGTH, h_bar, mu0, return_gyromagnetic_ratio
35 from relax_errors import RelaxError, RelaxFuncSetupError, RelaxNoSequenceError, RelaxNoValueError, RelaxProtonTypeError, RelaxSpinTypeError
36 from relax_warnings import RelaxDeselectWarning
37 import specific_fns
38
39
41 """Class containing functions specific to consistency testing."""
42
44 """Initialise the class by placing API_common methods into the API."""
45
46
47 super(Consistency_tests, self).__init__()
48
49
50 self.base_data_loop = self._base_data_loop_spin
51 self.create_mc_data = self._create_mc_relax_data
52 self.model_loop = self._model_loop_spin
53 self.return_conversion_factor = self._return_no_conversion_factor
54 self.return_error = self._return_error_relax_data
55 self.return_value = self._return_value_general
56 self.set_param_values = self._set_param_values_spin
57 self.set_selected_sim = self._set_selected_sim_spin
58 self.sim_pack_data = self._sim_pack_relax_data
59
60
61 self.PARAMS.add('j0', scope='spin', desc='Spectral density value at 0 MHz (from Farrow et al. (1995) JBNMR, 6: 153-162)', py_type=float, grace_string='\\qJ(0)\\Q', err=True, sim=True)
62 self.PARAMS.add('f_eta', scope='spin', desc='Eta-test (from Fushman et al. (1998) JACS, 120: 10947-10952)', py_type=float, grace_string='\\qF\\s\\xh\\Q', err=True, sim=True)
63 self.PARAMS.add('f_r2', scope='spin', desc='R2-test (from Fushman et al. (1998) JACS, 120: 10947-10952)', py_type=float, grace_string='\\qF\\sR2\\Q', err=True, sim=True)
64 self.PARAMS.add('r', scope='spin', default=NH_BOND_LENGTH, units='Angstrom', desc='Bond length', py_type=float, grace_string='Bond length')
65 self.PARAMS.add('csa', scope='spin', default=N15_CSA, units='ppm', desc='CSA value', py_type=float, grace_string='\\qCSA\\Q')
66 self.PARAMS.add('heteronuc_type', scope='spin', default='15N', desc='The heteronucleus type', py_type=str)
67 self.PARAMS.add('proton_type', scope='spin', default='1H', desc='The proton type', py_type=str)
68 self.PARAMS.add('orientation', scope='spin', default=15.7, units='degrees', desc="Angle between the 15N-1H vector and the principal axis of the 15N chemical shift tensor", py_type=float, grace_string='\\q\\xq\\Q')
69 self.PARAMS.add('tc', scope='spin', default=13 * 1e-9, units='ns', desc="Correlation time", py_type=float, grace_string='\\q\\xt\\f{}c\\Q')
70
71
73 """Function for selecting which relaxation data to use in the consistency tests."""
74
75
76 pipes.test()
77
78
79 function_type = cdp.pipe_type
80 if function_type != 'ct':
81 raise RelaxFuncSetupError(specific_fns.setup.get_string(function_type))
82
83
84 if hasattr(cdp, 'ct_frq'):
85 raise RelaxError("The frequency for the run has already been set.")
86
87
88 if not hasattr(cdp, 'ct_frq'):
89 cdp.ct_frq = {}
90
91
92 cdp.ct_frq = frq
93
94
95 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
96 """Calculation of the consistency functions.
97
98 @keyword spin_id: The spin identification string.
99 @type spin_id: None or str
100 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity.
101 @type verbosity: int
102 @keyword sim_index: The optional MC simulation index.
103 @type sim_index: None or int
104 """
105
106
107 if not hasattr(cdp, 'ct_frq') or not isinstance(cdp.ct_frq, float):
108 raise RelaxError("The frequency has not been set up.")
109
110
111 if not exists_mol_res_spin_data():
112 raise RelaxNoSequenceError
113
114
115 for spin in spin_loop(spin_id):
116
117 if not spin.select:
118 continue
119
120
121 if not hasattr(spin, 'csa') or spin.csa == None:
122 raise RelaxNoValueError("CSA")
123
124
125 if not hasattr(spin, 'r') or spin.r == None:
126 raise RelaxNoValueError("bond length")
127
128
129 if not hasattr(spin, 'orientation') or spin.orientation == None:
130 raise RelaxNoValueError("angle Theta")
131
132
133 if not hasattr(spin, 'tc') or spin.tc == None:
134 raise RelaxNoValueError("correlation time")
135
136
137 if not hasattr(spin, 'heteronuc_type'):
138 raise RelaxSpinTypeError
139
140
141 if not hasattr(spin, 'proton_type'):
142 raise RelaxProtonTypeError
143
144
145 if cdp.ct_frq not in cdp.frq.values():
146 raise RelaxError("No relaxation data corresponding to the frequency %s has been loaded." % cdp.ct_frq)
147
148
149 for spin in spin_loop(spin_id):
150
151 if not spin.select:
152 continue
153
154
155 r1 = None
156 r2 = None
157 noe = None
158
159
160 for ri_id in cdp.ri_ids:
161
162 if cdp.frq[ri_id] != cdp.ct_frq:
163 continue
164
165
166 if cdp.ri_type[ri_id] == 'R1':
167 if sim_index == None:
168 r1 = spin.ri_data[ri_id]
169 else:
170 r1 = spin.ri_data_sim[ri_id][sim_index]
171
172
173 if cdp.ri_type[ri_id] == 'R2':
174 if sim_index == None:
175 r2 = spin.ri_data[ri_id]
176 else:
177 r2 = spin.ri_data_sim[ri_id][sim_index]
178
179
180 if cdp.ri_type[ri_id] == 'NOE':
181 if sim_index == None:
182 noe = spin.ri_data[ri_id]
183 else:
184 noe = spin.ri_data_sim[ri_id][sim_index]
185
186
187 if r1 == None or r2 == None or noe == None:
188 continue
189
190
191 self.ct = Consistency(frq=cdp.ct_frq, gx=return_gyromagnetic_ratio(spin.heteronuc_type), gh=return_gyromagnetic_ratio(spin.proton_type), mu0=mu0, h_bar=h_bar)
192
193
194 j0, f_eta, f_r2 = self.ct.func(orientation=spin.orientation, tc=spin.tc, r=spin.r, csa=spin.csa, r1=r1, r2=r2, noe=noe)
195
196
197 if sim_index == None:
198 spin.j0 = j0
199 spin.f_eta = f_eta
200 spin.f_r2 = f_r2
201
202
203 else:
204
205 self.data_init(spin, sim=1)
206 if spin.j0_sim == None:
207 spin.j0_sim = []
208 spin.f_eta_sim = []
209 spin.f_r2_sim = []
210
211
212 spin.j0_sim.append(j0)
213 spin.f_eta_sim.append(f_eta)
214 spin.f_r2_sim.append(f_r2)
215
216
217
219 """Initialise the data structures.
220
221 @param data_cont: The data container.
222 @type data_cont: instance
223 @keyword sim: The Monte Carlo simulation flag, which if true will initialise the simulation data structure.
224 @type sim: bool
225 """
226
227
228 data_names = self.data_names()
229
230
231 for name in data_names:
232
233 if sim:
234
235 name = name + '_sim'
236
237
238 if not hasattr(data_cont, name):
239
240 setattr(data_cont, name, None)
241
242
243 default_value_doc = """
244 Consistency testing default values
245 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
246 These default values are found in the file 'physical_constants.py'.
247
248 ______________________________________________________________________________________
249 | | | |
250 | Data type | Object name | Value |
251 |_______________________________________|____________________|_________________________|
252 | | | |
253 | Bond length | 'r' | 1.02 * 1e-10 |
254 | | | |
255 | CSA | 'csa' | -172 * 1e-6 |
256 | | | |
257 | Heteronucleus type | 'heteronuc_type' | '15N' |
258 | | | |
259 | Proton type | 'proton_type' | '1H' |
260 | | | |
261 | Angle Theta | 'orientation' | 15.7 |
262 | | | |
263 | Correlation time | 'tc' | 13 * 1e-9 |
264 |_______________________________________|____________________|_________________________|
265
266 """
267
268
302
303
304 return_data_name_doc = """
305 Consistency testing data type string matching patterns
306 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
307
308 ___________________________________________
309 | | |
310 | Data type | Object name |
311 |_______________________|__________________|
312 | | |
313 | J(0) | 'j0' |
314 | | |
315 | F_eta | 'f_eta' |
316 | | |
317 | F_R2 | 'f_r2' |
318 | | |
319 | Bond length | 'r' |
320 | | |
321 | CSA | 'csa' |
322 | | |
323 | Heteronucleus type | 'heteronuc_type' |
324 | | |
325 | Proton type | 'proton_type' |
326 | | |
327 | Angle Theta | 'orientation' |
328 | | |
329 | Correlation time | 'tc' |
330 |_______________________|__________________|
331 """
332
333
334 set_doc = """
335 Consistency testing set details
336 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
337
338 In consistency testing, only four values can be set, the bond length, CSA, angle
339 Theta ('orientation') and correlation time values. These must be set prior to the
340 calculation of consistency functions.
341
342 """
343
344
345 - def set_error(self, model_info, index, error):
346 """Set the parameter errors.
347
348 @param model_info: The spin container originating from model_loop().
349 @type model_info: SpinContainer instance
350 @param index: The index of the parameter to set the errors for.
351 @type index: int
352 @param error: The error value.
353 @type error: float
354 """
355
356
357 spin = model_info
358
359
360 if index == 0:
361 spin.j0_err = error
362
363
364 if index == 1:
365 spin.f_eta_err = error
366
367
368 if index == 2:
369 spin.f_r2_err = error
370
371
373 """Return the array of simulation parameter values.
374
375 @param model_info: The spin container originating from model_loop().
376 @type model_info: SpinContainer instance
377 @param index: The index of the parameter to return the array of values for.
378 @type index: int
379 @return: The array of simulation parameter values.
380 @rtype: list of float
381 """
382
383
384 spin = model_info
385
386
387 if not spin.select:
388 return
389
390
391 if index == 0:
392 return spin.j0_sim
393
394
395 if index == 1:
396 return spin.f_eta_sim
397
398
399 if index == 2:
400 return spin.f_r2_sim
401
402
404 """Return the array of selected simulation flags.
405
406 @param model_info: The spin container originating from model_loop().
407 @type model_info: SpinContainer instance
408 @return: The array of selected simulation flags.
409 @rtype: list of int
410 """
411
412
413 spin = model_info
414
415
416 return spin.select_sim
417