1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """The consistency testing analysis API object."""
25
26
27 from warnings import warn
28
29
30 from lib.errors import RelaxError, RelaxNoSequenceError, RelaxNoValueError, RelaxSpinTypeError
31 from lib.float import isInf
32 from lib.physical_constants import h_bar, mu0, return_gyromagnetic_ratio
33 from lib.warnings import RelaxDeselectWarning
34 from pipe_control.interatomic import return_interatom_list
35 from pipe_control.mol_res_spin import exists_mol_res_spin_data, return_spin, spin_loop
36 from specific_analyses.api_base import API_base
37 from specific_analyses.api_common import API_common
38 from specific_analyses.consistency_tests.parameter_object import Consistency_tests_params
39 from target_functions.consistency_tests import Consistency
40
41
43 """Class containing functions specific to consistency testing."""
44
45
46 instance = None
47
64
65
66 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
67 """Calculation of the consistency functions.
68
69 @keyword spin_id: The spin identification string.
70 @type spin_id: None or str
71 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity.
72 @type verbosity: int
73 @keyword sim_index: The optional MC simulation index.
74 @type sim_index: None or int
75 """
76
77
78 if not hasattr(cdp, 'ct_frq') or not isinstance(cdp.ct_frq, float):
79 raise RelaxError("The frequency has not been set up.")
80
81
82 if not exists_mol_res_spin_data():
83 raise RelaxNoSequenceError
84
85
86 for spin, id in spin_loop(spin_id, return_id=True):
87
88 if not spin.select:
89 continue
90
91
92 if not hasattr(spin, 'isotope'):
93 raise RelaxSpinTypeError
94
95
96 if not hasattr(spin, 'csa') or spin.csa == None:
97 raise RelaxNoValueError("CSA")
98
99
100 if not hasattr(spin, 'orientation') or spin.orientation == None:
101 raise RelaxNoValueError("angle Theta")
102
103
104 if not hasattr(spin, 'tc') or spin.tc == None:
105 raise RelaxNoValueError("correlation time")
106
107
108 interatoms = return_interatom_list(id)
109 for interatom in interatoms:
110
111 if not interatom.dipole_pair:
112 continue
113
114
115 if id != interatom.spin_id1:
116 spin_id2 = interatom.spin_id1
117 else:
118 spin_id2 = interatom.spin_id2
119 spin2 = return_spin(spin_id2)
120
121
122 if not hasattr(spin2, 'isotope'):
123 raise RelaxSpinTypeError
124
125
126 if not hasattr(interatom, 'r') or interatom.r == None:
127 raise RelaxNoValueError("interatomic distance", spin_id=spin_id, spin_id2=spin_id2)
128
129
130 if cdp.ct_frq not in cdp.spectrometer_frq.values():
131 raise RelaxError("No relaxation data corresponding to the frequency %s has been loaded." % cdp.ct_frq)
132
133
134 for spin, id in spin_loop(spin_id, return_id=True):
135
136 if not spin.select:
137 continue
138
139
140 r1 = None
141 r2 = None
142 noe = None
143
144
145 for ri_id in cdp.ri_ids:
146
147 if cdp.spectrometer_frq[ri_id] != cdp.ct_frq:
148 continue
149
150
151 if cdp.ri_type[ri_id] == 'R1':
152 if sim_index == None:
153 r1 = spin.ri_data[ri_id]
154 else:
155 r1 = spin.ri_data_sim[ri_id][sim_index]
156
157
158 if cdp.ri_type[ri_id] == 'R2':
159 if sim_index == None:
160 r2 = spin.ri_data[ri_id]
161 else:
162 r2 = spin.ri_data_sim[ri_id][sim_index]
163
164
165 if cdp.ri_type[ri_id] == 'NOE':
166 if sim_index == None:
167 noe = spin.ri_data[ri_id]
168 else:
169 noe = spin.ri_data_sim[ri_id][sim_index]
170
171
172 if r1 == None or r2 == None or noe == None:
173 continue
174
175
176 interatoms = return_interatom_list(id)
177 for i in range(len(interatoms)):
178
179 if not interatoms[i].dipole_pair:
180 continue
181
182
183 if id != interatoms[i].spin_id1:
184 spin_id2 = interatoms[i].spin_id1
185 else:
186 spin_id2 = interatoms[i].spin_id2
187 spin2 = return_spin(spin_id2)
188
189
190 gx = return_gyromagnetic_ratio(spin.isotope)
191 gh = return_gyromagnetic_ratio(spin2.isotope)
192
193
194 r = interatoms[i].r
195
196
197 ct = Consistency(frq=cdp.ct_frq, gx=gx, gh=gh, mu0=mu0, h_bar=h_bar)
198
199
200 j0, f_eta, f_r2 = ct.func(orientation=spin.orientation, tc=spin.tc, r=r, csa=spin.csa, r1=r1, r2=r2, noe=noe)
201
202
203 if sim_index == None:
204 spin.j0 = j0
205 spin.f_eta = f_eta
206 spin.f_r2 = f_r2
207
208
209 else:
210
211 self.data_init(spin, sim=1)
212 if spin.j0_sim == None:
213 spin.j0_sim = []
214 spin.f_eta_sim = []
215 spin.f_r2_sim = []
216
217
218 spin.j0_sim.append(j0)
219 spin.f_eta_sim.append(f_eta)
220 spin.f_r2_sim.append(f_r2)
221
222
224 """Initialise the data structures.
225
226 @param data_cont: The data container.
227 @type data_cont: instance
228 @keyword sim: The Monte Carlo simulation flag, which if true will initialise the simulation data structure.
229 @type sim: bool
230 """
231
232
233 data_names = self.data_names()
234
235
236 for name in data_names:
237
238 if sim:
239
240 name = name + '_sim'
241
242
243 if not hasattr(data_cont, name):
244
245 setattr(data_cont, name, None)
246
247
249 """Deselect spins which have insufficient data to support calculation.
250
251 @keyword data_check: A flag to signal if the presence of base data is to be checked for.
252 @type data_check: bool
253 @keyword verbose: A flag which if True will allow printouts.
254 @type verbose: bool
255 """
256
257
258 if verbose:
259 print("\nOver-fit spin deselection:")
260
261
262 if not exists_mol_res_spin_data():
263 raise RelaxNoSequenceError
264
265
266 deselect_flag = False
267 spin_count = 0
268 for spin, spin_id in spin_loop(return_id=True):
269
270 if not spin.select:
271 continue
272
273
274 interatoms = return_interatom_list(spin_id)
275
276
277 dipole_relax = False
278 for i in range(len(interatoms)):
279
280 if not interatoms[i].dipole_pair:
281 continue
282
283
284 if spin_id != interatoms[i].spin_id1:
285 spin_id2 = interatoms[i].spin_id1
286 else:
287 spin_id2 = interatoms[i].spin_id2
288 spin2 = return_spin(spin_id2)
289
290
291 dipole_relax = True
292
293
294 if not dipole_relax or not hasattr(spin, 'csa') or spin.csa == None:
295 warn(RelaxDeselectWarning(spin_id, 'an absence of relaxation mechanisms'))
296 spin.select = False
297 deselect_flag = True
298 continue
299
300
301 if data_check:
302
303 data_points = 0
304 inf_data = False
305 if hasattr(cdp, 'ri_ids') and hasattr(spin, 'ri_data'):
306 for id in cdp.ri_ids:
307 if id in spin.ri_data and spin.ri_data[id] != None:
308 data_points += 1
309
310
311 if isInf(spin.ri_data[id]):
312 inf_data = True
313
314
315 if inf_data:
316 warn(RelaxDeselectWarning(spin_id, 'infinite relaxation data'))
317 spin.select = False
318 deselect_flag = True
319 continue
320
321
322 if not hasattr(spin, 'ri_data'):
323 warn(RelaxDeselectWarning(spin_id, 'missing relaxation data'))
324 spin.select = False
325 deselect_flag = True
326 continue
327
328
329 if data_points < 3:
330 warn(RelaxDeselectWarning(spin_id, 'insufficient relaxation data, 3 or more data points are required'))
331 spin.select = False
332 deselect_flag = True
333 continue
334
335
336 spin_count += 1
337
338
339 if spin_count == 0:
340 warn(RelaxWarning("No spins are selected therefore the optimisation or calculation cannot proceed."))
341
342
343 if verbose and not deselect_flag:
344 print("No spins have been deselected.")
345
346
347 - def set_error(self, model_info, index, error):
348 """Set the parameter errors.
349
350 @param model_info: The spin container originating from model_loop().
351 @type model_info: SpinContainer instance
352 @param index: The index of the parameter to set the errors for.
353 @type index: int
354 @param error: The error value.
355 @type error: float
356 """
357
358
359 spin = model_info
360
361
362 if index == 0:
363 spin.j0_err = error
364
365
366 if index == 1:
367 spin.f_eta_err = error
368
369
370 if index == 2:
371 spin.f_r2_err = error
372
373
375 """Return the array of simulation parameter values.
376
377 @param model_info: The spin container originating from model_loop().
378 @type model_info: SpinContainer instance
379 @param index: The index of the parameter to return the array of values for.
380 @type index: int
381 @return: The array of simulation parameter values.
382 @rtype: list of float
383 """
384
385
386 spin = model_info
387
388
389 if not spin.select:
390 return
391
392
393 if index == 0:
394 return spin.j0_sim
395
396
397 if index == 1:
398 return spin.f_eta_sim
399
400
401 if index == 2:
402 return spin.f_r2_sim
403
404
406 """Return the array of selected simulation flags.
407
408 @param model_info: The spin container originating from model_loop().
409 @type model_info: SpinContainer instance
410 @return: The array of selected simulation flags.
411 @rtype: list of int
412 """
413
414
415 spin = model_info
416
417
418 return spin.select_sim
419