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

1import unittest 

2from unittest.mock import patch 

3from pathlib import Path 

4import json 

5 

6import pytest 

7import numpy as np 

8import nmrglue as ng 

9import pandas as pd 

10 

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 

24 

25 

26@pytest.fixture 

27def test_directory(): 

28 return Path(__file__).parent 

29 

30 

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) 

39 

40 

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) 

47 

48 

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) 

55 

56 

57class TestReadScript(unittest.TestCase): 

58 test_directory = "./test/" 

59 

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) 

65 

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") 

80 

81 

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) 

87 

88 loaded_config = load_config(config_path) 

89 

90 assert loaded_config == {"key1": "value1"} 

91 

92 # Clean up 

93 config_path.unlink() 

94 

95 

96def test_load_config_nonexistent(): 

97 config_path = Path("test_config.json") 

98 

99 loaded_config = load_config(config_path) 

100 

101 assert loaded_config == {} 

102 

103 

104def test_write_config(): 

105 config_path = Path("test_config.json") 

106 config_kvs = {"key1": "value1", "key2": "value2"} 

107 

108 write_config(config_path, config_kvs) 

109 

110 # Check if the config file is created correctly 

111 assert config_path.exists() 

112 

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"} 

117 

118 # Clean up 

119 config_path.unlink() 

120 

121 

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) 

127 

128 config_kvs = {"key2": "value2", "key3": "value3"} 

129 updated_config = update_config_file(config_path, config_kvs) 

130 

131 assert updated_config == {"key1": "value1", "key2": "value2", "key3": "value3"} 

132 

133 # Clean up 

134 config_path.unlink() 

135 

136 

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) 

141 

142 assert updated_config == {"key1": "value1", "key2": "value2"} 

143 

144 # Clean up 

145 config_path.unlink() 

146 

147 

148@pytest.fixture 

149def sample_data(): 

150 return np.zeros((10, 10)) 

151 

152 

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] 

157 

158 

159def test_peak_limits_max_min(sample_peak, sample_data): 

160 limits = PeakLimits(sample_peak, sample_data) 

161 

162 assert limits.max_x == 8 

163 assert limits.max_y == 8 

164 assert limits.min_x == 3 

165 assert limits.min_y == 3 

166 

167 

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) 

172 

173 assert limits.max_x == 10 

174 assert limits.max_y == 10 

175 assert limits.min_x == 6 

176 assert limits.min_y == 6 

177 

178 

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) 

183 

184 assert limits.max_x == 3 

185 assert limits.max_y == 3 

186 assert limits.min_x == 0 

187 assert limits.min_y == 0 

188 

189 

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) 

195 

196 

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) 

203 

204 

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" 

210 

211 

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" 

218 

219 

220def test_OutFmt(): 

221 assert OutFmt.csv.value == "csv" 

222 assert OutFmt.pkl.value == "pkl" 

223 

224 

225@pytest.fixture 

226def test_data_path(): 

227 return Path("./test/test_protein_L") 

228 

229 

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 

235 

236 

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) 

245 

246 

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 

253 

254 

255def test_Peaklist_initialization(test_data_path, peaklist): 

256 

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] 

261 

262 

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() 

271 

272 

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() 

281 

282 

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) 

290 

291 

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) 

300 

301 

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() 

311 

312 

313def test_LoadData_with_Edited_column(loaddata): 

314 loaddata.df["Edited"] = "yes" 

315 loaddata.check_data_frame() 

316 

317 

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") 

323 

324 

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 

329 

330 

331def test_UnknownFormat(): 

332 with pytest.raises(UnknownFormat): 

333 raise UnknownFormat("This is an unknown format") 

334 

335 

336def test_update_df(peaklist): 

337 peaklist.update_df() 

338 

339 df = peaklist.df 

340 

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 

344 

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 

348 

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 

352 

353 # Check that XW and YW columns are created 

354 assert "XW" in df.columns 

355 assert "YW" in df.columns 

356 

357 # Check the assignment column 

358 assert "ASS" in df.columns 

359 

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 

365 

366 # Check 'include' column is created and set to 'yes' 

367 assert "include" in df.columns 

368 assert all(df["include"] == "yes") 

369 

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 ) 

377 

378 

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() 

382 

383 df = peaklist.df 

384 

385 # Check that out of bounds peak is excluded 

386 assert len(df) == 62 

387 assert not ((df["X_PPM"] == 100.0).any()) 

388 

389 

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)] 

395 

396 clusters_result = ClustersResult(labeled_array, num_features, closed_data, peaks) 

397 

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 

402 

403 

404def test_get_vclist_None(): 

405 assert get_vclist(None, {})["vclist"] == False 

406 

407 

408def test_get_vclist_exists(test_data_path): 

409 vclist = test_data_path / "vclist" 

410 assert get_vclist(vclist, {})["vclist"] == True 

411 

412 

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 

417 

418 

419if __name__ == "__main__": 

420 unittest.main(verbosity=2)