1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """The main methods of the analysis specific API for the steady-state heteronuclear NOE calculation."""
24
25
26 from math import sqrt
27 from re import match
28 from warnings import warn
29
30
31 from generic_fns import pipes
32 from generic_fns.mol_res_spin import exists_mol_res_spin_data, spin_loop
33 from relax_errors import RelaxArgNotInListError, RelaxError, RelaxNoSequenceError
34 from relax_warnings import RelaxDeselectWarning
35 from specific_fns.api_common import API_common
36 from user_functions.data import Uf_tables; uf_tables = Uf_tables()
37 from user_functions.objects import Desc_container
38
39
41 """Class containing functions for relaxation data."""
42
43 - def _assign_function(self, spin=None, intensity=None, spectrum_type=None):
44 """Place the peak intensity data into the spin container.
45
46 The intensity data can be either that of the reference or saturated spectrum.
47
48 @keyword spin: The spin container.
49 @type spin: SpinContainer instance
50 @keyword intensity: The intensity value.
51 @type intensity: float
52 @keyword spectrum_type: The type of spectrum, one of 'ref' or 'sat'.
53 @type spectrum_type: str
54 """
55
56
57 if spectrum_type == 'ref':
58 spin.ref = intensity
59 elif spectrum_type == 'sat':
60 spin.sat = intensity
61 else:
62 raise RelaxError("The spectrum type '%s' is unknown." % spectrum_type)
63
64
65 - def _spectrum_type(self, spectrum_type=None, spectrum_id=None):
66 """Set the spectrum type corresponding to the spectrum_id.
67
68 @keyword spectrum_type: The type of NOE spectrum, one of 'ref' or 'sat'.
69 @type spectrum_type: str
70 @keyword spectrum_id: The spectrum id string.
71 @type spectrum_id: str
72 """
73
74
75 pipes.test()
76
77
78 if spectrum_id not in cdp.spectrum_ids:
79 raise RelaxError("The peak intensities corresponding to the spectrum id '%s' does not exist." % spectrum_id)
80
81
82 if not hasattr(cdp, 'spectrum_type'):
83 cdp.spectrum_type = {}
84
85
86 cdp.spectrum_type[spectrum_id] = spectrum_type
87
88
89 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
90 """Calculate the NOE and its error.
91
92 The error for each peak is calculated using the formula::
93 ___________________________________________
94 \/ {sd(sat)*I(unsat)}^2 + {sd(unsat)*I(sat)}^2
95 sd(NOE) = -----------------------------------------------
96 I(unsat)^2
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 MC simulation index (unused).
103 @type sim_index: None
104 """
105
106
107 pipes.test()
108
109
110 if not hasattr(cdp, 'spectrum_type'):
111 raise RelaxError("The spectrum types have not been set.")
112
113
114 if not 'ref' in cdp.spectrum_type.values() or not 'sat' in cdp.spectrum_type.values():
115 raise RelaxError("The reference and saturated NOE spectra have not been loaded.")
116
117
118 for spin in spin_loop():
119
120 if not spin.select:
121 continue
122
123
124 sat = 0.0
125 sat_err = 0.0
126 ref = 0.0
127 ref_err = 0.0
128 for id in cdp.spectrum_ids:
129
130 if cdp.spectrum_type[id] == 'sat':
131 sat = sat + spin.intensities[id]
132 sat_err = sat_err + spin.intensity_err[id]
133
134
135 if cdp.spectrum_type[id] == 'ref':
136 ref = ref + spin.intensities[id]
137 ref_err = ref_err + spin.intensity_err[id]
138
139
140 spin.noe = sat / ref
141
142
143 spin.noe_err = sqrt((sat_err * ref)**2 + (ref_err * sat)**2) / ref**2
144
145
146 - def overfit_deselect(self, data_check=True, verbose=True):
147 """Deselect spins which have insufficient data to support calculation.
148
149 @keyword data_check: A flag to signal if the presence of base data is to be checked for.
150 @type data_check: bool
151 @keyword verbose: A flag which if True will allow printouts.
152 @type verbose: bool
153 """
154
155
156 if verbose:
157 print("\nOver-fit spin deselection:")
158
159
160 if not exists_mol_res_spin_data():
161 raise RelaxNoSequenceError
162
163
164 deselect_flag = False
165 for spin, spin_id in spin_loop(return_id=True):
166
167 if not spin.select:
168 continue
169
170
171 if not hasattr(spin, 'intensities') or not len(spin.intensities) == 2:
172 warn(RelaxDeselectWarning(spin_id, 'insufficient data'))
173 spin.select = False
174 deselect_flag = True
175 continue
176
177
178 elif not hasattr(spin, 'intensity_err') or not len(spin.intensity_err) == 2:
179 warn(RelaxDeselectWarning(spin_id, 'missing errors'))
180 spin.select = False
181 deselect_flag = True
182 continue
183
184
185 if verbose and not deselect_flag:
186 print("No spins have been deselected.")
187
188
189 return_data_name_doc = Desc_container("NOE calculation data type string matching patterns")
190 _table = uf_tables.add_table(label="table: NOE data type patterns", caption="NOE data type string matching patterns.")
191 _table.add_headings(["Data type", "Object name"])
192 _table.add_row(["Reference intensity", "'ref'"])
193 _table.add_row(["Saturated intensity", "'sat'"])
194 _table.add_row(["NOE", "'noe'"])
195 return_data_name_doc.add_table(_table.label)
196
197
198 - def return_units(self, param):
199 """Dummy function which returns None as the stats have no units.
200
201 @param param: The name of the parameter to return the units string for.
202 @type param: str
203 @return: Nothing.
204 @rtype: None
205 """
206
207 return None
208