@@ -22,13 +22,11 @@ def test_single_csv(tmp_path: Path):
2222 with open (str (tmp_path / "data.csv" ), "w" ) as f :
2323 f .write ("""well,channel1,channel2\n A1,1,2""" )
2424 yaml_path = str (tmp_path ) + "/test.yaml"
25- df = qpcr .load_single_csv_with_metadata (str (tmp_path )+ "/data.csv" , yaml_path )
25+ df = qpcr .load_single_csv_with_metadata (str (tmp_path ) + "/data.csv" , yaml_path )
2626 df .sort_values (by = "well" , inplace = True , ignore_index = True )
2727
2828 data = [["A1" , 1 , 2 , "cond1" ]]
29- df_manual = pd .DataFrame (
30- data , columns = ["well" , "channel1" , "channel2" , "condition" ]
31- )
29+ df_manual = pd .DataFrame (data , columns = ["well" , "channel1" , "channel2" , "condition" ])
3230 assert df .equals (df_manual )
3331
3432
@@ -47,13 +45,13 @@ def test_single_csv_kwargs(tmp_path: Path):
4745 with open (str (tmp_path / "data.txt" ), "w" ) as f :
4846 f .write ("""well\t channel1\t channel2\n A1\t 1\t 2""" )
4947 yaml_path = str (tmp_path ) + "/test.yaml"
50- df = qpcr .load_single_csv_with_metadata (str (tmp_path )+ "/data.txt" , yaml_path , csv_kwargs = dict (sep = '\t ' ))
48+ df = qpcr .load_single_csv_with_metadata (
49+ str (tmp_path ) + "/data.txt" , yaml_path , csv_kwargs = {"delimiter" : "," }
50+ )
5151 df .sort_values (by = "well" , inplace = True , ignore_index = True )
5252
5353 data = [["A1" , 1 , 2 , "cond1" ]]
54- df_manual = pd .DataFrame (
55- data , columns = ["well" , "channel1" , "channel2" , "condition" ]
56- )
54+ df_manual = pd .DataFrame (data , columns = ["well" , "channel1" , "channel2" , "condition" ])
5755 assert df .equals (df_manual )
5856
5957
@@ -72,17 +70,18 @@ def test_single_csv_well_column(tmp_path: Path):
7270 with open (str (tmp_path / "data.csv" ), "w" ) as f :
7371 f .write ("""my_well,channel1,channel2\n A1,1,2""" )
7472 yaml_path = str (tmp_path ) + "/test.yaml"
75- df = qpcr .load_single_csv_with_metadata (str (tmp_path )+ "/data.csv" , yaml_path , well_column = 'my_well' )
73+ df = qpcr .load_single_csv_with_metadata (
74+ str (tmp_path ) + "/data.csv" , yaml_path , well_column = "my_well"
75+ )
7676 df .sort_values (by = "my_well" , inplace = True , ignore_index = True )
7777
7878 data = [["A1" , 1 , 2 , "A1" , "cond1" ]]
79- df_manual = pd .DataFrame (
80- data , columns = ["my_well" , "channel1" , "channel2" , "well" , "condition" ]
81- )
79+ df_manual = pd .DataFrame (data , columns = ["my_well" , "channel1" , "channel2" , "well" , "condition" ])
8280 assert df .equals (df_manual )
8381 # Reload specifying columns
84- df = qpcr .load_single_csv_with_metadata (str (tmp_path )+ "/data.csv" , yaml_path , well_column = 'my_well' ,
85- columns = ['channel1' ])
82+ df = qpcr .load_single_csv_with_metadata (
83+ str (tmp_path ) + "/data.csv" , yaml_path , well_column = "my_well" , columns = ["channel1" ]
84+ )
8685 assert "channel1" in df .columns
8786 assert "channel2" not in df .columns
8887
@@ -102,13 +101,15 @@ def test_single_csv_invalid_well_column(tmp_path: Path):
102101 with open (str (tmp_path / "data.csv" ), "w" ) as f :
103102 f .write ("""my_well,channel1,channel2\n A1,1,2""" )
104103 yaml_path = str (tmp_path ) + "/test.yaml"
105-
104+
106105 with pytest .raises (qpcr .ColumnError ):
107- _ = qpcr .load_single_csv_with_metadata (str (tmp_path ) + "/data.csv" , yaml_path , well_column = 'other_well' )
106+ _ = qpcr .load_single_csv_with_metadata (
107+ str (tmp_path ) + "/data.csv" , yaml_path , well_column = "other_well"
108+ )
108109
109110
110111def test_single_csv_invalid_path (tmp_path : Path ):
111- os .mkdir (tmp_path / ' my_dir' )
112+ os .mkdir (tmp_path / " my_dir" )
112113 with open (str (tmp_path / "test.yaml" ), "w" ) as f :
113114 f .write (
114115 """
@@ -119,12 +120,22 @@ def test_single_csv_invalid_path(tmp_path: Path):
119120 )
120121
121122 with pytest .raises (qpcr .DataPathError ):
122- _ = qpcr .load_single_csv_with_metadata (str (tmp_path ) + "/my_dir" , str (tmp_path ) + "/test.yaml" )
123+ _ = qpcr .load_single_csv_with_metadata (
124+ str (tmp_path ) + "/my_dir" , str (tmp_path ) + "/test.yaml"
125+ )
126+
127+
128+ def test_invalid_yaml_path (tmp_path : Path ):
129+ """
130+ Tests that invalid .yaml files throw errors
131+ """
132+ with pytest .raises (qpcr .YamlError ):
133+ _ = qpcr .load_single_csv_with_metadata ("" , tmp_path / "nonexistent.yaml" )
123134
124135
125136def test_qpcr_default (tmp_path : Path ):
126137 """
127- Tests that a file with the qPCR default output can be loaded,
138+ Tests that a file with the qPCR default output can be loaded,
128139 and that it overrides previous kwargs
129140 """
130141 with open (str (tmp_path / "test.yaml" ), "w" ) as f :
@@ -138,15 +149,18 @@ def test_qpcr_default(tmp_path: Path):
138149 with open (str (tmp_path / "data.txt" ), "w" ) as f :
139150 f .write ("""Nonsense first line\n Pos\t Cp\t extra channel\n A1\t 1\t 2""" )
140151 yaml_path = str (tmp_path ) + "/test.yaml"
141- df = qpcr .load_single_csv_with_metadata (str (tmp_path )+ "/data.txt" , yaml_path ,
142- well_column = 'bad_well' , columns = ['old_col' ], csv_kwargs = {'delimiter' : ',' },
143- is_default = True )
152+ df = qpcr .load_single_csv_with_metadata (
153+ str (tmp_path ) + "/data.txt" ,
154+ yaml_path ,
155+ well_column = "bad_well" ,
156+ columns = ["old_col" ],
157+ csv_kwargs = {"delimiter" : "," },
158+ is_default = True ,
159+ )
144160 df .sort_values (by = "well" , inplace = True , ignore_index = True )
145161
146162 data = [["A1" , 1 , "A1" , "cond1" ]]
147- df_manual = pd .DataFrame (
148- data , columns = ["Pos" , "Cp" , "well" , "condition" ]
149- )
163+ df_manual = pd .DataFrame (data , columns = ["Pos" , "Cp" , "well" , "condition" ])
150164 assert df .equals (df_manual )
151165
152166
@@ -164,17 +178,15 @@ def test_qpcr_default_real_data(tmp_path: Path):
164178 """
165179 )
166180 with open (str (tmp_path / "data.txt" ), "w" ) as f :
167- f .write ("""Experiment: 2025.08.07_galloway-gaprun-lib-quant_KL Selected Filter: SYBR Green I / HRM Dye (465-510)
181+ f .write ("""Experiment: 2025.08.07_galloway-gaprun-lib-quant_KL Filter: SYBR Green I
168182 Include Color Pos Name Cp Concentration Standard Status
169183 True 255 A1 Sample 1 27.23 0 """ )
170184 yaml_path = str (tmp_path ) + "/test.yaml"
171- df = qpcr .load_single_csv_with_metadata (str (tmp_path )+ "/data.txt" , yaml_path , is_default = True )
185+ df = qpcr .load_single_csv_with_metadata (str (tmp_path ) + "/data.txt" , yaml_path , is_default = True )
172186 df .sort_values (by = "well" , inplace = True , ignore_index = True )
173187
174188 data = [["A1" , 27.23 , "A1" , "cond1" ]]
175- df_manual = pd .DataFrame (
176- data , columns = ["Pos" , "Cp" , "well" , "condition" ]
177- )
189+ df_manual = pd .DataFrame (data , columns = ["Pos" , "Cp" , "well" , "condition" ])
178190 assert df .equals (df_manual )
179191
180192
@@ -196,7 +208,6 @@ def test_plates(tmp_path: Path):
196208 )
197209 with open (str (tmp_path / sub_dir [0 ] / "plate1.csv" ), "w" ) as f :
198210 f .write ("""well,channel1,channel2\n A1,1,2\n G12,10,20""" )
199-
200211
201212 with open (str (tmp_path / sub_dir [1 ] / "test.yaml" ), "w" ) as f :
202213 f .write (
@@ -207,12 +218,12 @@ def test_plates(tmp_path: Path):
207218 """
208219 )
209220 with open (str (tmp_path / sub_dir [1 ] / "plate2.csv" ), "w" ) as f :
210- f .write ("""well,channel1,channel2\n A1,3,4\n G12,30,""" "" )
221+ f .write ("""well,channel1,channel2\n A1,3,4\n G12,30,""" "" )
211222
212223 # Call function
213224 plates = pd .DataFrame (
214225 {
215- "data_path" : [Path (tmp_path / d / f' plate{ i + 1 } .csv' ) for i ,d in enumerate (sub_dir )],
226+ "data_path" : [Path (tmp_path / d / f" plate{ i + 1 } .csv" ) for i , d in enumerate (sub_dir )],
216227 "yaml_path" : [Path (tmp_path / d / "test.yaml" ) for d in sub_dir ],
217228 "extra_metadata" : ["meta1" , "meta2" ],
218229 }
@@ -229,8 +240,10 @@ def test_plates(tmp_path: Path):
229240 df_manual = pd .DataFrame (
230241 data , columns = ["condition" , "channel1" , "channel2" , "well" , "extra_metadata" ]
231242 )
232- df = df .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = 'columns' )
233- df_manual = df_manual .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = 'columns' )
243+ df = df .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = "columns" )
244+ df_manual = df_manual .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (
245+ axis = "columns"
246+ )
234247 assert df .equals (df_manual )
235248
236249 df = qpcr .load_plates_with_metadata (plates , filename_regex = r"plate(?P<plate>\d+)\.csv" )
@@ -243,8 +256,10 @@ def test_plates(tmp_path: Path):
243256 df_manual = pd .DataFrame (
244257 data , columns = ["condition" , "channel1" , "channel2" , "well" , "extra_metadata" , "plate" ]
245258 )
246- df = df .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = 'columns' )
247- df_manual = df_manual .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = 'columns' )
259+ df = df .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = "columns" )
260+ df_manual = df_manual .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (
261+ axis = "columns"
262+ )
248263 assert df .equals (df_manual )
249264
250265
@@ -253,7 +268,7 @@ def test_plates_valid_base_path(tmp_path: Path):
253268 Tests that several plates can be loaded using a valid base_path
254269 """
255270 # Create data
256- os .mkdir (tmp_path / "dir" )
271+ os .mkdir (tmp_path / "dir" )
257272 with open (str (tmp_path / "dir" / "test1.yaml" ), "w" ) as f :
258273 f .write (
259274 """
@@ -264,7 +279,6 @@ def test_plates_valid_base_path(tmp_path: Path):
264279 )
265280 with open (str (tmp_path / "dir" / "plate1.csv" ), "w" ) as f :
266281 f .write ("""well,channel1,channel2\n A1,1,2\n G12,10,20""" )
267-
268282
269283 with open (str (tmp_path / "dir" / "test2.yaml" ), "w" ) as f :
270284 f .write (
@@ -285,7 +299,7 @@ def test_plates_valid_base_path(tmp_path: Path):
285299 "extra_metadata" : ["meta1" , "meta2" ],
286300 }
287301 )
288- df = qpcr .load_plates_with_metadata (plates , base_path = (tmp_path / "dir" ))
302+ df = qpcr .load_plates_with_metadata (plates , base_path = (tmp_path / "dir" ))
289303
290304 # Check against manual output
291305 data = [
@@ -297,18 +311,20 @@ def test_plates_valid_base_path(tmp_path: Path):
297311 df_manual = pd .DataFrame (
298312 data , columns = ["condition" , "channel1" , "channel2" , "well" , "extra_metadata" ]
299313 )
300- df = df .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = 'columns' )
301- df_manual = df_manual .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = 'columns' )
314+ df = df .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = "columns" )
315+ df_manual = df_manual .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (
316+ axis = "columns"
317+ )
302318 assert df .equals (df_manual )
303319
304320
305321def test_plates_df_regex (tmp_path : Path ):
306322 """
307- Tests that several plates can be loaded using a valid filename_regex
323+ Tests that several plates can be loaded using a valid filename_regex
308324 for each plate
309325 """
310326 # Create data
311- os .mkdir (tmp_path / "dir" )
327+ os .mkdir (tmp_path / "dir" )
312328 with open (str (tmp_path / "dir" / "test1.yaml" ), "w" ) as f :
313329 f .write (
314330 """
@@ -319,7 +335,6 @@ def test_plates_df_regex(tmp_path: Path):
319335 )
320336 with open (str (tmp_path / "dir" / "2025_plate1.csv" ), "w" ) as f :
321337 f .write ("""well,channel1,channel2\n A1,1,2\n G12,10,20""" )
322-
323338
324339 with open (str (tmp_path / "dir" / "test2.yaml" ), "w" ) as f :
325340 f .write (
@@ -337,11 +352,14 @@ def test_plates_df_regex(tmp_path: Path):
337352 {
338353 "data_path" : ["2025_plate1.csv" , "plate2_2026.csv" ],
339354 "yaml_path" : ["test1.yaml" , "test2.yaml" ],
340- "filename_regex" : [r"(?P<date>\d+)_plate(?P<plate>\d+)\.csv" , r"plate(?P<plate>\d+)_(?P<date>\d+)\.csv" ],
355+ "filename_regex" : [
356+ r"(?P<date>\d+)_plate(?P<plate>\d+)\.csv" ,
357+ r"plate(?P<plate>\d+)_(?P<date>\d+)\.csv" ,
358+ ],
341359 "extra_metadata" : ["meta1" , "meta2" ],
342360 }
343361 )
344- df = qpcr .load_plates_with_metadata (plates , base_path = (tmp_path / "dir" ))
362+ df = qpcr .load_plates_with_metadata (plates , base_path = (tmp_path / "dir" ))
345363
346364 # Check against manual output
347365 data = [
@@ -351,10 +369,22 @@ def test_plates_df_regex(tmp_path: Path):
351369 ["cond1" , 30 , 40 , "G12" , "meta2" , "2026" , r"plate(?P<plate>\d+)_(?P<date>\d+)\.csv" , "2" ],
352370 ]
353371 df_manual = pd .DataFrame (
354- data , columns = ["condition" , "channel1" , "channel2" , "well" , "extra_metadata" , "date" , "filename_regex" , "plate" ]
372+ data ,
373+ columns = [
374+ "condition" ,
375+ "channel1" ,
376+ "channel2" ,
377+ "well" ,
378+ "extra_metadata" ,
379+ "date" ,
380+ "filename_regex" ,
381+ "plate" ,
382+ ],
383+ )
384+ df = df .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = "columns" )
385+ df_manual = df_manual .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (
386+ axis = "columns"
355387 )
356- df = df .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = 'columns' )
357- df_manual = df_manual .sort_values (by = ["extra_metadata" , "well" ], ignore_index = True ).sort_index (axis = 'columns' )
358388 assert df .equals (df_manual )
359389
360390
@@ -363,7 +393,7 @@ def test_plates_invalid_regex(tmp_path: Path):
363393 Tests that error is raised if plate filename doesn't match passed regex
364394 """
365395 # Create data
366- os .mkdir (tmp_path / "dir" )
396+ os .mkdir (tmp_path / "dir" )
367397 with open (str (tmp_path / "dir" / "test.yaml" ), "w" ) as f :
368398 f .write (
369399 """
@@ -386,8 +416,11 @@ def test_plates_invalid_regex(tmp_path: Path):
386416 }
387417 )
388418 with pytest .raises (qpcr .RegexError ):
389- _ = qpcr .load_plates_with_metadata (plates , base_path = (tmp_path / "dir" ),
390- filename_regex = r"plate(?P<plate>\d+)_(?P<date>\d+)\.csv" )
419+ _ = qpcr .load_plates_with_metadata (
420+ plates ,
421+ base_path = (tmp_path / "dir" ),
422+ filename_regex = r"plate(?P<plate>\d+)_(?P<date>\d+)\.csv" ,
423+ )
391424
392425
393426def test_plates_invalid_df ():
@@ -401,4 +434,4 @@ def test_plates_invalid_df():
401434 df_list = [df1 , df2 , df3 ]
402435 for df in df_list :
403436 with pytest .raises (qpcr .GroupsError ):
404- _ = qpcr .load_plates_with_metadata (df )
437+ _ = qpcr .load_plates_with_metadata (df )
0 commit comments