Coverage for test/test_io.py: 99%
262 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
1import unittest
2from unittest.mock import patch
3from pathlib import Path
4import json
6import pytest
7import numpy as np
8import nmrglue as ng
9import pandas as pd
11from peakipy.io import (
12 Pseudo3D,
13 Peaklist,
14 LoadData,
15 PeaklistFormat,
16 OutFmt,
17 StrucEl,
18 UnknownFormat,
19 ClustersResult,
20 get_vclist,
21)
22from peakipy.fitting import PeakLimits
23from peakipy.utils import load_config, write_config, update_config_file
26@pytest.fixture
27def test_directory():
28 return Path(__file__).parent
31# test for read, edit, fit, check and spec scripts
32# need to actually write proper tests
33class TestBokehScript(unittest.TestCase):
34 @patch("peakipy.cli.edit.BokehScript")
35 def test_BokehScript(self, MockBokehScript):
36 args = {"<peaklist>": "hello", "<data>": "data"}
37 bokeh_plots = MockBokehScript(args)
38 self.assertIsNotNone(bokeh_plots)
41class TestCheckScript(unittest.TestCase):
42 @patch("peakipy.cli.main.check")
43 def test_main(self, MockCheck):
44 args = {"<peaklist>": "hello", "<data>": "data"}
45 check = MockCheck(args)
46 self.assertIsNotNone(check)
49class TestFitScript(unittest.TestCase):
50 @patch("peakipy.cli.main.fit")
51 def test_main(self, MockFit):
52 args = {"<peaklist>": "hello", "<data>": "data"}
53 fit = MockFit(args)
54 self.assertIsNotNone(fit)
57class TestReadScript(unittest.TestCase):
58 test_directory = "./test/"
60 @patch("peakipy.cli.main.read")
61 def test_main(self, MockRead):
62 args = {"<peaklist>": "hello", "<data>": "data"}
63 read = MockRead(args)
64 self.assertIsNotNone(read)
66 def test_read_pipe_peaklist(self):
67 args = {
68 "path": f"{self.test_directory}/test_pipe.tab",
69 "data_path": f"{self.test_directory}/test_pipe.ft2",
70 "dims": [0, 1, 2],
71 "fmt": PeaklistFormat.pipe,
72 }
73 peaklist = Peaklist(**args)
74 self.assertIsNotNone(peaklist)
75 self.assertIs(len(peaklist.df), 3)
76 # self.assertIs(peaklist.df.X_AXISf.iloc[0], 323.019)
77 self.assertIs(peaklist.fmt.value, "pipe")
78 # self.assertEqual(peaklist.df.ASS.iloc[0], "None")
79 # self.assertEqual(peaklist.df.ASS.iloc[1], "None_dummy_1")
82def test_load_config_existing():
83 config_path = Path("test_config.json")
84 # Create a dummy existing config file
85 with open(config_path, "w") as f:
86 json.dump({"key1": "value1"}, f)
88 loaded_config = load_config(config_path)
90 assert loaded_config == {"key1": "value1"}
92 # Clean up
93 config_path.unlink()
96def test_load_config_nonexistent():
97 config_path = Path("test_config.json")
99 loaded_config = load_config(config_path)
101 assert loaded_config == {}
104def test_write_config():
105 config_path = Path("test_config.json")
106 config_kvs = {"key1": "value1", "key2": "value2"}
108 write_config(config_path, config_kvs)
110 # Check if the config file is created correctly
111 assert config_path.exists()
113 # Check if the config file content is correct
114 with open(config_path) as f:
115 created_config = json.load(f)
116 assert created_config == {"key1": "value1", "key2": "value2"}
118 # Clean up
119 config_path.unlink()
122def test_update_config_file_existing():
123 config_path = Path("test_config.json")
124 # Create a dummy existing config file
125 with open(config_path, "w") as f:
126 json.dump({"key1": "value1"}, f)
128 config_kvs = {"key2": "value2", "key3": "value3"}
129 updated_config = update_config_file(config_path, config_kvs)
131 assert updated_config == {"key1": "value1", "key2": "value2", "key3": "value3"}
133 # Clean up
134 config_path.unlink()
137def test_update_config_file_nonexistent():
138 config_path = Path("test_config.json")
139 config_kvs = {"key1": "value1", "key2": "value2"}
140 updated_config = update_config_file(config_path, config_kvs)
142 assert updated_config == {"key1": "value1", "key2": "value2"}
144 # Clean up
145 config_path.unlink()
148@pytest.fixture
149def sample_data():
150 return np.zeros((10, 10))
153@pytest.fixture
154def sample_peak():
155 peak_data = {"X_AXIS": [5], "Y_AXIS": [5], "XW": [2], "YW": [2]}
156 return pd.DataFrame(peak_data).iloc[0]
159def test_peak_limits_max_min(sample_peak, sample_data):
160 limits = PeakLimits(sample_peak, sample_data)
162 assert limits.max_x == 8
163 assert limits.max_y == 8
164 assert limits.min_x == 3
165 assert limits.min_y == 3
168def test_peak_limits_boundary(sample_data):
169 peak_data = {"X_AXIS": [8], "Y_AXIS": [8], "XW": [2], "YW": [2]}
170 peak = pd.DataFrame(peak_data).iloc[0]
171 limits = PeakLimits(peak, sample_data)
173 assert limits.max_x == 10
174 assert limits.max_y == 10
175 assert limits.min_x == 6
176 assert limits.min_y == 6
179def test_peak_limits_at_boundary(sample_data):
180 peak_data = {"X_AXIS": [0], "Y_AXIS": [0], "XW": [2], "YW": [2]}
181 peak = pd.DataFrame(peak_data).iloc[0]
182 limits = PeakLimits(peak, sample_data)
184 assert limits.max_x == 3
185 assert limits.max_y == 3
186 assert limits.min_x == 0
187 assert limits.min_y == 0
190def test_peak_limits_outside_boundary(sample_data):
191 peak_data = {"X_AXIS": [15], "Y_AXIS": [15], "XW": [2], "YW": [2]}
192 peak = pd.DataFrame(peak_data).iloc[0]
193 with pytest.raises(AssertionError):
194 limits = PeakLimits(peak, sample_data)
197def test_peak_limits_1d_data():
198 data = np.zeros(10)
199 peak_data = {"X_AXIS": [5], "Y_AXIS": [0], "XW": [2], "YW": [0]}
200 peak = pd.DataFrame(peak_data).iloc[0]
201 with pytest.raises(IndexError):
202 limits = PeakLimits(peak, data)
205def test_StrucEl():
206 assert StrucEl.square.value == "square"
207 assert StrucEl.disk.value == "disk"
208 assert StrucEl.rectangle.value == "rectangle"
209 assert StrucEl.mask_method.value == "mask_method"
212def test_PeaklistFormat():
213 assert PeaklistFormat.a2.value == "a2"
214 assert PeaklistFormat.a3.value == "a3"
215 assert PeaklistFormat.sparky.value == "sparky"
216 assert PeaklistFormat.pipe.value == "pipe"
217 assert PeaklistFormat.peakipy.value == "peakipy"
220def test_OutFmt():
221 assert OutFmt.csv.value == "csv"
222 assert OutFmt.pkl.value == "pkl"
225@pytest.fixture
226def test_data_path():
227 return Path("./test/test_protein_L")
230@pytest.fixture
231def pseudo3d_args(test_data_path):
232 dic, data = ng.pipe.read(test_data_path / "test1.ft2")
233 dims = [0, 1, 2]
234 return dic, data, dims
237@pytest.fixture
238def peaklist(test_data_path):
239 dims = [0, 1, 2]
240 path = test_data_path / "test.tab"
241 data_path = test_data_path / "test1.ft2"
242 fmt = PeaklistFormat.pipe
243 radii = [0.04, 0.4]
244 return Peaklist(path, data_path, fmt, dims, radii)
247def test_Pseudo3D_properties(pseudo3d_args):
248 dic, data, dims = pseudo3d_args
249 pseudo3d = Pseudo3D(dic, data, dims)
250 assert pseudo3d.dic == dic
251 assert np.array_equal(pseudo3d._data, data.reshape((4, 256, 546)))
252 assert pseudo3d.dims == dims
255def test_Peaklist_initialization(test_data_path, peaklist):
257 assert peaklist.peaklist_path == test_data_path / "test.tab"
258 assert peaklist.data_path == test_data_path / "test1.ft2"
259 assert peaklist.fmt == PeaklistFormat.pipe
260 assert peaklist.radii == [0.04, 0.4]
263def test_Peaklist_a2(test_data_path):
264 dims = [0, 1, 2]
265 path = test_data_path / "peaks.a2"
266 data_path = test_data_path / "test1.ft2"
267 fmt = PeaklistFormat.a2
268 radii = [0.04, 0.4]
269 peaklist = Peaklist(path, data_path, fmt, dims, radii)
270 peaklist.update_df()
273def test_Peaklist_a3(test_data_path):
274 dims = [0, 1, 2]
275 path = test_data_path / "ccpnTable.tsv"
276 data_path = test_data_path / "test1.ft2"
277 fmt = PeaklistFormat.a3
278 radii = [0.04, 0.4]
279 peaklist = Peaklist(path, data_path, fmt, dims, radii)
280 peaklist.update_df()
283def test_Peaklist_sparky(test_data_path):
284 dims = [0, 1, 2]
285 path = test_data_path / "peaks.sparky"
286 data_path = test_data_path / "test1.ft2"
287 fmt = PeaklistFormat.sparky
288 radii = [0.04, 0.4]
289 Peaklist(path, data_path, fmt, dims, radii)
292@pytest.fixture
293def loaddata(test_data_path):
294 dims = [0, 1, 2]
295 path = test_data_path / "test.csv"
296 data_path = test_data_path / "test1.ft2"
297 fmt = PeaklistFormat.peakipy
298 radii = [0.04, 0.4]
299 return LoadData(path, data_path, fmt, dims, radii)
302def test_LoadData_initialization(test_data_path, loaddata):
303 assert loaddata.peaklist_path == test_data_path / "test.csv"
304 assert loaddata.data_path == test_data_path / "test1.ft2"
305 assert loaddata.fmt == PeaklistFormat.peakipy
306 assert loaddata.radii == [0.04, 0.4]
307 loaddata.check_data_frame()
308 loaddata.check_assignments()
309 loaddata.check_peak_bounds()
310 loaddata.update_df()
313def test_LoadData_with_Edited_column(loaddata):
314 loaddata.df["Edited"] = "yes"
315 loaddata.check_data_frame()
318def test_LoadData_without_include_column(loaddata):
319 loaddata.df.drop(columns=["include"], inplace=True)
320 loaddata.check_data_frame()
321 assert "include" in loaddata.df.columns
322 assert np.all(loaddata.df.include == "yes")
325def test_LoadData_with_X_DIAMETER_PPM_column(loaddata):
326 loaddata.df["X_DIAMETER_PPM"] = 0.04
327 loaddata.check_data_frame()
328 assert "X_DIAMETER_PPM" in loaddata.df.columns
331def test_UnknownFormat():
332 with pytest.raises(UnknownFormat):
333 raise UnknownFormat("This is an unknown format")
336def test_update_df(peaklist):
337 peaklist.update_df()
339 df = peaklist.df
341 # Check that X_AXIS and Y_AXIS columns are created and values are set correctly
342 assert "X_AXIS" in df.columns
343 assert "Y_AXIS" in df.columns
345 # Check that X_AXISf and Y_AXISf columns are created and values are set correctly
346 assert "X_AXISf" in df.columns
347 assert "Y_AXISf" in df.columns
349 # Check that XW_HZ and YW_HZ columns are converted to float correctly
350 assert df["XW_HZ"].dtype == float
351 assert df["YW_HZ"].dtype == float
353 # Check that XW and YW columns are created
354 assert "XW" in df.columns
355 assert "YW" in df.columns
357 # Check the assignment column
358 assert "ASS" in df.columns
360 # Check radii columns
361 assert "X_RADIUS_PPM" in df.columns
362 assert "Y_RADIUS_PPM" in df.columns
363 assert "X_RADIUS" in df.columns
364 assert "Y_RADIUS" in df.columns
366 # Check 'include' column is created and set to 'yes'
367 assert "include" in df.columns
368 assert all(df["include"] == "yes")
370 # Check that the peaks are within bounds
371 assert all(
372 (df["X_PPM"] < peaklist.f2_ppm_max) & (df["X_PPM"] > peaklist.f2_ppm_min)
373 )
374 assert all(
375 (df["Y_PPM"] < peaklist.f1_ppm_max) & (df["Y_PPM"] > peaklist.f1_ppm_min)
376 )
379def test_update_df_with_excluded_peaks(peaklist):
380 peaklist._df.loc[1, "X_PPM"] = 100.0 # This peak should be out of bounds
381 peaklist.update_df()
383 df = peaklist.df
385 # Check that out of bounds peak is excluded
386 assert len(df) == 62
387 assert not ((df["X_PPM"] == 100.0).any())
390def test_clusters_result_initialization():
391 labeled_array = np.array([[1, 2], [3, 4]])
392 num_features = 5
393 closed_data = np.array([[5, 6], [7, 8]])
394 peaks = [(1, 2), (3, 4)]
396 clusters_result = ClustersResult(labeled_array, num_features, closed_data, peaks)
398 assert np.array_equal(clusters_result.labeled_array, labeled_array)
399 assert clusters_result.num_features == num_features
400 assert np.array_equal(clusters_result.closed_data, closed_data)
401 assert clusters_result.peaks == peaks
404def test_get_vclist_None():
405 assert get_vclist(None, {})["vclist"] == False
408def test_get_vclist_exists(test_data_path):
409 vclist = test_data_path / "vclist"
410 assert get_vclist(vclist, {})["vclist"] == True
413def test_get_vclist_not_exists(test_data_path):
414 vclist = test_data_path / "vclistbla"
415 with pytest.raises(Exception):
416 get_vclist(vclist, {})["vclist"] == True
419if __name__ == "__main__":
420 unittest.main(verbosity=2)