1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """The steady-state heteronuclear NOE API object."""
24
25
26 from math import sqrt
27 from warnings import warn
28
29
30 from lib.errors import RelaxError, RelaxNoSequenceError
31 from lib.warnings import RelaxDeselectWarning
32 from pipe_control import pipes
33 from pipe_control.mol_res_spin import exists_mol_res_spin_data, spin_loop
34 from specific_analyses.api_base import API_base
35 from specific_analyses.api_common import API_common
36 from specific_analyses.noe.parameter_object import Noe_params
37
38
39 -class Noe(API_base, API_common):
40 """Specific analysis API class for the steady-state heternuclear NOE analysis."""
41
42
43 instance = None
44
54
55
56 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
57 """Calculate the NOE and its error.
58
59 The error for each peak is calculated using the formula::
60 ___________________________________________
61 \/ {sd(sat)*I(unsat)}^2 + {sd(unsat)*I(sat)}^2
62 sd(NOE) = -----------------------------------------------
63 I(unsat)^2
64
65 @keyword spin_id: The spin identification string.
66 @type spin_id: None or str
67 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity.
68 @type verbosity: int
69 @keyword sim_index: The MC simulation index (unused).
70 @type sim_index: None
71 """
72
73
74 pipes.test()
75
76
77 if not hasattr(cdp, 'spectrum_type'):
78 raise RelaxError("The spectrum types have not been set.")
79
80
81 if not 'ref' in cdp.spectrum_type.values() or not 'sat' in cdp.spectrum_type.values():
82 raise RelaxError("The reference and saturated NOE spectra have not been loaded.")
83
84
85 for spin in spin_loop():
86
87 if not spin.select:
88 continue
89
90
91 sat = 0.0
92 sat_err2 = 0.0
93 sat_count = 0
94 ref = 0.0
95 ref_err2 = 0.0
96 ref_count = 0
97 for id in cdp.spectrum_ids:
98
99 if cdp.spectrum_type[id] == 'sat':
100 sat += spin.peak_intensity[id]
101 sat_err2 += spin.peak_intensity_err[id]**2
102 sat_count += 1
103
104
105 if cdp.spectrum_type[id] == 'ref':
106 ref += spin.peak_intensity[id]
107 ref_err2 += spin.peak_intensity_err[id]**2
108 ref_count += 1
109
110
111 sat = sat / sat_count
112 sat_err2 = sat_err2 / sat_count
113 ref = ref / ref_count
114 ref_err2 = ref_err2 / ref_count
115
116
117 spin.noe = sat / ref
118
119
120 spin.noe_err = sqrt(sat_err2 * ref**2 + ref_err2 * sat**2) / ref**2
121
122
124 """Deselect spins which have insufficient data to support calculation.
125
126 @keyword data_check: A flag to signal if the presence of base data is to be checked for.
127 @type data_check: bool
128 @keyword verbose: A flag which if True will allow printouts.
129 @type verbose: bool
130 """
131
132
133 if verbose:
134 print("\nOver-fit spin deselection:")
135
136
137 if not exists_mol_res_spin_data():
138 raise RelaxNoSequenceError
139
140
141 deselect_flag = False
142 all_desel = True
143 for spin, spin_id in spin_loop(return_id=True):
144
145 if not spin.select:
146 continue
147
148
149 if not hasattr(spin, 'peak_intensity'):
150 warn(RelaxDeselectWarning(spin_id, 'the absence of intensity data'))
151 spin.select = False
152 deselect_flag = True
153 continue
154
155
156 if not len(spin.peak_intensity) >= 2:
157 warn(RelaxDeselectWarning(spin_id, 'insufficient data (less than two data points)'))
158 spin.select = False
159 deselect_flag = True
160 continue
161
162
163 if not hasattr(spin, 'peak_intensity_err'):
164 warn(RelaxDeselectWarning(spin_id, 'the absence of errors'))
165 spin.select = False
166 deselect_flag = True
167 continue
168
169
170 if not len(spin.peak_intensity_err) >= 2:
171 warn(RelaxDeselectWarning(spin_id, 'missing errors (less than two error points)'))
172 spin.select = False
173 deselect_flag = True
174 continue
175
176
177 all_desel = False
178
179
180 if verbose and not deselect_flag:
181 print("No spins have been deselected.")
182
183
184 if all_desel:
185 raise RelaxError("All spins have been deselected.")
186