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