Coverage for test/test_lineshapes.py: 99%
151 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-09-14 14:49 -0400
« prev ^ index » next coverage.py v7.4.4, created at 2024-09-14 14:49 -0400
1from pathlib import Path
2from unittest.mock import Mock
4import pytest
5import pandas as pd
6import numpy as np
7from numpy.testing import assert_almost_equal
9from peakipy.io import Peaklist, PeaklistFormat
10from peakipy.constants import tiny
11from peakipy.lineshapes import (
12 gaussian,
13 gaussian_lorentzian,
14 pv_g,
15 pv_l,
16 voigt2d,
17 pvoigt2d,
18 pv_pv,
19 get_lineshape_function,
20 Lineshape,
21 calculate_height_for_voigt_lineshape,
22 calculate_fwhm_for_voigt_lineshape,
23 calculate_fwhm_for_pseudo_voigt_lineshape,
24 calculate_height_for_pseudo_voigt_lineshape,
25 calculate_height_for_gaussian_lineshape,
26 calculate_height_for_lorentzian_lineshape,
27 calculate_height_for_pv_pv_lineshape,
28 calculate_lineshape_specific_height_and_fwhm,
29 calculate_peak_linewidths_in_hz,
30 calculate_peak_centers_in_ppm,
31)
34def test_gaussian_typical_values():
35 x = np.array([0, 1, 2])
36 center = 0.0
37 sigma = 1.0
38 expected = (1.0 / (np.sqrt(2 * np.pi) * sigma)) * np.exp(
39 -((x - center) ** 2) / (2 * sigma**2)
40 )
41 result = gaussian(x, center, sigma)
42 assert_almost_equal(result, expected, decimal=7)
45def test_gaussian_center_nonzero():
46 x = np.array([0, 1, 2])
47 center = 1.0
48 sigma = 1.0
49 expected = (1.0 / (np.sqrt(2 * np.pi) * sigma)) * np.exp(
50 -((x - center) ** 2) / (2 * sigma**2)
51 )
52 result = gaussian(x, center, sigma)
53 assert_almost_equal(result, expected, decimal=7)
56def test_gaussian_sigma_nonzero():
57 x = np.array([0, 1, 2])
58 center = 0.0
59 sigma = 2.0
60 expected = (1.0 / (np.sqrt(2 * np.pi) * sigma)) * np.exp(
61 -((x - center) ** 2) / (2 * sigma**2)
62 )
63 result = gaussian(x, center, sigma)
64 assert_almost_equal(result, expected, decimal=7)
67def test_gaussian_zero_center():
68 x = np.array([0, 1, 2])
69 center = 0.0
70 sigma = 1.0
71 expected = (1.0 / (np.sqrt(2 * np.pi) * sigma)) * np.exp(
72 -((x - center) ** 2) / (2 * sigma**2)
73 )
74 result = gaussian(x, center, sigma)
75 assert_almost_equal(result, expected, decimal=7)
78def test_calculate_height_for_voigt_lineshape():
79 data = {
80 "sigma_x": [1.0, 2.0],
81 "sigma_y": [1.0, 2.0],
82 "gamma_x": [1.0, 2.0],
83 "gamma_y": [1.0, 2.0],
84 "amp": [10.0, 20.0],
85 "amp_err": [1.0, 2.0],
86 }
87 df = pd.DataFrame(data)
88 result_df = calculate_height_for_voigt_lineshape(df)
90 assert np.allclose(result_df["height"], [0.435596, 0.217798])
91 assert np.allclose(result_df["height_err"], [0.04356, 0.02178])
94def test_calculate_fwhm_for_voigt_lineshape():
95 data = {
96 "sigma_x": [1.0, 2.0],
97 "sigma_y": [1.0, 2.0],
98 "gamma_x": [1.0, 2.0],
99 "gamma_y": [1.0, 2.0],
100 "amp": [10.0, 20.0],
101 "amp_err": [1.0, 2.0],
102 }
103 df = pd.DataFrame(data)
104 result_df = calculate_fwhm_for_voigt_lineshape(df)
106 assert np.allclose(result_df["fwhm_l_x"], [2.0, 4.0])
107 assert np.allclose(result_df["fwhm_l_y"], [2.0, 4.0])
108 assert np.allclose(result_df["fwhm_g_x"], [2.35482, 4.70964])
109 assert np.allclose(result_df["fwhm_g_y"], [2.35482, 4.70964])
110 assert np.allclose(result_df["fwhm_x"], [3.601309, 7.202619])
111 assert np.allclose(result_df["fwhm_y"], [3.601309, 7.202619])
114def test_calculate_height_for_pseudo_voigt_lineshape():
115 data = {
116 "sigma_x": [1.0, 2.0],
117 "sigma_y": [1.0, 2.0],
118 "gamma_x": [1.0, 2.0],
119 "gamma_y": [1.0, 2.0],
120 "amp": [10.0, 20.0],
121 "amp_err": [1.0, 2.0],
122 "fraction": [0.5, 0.5],
123 }
124 df = pd.DataFrame(data)
125 result_df = calculate_height_for_pseudo_voigt_lineshape(df)
127 assert np.allclose(result_df["height"], [1.552472, 0.776236])
128 assert np.allclose(result_df["height_err"], [0.155247, 0.077624])
131def test_calculate_fwhm_for_pseudo_voigt_lineshape():
132 data = {
133 "sigma_x": [1.0, 2.0],
134 "sigma_y": [1.0, 2.0],
135 "gamma_x": [1.0, 2.0],
136 "gamma_y": [1.0, 2.0],
137 "amp": [10.0, 20.0],
138 "amp_err": [1.0, 2.0],
139 "fraction": [0.5, 0.5],
140 }
141 df = pd.DataFrame(data)
142 result_df = calculate_fwhm_for_pseudo_voigt_lineshape(df)
144 assert np.allclose(result_df["fwhm_x"], [2.0, 4.0])
145 assert np.allclose(result_df["fwhm_y"], [2.0, 4.0])
148def test_calculate_height_for_gaussian_lineshape():
149 data = {
150 "sigma_x": [1.0, 2.0],
151 "sigma_y": [1.0, 2.0],
152 "gamma_x": [1.0, 2.0],
153 "gamma_y": [1.0, 2.0],
154 "amp": [10.0, 20.0],
155 "amp_err": [1.0, 2.0],
156 "fraction": [0.5, 0.5],
157 }
158 df = pd.DataFrame(data)
159 result_df = calculate_height_for_gaussian_lineshape(df)
161 assert np.allclose(result_df["height"], [2.206356, 1.103178])
162 assert np.allclose(result_df["height_err"], [0.220636, 0.110318])
165def test_calculate_height_for_lorentzian_lineshape():
166 data = {
167 "sigma_x": [1.0, 2.0],
168 "sigma_y": [1.0, 2.0],
169 "gamma_x": [1.0, 2.0],
170 "gamma_y": [1.0, 2.0],
171 "amp": [10.0, 20.0],
172 "amp_err": [1.0, 2.0],
173 "fraction": [0.5, 0.5],
174 }
175 df = pd.DataFrame(data)
176 result_df = calculate_height_for_lorentzian_lineshape(df)
178 assert np.allclose(result_df["height"], [1.013212, 0.506606])
179 assert np.allclose(result_df["height_err"], [0.101321, 0.050661])
182def test_calculate_height_for_pv_pv_lineshape():
183 data = {
184 "sigma_x": [1.0, 2.0],
185 "sigma_y": [1.0, 2.0],
186 "gamma_x": [1.0, 2.0],
187 "gamma_y": [1.0, 2.0],
188 "amp": [10.0, 20.0],
189 "amp_err": [1.0, 2.0],
190 "fraction_x": [0.5, 0.5],
191 "fraction_y": [0.5, 0.5],
192 }
193 df = pd.DataFrame(data)
194 result_df = calculate_height_for_pv_pv_lineshape(df)
196 assert np.allclose(result_df["height"], [1.552472, 0.776236])
197 assert np.allclose(result_df["height_err"], [0.155247, 0.077624])
200def test_calculate_height_for_pv_pv_lineshape_fraction_y():
201 data = {
202 "sigma_x": [1.0, 2.0],
203 "sigma_y": [1.0, 2.0],
204 "gamma_x": [1.0, 2.0],
205 "gamma_y": [1.0, 2.0],
206 "amp": [10.0, 20.0],
207 "amp_err": [1.0, 2.0],
208 "fraction_x": [0.5, 0.5],
209 "fraction_y": [1.0, 1.0],
210 }
211 df = pd.DataFrame(data)
212 result_df = calculate_height_for_pv_pv_lineshape(df)
214 assert np.allclose(result_df["height"], [1.254186, 0.627093])
215 assert np.allclose(result_df["height_err"], [0.125419, 0.062709])
218def test_calculate_lineshape_specific_height_and_fwhm():
219 data = {
220 "sigma_x": [1.0, 2.0],
221 "sigma_y": [1.0, 2.0],
222 "gamma_x": [1.0, 2.0],
223 "gamma_y": [1.0, 2.0],
224 "amp": [10.0, 20.0],
225 "amp_err": [1.0, 2.0],
226 "fraction": [0.5, 0.5],
227 "fraction_x": [0.5, 0.5],
228 "fraction_y": [0.5, 0.5],
229 }
230 df = pd.DataFrame(data)
231 calculate_lineshape_specific_height_and_fwhm(Lineshape.G, df)
232 calculate_lineshape_specific_height_and_fwhm(Lineshape.L, df)
233 calculate_lineshape_specific_height_and_fwhm(Lineshape.V, df)
234 calculate_lineshape_specific_height_and_fwhm(Lineshape.PV, df)
235 calculate_lineshape_specific_height_and_fwhm(Lineshape.PV_PV, df)
236 calculate_lineshape_specific_height_and_fwhm(Lineshape.PV_G, df)
237 calculate_lineshape_specific_height_and_fwhm(Lineshape.PV_L, df)
240def test_get_lineshape_function():
241 assert get_lineshape_function(Lineshape.PV) == pvoigt2d
242 assert get_lineshape_function(Lineshape.L) == pvoigt2d
243 assert get_lineshape_function(Lineshape.G) == pvoigt2d
244 assert get_lineshape_function(Lineshape.G_L) == gaussian_lorentzian
245 assert get_lineshape_function(Lineshape.PV_G) == pv_g
246 assert get_lineshape_function(Lineshape.PV_L) == pv_l
247 assert get_lineshape_function(Lineshape.PV_PV) == pv_pv
248 assert get_lineshape_function(Lineshape.V) == voigt2d
251def test_get_lineshape_function_exception():
252 with pytest.raises(Exception):
253 get_lineshape_function("bla")
256@pytest.fixture
257def peakipy_data():
258 test_data_path = Path("./test/test_protein_L/")
259 return Peaklist(
260 test_data_path / "test.tab", test_data_path / "test1.ft2", PeaklistFormat.pipe
261 )
264def test_calculate_peak_linewidths_in_hz():
265 # Sample data for testing
266 data = {
267 "sigma_x": [1.0, 2.0, 3.0],
268 "sigma_y": [1.5, 2.5, 3.5],
269 "fwhm_x": [0.5, 1.5, 2.5],
270 "fwhm_y": [0.7, 1.7, 2.7],
271 }
272 df = pd.DataFrame(data)
274 # Mock peakipy_data object
275 peakipy_data = Mock()
276 peakipy_data.ppm_per_pt_f2 = 0.01
277 peakipy_data.ppm_per_pt_f1 = 0.02
278 peakipy_data.hz_per_pt_f2 = 10.0
279 peakipy_data.hz_per_pt_f1 = 20.0
281 # Expected results
282 expected_sigma_x_ppm = [0.01, 0.02, 0.03]
283 expected_sigma_y_ppm = [0.03, 0.05, 0.07]
284 expected_fwhm_x_ppm = [0.005, 0.015, 0.025]
285 expected_fwhm_y_ppm = [0.014, 0.034, 0.054]
286 expected_fwhm_x_hz = [5.0, 15.0, 25.0]
287 expected_fwhm_y_hz = [14.0, 34.0, 54.0]
289 # Run the function
290 result_df = calculate_peak_linewidths_in_hz(df, peakipy_data)
292 # Assertions
293 pd.testing.assert_series_equal(
294 result_df["sigma_x_ppm"], pd.Series(expected_sigma_x_ppm), check_names=False
295 )
296 pd.testing.assert_series_equal(
297 result_df["sigma_y_ppm"], pd.Series(expected_sigma_y_ppm), check_names=False
298 )
299 pd.testing.assert_series_equal(
300 result_df["fwhm_x_ppm"], pd.Series(expected_fwhm_x_ppm), check_names=False
301 )
302 pd.testing.assert_series_equal(
303 result_df["fwhm_y_ppm"], pd.Series(expected_fwhm_y_ppm), check_names=False
304 )
305 pd.testing.assert_series_equal(
306 result_df["fwhm_x_hz"], pd.Series(expected_fwhm_x_hz), check_names=False
307 )
308 pd.testing.assert_series_equal(
309 result_df["fwhm_y_hz"], pd.Series(expected_fwhm_y_hz), check_names=False
310 )
313def test_calculate_peak_centers_in_ppm():
314 # Sample data for testing
315 data = {
316 "center_x": [10, 20, 30],
317 "center_y": [15, 25, 35],
318 "init_center_x": [12, 22, 32],
319 "init_center_y": [18, 28, 38],
320 }
321 df = pd.DataFrame(data)
323 # Mock peakipy_data object
324 peakipy_data = Mock()
325 peakipy_data.uc_f2.ppm = Mock(side_effect=lambda x: x * 0.1)
326 peakipy_data.uc_f1.ppm = Mock(side_effect=lambda x: x * 0.2)
328 # Expected results
329 expected_center_x_ppm = [1.0, 2.0, 3.0]
330 expected_center_y_ppm = [3.0, 5.0, 7.0]
331 expected_init_center_x_ppm = [1.2, 2.2, 3.2]
332 expected_init_center_y_ppm = [3.6, 5.6, 7.6]
334 # Run the function
335 result_df = calculate_peak_centers_in_ppm(df, peakipy_data)
337 # Assertions
338 pd.testing.assert_series_equal(
339 result_df["center_x_ppm"], pd.Series(expected_center_x_ppm), check_names=False
340 )
341 pd.testing.assert_series_equal(
342 result_df["center_y_ppm"], pd.Series(expected_center_y_ppm), check_names=False
343 )
344 pd.testing.assert_series_equal(
345 result_df["init_center_x_ppm"],
346 pd.Series(expected_init_center_x_ppm),
347 check_names=False,
348 )
349 pd.testing.assert_series_equal(
350 result_df["init_center_y_ppm"],
351 pd.Series(expected_init_center_y_ppm),
352 check_names=False,
353 )