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