@@ -588,3 +588,150 @@ def test_group_custom_regex(tmp_path: Path):
588588 print (df ["plate" ])
589589 print (df_manual ["plate" ])
590590 pd .testing .assert_frame_equal (df_manual , df )
591+
592+ def test_single_csv (tmp_path : Path ):
593+ """
594+ Tests that a single file can be read using defaults
595+ """
596+ with open (str (tmp_path / "test.yaml" ), "w" ) as f :
597+ f .write (
598+ """
599+ metadata:
600+ condition:
601+ - cond1: A1
602+ """
603+ )
604+ with open (str (tmp_path / "data.csv" ), "w" ) as f :
605+ f .write ("""well,channel1,channel2\n A1,1,2""" )
606+ yaml_path = str (tmp_path ) + "/test.yaml"
607+ df = flow .load_single_csv_with_metadata (str (tmp_path )+ "/data.csv" , yaml_path )
608+ df .sort_values (by = "well" , inplace = True , ignore_index = True )
609+
610+ data = [["A1" , 1 , 2 , "cond1" ]]
611+ df_manual = pd .DataFrame (
612+ data , columns = ["well" , "channel1" , "channel2" , "condition" ]
613+ )
614+ assert df .equals (df_manual )
615+
616+ def test_single_csv_kwargs (tmp_path : Path ):
617+ """
618+ Tests that a single file can be read using custom kwargs
619+ """
620+ with open (str (tmp_path / "test.yaml" ), "w" ) as f :
621+ f .write (
622+ """
623+ metadata:
624+ condition:
625+ - cond1: A1
626+ """
627+ )
628+ with open (str (tmp_path / "data.txt" ), "w" ) as f :
629+ f .write ("""well\t channel1\t channel2\n A1\t 1\t 2""" )
630+ yaml_path = str (tmp_path ) + "/test.yaml"
631+ df = flow .load_single_csv_with_metadata (str (tmp_path )+ "/data.txt" , yaml_path , csv_kwargs = dict (sep = '\t ' ))
632+ df .sort_values (by = "well" , inplace = True , ignore_index = True )
633+
634+ data = [["A1" , 1 , 2 , "cond1" ]]
635+ df_manual = pd .DataFrame (
636+ data , columns = ["well" , "channel1" , "channel2" , "condition" ]
637+ )
638+ assert df .equals (df_manual )
639+
640+ def test_single_csv_well_column (tmp_path : Path ):
641+ """
642+ Tests that a single file can be read using custom well column
643+ """
644+ with open (str (tmp_path / "test.yaml" ), "w" ) as f :
645+ f .write (
646+ """
647+ metadata:
648+ condition:
649+ - cond1: A1
650+ """
651+ )
652+ with open (str (tmp_path / "data.csv" ), "w" ) as f :
653+ f .write ("""my_well,channel1,channel2\n A1,1,2""" )
654+ yaml_path = str (tmp_path ) + "/test.yaml"
655+ df = flow .load_single_csv_with_metadata (str (tmp_path )+ "/data.csv" , yaml_path , well_column = 'my_well' )
656+ df .sort_values (by = "well" , inplace = True , ignore_index = True )
657+
658+ data = [["A1" , 1 , 2 , "cond1" ]]
659+ df_manual = pd .DataFrame (
660+ data , columns = ["well" , "channel1" , "channel2" , "condition" ]
661+ )
662+ assert df .equals (df_manual )
663+ # Reload specifying columns
664+ df = flow .load_single_csv_with_metadata (str (tmp_path )+ "/data.csv" , yaml_path , well_column = 'my_well' ,
665+ columns = ['channel1' ])
666+ assert "channel1" in df .columns
667+ assert "channel2" not in df .columns
668+
669+ def test_single_csv_well_column_error (tmp_path : Path ):
670+ """
671+ Tests that a custom well column that is missing from the data correctly raises an error
672+ """
673+ with open (str (tmp_path / "test.yaml" ), "w" ) as f :
674+ f .write (
675+ """
676+ metadata:
677+ condition:
678+ - cond1: A1
679+ """
680+ )
681+ with open (str (tmp_path / "data.csv" ), "w" ) as f :
682+ f .write ("""my_well,channel1,channel2\n A1,1,2""" )
683+ yaml_path = str (tmp_path ) + "/test.yaml"
684+
685+ with pytest .raises (flow .ColumnError ):
686+ _ = flow .load_single_csv_with_metadata (str (tmp_path )+ "/data.csv" , yaml_path , well_column = 'other_well' )
687+
688+ def test_qpcr_loading (tmp_path : Path ):
689+ """
690+ Tests that a file with the qPCR default output can be loaded
691+ """
692+ with open (str (tmp_path / "test.yaml" ), "w" ) as f :
693+ f .write (
694+ """
695+ metadata:
696+ condition:
697+ - cond1: A1
698+ """
699+ )
700+ with open (str (tmp_path / "data.txt" ), "w" ) as f :
701+ f .write ("""Nonsense first line\n Pos\t Cp\t extra channel\n A1\t 1\t 2""" )
702+ yaml_path = str (tmp_path ) + "/test.yaml"
703+ df = flow .load_qpcr_with_metadata (str (tmp_path )+ "/data.txt" , yaml_path )
704+ df .sort_values (by = "well" , inplace = True , ignore_index = True )
705+
706+ data = [["A1" , 1 , "cond1" ]]
707+ df_manual = pd .DataFrame (
708+ data , columns = ["well" , "Cp" , "condition" ]
709+ )
710+ assert df .equals (df_manual )
711+
712+ def test_qpcr_loading_real_data (tmp_path : Path ):
713+ """
714+ Tests that a file with the qPCR default output can be loaded,
715+ copy-pasting from actual qPCR output file
716+ """
717+ with open (str (tmp_path / "test.yaml" ), "w" ) as f :
718+ f .write (
719+ """
720+ metadata:
721+ condition:
722+ - cond1: A1
723+ """
724+ )
725+ with open (str (tmp_path / "data.txt" ), "w" ) as f :
726+ f .write ("""Experiment: 2025.08.07_galloway-gaprun-lib-quant_KL Selected Filter: SYBR Green I / HRM Dye (465-510)
727+ Include Color Pos Name Cp Concentration Standard Status
728+ True 255 A1 Sample 1 27.23 0 """ )
729+ yaml_path = str (tmp_path ) + "/test.yaml"
730+ df = flow .load_qpcr_with_metadata (str (tmp_path )+ "/data.txt" , yaml_path )
731+ df .sort_values (by = "well" , inplace = True , ignore_index = True )
732+
733+ data = [["A1" , 27.23 , "cond1" ]]
734+ df_manual = pd .DataFrame (
735+ data , columns = ["well" , "Cp" , "condition" ]
736+ )
737+ assert df .equals (df_manual )
0 commit comments