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