From 5b174ea47ab3cbc338ce515a4f6c668c0e67e425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20=C5=9Acise=C5=82?= Date: Tue, 20 May 2025 19:22:11 +0200 Subject: [PATCH 1/6] Initial version of base sequence quality --- Cargo.lock | 5 +- Cargo.toml | 1 + docs/notebooks/example.fastq | 800 +++++++++++++++++++++++++++++++++ docs/notebooks/example.parquet | Bin 0 -> 20352 bytes docs/notebooks/tutorial.ipynb | 211 ++++++--- polars_bio/__init__.py | 2 + polars_bio/quality_stats.py | 25 ++ src/lib.rs | 36 ++ src/operation.rs | 133 ++++++ 9 files changed, 1145 insertions(+), 68 deletions(-) create mode 100644 docs/notebooks/example.fastq create mode 100644 docs/notebooks/example.parquet create mode 100644 polars_bio/quality_stats.py diff --git a/Cargo.lock b/Cargo.lock index d84574f0..2527967b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5424,6 +5424,7 @@ dependencies = [ "pyo3-log", "rand", "sequila-core", + "serde_json", "tokio", "tracing", ] @@ -6346,9 +6347,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "indexmap", "itoa", diff --git a/Cargo.toml b/Cargo.toml index 47d326b7..919b38d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,3 +43,4 @@ coitrees = "0.4.0" fnv = "1.0.7" async-stream = "0.3.6" rand = "0.8.5" +serde_json = "1.0.140" diff --git a/docs/notebooks/example.fastq b/docs/notebooks/example.fastq new file mode 100644 index 00000000..4b357e52 --- /dev/null +++ b/docs/notebooks/example.fastq @@ -0,0 +1,800 @@ +@SRR9130495.1 D00236:723:HG32CBCX2:1:1108:1330:1935/1 +NCAATACAAAAGCAATATGGGAGAAGCTACCTACCATGCTTAAAAACGCCAATGAGCAGNGATTTGTCANCNNNNNNNNCNNNNNNNNTNNTANNANNCTC ++ +#4BDFDFFHGHGGJJJHIIIIGGIIJGJJGIIIIBHIJJJIIJIJJIJDHIGGGIJJJI#-@AEHGEFF#,########,########+##++##+##+2< +@SRR9130495.2 D00236:723:HG32CBCX2:1:1108:1472:1938/1 +NGTCAAAGATAAGATCAAAAGGCACTGGCTTACCTGATTAAGAAATTGTGTAGTCCAACATCAAAATACNTNTNNNNNAGAGNCANGNCAAGCNNANNAAT ++ +#1=DDDDD>DHFH@EFHHGHGGFGIIIGIGGGGIIGIIDDCHIIIIIID@FEGGGIIIIICHIIIIIIG#-#-#####,,;;#,5#,#,,85@A:AB@8>@:@A@9(:((+(834 +@SRR9130495.6 D00236:723:HG32CBCX2:1:1108:2392:1965/1 +CGATAAAGGACTTTCAGTCAACCAACTAGATAATGACCACTGGGCACCCATTCATTATGCATGCTGGTAAATAAATTATTCTGTTCAGGAACATTGAACTC ++ +CC@DDDBDFFHHHJJIJJIIJIJJJIIIHGIGGHCGGIGHHAACC??A< +@SRR9130495.11 D00236:723:HG32CBCX2:1:1108:4089:1977/1 +CATTCCAACCAGCCGCTTAAAGTTTCTAAAAGAAGCTGGTCATGGAACCCAGAAGGAGGAGATACCTGAGGAGGAATTAGCAGAGGATGTTGAAGAGATTG ++ +CCCFFFDFHHHHHJIJJJJIIJJJJJJJJJJJIIGJJJIGHGIJJIJJIJJIIFHGHIJJGHEHHFCEFFDEDDBDDDDDDDDDDDBACDDDDDDDDDDDD +@SRR9130495.12 D00236:723:HG32CBCX2:1:1108:6197:1936/1 +NCTTAAAGGCAAGGTGCTCGGCTTCCGCTATCAAGACCTCCGACAGAAAATCCGGCCTGNGGCTAAAGANCNNNNNNNNANNNNNNNNCNNGGNNCNNGGC ++ +#1BDFDEFGHHHHIJJJJJJIJJJJJJJJJJIJJIGIJJIJJJIJJJJHIJJHHHFFDC#,;?BBDDDD#,########+########+##++##+##++8 +@SRR9130495.13 D00236:723:HG32CBCX2:1:1108:6415:1939/1 +NTGTGTATGGGGATGAGGAAGGATATTAATATGTTCTATTTGAGATTTAGGGATTACATTTGTTTTTGCNCNCNNNNNTTTTNTCNTCATTTGNNGTNAAT ++ +#1:ADDDFHGGHFGGBHIGGIIJJEIIIJJIJIJJJFGJIIHGHGDGHJGHIHIIIIJJIIHFHIIJJJ#-#-#####,,;?#,;#,8?DDEE##,+#+2< +@SRR9130495.14 D00236:723:HG32CBCX2:1:1108:6361:1952/1 +TCAGATCTTATTTTAATAGTTGACTTTACCTCTTCTTTGACTTCCTCTTCCTCGGTCTCAGTAGATATAGATGGTACCTTGGGCTTATGCCATGAGATCTG ++ +CCCFFFFFHHHHDHIIIIJJJJJJJJJJHIIIJJJJJJJIHJHJII>GHIEGHIIIIJJJIJJIHHIJJJIJIGHIJJGJJHFHHFFDCFFEDCEDCCDEC +@SRR9130495.15 D00236:723:HG32CBCX2:1:1108:6263:1960/1 +CAATATCTGACTGAATGGGCCCATTTTCATAATATTCTGAAACTGTTCATACATGTCTCGCAATGTAAACTGACCTGAAATGCAATACAAAAAAATTCAGA ++ +CCCFFFFFHHGHGGGIIIIJJIJIJJIIIIIIIIEIHGGIEGGHGIJJIJJJCECGHIIIJJJJJIFGHIIHGIIJJHHGEFHDFFFFFCCCDDBBCCDCA +@SRR9130495.16 D00236:723:HG32CBCX2:1:1108:6338:1988/1 +AGACACTAAAATGCCATGTATGAGACTACATAGACATACCAATTTACAACACAAACACATGAAATATACATGAGAAAACATTAACTTACTTCCAGTTGGGA ++ +C@CFFDDDHGHHHIIIIHJJIIHIHGIJJJJJIJJJIJIIHEHIIJJJJJJIJJIIIIIJJDHIJIJGIJIJJIJJHHGGHFFFFFFFEEEDCCC@ACCBA +@SRR9130495.17 D00236:723:HG32CBCX2:1:1108:6742:1944/1 +NGAAACACTCTTTTTCTGGAATTTGCAAGTGGAGATTTCAGCCGCTTTGTGGTCAATGGTAGAAAAGGAAATATNTNCATATAAAAACTAGACAGAATGAT ++ +#1BDFDFFHGHGHJJJJJJJJHIJHHIJIIJJIJJGIJJIJIIJJGIJIHIJJJIIJJJHIEIIJJJJIHDEFH#,#,5=ADEEEDCDDDDDDDCDD5@CD +@SRR9130495.18 D00236:723:HG32CBCX2:1:1108:7076:1942/1 +NGTCTAAGAATGAAGTGCTTATGGTCAACATAGGCTCCCTGTCGACAGGAGGAAGAGTTAGTGCAGTCAAGGCTNANTTGGGCAAAATTGTTTNNACCAAT ++ +#1:B:BDDHHFFHIEGGIGIDEHGEEGIGHIIIFACHIGIGCFGEHIGGHHGHGH@DCGGIDEIIIIFFHHAEE#,#,5=@BBC@BCCCCCCC##,+8?BC +@SRR9130495.19 D00236:723:HG32CBCX2:1:1108:7440:1957/1 +CACCTGATGTCCCACAGTCCTCATAGACACTAGCACTGACTGCTGGCCATCGTCTCAGCCAGATGATGTTGACCTGCTAGCTTTTCAATTAAATTATTAAA ++ ++=144=DD>D4CCD?E@AECFFIIIIEI?E+??;3EBDECEIBEECDIEIIADDDDEIDCDCA;=A@CECE7ACD=(;;A@DA@A@A:ADAAAD>AADBB> +@SRR9130495.20 D00236:723:HG32CBCX2:1:1108:7363:1977/1 +ACTCATAGAGTTGAAGATTCCCTTTCATAGAGCAGGTTTGAAACACTCTTTCTGGAGTATCTGGATGTGGACATTTGGAGCGCTTTGATGCCTACGGTGGA ++ +CCCFFDDDFHHHHJJJIJJJJHHIIHGIJIJJJIGGHGIJIJJIIIJJJJJIJIGBFDHIIJIJGIJIGGCHGGIJHIIHHHFECDECEEDCDDCBD9?B? +@SRR9130495.21 D00236:723:HG32CBCX2:1:1108:7298:1979/1 +AACCGTCGCCAGGTACCATCCCAGAGAACTCTGTCTTCCTTACTTATAGCCAAGTTGCCGGCAGATCACAGCTGCATGCTTATCGGTCCATCCGTCATCGC ++ +BCCDDDFFGGFGFJIBBHHIJJIIHHIIIGJIIHIIJJJIIEIGHJIIJJJJIIHHGIJFGHGFDDCEECDDDDDDDDDDEDDDDDDDBDEDDDCCC +@SRR9130495.23 D00236:723:HG32CBCX2:1:1108:7307:1995/1 +TAATTTGGTATATGTCTTTTTAAAGGCATTTTTATTAGATATTTCCTTAATTTACATTTCAAATGTTATCCCCAAAGCCCCCTATAATCTACCCCTGCCTT ++ +;?7DD?;DBFHHFIA;A@AABBB@B?2<58+:?<<9<@: +@SRR9130495.25 D00236:723:HG32CBCX2:1:1108:7870:1955/1 +CTATCCCGTCGGGTGACTGTTTCCTGCTTTGCAGTTATTCAGTGGCAGAGCGTGGCGCTCTAATTTCTGCTTTCCTCTTTCCTGCAGATTGTGTGCTACAT ++ +CCCFFFDFFHHFHBHGJIIIHGIIIJJIJIIIIJHIIIIEIJJIIJJJJIJIJIJDFEDDDCEEEEEEDDDDDDDDCDDDCDDDDDDDCDDDCDDDDDDDD +@SRR9130495.26 D00236:723:HG32CBCX2:1:1108:8157:1994/1 +GAAGTGCTCTTCGTTACTACTTAAATCCCCCTGGGCATGTTTCATTATTTTACAATTTGTGCAGAACCCTATCCAAACACACATGGAGTACAAATGACTTC ++ +CCCFFDDDDHHDHHIGIIBIHHHJJJ@FGGA?@CCCCCC@CCCDD +@SRR9130495.27 D00236:723:HG32CBCX2:1:1108:8703:1937/1 +NATAAAAAAATAACATCCTTTCCTCCTAATAGCTTAATTATTTGAAAAAAAATATTTTCNAATCACATGNANNNNNNNNTNNNNNNNNTCTTTNNTNNCCT ++ +#1=DFDDDHHHHHIIJJJJJFIJJJIGIEGIIJJJHHIJJJJJIIJIIIIIJEHEHHHA#,;??AEDDC#,########,########++8??##+##(+2 +@SRR9130495.28 D00236:723:HG32CBCX2:1:1108:8702:1991/1 +CTCAGAGATTAAAAATGAATAACGCCTGCCGGCCAATGAGCGGACTCACAGTCCCTGTTTGTTTGTAAGCTAGGTGATTTTCAATCCACAGGGCAGGCTGA ++ +@@@DFDFFGGDHFGIIBGEHJIIIBGIIIJJIIJIJIIFGGEGIJJJHGGHHHDCFFDDDEDEDDDDDCDDDCBDDACDEDEDDDDCCCCDGII@GIFGFE???BFBBEHIGGIEEHIHIGGHHGIHA3?CH;?@CB@DCCEDEDD3 +@SRR9130495.34 D00236:723:HG32CBCX2:1:1108:10535:1962/1 +AATACAGAAAAGTTAAGAGCCAGCCCCAGGCGGATTGGATGAATAGGTTGCATCTCTTTCTTGCTTATATCAAATGCCTCTTGGCAGGCTCCTTGGGAATT ++ +???BD:A:3=?B:;?;;CA;;;A3-5>5-5:(::@8/2?8?9>>3(83(+ +@SRR9130495.35 D00236:723:HG32CBCX2:1:1108:11147:1968/1 +GCTGCCTTCTCCCCTCAAGGATGCAGTGGAAGTGTCAACCTGGAGAAGATGCTACACGATGCAGGAGGTGAACTCGGCCCTCAGTAAAATCCAGCTGGTGG ++ +CCCFFFDFHHHGHJFEGIHEGHIGIIGCCGGGIIJJIJJGGGGHCGIF>DGHIIIEHHGIIJJDBGHFHFCCFFFDDCDDDDBDDDCCDEDA:CACD@CDD +@SRR9130495.36 D00236:723:HG32CBCX2:1:1108:11124:1986/1 +GACAGGGTTTCACCATGTTAGCCAGGACGGTCTTGATCTCCTGACCTCGTGATCCGCCTGTCTCGGCCTCCCAAAGTCCTGGGATTACAGGCGTGAGCCAC ++ +CCCFFFFBFFFHGGHGHIHIIGIJFJJJIJHIIIFGHGGIIGEGHIH@@FGGIJIIGGIHIEEHEEFFDDCCCCBDDACCDCDBAACCDDDBDDDDBDDCC +@SRR9130495.37 D00236:723:HG32CBCX2:1:1108:11773:1947/1 +TACCTGCCTCTGCCTCTCGAGTGCTGGGATGAAAGATGTGCACACCCCCACCACCACCACCACCACTGCCTGGCNCNGTTTTTGATTTCTTATTCTCCAGA ++ +CCCFFFFFHGHHHJIJIJIIEHIJJIJJIJJIHIHJJIGFIIIIJBHHGFF>HGIJIEHHHFGDEEEEEECC?B#,#,,5?@HF1CGBGHCDDFF7=DEG.?AAC?3@EED;6@;>(-;@AC?31(,5?(4::A>AC +@SRR9130495.46 D00236:723:HG32CBCX2:1:1108:14226:1948/1 +AACCTGCACCCAGAATGGCAGGAGGTCCTGGTGGCCCAGGGGGTCCTGGTGGTCCAGGAACACCAGGTCTCCCANANCCAGGTGGCCCAGGCAGGCCTGGA ++ +??1D1BDDHFHHBBHGGGAFG)AF1:?CEGD@BGAFDGIGGB'5;CE77?=???>>CC3#+#++228>>28((2(>ACC?CCDDCCD@ +@SRR9130495.48 D00236:723:HG32CBCX2:1:1108:15049:1993/1 +TGACCAAGAACTCACAGAGATCCCCCCCCCCAGGGCTAAGATTAAAGGCATGTGCCACTGCCACTGGATAGATATTATCTTTTATTTTACCTGACTGGTTG ++ +@CCFFDDDHDFHGJJJJIJGIHHHIIJJIJFE=(5;?@>@A@;@C>CAB=@<:@C@CA:>CC3:>CB<@@?344>>@@A>CDC>ACDD:>4>>>ACD?CC( +@SRR9130495.49 D00236:723:HG32CBCX2:1:1108:15487:1951/1 +ACGGAGGGTGGGGCTGGGTGATTGTGGTTGTCTCCTTCTTCACCCAGTTCCTCTCTTACGGATCCCCGTTAGCTNTNGGGGTCTTGTATGTAGAATGGCTG ++ +BCCFD@DFDFHHGDGIIICGHIIJJIJGHIIJIIJJJIJIJIJEHIGHHHHHHHFFFFFFDDCDDCD@DDDDD:#+#+2<@8GHIIIEHGACFHIIGGIBHIIHHC??BDC@BBCECDCE63>@@CACCDD@ +@SRR9130495.51 D00236:723:HG32CBCX2:1:1108:15923:1957/1 +CCGCAACTGCCATGGAGCCACAGCCTGGTCCGTAATAGATGCAAAGCTTCTCAATAGTCAGGGGCGTGGTTTCGCGCAGCTTGGAGGCCAGCAACAGGCAG ++ +CCCFFFFFHFHHHIIFIIIGIIFIIGJIIJJIFHGHIIIIIJIIFIJIIIJJJJJJJGGIGJFFH@?BBBDBCDDDDDDDDDDDDDDDDDDDDDDDDDDD? +@SRR9130495.52 D00236:723:HG32CBCX2:1:1108:15793:1968/1 +GTTTTTCCACAGACCTCTGATCTCTTACATTCGAAAGTTCTACTACTATGATCCTCAGGAAGAGGTGTACCTGTCCCTAAAGGAAGCGCAGCTCATTTCCA ++ +BB@FFFFFFFHGDGFHJJJJIFIIGGG@FIIIGIBGGDHIIIJCHIIJJDHIIJJJIIIGIIJJFHHIJCHGDHIIHHHHHFFFFFDDDDDDCDDDDEDDE +@SRR9130495.53 D00236:723:HG32CBCX2:1:1108:16082:1968/1 +GAAACTTGTTTGTGACGTGTGTATTCAACTAACAGAGTTGAACCTTTCTTTTTACAGAGCAGCTTTGAAACACGCTTTTTGTAGAATCAGATCGGAAGAGC ++ +@<@ADDDECBFFHIFEGDG;EEHHB@FHGHIIGGEHGGHGGEGEGICGCEFFDB@D>AE>ADC@CBBFGIIJJJJIHHIJJGH?DGGHCFHHIJJEEIIJAHIJJFG=FGGGIFHHIIDHGEHIHHHHGHGEB;?CDCECEEDD +@SRR9130495.55 D00236:723:HG32CBCX2:1:1108:16048:2000/1 +AGGACAGGAAGGACGCTTTGAGATATGATTTCACAGGCGACAGTGAGAGAAAACCAATGTCTTTAATGCATTTCTCTGCAGCATGTGACAAACTTTCAACA ++ +CCCFFFFDFHGHHIIJJJJIFGGIJJIIIIJIJIHJIIJIHGIJJIJGGIIJIJJHHHHEDCDFFFEEEDDEDEEDDDDDDDDDDCDEDDCDDDDDDCCD@ +@SRR9130495.56 D00236:723:HG32CBCX2:1:1108:16580:1970/1 +GCCTGTACTCCCAGCTACTTGGGAGGCTGAGACAGGAGAATCACTTGAACCCAGGAGGTGGAGGTTGCAGTGAGCCAAGACCGGGCTATTGCACTAGATCG ++ +@@@FFD?DBFFHHIIEHCIJIFIJHEDCH@GGEBFHHIJJIIIIIJJJJJIFHFHF@G-6@AAEDFFF>AEC@@A?;=?BCD6/<@>BAAC>:@C:CDDA? +@SRR9130495.57 D00236:723:HG32CBCX2:1:1108:16594:1971/1 +TCCTCTGACTTTGACACTAGTGTTGACCTTGCATGAGGAGATGTTCTCCATTTGGACTAACCTGATGTACACAGACGTTACACTTATCACAGAATACCATA ++ +CCCFFDDFFHFHFHIJIJJIHIIIJJJJJIJJJJIIIIHIGIIJJJIGIIJJIIJEHIIJIJJJIGIJJJEIHJJIIHHEFFFFFFCCEEEEDCDDDDDDC +@SRR9130495.58 D00236:723:HG32CBCX2:1:1108:16808:1998/1 +ACCAATTTTCCCCTCCCCTTCCTCCCTCCCTCCCAGCCCCCTTCCTCTCTCTACCTCCTGTTATTGTTTTGTTCCTTGTTCTATGTAGGATTGAAGCATCT ++ +@@@FFDDFHDFHGIJJJJIIGGDFHI>DGC;DHI9??FHIJIIHG>>3>;ACCCC9:@>@:>AA +@SRR9130495.59 D00236:723:HG32CBCX2:1:1108:17428:1967/1 +TGCATGGTGCTGAAAGCTTTGTTGCAGCTTTTCTTGGGATTGCTTAGCTGCTCCGGGTCGATCCACTTGCAGATGAGCTCTTGCTTGATGCACTGCTGCCG ++ +?<A3>A>>AAAA?3 +@SRR9130495.60 D00236:723:HG32CBCX2:1:1108:17508:1988/1 +TTGTTCAGAAAAAAGTATCTTGAAACCAAAAGAACTGGGATCTTGTTAAATGCAGATTCTGTTCATTAGGTATAGGTATGCAGTCTTACAAAATGAGGTAG ++ +CCCFFEFFHHHHHJJJJJJJJJJJJJJJJJGIJJJJJJJIIJJJJJJJJIJJIJJJJJJJJJJJIJJIIIEHHBHGHHEFFFFFEEEEDEEDDCDCDDCDC +@SRR9130495.61 D00236:723:HG32CBCX2:1:1108:18425:1951/1 +CCACTTAATAAATCACCTATCAAGTTGAATTATTTGTGCAAAGGCACTAGGCTGAATAGAGACCACTCAGTAGCNTNTTTTTAATCTTGCTAAGAAAGAAT ++ +CCCFFDDFHFHHGJIIJJJJJJHGHEHHHIIJIJJIJGJIHIJHEFDHGHIFIJJGHIJJJFIGGIHIIIJIII#-#-5@DFFEEEDEEEDEDDACDCCBC +@SRR9130495.62 D00236:723:HG32CBCX2:1:1108:18468:1964/1 +CTATTGACTTTTATTAGAAAGGGTCTTGTTGCATAGGTAGGTCTTTAACAACCATCTCTTAAAGGGCTGGGATTGCCAGAGTAGGCCAACACGCCCAGCTA ++ +CCCFFFFFGGHHGIGIJIJJIIIJJJJIJJIJJJJIIJDGEHGIIJJJIJJJHIJJIGFHGIJGEGIJJJIIHHHHHHFFFFFEDEEDDDDDDDBDDBBD@ +@SRR9130495.63 D00236:723:HG32CBCX2:1:1108:18615:1941/1 +NAGCCGAGAGGCGCCGGCTCACCTGCCTGGGTCCCGGCCTTTCTCCTGCAGTGCCAGGGATTCACCTGANGNCNNNNNNTCTNCTAGGCAAGCNNATNCTT ++ +#1:DDFDDHHHHHIIJIIFGJJIEFHHIHHIIIJJIEHFFEEEEEEE?DFF;5:AAB9>29(#+#++8++4>>:@>AA:@1<@@A(:4? +@SRR9130495.72 D00236:723:HG32CBCX2:1:1108:1440:2047/1 +GCTGGTGCAGGACACCAGAATCCGCTCGATCATGCTCCCTAGAGAGGAGGGGCACAGTGAGTACACATAAGCACATGTACACACACACCCAGGACCCAAAG ++ +CCCFFFDEHHGHHHIIIIIIIIJJIJJJGEGHIJIJJJJIIJGHIIJJJIDFEDFFFFEEEEDEDDDDDDDDDDDDDEEEEDDDDDDDDDDDDDDDDDDDA +@SRR9130495.73 D00236:723:HG32CBCX2:1:1108:1468:2080/1 +ACTGTCTTTTTTTTAAAACAGGTGATTGCCCGTTGATTGTTCAGTTTGCTGCTAATGATGCAAGACTTTTATCTGATGCTGCCCTGCTAGTCTGTCCCTAT ++ +CCCFFDDEHFFDHIEIIJHGCGFHCIIHIIIHH@FGGIHIGHIJJIJGIIIJBHIGEIHGHHGGHFFFFFFEEEEDEDDDDDDDDDDDCDDDEDDDDDDDD +@SRR9130495.74 D00236:723:HG32CBCX2:1:1108:1333:2084/1 +ATGAGCACACAAGGGATGATCAGATTGATGGTGTAGAAGAGTGGCTTGCGCTTGATGATGAAGTCATAGGTCACGTCCACATAGCTGGGGTCCTGTGGGTT ++ +CCCFFFFFHHHHHJIJHDIIHHHIIJIIJJJJJIJJIIJIJJJIBDGIJJJJIJJJJGIIIJIAHEEHEFFFFF>EDCDDDDDCDDCDDDDDDDDDCDDDD +@SRR9130495.75 D00236:723:HG32CBCX2:1:1108:1447:2137/1 +TCCACTTGTACAAAAAATTACAAAAATTAGCTGGGCATGGTGGCACACACCTGTAGTCCCAGCTACTCGGGAGGCTGAAGTGGCAGGATCACTTGAGGCAG ++ +CCCFFEFFHFHGHJJJJIJJJJIIDIEHJIIJJJIGJJJHGJIIDHIDGIJIJJIGHIJJJJJHHHFEEBDCDBBDDDDDDDDDDDDDDDDDDDDDCDDD@ +@SRR9130495.76 D00236:723:HG32CBCX2:1:1108:1499:2151/1 +GAGAAAAAGCATCCCTTTAATAAGGCCGCCCCGGTTCCAAATCAATCCTGGCATTGCAGGAGGCAAGGGGGAAACACAGCCACGAAATTGGATTAGCTCTT ++ +CCCFFFFFGGHHHJIIJHIEIJJIIIIJIIGJJIHJIJJIGIJJJIIJJHHHHHFFFFFFDCDBDDDDDDDDDDDCDDDBDBDDBBDDDDDCDDDDCDDCD +@SRR9130495.77 D00236:723:HG32CBCX2:1:1108:1280:2166/1 +GCCTTCTTCCCAGCAGCAATATGGCTCTTTCTTCAGCTCTTATCAGTCACATCCATCAACGAGTGGCTTTTAAAAGGGTATGTTTAAACCTTTTGACGGGA ++ +CCCFFDEFHHHGGJIJJIJIJEIJJJJJIFGIIIIIIIJIIGIJJGIIBHIJJJJIJIEH>CG;CHCHGHICHFFFFFFDDC;@CCEEDDCDDCCDDDDDB +@SRR9130495.78 D00236:723:HG32CBCX2:1:1108:1458:2216/1 +TTTCTTTCCACACATCCCACCTAACACCCAAACTAAGCACTCAGTGCTTGGAATCTCCCCACCCATTCCCTCACCCCTGCTCTTCCATCATTTCCTCCAGC ++ +CCCFFFFFHHHHHIDHIIJJJJHIIJFHIJIJIGIJHGIIIIGJEHIGIIJCGEEHJJJJJJJDHEHHGFFFFFDCDDDDDDDDDDDECCDDEEEDDDDDD +@SRR9130495.79 D00236:723:HG32CBCX2:1:1108:1634:2001/1 +TGTGCATTTCTCATTTTTCACGATTTTCAGTGATTTCGTCATTTTTCAAGTCGTCAAGTGGATGTTTATGATTTTCCATGATTTTCAGTTTTCTTGCCATA ++ +CCCFFFFFHHHHGJJJJJJJJIJHGIJJJJIIIIJJIGIIJJJIJJJIIFIIJJJJJIJJJIJIIIIIIJIJGJJJJFHHGGHGFFFFCEFFDEEDEEDDD +@SRR9130495.80 D00236:723:HG32CBCX2:1:1108:1566:2120/1 +GGACGAAGTAAGGGAGGAGCAACTGACAACATTCATCTTGTCTGTCTCCTCCACGTCCCGAGGTACAAGGCGGATGTCATTCTTACTAATTTTTTTCTTCT ++ +CCCFFFFFHHHHHIIJJJJIJJJIJJJJJJJIFIJJJIJIJIJIIJJIJIJJJJIJJIIJHHFFEEEEEDDDDDDDCDEDEDEEDDDEDDEECDDDDDDDD +@SRR9130495.81 D00236:723:HG32CBCX2:1:1108:1863:2047/1 +AAATTCGGACCCCTTGGGTGGAATATTCCTTACGAATTCAATGAGACAGATCTAAGAATCAGTGTGCAGCAACTCCACATGTTCCTGGACCAGTATGAGGT ++ +@BCFFFFFHHFHHHIJIJGIIIJIJJJJIIJJIIIIJJJJGIJJJIJJIEGIIGIJIJJJEGHHHGEEHFFFFDEEEDDDDEEEDDDDDDDBBCDDCCCCC +@SRR9130495.82 D00236:723:HG32CBCX2:1:1108:1844:2145/1 +TAACTCTCTGCCTGCGATGTCCCTACCTTCCAGAATGGTGCCATGACAACGGTGTCAACTACAAGATCGGAGAGAAGTGGGATCGGCAGGGAGAAAATGGC ++ +@CCFFFFFHHGHHJJJJJJJIJJJJJIJIIIHIIIJIIJJJJIJIIJIJJJJJJJJJIJJIIJEHHGHHFDFDDDDDCDCDDDDDDDDDDD?>BDDDDDDD +@SRR9130495.83 D00236:723:HG32CBCX2:1:1108:1772:2188/1 +GAGGTAGGGGTGTGTGTGAATGGGTGAGTGTGTGCCTATGCTTGTATGCCATATGAGAGAAAATGCAGCATTTAAAATCAGTGGTTAACGGCCAGCACAGT ++ +B@BFDFDDHHDDHHGIGIJIJGIJ:CFHHIGGIJJIEHGIIIJIIIFHGIJBHIJJJJJJCHHIHHHHHGFDFFFFEEEECEEDDDDDDDDDDBDDDDDCA +@SRR9130495.84 D00236:723:HG32CBCX2:1:1108:2103:2085/1 +TACAAATGTGCCAGGCACTCTTCTAAGTCCTCACATGCATGAAGTTATACAACTCTACAACAAACCTAGGAATATAAACTGAGGGCAGGGACCCCCAGCAA ++ +CCCFFFFFHHHHHJIJIJJJJJJJJJJJJIJJJJJJIJJJIJJJFHIJJJJIIJJJJJIJIIHIICHHIJJJIIIJJHHHFHHFDDDDDBDDDDDBDDDDD +@SRR9130495.85 D00236:723:HG32CBCX2:1:1108:2067:2091/1 +ACCAGCCCTGCTGCCACCCAGCCCACGTCCCGCGCGCCACCCATGCTGCTGCCTCGGAGCTGCAGGGAGCCGGGGAGCCAGGGCCACACGCAGGTGCAGCT ++ +?@@D?A:BF8DDFFFFFFFFAECBF@GFECAEFIIIIIIFBE?DBBD;@CCCCBBBBBB@B::AABBBBBB7>BBB>@BB?B>B>BB?/?A?BCCCBDDDD>@ +@SRR9130495.87 D00236:723:HG32CBCX2:1:1108:2387:2038/1 +GGCTAACCACTGCCTTGTCAAGTTGTGTAGAGTGAGATTCAGGGGTGTTGAAGTAATGTCCTTGTTACTTGCTGTAGGGCATCTGTTTTCTGTGTATCCCA ++ +CCCFFDDDDHGHGJEIGHHIJIHGGIIHGIIIIIEGBEHGGHIGGAFHIJJJJJJJJIDGHIIGIJJJIIHGFHEHFDFEDCEECDCDDACCCAACDFCCC +@SRR9130495.88 D00236:723:HG32CBCX2:1:1108:2285:2075/1 +CTGAAAGCTGAGCGTGAGCGTGGTATCACTATTGACATCTCCCTGTGGAAATTCGAGACCAGCAAATACTATGTGACCATCATTGATGCCCCAGGACACAG ++ +?;@DDBDDDFFD>ACGED@D8@):E*::??FFC@;FEF>E;CC=CC=@DDD>?;>A>A>A;AB3;A(;@:??DFBCB4<CCD@=BB@-(4812>>> +@SRR9130495.93 D00236:723:HG32CBCX2:1:1108:2748:2098/1 +CATCATCTTTTTTTTTTTTTTCTCCTGAAAACTGTCTAGTAGTTTGATATATTTTGTCCGAGGTTATTTCAAGTGTTTTTTTTTTTTTTTTTAAAACGGTG ++ +@@@DDDDDHHHHHIIFEHIIH8))7)7CEF9).)7;;>B@>9BD;;(6(55>DDDCBCC@/8-084@CC>C(((+4>?CBBBBBBBBBBB>&23:A(5?(( +@SRR9130495.94 D00236:723:HG32CBCX2:1:1108:2733:2156/1 +GACTGAGAAGAACAGAAAGGGAGAGAGAGGCCAATGGAAATACATGAGAAGGGAGAGAGGGAGAGAGAGGGAGGGAGGGAGGGAAGGAGGGGGAGAGGGAG ++ +CCCFFFEFGHHHHJJGIIIJJHIIHHIIJJJJJIJIIHGJJJGIJJJJJJJJJHGGHHIHHHFDFCDCDDD>BDDBDDDDDDD>BDD?BDDDDBDBDBD@D?ABD@BD?BBDDDC +@SRR9130495.96 D00236:723:HG32CBCX2:1:1108:2818:2076/1 +ACACTTCATGGCAACCTGGCTTAGATTCTTCAAAATTTCTGATCCTATACCAAAGCCTCTGTAATCACTCATCACGAAGAAGTCTTCAAGATACAGTAACT ++ +CCCFFFDDHGHHHJJJJIIJIIHIJHGCHIFEGGJJJJIJIGIIJJJIIJCEHIIIIJIBGHGGIIJIIBFGGGGHHGHFFFFDEEDECEDDDDCD>CCDE +@SRR9130495.97 D00236:723:HG32CBCX2:1:1108:2848:2112/1 +AACCTCTTCTCTTTGTCTTTCTCTTTATCCTTCTCCCTCTTGCCAGGACTGGACTCGCTGGTGATGGTGACGACGCTGGTGGGTAAGGTCTGCGCCCGACT ++ +@@BFFFFEHGHHGIJDEHIJIIIIIIJIFHIIIJEIDHIIIIJJIIIGIEIIJJIIIJFEHFHIIIGIIJIFBEDDBD>=?BB@CACCCAACDDBDBB5;6@;ACBCCCC?@AA>C>?<<<9)?FHFCAG=GFFG>FGGEGHIEEBEDEFC>C@::=BB@BCACCC@CA3:(8@C<8?CC +@SRR9130495.100 D00236:723:HG32CBCX2:1:1108:3014:2117/1 +CCCTCCTGAAAAGGTCCAGCTCCAAAGCCTGACCCGTAGCTGCAGAGAAGAAAGCTTTTCCTCTAAAGGCTGAGGAAAAGATGAAAAATCACTGCTAGAAC ++ +CCCFFFFFHHHHGIJIJJJJJJJJJJJJJJJIJJJIJJIJJJJIJGIDHHIIIJJIJJJJJIJJJHHHHHFFFFDEEEEDDDDDDDDDDDDDDDDDDDDDD +@SRR9130495.101 D00236:723:HG32CBCX2:1:1108:3316:2011/1 +GCAGAGCTGAATGGGCAAGCCCAGGACCCTTTTCAGACATTCTGCTGGCCTTTGGAAAGTGTACTCCTGTTGTATTTGATTACTTTTAGAGGACAGTACAT ++ +CCCFFDDFHHHGHJJJJIJFGIGHJGIJIIIIIHIIGIIJIIIIJJJIIIIJIIIGIJGIJJJJIIJJJEEEE?ECFFFFFFCCEDEEEDDDDDDDDEDCD +@SRR9130495.102 D00236:723:HG32CBCX2:1:1108:3264:2036/1 +GGGTGCTGGAGATAGCCCACGTACACTCCTTCTTGCTGGGGTACTTGTCAGGCCAGTTGGGGCTGGTGATGGTGCCACTGGTGGATGTCACCTTGTGTTCA ++ +=@<=B+AD>BFDFIIDEDGEIGFIIIIIICDFGFFGIII;D?F>?*/9BF>DAF;CFFGI>/:=?>7@BAA:;@5=A5>@=,98?:>@(;:4>ABAB?ABD +@SRR9130495.103 D00236:723:HG32CBCX2:1:1108:3400:2065/1 +TCTGTCTGTCACCAGGTTGGAGTGCAGTGGTAGGATCATGGCTCACTGCAGCCTCGTCCTCTTGGGTTCAAGCAATCCTCCTGCCTCAGCCTCCCAGGTAG ++ +@@BDFFFFHHHGHIJJFHEG@GHHIIAFD@HGGGEHIJJJGIJJGGGIHFDAHHHHJFCGGGHGJI;CHFCEDDFFFCEDEEDDDDDDDD<C +@SRR9130495.104 D00236:723:HG32CBCX2:1:1108:3468:2219/1 +TGCACTTCGTTCTCTTAATGAAACCCTTTGACTTAACCATGACTCCGCTCTGCTCTTGAGTTTGCAAGTGTGTGCGAGTGCCCGAGAGACAGTTTTTTTTT ++ +CCCFFEFFHHHHHJIJIIJJIIJJJIIJJIHIHJJJJJFHFHIIJIJJJJIJIJJJJJGGIIJJJGDIJJJIHHHGFFDDEEEDDDDDDDCCDCEDDDDDD +@SRR9130495.105 D00236:723:HG32CBCX2:1:1108:3722:2006/1 +TCCATAGTTTCGCAGAAGACTTGGAAGGATGTTGATGTATATGCAGGTCCATTATCAGTTTTTAAATTAGATGGTTTTCCCCAAGCTGCCCATGCGTCTAA ++ +CCCFFFDDHHHHHJJIJJIIHGHIGIIDFHHIIIHHIJJIJJIJIJJJJJJIIJJIJG=DHHJJIJIIIJJJJJIGHGHHFFBFDDEEEDDDDDDBBDDDD +@SRR9130495.106 D00236:723:HG32CBCX2:1:1108:3517:2148/1 +CTCTGTTCTGTTCCATTGATCTATATCTCTGTTTTGGTACCAGTACCATGCTGTTTTGGTTACTGTAGCCTTGTAGTATAGTTTGAAGTCAGGTAACGTGA ++ +CCCFFEBFHHHHFGGGIEEHIIJIJJIJJIIJIJJHIIJIIJJIIFHGIIIIJJJJJJFIJIJJJJGIIJIJCHIJIJHGJIJHHHHHHFFFFFFEEDECA +@SRR9130495.107 D00236:723:HG32CBCX2:1:1108:3927:2234/1 +CTGTGCTCTATGTACACGCCCATCTGTTTGCCTGACTACCACAAGCCGCTACCACCGTGCCGTTCCGTGTGCGAGCGCGCCAAGGCCGGCTGCTCGCCGCT ++ +@C@FFFFFHHHHHJJJJGIIJIJJIJEHIIGHGJJIJJJJJJIIGHHIJIJIGHJIIJIHHGFFDEDE?BBDDBDCDDDBDDDDBDD>BDBDDDDBDDDB< +@SRR9130495.108 D00236:723:HG32CBCX2:1:1108:4124:2011/1 +GACTCAGAGCCAGGGCCCGGGAACAGAGATGACTCGAAGGCTAGGGCTCCAGCCAGACTTACCGGCACACGTACACCTCTAGGGGTGGCAGGGTGCTGGGT ++ +CCCFFDDEGGGHHIJIIIJIIIIJIHHJJIJIIJIJIGGIIGIIHIGGIGHBHGHFEFFEECEDDDDDDDDBDDDDDCBACCDDDDDDBDDDDDDDDCD?9 +@SRR9130495.109 D00236:723:HG32CBCX2:1:1108:4130:2090/1 +TTCTATTTCTATAAACTGGCCTATTTTGGGTATTTCATATATATGGAAATATATAATTTGATTTTTTTGTTCTCTTAGCTGTATGTTTTCAGGATTCTTTC ++ +@BBFDFFFHHGHHIJJJJJJJIIIJJJJIJJJIJJJJIJJIIIJJJIJJJJIJIIJJJJJJJJJIHJIJJHHHHHHFFFFFFEEEDECEEDDDDDCDDEDD +@SRR9130495.110 D00236:723:HG32CBCX2:1:1108:4176:2091/1 +AAATTGAAAGTAAATGTATACTGTAGTCCCACGCACGAGTGAATAAAGGGGTGTCTAAAAGGAGTGTGTTCTCTTCCAGGCTGCATCTCTCGGTACTCAGC ++ +;8;ABD?+AA=ADBHIGBHE?ACCCCC +@SRR9130495.111 D00236:723:HG32CBCX2:1:1108:4108:2121/1 +ATGCGGAAGTAGGCAAAAATGATGTGCTAGACTACAAGAATTCCTTTTACAGAAAGTAACAAATACAGAGCCAAGAAAGTTTTTGTTAATTATCACGGTGT ++ +@@@ADADA@AD>FIIBBBFGIBGHJDCIGEGGGHHHIJIIJJJJGHIIEHHEGHJIHGGGIFAGGGGIIG>=CHHFD?@;CCEDDDDCDD>>ACDCB@8<5 +@SRR9130495.112 D00236:723:HG32CBCX2:1:1108:4384:2110/1 +ACACAGGCAGCAATGATGTCTTTACTTCTTTATTTTTTTCGACTTCATCTACAGAGCTTAGCACAGCCATTGGAACAAAATTGGAGCTCAGTGCACAGTTA ++ +@@@FDEFDDFF3CCF?FHCH@DEEGEFHIIFGBGGGDGIHAFBGDDHHIBAGGDGHE@CHAHBFFFFBDD +@SRR9130495.115 D00236:723:HG32CBCX2:1:1108:4445:2247/1 +TCTGTATTCTGTGTCATCTGCCATTCCTTGACTCCCTGCGCCCTTCAGCCCACAGGAAACGTGTGGATGACACACGAGGAGATGGAGTCTCTGACGGCAGC ++ +CCCFFDDDHHHHGJJJJIJJJJBHHJJIIGIIJJJIIGIFIJJIIIIGIJJIIIJIJCHIIJJJIHHFHEFFFFDDDDDBDDCDDCDCDDDDCCCDBBDDB +@SRR9130495.116 D00236:723:HG32CBCX2:1:1108:4698:2005/1 +GAGGGAAGGAGGGAGGGAAAGAAGAAGGGAGAGAGGGAGGAAGGCAGGACTGTCGATGCAAGTACCTCGCTTCCTTGTTCTTAACTCATTTGATTCTTGCT ++ +C@BFFFFFGHHGHIIIJJIBGGDHC@FEGDHIIIHGEHHEGCGIHHHFFFFDEEDDDEDDDDCDCCCDDDDDDDDDDDDDEDCCCDDDCDDDED:CCDDDD +@SRR9130495.117 D00236:723:HG32CBCX2:1:1108:4588:2182/1 +CTGGGGTGCAGTGGTGCAATCATAGCTCACTGCAGCCTCAATTTCCTAGGCTTAAGCATTTCTTCCACCTCAACTTCCCAAGTAGCCAGGATTACAAGCAC ++ +CCCFFADDFFHHGGHHGIIJIJJJJJJHIIJIJJIFIJJEIIJIJIGIJIJJJJJJIJJJIIHIIJHIIFFHGHHFFFFFEDEECCCCBDBDDDDDDCDBC +@SRR9130495.118 D00236:723:HG32CBCX2:1:1108:4964:2029/1 +CCCCGTCTCTACTGAAACACACACACACACACACACACACACACACACACAATTAGCCAGGCGTGGCAGCGTCTGCCTGTAGTCCCAGCTACTCAGGAGGC ++ +;8=:DDDDFFFAFIIFFBEIIEFIFIFIEFFFIIBEGEF?BF<4;A@EE/?;AB>7;7;>@?>B?''5<@;@?;0((4:@>34@@>:4<@>BAB@(948&+ +@SRR9130495.119 D00236:723:HG32CBCX2:1:1108:4831:2078/1 +GCGAAGAAAACTGAAAAAGGTGGAAAATTTAGAAATGTCCACTGTAGGACGTGGAATATGGCAAGAAAACTGAAAATCATGGAAAATGAGAAACATCCACT ++ +CCCFFFFFGFHHFFHGIHDICFHIGGIDHIIJJJJIIIIIGIGHGIJJJJJJJJJJJIJJJIJJIHHHHHFFFFFEEEEEEEDDDDDDDDDDDDDDDDCDD +@SRR9130495.120 D00236:723:HG32CBCX2:1:1108:4877:2117/1 +GCATAATGTTGCCACTGCACTCCAGCTGGGACGACAAAGACTGTCTCTAAAAAAGTAATAAATAAATAAAAGTTTGAAATGCATTGTCCTAGGTTTTAGTC ++ +CCCFFDEFHHHHHIIJJJJJIJIIIGIJJJJJJIIJIJJJIJJJJJJJJJJJJJIIHHGHHHHHFDFFFFFEEEEEEDDDDDCEEDEEDDDDDCDDDDDDD +@SRR9130495.121 D00236:723:HG32CBCX2:1:1108:4918:2158/1 +AAACATGTCAATGGCCAAAAAAAACAGACAATCAAAAAATGGACAAATATATGAACAGACATTTCTCACAAGAGGACATACAAATGGCCAGCAAATATATA ++ +CCCFFFFDHHGHHIIJIJJJIIIJJJJJJJIJJIJJJIIJJJJIJJIJJIHGFHHHHFFFFFEFEEEEEDDDDDDDDCDDDDDDDCCBCDDDDDDDDEEEE +@SRR9130495.122 D00236:723:HG32CBCX2:1:1108:4939:2211/1 +CCTGGTCTCAGCATTCCTCACACGTCATAGCGAGGCCCATGGCTGTAGAAATCCCACCATTCTCTTCTCCCCAGGCCTGGCATCCGTAGAAGCCTACAGCT ++ +@CCFFFFFHHHHDHIDIHIJIJJJJJIGGEGIJIIGIIIJJJGGIJJJJIGGHGIIIJJGHHHHHFFFFEFDEDDDDDDBDDDDDDDDD?CDDDDDDDDAC +@SRR9130495.123 D00236:723:HG32CBCX2:1:1108:5169:2188/1 +TCTGACCCCATGTCCTCAGGCCAGAACCCGGGAGCCTGTCAGAAAAGGTCTCTCACCTAGAGTCCATGCTCTGGAAGCTCCAGGAGGACCTGCAGAGGGTG ++ +??@DD?DFHDFHFIIIIGFHEGGDFFHIBHGIAFIGGIIIFI@CHE@FGH@CDGGIFHEEFCCED@DEEEECCCCCCCCCCCCCCBB8ABC?ACAAABBBB +@SRR9130495.124 D00236:723:HG32CBCX2:1:1108:5192:2231/1 +ACTCTCCTGGCCCACGAGAGAGTCCACACAGGAGAGAAACCTTACCAGTGTCATGAGTGCGGCAAGAACTTTAGTCAGAAATCCTACCTTCAAAGCCATCA ++ +CCCFFFFFHFHHGJJGEFGHGIIEIIFJJJIHGIJIIJIIIJIIGIEHHIGIHIJIIJIIBDFDDDDDDDDDCDDDCCDDDDDDDCDDCDDDDDCDDDDDA +@SRR9130495.125 D00236:723:HG32CBCX2:1:1108:5408:2041/1 +TGTGTGCATCCTCATGTGTCCTTGATAAGTGGTGTGATAAATGAAGGCTTTGCCACATTCCTTACACATGTAGGGCTTCTCTCCAGTGTGAGTCCTCTCAT ++ +@@@DDDEBFHHHHIIIHIFHIDHIIIJHHJIHEGFIIHIJJIIJJEIJGHHIEIEGIIJIJJJGIGHGJJIIGIGIHJEHHHHHFFEFFFCC@CEEDDDDE +@SRR9130495.126 D00236:723:HG32CBCX2:1:1108:5351:2057/1 +CTCTATATATTTTAACAAATGCATAATGTCATGTGTTTACCATTACAGTAGGATAAAGAACAGTCTCATTGCCTTAAAAAGTTCCCTAACATTTTAATTGT ++ +CCCFFDEDFHHHHJIJIIJJJIJJJHJJJJIJIIIHHIJIJIJJJJIIHIJJIIJJJJJIJJJJJJIJIJIJIIJJJJJJJGGIGHHFHFFFFFFFEEEEE +@SRR9130495.127 D00236:723:HG32CBCX2:1:1108:5475:2108/1 +AGCCCAGAAGGCTGGACACACCTCCCCCTCACCCCATCCCGCTCCCCAATCAACCCAGTCCTCAAGAAGCACACTGTGGCTGCTTGCTCTCTTGCCCCCCT ++ +CCCFFDFFHGHGHJJIJJJIGIIIHIGIIJIIJJJIJJJHGIJIJIIIJHHGHHFFEDEEEECCDDDDDDDDDDDDDDDDDDDDDDDDDDCCDCDDDDDDB +@SRR9130495.128 D00236:723:HG32CBCX2:1:1108:5542:2138/1 +TGGCTAGCTACTGCTGCTGCTGCATCAAAGCCCAAATATTCACTGGCATCAGCTGTTTTGTTCTTTAGCATATTAGTAAAGTGCTCATTTAGAGACATCTT ++ +@CCFFFFFHHHHGJIJJIJJJIJJJJJJJJJJJJJJIGGIJJJJJHJJJJJJJJJHIEIIJJJIIJJJIJIIJJJJHHHHHHHF@DFFFFEDEEEEDDCDD +@SRR9130495.129 D00236:723:HG32CBCX2:1:1108:5707:2147/1 +CCAGCATCACTCATGGAACCGGAGGCACTAAGGCCCCTCGGGAGACGCTGAGCAGGTGGGTAGAGGCATACTTCTGGGAGATGGCATCAAGAGCCAGTCAA ++ +CC@FFDDFFDHG>FFFHGGIJIEIIIHIGIGHBHCEHGGGFH@FHGIHHFBFDEEDDEDDDDBDC?BBDCDDDDDC:?A?BDDDCCDC>ACDDDBDDACCC +@SRR9130495.130 D00236:723:HG32CBCX2:1:1108:5614:2168/1 +AAACCATGTCTCTACTAAAACTACAAAAATTAGCTGGGCAACATGGTGGGTGCCTGTATCCCAGCTACCTGGGAGGGTGAGGCACGAGAATCACTTGAACC ++ +CCCFFFFFHHHHHIJJJJIJGJIJJJIJJJJIJJJJJIJJJJIJJHIIHJIJJJJJJJJJJJJJJJJGHFHHF@DDDDDDDDDDDDDDDBDDDDDDDDDDD +@SRR9130495.131 D00236:723:HG32CBCX2:1:1108:5985:2027/1 +GCGGCAGCGGCCGCGATGGAAGAACTTACGGCGTTCGTCTCCAAGTCTTTTGACCAGAAAGTGAAGGAGAAGAAGGAGGCCATCACGTACCGGGAGGTGCT ++ +CCCFFFDDHHDGHFIJFHFFHHBFGHGEIJJJFFDDDDDDDDDDD@CCDCDDDDDAAACACDC@CCDBBBDBD@ +@SRR9130495.132 D00236:723:HG32CBCX2:1:1108:5816:2071/1 +TTTACATATAAGAACCTGATGACCTTTTGTTTTTGTCCAGGAGAGTCCTTCTTGTCTACGAAATGCAGCTATCACAGCAGCTGGACTTGTTTCCTGAATGC ++ +C@CFFDDAFFFHHHHHHGFIHJIJFHHHCAAEHIGHJGCCGHIHEHJJJEHGIIIFIGBBAEHGIJIGIIHHEHHHFFFFEECCABCDCCCCACDDACDA: +@SRR9130495.133 D00236:723:HG32CBCX2:1:1108:5835:2081/1 +CCAGGGCTCCAAGGGGCTGGTTACGAAGTGTCTCCTGCTGCATGAGGTCCCCACGGGAGAGATTGTGGTCCGCCTTGACCTGCAGTTGTTTGATGAGCCGT ++ +@CCDDDFFHHHGHGJGJFHIEHIGCGHIGJGIIIJJJJJJJJJIIIEIJFGIJJIJGCCDDBDDCDDDBDDDDCDDDDDDDD>BACDDDEDDCBD +@SRR9130495.134 D00236:723:HG32CBCX2:1:1108:5841:2101/1 +GGGCATGGTGGCATGCGCCTGTAGTCCCAGCTATTCGGGAAGCTGAGGCAGGAAAATCTCTTGAACCCAGGAGGCGGAGGTTGCAGTGAGCCAAGCTTGCA ++ +@CCF?BDDHFHGHIIIIIIIIIGHGHHIIIFIIIIIGGFGGIIIIEFGGEGHCD>CGGFHHHGGHFFFCDDADDDDDDDBDBCDCCCCA@CCCCBDDDDDD +@SRR9130495.135 D00236:723:HG32CBCX2:1:1108:6165:2044/1 +TTTATACCATTTTTTTTTTTAGCATATATCCTTGTACTTTATAGGAATTATTTGCTTTATTCTCTTGTGACTTGTAAATTGATGTACTTAATTAAATCTTT ++ +@@CBAB;DHFFHHIGIIGGHGFF@?BGB@8=FHEGHIGD=@CGHIA;@EHFHGHBFFFCBD;>(>@A@C>>;>CA;;35>@3;>5>,;3>:;(:@:>:@@C +@SRR9130495.136 D00236:723:HG32CBCX2:1:1108:6059:2069/1 +CTATGACCGCTATGTTGCCATCTGTAGCCCACTGCTTTATAACACTGTAATGTCCCACAAGGTCTGTTCCATAATGATGGCTGTGGTATACTCACTGGGCT ++ +CCBFFDBEHHHHFEGIIGHGIIIJIIHIJIFIJJJJJJJJJJIIJJIJJJJIIHHIJIIIFIHIJFIGIIIHGGHHHHFFFFDEEEEEDEFEDDDCDDDBC +@SRR9130495.137 D00236:723:HG32CBCX2:1:1108:6161:2181/1 +ATGAAGCAACAACCTTATAGGCATTTTAACTCATAGGTTTTAAAACTTAAGGTTATTTTCATAGGAGTCCCTTTTAGCAGAAATGCTCACCACAGGACCAG ++ +@@CGGDD@4???BDHCH@GH<=FHGEGGGIGCEG@E7ACH@:77?C@A@CBAA???2FFFIGIIGIIIIFDADBDDDDDDDBBBBBBCDD@CDDDD?BDDDDDDCDDBDDDBDDDCCCCCBBCCCDCCCCDDAC>ABDDDCDDDDA@C +@SRR9130495.144 D00236:723:HG32CBCX2:1:1108:6837:2146/1 +CCTGTTATTTTAGTTGTTAAAGGTGGCATTCTGTTCTTGTGGCTGTCTTCTTTTAGGTTTGTTGAGGGATTACCTTCTTGTTTTTTCTAGGGCATTGTTCC ++ +BCCFDDFDHFDHFGIIIIJIGIIJJIDGHIJIIJJJJJJGFIIIHFHHIJJJIGDGIGHGHIJICHGGEHGCHGFEHFHHFDDDDDDDDDDDC?CDDDDCC +@SRR9130495.145 D00236:723:HG32CBCX2:1:1108:6804:2189/1 +TGAATCTCTCTTGGCCTCCTCCCCTCTCATGTCCCCTCCTCCCTCCTCTCCACTTACTCCTCCTCCTCCCCTCCCTCCTCCCAGATGGTTCTGTGTCTTTT ++ +CCCFFEFFHHGHHJJJIJJIJJJJIJJJJJIJIFIJIGIIGGJIJJIIIIIGIIJIJIJGIIIJIJJHHHFDFFDCDCCDDDCDBCCDCDDD@ACCCDDDD +@SRR9130495.146 D00236:723:HG32CBCX2:1:1108:6940:2229/1 +CTTAATGCCACTATCACCACTTCCTTCAAGAGTGAGGGAGAGGAAGAGGAGGAAGAGGAGGAGGAAGAAGAGGAGGAGGAGGAAGAGGAGGGTGAAGGGGA ++ +@@@DBDDEFHHHHGIJIEGGIGECHIFIIJGFHHACCF?D:DFF;?FHH9DFCGGHFG@CA?AB?DD>?A@BDDBB=?B5@BBFCAA@A;;5?BB9;=>;BB?1>A?ABDCC +@SRR9130495.149 D00236:723:HG32CBCX2:1:1108:7167:2101/1 +TTTCATGTTTTAGGTCTTGTAAGCAAGATTTTTCCTGTTGAAAAACTGGTTGAAGAAGCCATCCAATGTGCAGAAAAAATTGCCAGCAATTCTAAAATCGT ++ +?@?DB?DDHHGDHIHHGBIECFDHHE>C7?BB7;@A(5==;88323>CDC9B +@SRR9130495.152 D00236:723:HG32CBCX2:1:1108:7449:2110/1 +GGCTTCAGGAGCTTCAGAAGTTAAGAGCTGCAAAAAAGAAGAAAAAGGATCGGCCAAGTAAAGACTGTTCCAAGTTGGACATGCTTGCTAGAAATTTCCAG ++ +CCCFFDFEHGHHGJIIBEEHHIIIHHIGGJIIJIIGIIGGHIIIJIGGGGGGGIIJJHHFHHGFFFFFEEEEEEEDDDDDDDCDDEDDDDDDDDDDDDEDC +@SRR9130495.153 D00236:723:HG32CBCX2:1:1108:7499:2197/1 +TTCTCATAGTTCAGCTTCCACTTGCGGTAGCTTGTTCCACTTGCGGAACATGTGGTGTTTGGTTTTTTGTACCTGCACTAGTTTGCTGAGAAAGATCGGAA ++ +@@@DDDDEHHFFHABECCAFHHHFDGIHJIIEFGHIIGIGEHEBGG0AEDHGFFFGIDG@EH=ADEBADDE@CCCBCACDDDEEDDCCCBCCC@CC>AB@@ +@SRR9130495.154 D00236:723:HG32CBCX2:1:1108:7309:2205/1 +GGAGGCTGAGGCAGGAGAATCGCTTGGACCCGGGAGGTGTAGGTTGCAGTGAGCCAAGATTGCGCCACTGCACTCCAGCCTGGGTGACAAAGTGAGATATT ++ +BC@FFFDFDHHGFIGIIIJIJJJJJIJJJIIJJJIIIHHIJIJJJIJHHHHGHFFFEBAEECEDDB:@CDDDDCDDDDDDDDDBCBDCDCDDDCDBDCC?ACDD34>C@BD<>>:CB<>@BA8 +@SRR9130495.156 D00236:723:HG32CBCX2:1:1108:7518:2119/1 +TTATCAAAGAGGCCCAAGAGAAACCACTTGTCTGACTTCTACCATATGAGTTTAGAATAAGATGATGGCTGCCTATGAGGAAGCAGGCCCTCAACAGATAC ++ +@@@DDBD4CFFAAHII=G9FDHG;?F@;EEBEFCF>BGBGDBECC@BBBBBBBCCABC@CC +@SRR9130495.157 D00236:723:HG32CBCX2:1:1108:7577:2169/1 +AGTTACTTAATATACCTTAGCCGAAACTTCTGCACTGATTTCCTCCTGTGTTTCAGCCAGCCGCTTTTTGGCAAGTTCGGTTCTCCGATCACACTCTGCAA ++ +@@@DDDFFFFHGHIICGHFH@FGGHGHHJGIHJIJIJGIIIBDHCBGGHEHIJJIGIIIBGIEIGGHHCEBDFEDECD?@DDDDDDDDDDBCCDDDDDDC> +@SRR9130495.158 D00236:723:HG32CBCX2:1:1108:7659:2196/1 +TTCTGATTTTTGCTGCAGCTTCTGCTTATAATCATATGGCCAGTTGTGCTTGTCAGAGTAATGGTGAAGTCCACAAAACAAATTTCCACATCGGCAGTCAA ++ +CCCFDDDDHDFHFGIFCHIII9FHHIGGHHIJJJJIJJEHGEGIIJJJJJJJJDHGI:DFGIIGHGJGCGHGIJJGIIHGHGFFECB@CEC@B@BDD?CCD +@SRR9130495.159 D00236:723:HG32CBCX2:1:1108:7733:2213/1 +GGCCAGATGTTTCTGTAAAGATTGAATTAGATCCCCAGGGAGAGGCAGCACAAAGTGCAAATGAATCAAAAACTGAGTAGAATATTGTAGAGTGCCAATTA ++ +@<@DDA+AFFHHHIIFBHC@@F>@>CC: +@SRR9130495.160 D00236:723:HG32CBCX2:1:1108:7590:2217/1 +GGGGCTGGGCCCACCTGGGACAGAGGGCCACATGTAGAGGCAGCGCTCCCCCGTCTTGAGCTGATCTTTGCAGTCGAATAGCATGAGGTTGGCCCAAGCGA ++ +CC@FFDDDGHHDHIJDGIIACBDDBBBDDD@ +@SRR9130495.161 D00236:723:HG32CBCX2:1:1108:7735:2228/1 +GCAGCACTGTCTGAGTATGGGAGCAAAGCCTAATCTGGCTTGCCCGGCCTCTCACCTCTGTGGCGCTCTGCATCATGGTGCTTCTTGTCATCTTTTATTGC ++ +?@;DDDDDFCFFHIHHGBHIBH?FHIBDEHB@GEIHIEHGHAFFHGEEH<@CC@C@CCA +@SRR9130495.162 D00236:723:HG32CBCX2:1:1108:7898:2065/1 +GTTGGCTTCCCCCTCCCCTCTCCCGTGAGCTGAAAAGCAACAAGGGCTCCACCAGCCTGCAAAATAAGACTTGGGGGGGGGGGGGCAGGGATTGCTTTTTT ++ +@@@FDDDDHHFHFIJIFHIIJJJDHFGIGIGJAFHIDG>@GGFHGGHJIGCHIIGEEHFGF@CFEECC>;>CCABBD<99B@BD99&)&&+9(3(4>(+:0 +@SRR9130495.163 D00236:723:HG32CBCX2:1:1108:7872:2066/1 +CACGCTGGATGAGTTCCTGTTCAGCGACCTGCAGGCGCTGGAAGTGCTGTTGCTCTACAATAACCACATTGTGGTGGTGGACCGGAATGCCTTTGAGGACA ++ +CCCFFFFFGHGGHJJJJJJJJJJIJJJJJJHJJJJJIJJIJJJIGIJJIJJJJIHHHHHHFFDFFEDDEEEEDDDDBDDDDDDDDDDDDDDDDDDDDDDDD +@SRR9130495.164 D00236:723:HG32CBCX2:1:1108:7826:2191/1 +ATCTCTGGACCCAAACTGGAGGGTGACATTAAAGTTCCCAGGGTGGATTTGAAGGGCCCAGAAGTGGACATTTCTGCTCCCAAGGTCAATATTGATGGGAA ++ +CCCFFEFFGHHGHIHHIIJIIIJJIJIGIIJIHIGIJJJJIJJBFGGIJJIJJJJJIJIHFHHFFF@EEDEEFEEDDDDDDDDDBACDDF@CDEDEDDBDD +@SRR9130495.165 D00236:723:HG32CBCX2:1:1108:7791:2195/1 +GGAGAACAGCGTGTAGAGCACTCACAGTCTGCTGCCTTCAGGTGTGGGAGGCACTGCTCACACTGATCTTCTTCCCGGTGTGTGTGGTGTTTGCCTGGATG ++ +CCCFFDEFFGHHHJDIIJJIFJJJJJIJJJGIJJIIJIIIJIJIIGEGHHJJJJJIIFIJJJHHHHFHFFDDFFEDC>9;?BBDDD?CDDDDDDDCC?BDC +@SRR9130495.166 D00236:723:HG32CBCX2:1:1108:7767:2199/1 +GACTAGCCTGGCCAACATGGCAAAACCCAGTCTCTATTAAAAATACAAAAATTAGCTGGGCATGGTGGTGCACGCCTGTAGTCCCAGCTATTCAAGAGGCT ++ +@@@DDDFFFHHFBHBHBDEHHGGGHIIJIIHIHJIEEEIGHEIHIIGHIIHHGJIEHGI?G@CDHI=CA?BDFFACDCCDFCC32??A +@SRR9130495.167 D00236:723:HG32CBCX2:1:1108:7824:2210/1 +GCACCACCGTGCCTGGCTAATTTTTATATATTTAGTAGAGATTGGGTTTCACTGTGTTGGCCAGGCTGATCTTGAACTCTGGACCTCAGGTGATCCTCCCG ++ +@@@FFDDFDFAHHJJIJIIGHHHHHIIJIIDGG>GHHIGGCGHGIEHGGH>FFHJJJHDGBGHJCGGGHFEHHHHFFFFFECDECEDDDCDDDDCCDDCDD +@SRR9130495.168 D00236:723:HG32CBCX2:1:1108:8205:2084/1 +CTTAGCCGCTGGTGATGCTAAGGGCATGGTCAAAGTGTGGCAGCTGAGCACAGCCTTCACAGAACAAGGGCCCCGGGAGGTGGAGGACTTGGATCAGCTAG ++ +CCCFFDEDFFHHHJEGIDHHIIIIJJJIJGIJJJGHJIJIJJJIIIJIGGIIGIJJIGHIIJGEFHGBEFDDDBDDD;>B2<@BBDBBCCCCDDDDDDDDD +@SRR9130495.169 D00236:723:HG32CBCX2:1:1108:8202:2124/1 +GAGACTCTTGCACACATACCGGGGAGCTGGCTCACCCTGGCCCCTCCATCCTGTCAGACTGAAGAGAACAAGTGTCTTAATTTGGGTTTTTCTTATTATTA ++ +CCCFFEFDHFHGHGJIIIJJIJJJIIIGIJJJJFIJJHGIJGHIIJJEEEHFGFFEFECCEEEEDDDDCCAD>CCDDDDCCD?@@A=?8=?=BA93>CA??B@A????8CD(8&8?()(+224@?@>35 +@SRR9130495.179 D00236:723:HG32CBCX2:1:1108:8868:2131/1 +GTACATTGTATCTTTGTTCTCATTAGTTTCAGAGAAATTATTGATTTCTGCCTTTATTTCATTATTTACCCAAGAGTGATTTGGAAGCAGGTTGTTCAGTT ++ +<;;B?D>DFC:DBF@AEDHHAHHGH:A:AC4?BFFEDA?ABD@ACCD:> +@SRR9130495.183 D00236:723:HG32CBCX2:1:1108:9106:2031/1 +CTAGAAATCCTGGATTTTCAGCACAATAACTTAGCCAGGCTCTGGAAACGCGCAAACCCCGGTGGTCCCGTTAATTTCCTGAAGGGGCTGTCTCACCTCCA ++ +C@CFFDFFGGHHFJHIIJGIHCCEHHIGIFIIHIJJFIGJIGIJJIIJHIFGIJIJFFHHFDAD@BCCBDDDDBCC@CDDCCDDAEFC'8;&+)+((&28&&&+((&)&&++((++8((2(((25(&&&(++(0&&&(+((+4(+ +@SRR9130495.186 D00236:723:HG32CBCX2:1:1108:9230:2213/1 +ACTTAGTGCAGTACCCACTATTCCCGCTCAGGCTCCGAATAGTAGATAGAGGGTTCCGATATCTTTGTGATTGGTTGAGAATAATCAACGATTAATGAACA ++ +CCCFFFFEHGFFHFIICIIFIJHHGBHHGIGJJIJGGHIGFHIGIIJJJIIGJCFIJI@EFDFEDFFCCEEEEDDDBDDDDDDDECCDD@BDDDCDDDCDC +@SRR9130495.187 D00236:723:HG32CBCX2:1:1108:9264:2024/1 +AACATAAGGTTTCTCATAAAACAAAGAAAAATGTCAATTCAGTTGTGAATTCATATTGATACCTGGAACTCTCCTGCTAGACCACCTCTAAAGGCCCAGGG ++ +CCCFFFFFHHHGHIJJIDJIJJJDHIIJJJJIJJJJJJJIJJGCHIIJJJJJJJJJJIHJJJJJJGIJJIJIJIIIIJJHHHHGFFFFFECEEDDDDBBBB +@SRR9130495.188 D00236:723:HG32CBCX2:1:1108:9293:2034/1 +GTGGGGAGGTTTGGGAGTGAGCAGCACACCCCAGTTAGACTCCTGTTGGGTTTCATAGGAGCTGGCTGCTGAATGTAAGAGTGCAGGCTACCCCGGGACTT ++ +@@@FDA;1DAFHFIIFBGIGHGADHIGIIIIIIIIHBFEHIIIIIIIIHIACEEEHHBD@CDECECCBBCCACCCCEECCCCCCCCBBBCCCB?9>>>>BC +@SRR9130495.189 D00236:723:HG32CBCX2:1:1108:9484:2048/1 +ATGTAGAGAGAGGGAAAAAAGGAGAGAGAGAAGGATAAAGAGAAGGATGCACAAGAAGACCAAAATACCTGATCATGTAGGGGAGAGCCTCTGGGAGAAGG ++ +@@@DFDDDCDDFHICFHHDGIIHHCHCFFDGHHDCGIJIH@FFHFHGIIGIJIGIGF@CEBDFF@EECDCCCCCCDDEEEDDDDDDDDDDCDDCD<@BDCB +@SRR9130495.190 D00236:723:HG32CBCX2:1:1108:9388:2219/1 +AGCTGCTGCGAGATGGTGGCTTGCATCTCCTTGGACGGCCGCTTGTTCTCCTTGAAGATGGCAATCAGCGTGCGGCGCTGCAGGTCTGTGAACACGAGGCG ++ +B?>3=?>;@DF@>CACC>;>@A>',,88>>-09599(+8>C95>>>00 +@SRR9130495.191 D00236:723:HG32CBCX2:1:1108:9404:2245/1 +TCCGGCTGGTACCTTCATAACTACAGTAATAGAAGACATTGAGTGCCTCCACCGCAGCTGGCCCTCTCTGTTTGTAGCCAAAGATCAGATCTATCCATTCA ++ +CCCFFFFFHHHHHJJIJIIJEIIJJJJJIJJJIJJJIJIIIIIJJJIJJIIJJJJEIJJIHIGHHHFFFFFFDEEEEEDDDDDDDDDDDDDEDCDDDCDCC +@SRR9130495.192 D00236:723:HG32CBCX2:1:1108:9632:2134/1 +ATAGTGGCTGCTGATGGATGTGCTCTATGCAAGGGAGGTGCTCACTATTTCTGTTCGTCAATTTGTAACCCACGGGAGGAAAGGGAACAAAGAGTGAACAA ++ +CCCFFFFFHHHGAEFFHIICHGIJHGFIIIHIJDGIJJIIIEGIJJIIFHEGHGIICHIIFIJJJJIIJJHHHFFDBDD?BDDDDBDBDDBCDD:@CCCCD +@SRR9130495.193 D00236:723:HG32CBCX2:1:1108:9647:2175/1 +AATACCAGCCCAAGACTTTGGGAGAAGGGAAGAAAACAAAGTAAAATAACTTACCACTTTGGCCCAGTCCGAGAACAAGTGAAAATACCCAGGCTGCCCCA ++ +CCCFFFDFGHHFHIIJJGIIIJDIIJIJJJJIIHIIIIJJJHCFHHFHIJJJJJJGIHJJJIJJHGHHHFFFDDDDDCD>CCDDDDDDCDDDBDDDDDDDD +@SRR9130495.194 D00236:723:HG32CBCX2:1:1108:9552:2194/1 +CCATGCCGACACAGGTAGATGGTACGGGGCTGCACGTGGATGTTCATCAGGTAGTATACAATTCGGCTCTGGATGTGGTCCTGCACTCTGTTCACCAAGAA ++ +@@CFFFFFGHGHHJJJIJJJJIJJJIGHFEGGIFIJIJIIIIIJJIIJJIHHHHHHHFFFFFFFDCDDDC@@ACDDCDDDDDDDDDDDDCDDD@CCDDDDD +@SRR9130495.195 D00236:723:HG32CBCX2:1:1108:9620:2235/1 +CCAATGATGGCCAACTAGGCCATCTTCTACTATGTACGCAGCTAGAGGCACGAGCGCTGGGGGTACCGATTAGTTCATATTGGTGTTCCACCTATAGGGTT ++ +===BD?DBAABD8AC3?F?D9C6'5;:>7<<>8:(',&22>(((:>3>+:(+28(43>@B(>:>A((32 +@SRR9130495.196 D00236:723:HG32CBCX2:1:1108:9908:2124/1 +TCTTGTGAAGAAGATGCTGTTGGAAGCCTCTAAGAAGCCCGAACTGAATGCTCTTATAAACAATACCAGAGGAATTATTTTTTACAGTGTCCCTCACCATG ++ +CCCFFFFFHGDFGIIJJIJJIGGJJIIJJIIJHIIIIJJJJI>HHIFIJIJIJJIIHIHIJJJJIHIHHHGFDEFFEEEEEEDDDDDFDEDCCDCDDDDDD +@SRR9130495.197 D00236:723:HG32CBCX2:1:1108:9923:2206/1 +TGGGGCTGTGAACCGAAGTCTGCTCCTTTGCGTGAGCCACCCCTGCAGCCCCTCCCACAGTTCCTGAGGAGCCTTTAGTCCTCGTCCTTTCTCAGCTGTAT ++ +@BCFFDAFHHHHHIIIIHIIJIIJIIJJJIIIJJIGGIIIJJFGGGGGEIIIGFHHEFFFEECCCC@CB@BDDDCDDCCDCCDDABBBCDDCC@CCDCCCD +@SRR9130495.198 D00236:723:HG32CBCX2:1:1108:10131:2036/1 +ATGTGCTCAAAGGCTGGGTGGACCTTACCTCCAGTAAACCCCACGTTGTGAAGAAATCCATCAAGTACCTGGAACAAGGAACTCAAGACACCAAAGATGTG ++ +@CCFFFDDFFBHDHIIIBFEGFGHGHGDFHFGIJJIIHDGEGHIJHFHIIIIJJJJJIIIFHHHFHFFFFFFBAEAACBBCADDDDDDDDADBABCCC>AA +@SRR9130495.199 D00236:723:HG32CBCX2:1:1108:10246:2089/1 +GCCCTGGGATTGTCCCTCTGGGCACAGGGAGTCCTGGGGTTGTCCCTCTGAGTAGTTCTGTTGGGAGAGGAGGCCCTGGGATTGTCCCTCTGGGTACAGGG ++ +CCCFFBDDHHHFHJIIIJJJJIIIIIFIIEHGIGJIJDHJIJIIJJFJIJ@FFCHJJJBEGEHHHDFDCD@DBB;=?A?@BDDDCACDDDDD@?CCCCDCB +@SRR9130495.200 D00236:723:HG32CBCX2:1:1108:10051:2156/1 +ATGGAGGATGGCACCCTGCAGGCTGGCCCAGGAGGTGCCAGTGGGCCTCGTGCCCTGGAAATAAATAAAATGATTTCTTTTTGGAGGAATGCTCATAAACG ++ +@@CDFFDFGFHFFIJGGIICCDDADDB diff --git a/docs/notebooks/example.parquet b/docs/notebooks/example.parquet new file mode 100644 index 0000000000000000000000000000000000000000..017772b75ddd5cc787ad49beb2b077e023a560af GIT binary patch literal 20352 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 Nd1+4Hm4k1k?{$61mUoJMOGi;v{oi7S;D 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\n", + "[String, String, String, String]\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200rows [00:00, 67012.37rows/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200rows [00:00, 138084.08rows/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "'{\"base_quality_warn\":\"pass\",\"base_per_pos_data\":[{\"pos\":72,\"average\":66.265,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":70.0,\"median\":68.0},{\"pos\":80,\"average\":65.61,\"upper\":74.0,\"lower\":35.0,\"q1\":65.0,\"q3\":69.0,\"median\":68.0},{\"pos\":81,\"average\":65.76,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":69.0,\"median\":68.0},{\"pos\":83,\"average\":65.03,\"upper\":73.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":85,\"average\":65.195,\"upper\":73.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":19,\"average\":71.425,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":86,\"average\":64.815,\"upper\":73.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":91,\"average\":65.665,\"upper\":73.0,\"lower\":38.0,\"q1\":65.0,\"q3\":68.0,\"median\":68.0},{\"pos\":92,\"average\":64.835,\"upper\":72.0,\"lower\":38.0,\"q1\":65.0,\"q3\":68.0,\"median\":68.0},{\"pos\":94,\"average\":63.775,\"upper\":73.0,\"lower\":35.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":51,\"average\":70.53,\"upper\":74.0,\"lower\":40.0,\"q1\":69.0,\"q3\":74.0,\"median\":72.0},{\"pos\":78,\"average\":64.46,\"upper\":74.0,\"lower\":35.0,\"q1\":64.0,\"q3\":69.0,\"median\":68.0},{\"pos\":61,\"average\":68.99,\"upper\":74.0,\"lower\":40.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":88,\"average\":65.065,\"upper\":72.0,\"lower\":38.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":74,\"average\":63.83,\"upper\":74.0,\"lower\":35.0,\"q1\":65.0,\"q3\":70.0,\"median\":68.0},{\"pos\":1,\"average\":64.21,\"upper\":67.0,\"lower\":43.0,\"q1\":64.0,\"q3\":67.0,\"median\":67.0},{\"pos\":4,\"average\":68.68,\"upper\":70.0,\"lower\":49.0,\"q1\":68.0,\"q3\":70.0,\"median\":70.0},{\"pos\":0,\"average\":63.135,\"upper\":67.0,\"lower\":35.0,\"q1\":64.0,\"q3\":67.0,\"median\":66.0},{\"pos\":68,\"average\":68.91,\"upper\":74.0,\"lower\":40.0,\"q1\":67.0,\"q3\":72.0,\"median\":69.0},{\"pos\":56,\"average\":70.59,\"upper\":74.0,\"lower\":38.0,\"q1\":69.0,\"q3\":73.0,\"median\":72.0},{\"pos\":82,\"average\":64.525,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":97,\"average\":63.67,\"upper\":71.0,\"lower\":35.0,\"q1\":64.0,\"q3\":68.0,\"median\":67.0},{\"pos\":100,\"average\":64.105,\"upper\":70.0,\"lower\":40.0,\"q1\":64.0,\"q3\":68.0,\"median\":67.0},{\"pos\":2,\"average\":65.015,\"upper\":67.0,\"lower\":49.0,\"q1\":64.0,\"q3\":67.0,\"median\":67.0},{\"pos\":33,\"average\":71.245,\"upper\":74.0,\"lower\":40.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":34,\"average\":71.205,\"upper\":74.0,\"lower\":51.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":28,\"average\":71.445,\"upper\":74.0,\"lower\":49.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":65,\"average\":68.995,\"upper\":74.0,\"lower\":38.0,\"q1\":68.0,\"q3\":72.0,\"median\":70.0},{\"pos\":12,\"average\":70.5,\"upper\":72.0,\"lower\":52.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":3,\"average\":68.69,\"upper\":70.0,\"lower\":52.0,\"q1\":68.0,\"q3\":70.0,\"median\":70.0},{\"pos\":9,\"average\":70.36,\"upper\":72.0,\"lower\":52.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":39,\"average\":70.895,\"upper\":74.0,\"lower\":39.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":57,\"average\":70.35,\"upper\":74.0,\"lower\":38.0,\"q1\":69.0,\"q3\":73.0,\"median\":72.0},{\"pos\":70,\"average\":66.565,\"upper\":74.0,\"lower\":40.0,\"q1\":67.0,\"q3\":71.0,\"median\":68.0},{\"pos\":13,\"average\":71.94,\"upper\":74.0,\"lower\":58.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":46,\"average\":70.79,\"upper\":74.0,\"lower\":40.0,\"q1\":70.0,\"q3\":74.0,\"median\":73.0},{\"pos\":76,\"average\":63.265,\"upper\":74.0,\"lower\":35.0,\"q1\":64.0,\"q3\":70.0,\"median\":68.0},{\"pos\":44,\"average\":70.565,\"upper\":74.0,\"lower\":39.0,\"q1\":70.0,\"q3\":74.0,\"median\":73.0},{\"pos\":71,\"average\":66.005,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":71.0,\"median\":68.0},{\"pos\":54,\"average\":70.59,\"upper\":74.0,\"lower\":38.0,\"q1\":69.0,\"q3\":74.0,\"median\":73.0},{\"pos\":67,\"average\":68.96,\"upper\":74.0,\"lower\":39.0,\"q1\":67.0,\"q3\":72.0,\"median\":70.0},{\"pos\":79,\"average\":65.46,\"upper\":74.0,\"lower\":40.0,\"q1\":65.0,\"q3\":69.0,\"median\":68.0},{\"pos\":90,\"average\":65.275,\"upper\":72.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":42,\"average\":70.78,\"upper\":74.0,\"lower\":39.0,\"q1\":70.0,\"q3\":73.0,\"median\":73.0},{\"pos\":14,\"average\":71.965,\"upper\":74.0,\"lower\":60.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":10,\"average\":70.675,\"upper\":72.0,\"lower\":52.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":48,\"average\":70.61,\"upper\":74.0,\"lower\":40.0,\"q1\":69.0,\"q3\":74.0,\"median\":73.0},{\"pos\":18,\"average\":71.47,\"upper\":74.0,\"lower\":49.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":8,\"average\":70.625,\"upper\":72.0,\"lower\":60.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":50,\"average\":70.425,\"upper\":74.0,\"lower\":43.0,\"q1\":69.0,\"q3\":74.0,\"median\":72.0},{\"pos\":22,\"average\":71.41,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":60,\"average\":68.985,\"upper\":74.0,\"lower\":40.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":6,\"average\":68.145,\"upper\":70.0,\"lower\":43.0,\"q1\":68.0,\"q3\":70.0,\"median\":68.0},{\"pos\":49,\"average\":70.21,\"upper\":74.0,\"lower\":41.0,\"q1\":69.0,\"q3\":73.0,\"median\":72.0},{\"pos\":73,\"average\":65.68,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":70.0,\"median\":68.0},{\"pos\":75,\"average\":64.06,\"upper\":74.0,\"lower\":35.0,\"q1\":64.0,\"q3\":70.0,\"median\":68.0},{\"pos\":23,\"average\":71.635,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":26,\"average\":70.855,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":45,\"average\":70.45,\"upper\":74.0,\"lower\":41.0,\"q1\":69.0,\"q3\":74.0,\"median\":73.0},{\"pos\":62,\"average\":69.145,\"upper\":74.0,\"lower\":38.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":55,\"average\":70.55,\"upper\":74.0,\"lower\":39.0,\"q1\":69.0,\"q3\":73.0,\"median\":72.0},{\"pos\":84,\"average\":65.415,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":15,\"average\":71.725,\"upper\":74.0,\"lower\":51.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":87,\"average\":64.915,\"upper\":73.0,\"lower\":35.0,\"q1\":65.0,\"q3\":68.0,\"median\":68.0},{\"pos\":59,\"average\":69.08,\"upper\":74.0,\"lower\":35.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":66,\"average\":68.875,\"upper\":74.0,\"lower\":39.0,\"q1\":68.0,\"q3\":72.0,\"median\":70.0},{\"pos\":96,\"average\":64.315,\"upper\":71.0,\"lower\":35.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":53,\"average\":70.845,\"upper\":74.0,\"lower\":38.0,\"q1\":70.0,\"q3\":73.0,\"median\":72.0},{\"pos\":64,\"average\":69.095,\"upper\":74.0,\"lower\":38.0,\"q1\":68.0,\"q3\":73.0,\"median\":70.0},{\"pos\":17,\"average\":71.505,\"upper\":74.0,\"lower\":60.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":32,\"average\":71.29,\"upper\":74.0,\"lower\":42.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":29,\"average\":71.595,\"upper\":74.0,\"lower\":56.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":25,\"average\":71.2,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":58,\"average\":69.77,\"upper\":74.0,\"lower\":38.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":7,\"average\":68.4,\"upper\":70.0,\"lower\":43.0,\"q1\":68.0,\"q3\":70.0,\"median\":69.0},{\"pos\":47,\"average\":70.665,\"upper\":74.0,\"lower\":38.0,\"q1\":70.0,\"q3\":74.0,\"median\":72.0},{\"pos\":16,\"average\":71.48,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":99,\"average\":64.25,\"upper\":71.0,\"lower\":38.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":40,\"average\":70.95,\"upper\":74.0,\"lower\":47.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":21,\"average\":71.445,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":37,\"average\":71.0,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":95,\"average\":64.425,\"upper\":70.0,\"lower\":40.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":98,\"average\":64.55,\"upper\":73.0,\"lower\":40.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":35,\"average\":71.385,\"upper\":74.0,\"lower\":50.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":69,\"average\":66.7,\"upper\":74.0,\"lower\":35.0,\"q1\":67.0,\"q3\":72.0,\"median\":69.0},{\"pos\":89,\"average\":65.44,\"upper\":72.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":20,\"average\":71.625,\"upper\":74.0,\"lower\":56.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":36,\"average\":71.11,\"upper\":74.0,\"lower\":40.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":38,\"average\":70.64,\"upper\":74.0,\"lower\":39.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":93,\"average\":64.05,\"upper\":72.0,\"lower\":35.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":63,\"average\":69.25,\"upper\":74.0,\"lower\":40.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":41,\"average\":70.87,\"upper\":74.0,\"lower\":41.0,\"q1\":70.0,\"q3\":74.0,\"median\":73.0},{\"pos\":30,\"average\":71.245,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":43,\"average\":70.775,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":5,\"average\":68.095,\"upper\":70.0,\"lower\":43.0,\"q1\":68.0,\"q3\":70.0,\"median\":68.0},{\"pos\":77,\"average\":63.805,\"upper\":74.0,\"lower\":35.0,\"q1\":63.0,\"q3\":69.0,\"median\":68.0},{\"pos\":24,\"average\":71.265,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":31,\"average\":71.795,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":11,\"average\":70.71,\"upper\":72.0,\"lower\":51.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":27,\"average\":71.44,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":52,\"average\":70.77,\"upper\":74.0,\"lower\":40.0,\"q1\":70.0,\"q3\":73.0,\"median\":72.0}]}'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" } ], - "execution_count": 1 + "source": [ + "import polars_bio as pb\n", + "import pandas as pd\n", + "\n", + "a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", + "a_dataframe = a_lazyframe.collect()\n", + "print(type(a_lazyframe))\n", + "# display types of columns\n", + "print(a_lazyframe.dtypes)\n", + "print(type(a_dataframe))\n", + "a_pandas_dataframe = a_lazyframe.collect().to_pandas()\n", + "print(type(a_pandas_dataframe))\n", + "pb.base_sequence_quality(a_lazyframe)\n", + "pb.base_sequence_quality(a_dataframe)\n", + "pb.base_sequence_quality(a_pandas_dataframe)\n", + "pb.base_sequence_quality(\"./example.csv\")\n", + "pb.base_sequence_quality(\"./example.parquet\")\n" + ] }, { "cell_type": "markdown", "id": "d2bb8c193890f27f", "metadata": {}, - "source": "### Sample data" + "source": [ + "### Sample data" + ] }, { "cell_type": "code", + "execution_count": null, "id": "86fe039c3780140e", "metadata": { "ExecuteTime": { @@ -46,27 +107,44 @@ "start_time": "2025-02-24T16:59:37.452650Z" } }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "argument 'df_path_or_table': 'DataFrame' object cannot be converted to 'PyString'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 6\u001b[39m\n\u001b[32m 1\u001b[39m df1 = pd.DataFrame(\n\u001b[32m 2\u001b[39m [[\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m1\u001b[39m, \u001b[32m5\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m3\u001b[39m, \u001b[32m8\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m8\u001b[39m, \u001b[32m10\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m12\u001b[39m, \u001b[32m14\u001b[39m]],\n\u001b[32m 3\u001b[39m columns=[\u001b[33m\"\u001b[39m\u001b[33mchrom\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mstart\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mend\u001b[39m\u001b[33m\"\u001b[39m],\n\u001b[32m 4\u001b[39m )\n\u001b[32m----> \u001b[39m\u001b[32m6\u001b[39m \u001b[43mpb\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbase_sequance_quality\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdf1\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 8\u001b[39m df2 = pd.DataFrame(\n\u001b[32m 9\u001b[39m [[\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m4\u001b[39m, \u001b[32m8\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m10\u001b[39m, \u001b[32m11\u001b[39m]], columns=[\u001b[33m\"\u001b[39m\u001b[33mchrom\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mstart\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mend\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 10\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.pyenv/versions/3.12.9/lib/python3.12/site-packages/polars_bio/quality_stats.py:9\u001b[39m, in \u001b[36mbase_sequance_quality\u001b[39m\u001b[34m(df)\u001b[39m\n\u001b[32m 8\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mbase_sequance_quality\u001b[39m(df: Union[\u001b[38;5;28mstr\u001b[39m, pl.DataFrame, pl.LazyFrame, pd.DataFrame]):\n\u001b[32m----> \u001b[39m\u001b[32m9\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mpy_base_sequence_quality\u001b[49m\u001b[43m(\u001b[49m\u001b[43mctx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdf\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[31mTypeError\u001b[39m: argument 'df_path_or_table': 'DataFrame' object cannot be converted to 'PyString'" + ] + } + ], "source": [ "df1 = pd.DataFrame(\n", " [[\"chr1\", 1, 5], [\"chr1\", 3, 8], [\"chr1\", 8, 10], [\"chr1\", 12, 14]],\n", " columns=[\"chrom\", \"start\", \"end\"],\n", ")\n", "\n", + "pb.base_sequence_quality(df1)\n", + "\n", "df2 = pd.DataFrame(\n", " [[\"chr1\", 4, 8], [\"chr1\", 10, 11]], columns=[\"chrom\", \"start\", \"end\"]\n", ")" - ], - "outputs": [], - "execution_count": 2 + ] }, { "cell_type": "markdown", "id": "a884cd2960796fdb", "metadata": {}, - "source": "### Overlap" + "source": [ + "### Overlap" + ] }, { "cell_type": "code", + "execution_count": 3, "id": "304f3aa6fcdc9650", "metadata": { "ExecuteTime": { @@ -74,9 +152,6 @@ "start_time": "2025-02-24T16:59:37.538707Z" } }, - "source": [ - "overlapping_intervals = pb.overlap(df1, df2, output_type=\"pandas.DataFrame\")" - ], "outputs": [ { "name": "stderr", @@ -86,10 +161,13 @@ ] } ], - "execution_count": 3 + "source": [ + "overlapping_intervals = pb.overlap(df1, df2, output_type=\"pandas.DataFrame\")" + ] }, { "cell_type": "code", + "execution_count": 4, "id": "61c9254622598622", "metadata": { "ExecuteTime": { @@ -97,17 +175,9 @@ "start_time": "2025-02-24T16:59:37.552440Z" } }, - "source": [ - "display(overlapping_intervals)" - ], "outputs": [ { "data": { - "text/plain": [ - " chrom_1 start_1 end_1 chrom_2 start_2 end_2\n", - "0 chr1 1 5 chr1 4 8\n", - "1 chr1 3 8 chr1 4 8" - ], "text/html": [ "
\n", " + + + + + + + + + + + + +
+ +
+
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ average GC content + + 46.15999984741211 +
+ average read length + + 101 +
+ canonical + + True +
+ file name + + example.fastq +
+ k + + 5 +
+ total reads + + 200 +
+
+
+ + \ No newline at end of file diff --git a/docs/notebooks/tutorial.ipynb b/docs/notebooks/tutorial.ipynb index 42771c6a..5b98a620 100644 --- a/docs/notebooks/tutorial.ipynb +++ b/docs/notebooks/tutorial.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "7b173024d3e8f76", "metadata": { "ExecuteTime": { @@ -18,75 +18,36 @@ "start_time": "2025-02-24T16:59:36.960817Z" } }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:polars_bio:Table: example registered for path: ./example.fastq\n", - "200rows [00:00, 46795.76rows/s]\n", - "/tmp/ipykernel_220539/1600797315.py:8: PerformanceWarning: Determining the data types of a LazyFrame requires resolving its schema, which is a potentially expensive operation. Use `LazyFrame.collect_schema().dtypes()` to get the data types without this warning.\n", - " print(a_lazyframe.dtypes)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "[String, String, String, String]\n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "200rows [00:00, 67012.37rows/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "200rows [00:00, 138084.08rows/s]\n" - ] - }, - { - "data": { - "text/plain": [ - "'{\"base_quality_warn\":\"pass\",\"base_per_pos_data\":[{\"pos\":72,\"average\":66.265,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":70.0,\"median\":68.0},{\"pos\":80,\"average\":65.61,\"upper\":74.0,\"lower\":35.0,\"q1\":65.0,\"q3\":69.0,\"median\":68.0},{\"pos\":81,\"average\":65.76,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":69.0,\"median\":68.0},{\"pos\":83,\"average\":65.03,\"upper\":73.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":85,\"average\":65.195,\"upper\":73.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":19,\"average\":71.425,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":86,\"average\":64.815,\"upper\":73.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":91,\"average\":65.665,\"upper\":73.0,\"lower\":38.0,\"q1\":65.0,\"q3\":68.0,\"median\":68.0},{\"pos\":92,\"average\":64.835,\"upper\":72.0,\"lower\":38.0,\"q1\":65.0,\"q3\":68.0,\"median\":68.0},{\"pos\":94,\"average\":63.775,\"upper\":73.0,\"lower\":35.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":51,\"average\":70.53,\"upper\":74.0,\"lower\":40.0,\"q1\":69.0,\"q3\":74.0,\"median\":72.0},{\"pos\":78,\"average\":64.46,\"upper\":74.0,\"lower\":35.0,\"q1\":64.0,\"q3\":69.0,\"median\":68.0},{\"pos\":61,\"average\":68.99,\"upper\":74.0,\"lower\":40.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":88,\"average\":65.065,\"upper\":72.0,\"lower\":38.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":74,\"average\":63.83,\"upper\":74.0,\"lower\":35.0,\"q1\":65.0,\"q3\":70.0,\"median\":68.0},{\"pos\":1,\"average\":64.21,\"upper\":67.0,\"lower\":43.0,\"q1\":64.0,\"q3\":67.0,\"median\":67.0},{\"pos\":4,\"average\":68.68,\"upper\":70.0,\"lower\":49.0,\"q1\":68.0,\"q3\":70.0,\"median\":70.0},{\"pos\":0,\"average\":63.135,\"upper\":67.0,\"lower\":35.0,\"q1\":64.0,\"q3\":67.0,\"median\":66.0},{\"pos\":68,\"average\":68.91,\"upper\":74.0,\"lower\":40.0,\"q1\":67.0,\"q3\":72.0,\"median\":69.0},{\"pos\":56,\"average\":70.59,\"upper\":74.0,\"lower\":38.0,\"q1\":69.0,\"q3\":73.0,\"median\":72.0},{\"pos\":82,\"average\":64.525,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":97,\"average\":63.67,\"upper\":71.0,\"lower\":35.0,\"q1\":64.0,\"q3\":68.0,\"median\":67.0},{\"pos\":100,\"average\":64.105,\"upper\":70.0,\"lower\":40.0,\"q1\":64.0,\"q3\":68.0,\"median\":67.0},{\"pos\":2,\"average\":65.015,\"upper\":67.0,\"lower\":49.0,\"q1\":64.0,\"q3\":67.0,\"median\":67.0},{\"pos\":33,\"average\":71.245,\"upper\":74.0,\"lower\":40.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":34,\"average\":71.205,\"upper\":74.0,\"lower\":51.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":28,\"average\":71.445,\"upper\":74.0,\"lower\":49.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":65,\"average\":68.995,\"upper\":74.0,\"lower\":38.0,\"q1\":68.0,\"q3\":72.0,\"median\":70.0},{\"pos\":12,\"average\":70.5,\"upper\":72.0,\"lower\":52.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":3,\"average\":68.69,\"upper\":70.0,\"lower\":52.0,\"q1\":68.0,\"q3\":70.0,\"median\":70.0},{\"pos\":9,\"average\":70.36,\"upper\":72.0,\"lower\":52.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":39,\"average\":70.895,\"upper\":74.0,\"lower\":39.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":57,\"average\":70.35,\"upper\":74.0,\"lower\":38.0,\"q1\":69.0,\"q3\":73.0,\"median\":72.0},{\"pos\":70,\"average\":66.565,\"upper\":74.0,\"lower\":40.0,\"q1\":67.0,\"q3\":71.0,\"median\":68.0},{\"pos\":13,\"average\":71.94,\"upper\":74.0,\"lower\":58.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":46,\"average\":70.79,\"upper\":74.0,\"lower\":40.0,\"q1\":70.0,\"q3\":74.0,\"median\":73.0},{\"pos\":76,\"average\":63.265,\"upper\":74.0,\"lower\":35.0,\"q1\":64.0,\"q3\":70.0,\"median\":68.0},{\"pos\":44,\"average\":70.565,\"upper\":74.0,\"lower\":39.0,\"q1\":70.0,\"q3\":74.0,\"median\":73.0},{\"pos\":71,\"average\":66.005,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":71.0,\"median\":68.0},{\"pos\":54,\"average\":70.59,\"upper\":74.0,\"lower\":38.0,\"q1\":69.0,\"q3\":74.0,\"median\":73.0},{\"pos\":67,\"average\":68.96,\"upper\":74.0,\"lower\":39.0,\"q1\":67.0,\"q3\":72.0,\"median\":70.0},{\"pos\":79,\"average\":65.46,\"upper\":74.0,\"lower\":40.0,\"q1\":65.0,\"q3\":69.0,\"median\":68.0},{\"pos\":90,\"average\":65.275,\"upper\":72.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":42,\"average\":70.78,\"upper\":74.0,\"lower\":39.0,\"q1\":70.0,\"q3\":73.0,\"median\":73.0},{\"pos\":14,\"average\":71.965,\"upper\":74.0,\"lower\":60.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":10,\"average\":70.675,\"upper\":72.0,\"lower\":52.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":48,\"average\":70.61,\"upper\":74.0,\"lower\":40.0,\"q1\":69.0,\"q3\":74.0,\"median\":73.0},{\"pos\":18,\"average\":71.47,\"upper\":74.0,\"lower\":49.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":8,\"average\":70.625,\"upper\":72.0,\"lower\":60.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":50,\"average\":70.425,\"upper\":74.0,\"lower\":43.0,\"q1\":69.0,\"q3\":74.0,\"median\":72.0},{\"pos\":22,\"average\":71.41,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":60,\"average\":68.985,\"upper\":74.0,\"lower\":40.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":6,\"average\":68.145,\"upper\":70.0,\"lower\":43.0,\"q1\":68.0,\"q3\":70.0,\"median\":68.0},{\"pos\":49,\"average\":70.21,\"upper\":74.0,\"lower\":41.0,\"q1\":69.0,\"q3\":73.0,\"median\":72.0},{\"pos\":73,\"average\":65.68,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":70.0,\"median\":68.0},{\"pos\":75,\"average\":64.06,\"upper\":74.0,\"lower\":35.0,\"q1\":64.0,\"q3\":70.0,\"median\":68.0},{\"pos\":23,\"average\":71.635,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":26,\"average\":70.855,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":45,\"average\":70.45,\"upper\":74.0,\"lower\":41.0,\"q1\":69.0,\"q3\":74.0,\"median\":73.0},{\"pos\":62,\"average\":69.145,\"upper\":74.0,\"lower\":38.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":55,\"average\":70.55,\"upper\":74.0,\"lower\":39.0,\"q1\":69.0,\"q3\":73.0,\"median\":72.0},{\"pos\":84,\"average\":65.415,\"upper\":74.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":15,\"average\":71.725,\"upper\":74.0,\"lower\":51.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":87,\"average\":64.915,\"upper\":73.0,\"lower\":35.0,\"q1\":65.0,\"q3\":68.0,\"median\":68.0},{\"pos\":59,\"average\":69.08,\"upper\":74.0,\"lower\":35.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":66,\"average\":68.875,\"upper\":74.0,\"lower\":39.0,\"q1\":68.0,\"q3\":72.0,\"median\":70.0},{\"pos\":96,\"average\":64.315,\"upper\":71.0,\"lower\":35.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":53,\"average\":70.845,\"upper\":74.0,\"lower\":38.0,\"q1\":70.0,\"q3\":73.0,\"median\":72.0},{\"pos\":64,\"average\":69.095,\"upper\":74.0,\"lower\":38.0,\"q1\":68.0,\"q3\":73.0,\"median\":70.0},{\"pos\":17,\"average\":71.505,\"upper\":74.0,\"lower\":60.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":32,\"average\":71.29,\"upper\":74.0,\"lower\":42.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":29,\"average\":71.595,\"upper\":74.0,\"lower\":56.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":25,\"average\":71.2,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":58,\"average\":69.77,\"upper\":74.0,\"lower\":38.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":7,\"average\":68.4,\"upper\":70.0,\"lower\":43.0,\"q1\":68.0,\"q3\":70.0,\"median\":69.0},{\"pos\":47,\"average\":70.665,\"upper\":74.0,\"lower\":38.0,\"q1\":70.0,\"q3\":74.0,\"median\":72.0},{\"pos\":16,\"average\":71.48,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":99,\"average\":64.25,\"upper\":71.0,\"lower\":38.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":40,\"average\":70.95,\"upper\":74.0,\"lower\":47.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":21,\"average\":71.445,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":37,\"average\":71.0,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":95,\"average\":64.425,\"upper\":70.0,\"lower\":40.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":98,\"average\":64.55,\"upper\":73.0,\"lower\":40.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":35,\"average\":71.385,\"upper\":74.0,\"lower\":50.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":69,\"average\":66.7,\"upper\":74.0,\"lower\":35.0,\"q1\":67.0,\"q3\":72.0,\"median\":69.0},{\"pos\":89,\"average\":65.44,\"upper\":72.0,\"lower\":35.0,\"q1\":66.0,\"q3\":68.0,\"median\":68.0},{\"pos\":20,\"average\":71.625,\"upper\":74.0,\"lower\":56.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":36,\"average\":71.11,\"upper\":74.0,\"lower\":40.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":38,\"average\":70.64,\"upper\":74.0,\"lower\":39.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":93,\"average\":64.05,\"upper\":72.0,\"lower\":35.0,\"q1\":65.0,\"q3\":68.0,\"median\":67.0},{\"pos\":63,\"average\":69.25,\"upper\":74.0,\"lower\":40.0,\"q1\":68.0,\"q3\":73.0,\"median\":71.0},{\"pos\":41,\"average\":70.87,\"upper\":74.0,\"lower\":41.0,\"q1\":70.0,\"q3\":74.0,\"median\":73.0},{\"pos\":30,\"average\":71.245,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":43,\"average\":70.775,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":73.0,\"median\":73.0},{\"pos\":5,\"average\":68.095,\"upper\":70.0,\"lower\":43.0,\"q1\":68.0,\"q3\":70.0,\"median\":68.0},{\"pos\":77,\"average\":63.805,\"upper\":74.0,\"lower\":35.0,\"q1\":63.0,\"q3\":69.0,\"median\":68.0},{\"pos\":24,\"average\":71.265,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":31,\"average\":71.795,\"upper\":74.0,\"lower\":41.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":11,\"average\":70.71,\"upper\":72.0,\"lower\":51.0,\"q1\":70.0,\"q3\":72.0,\"median\":72.0},{\"pos\":27,\"average\":71.44,\"upper\":74.0,\"lower\":43.0,\"q1\":71.0,\"q3\":74.0,\"median\":73.0},{\"pos\":52,\"average\":70.77,\"upper\":74.0,\"lower\":40.0,\"q1\":70.0,\"q3\":73.0,\"median\":72.0}]}'" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "import polars_bio as pb\n", "import pandas as pd\n", "\n", - "a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", - "a_dataframe = a_lazyframe.collect()\n", - "print(type(a_lazyframe))\n", - "# display types of columns\n", - "print(a_lazyframe.dtypes)\n", - "print(type(a_dataframe))\n", - "a_pandas_dataframe = a_lazyframe.collect().to_pandas()\n", - "print(type(a_pandas_dataframe))\n", - "pb.base_sequence_quality(a_lazyframe)\n", - "pb.base_sequence_quality(a_dataframe)\n", - "pb.base_sequence_quality(a_pandas_dataframe)\n", - "pb.base_sequence_quality(\"./example.csv\")\n", - "pb.base_sequence_quality(\"./example.parquet\")\n" + "# print(type(a_lazyframe))\n", + "# # display types of columns\n", + "# print(a_lazyframe.dtypes)\n", + "# print(type(a_dataframe))\n", + "# print(type(a_pandas_dataframe))\n", + "# print(pb.sql(\"SHOW TABLES\").collect())\n", + "print(pb.sql(\"SHOW TABLES\").collect())\n", + "\n", + "# a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", + "# a_dataframe = a_lazyframe.collect()\n", + "# a_pandas_dataframe = a_lazyframe.collect().to_pandas()\n", + "# print(pb.base_sequence_quality(a_lazyframe))\n", + "# print(pb.base_sequence_quality(a_dataframe))\n", + "# print(pb.base_sequence_quality(a_pandas_dataframe))\n", + "\n", + "# result = pb.sql(\"SELECT base_sequence_quality(quality_scores) FROM example\").collect()\n", + "# print(result.item())\n", + "# print(pb.base_sequence_quality(\"./example.csv\"))\n", + "print(pb.base_sequence_quality(\"./example.fastq\"))\n", + "# print(pb.base_sequence_quality(\"./example.parquet\"))\n", + "\n", + "# sql display all tables and print it\n", + "print(pb.sql(\"SHOW TABLES\").collect())\n", + "# use sql and display result (it is aggregate function that returns string)\n", + "# print(result.item())\n" ] }, { @@ -107,20 +68,7 @@ "start_time": "2025-02-24T16:59:37.452650Z" } }, - "outputs": [ - { - "ename": "TypeError", - "evalue": "argument 'df_path_or_table': 'DataFrame' object cannot be converted to 'PyString'", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 6\u001b[39m\n\u001b[32m 1\u001b[39m df1 = pd.DataFrame(\n\u001b[32m 2\u001b[39m [[\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m1\u001b[39m, \u001b[32m5\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m3\u001b[39m, \u001b[32m8\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m8\u001b[39m, \u001b[32m10\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m12\u001b[39m, \u001b[32m14\u001b[39m]],\n\u001b[32m 3\u001b[39m columns=[\u001b[33m\"\u001b[39m\u001b[33mchrom\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mstart\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mend\u001b[39m\u001b[33m\"\u001b[39m],\n\u001b[32m 4\u001b[39m )\n\u001b[32m----> \u001b[39m\u001b[32m6\u001b[39m \u001b[43mpb\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbase_sequance_quality\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdf1\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 8\u001b[39m df2 = pd.DataFrame(\n\u001b[32m 9\u001b[39m [[\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m4\u001b[39m, \u001b[32m8\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mchr1\u001b[39m\u001b[33m\"\u001b[39m, \u001b[32m10\u001b[39m, \u001b[32m11\u001b[39m]], columns=[\u001b[33m\"\u001b[39m\u001b[33mchrom\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mstart\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mend\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 10\u001b[39m )\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.pyenv/versions/3.12.9/lib/python3.12/site-packages/polars_bio/quality_stats.py:9\u001b[39m, in \u001b[36mbase_sequance_quality\u001b[39m\u001b[34m(df)\u001b[39m\n\u001b[32m 8\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mbase_sequance_quality\u001b[39m(df: Union[\u001b[38;5;28mstr\u001b[39m, pl.DataFrame, pl.LazyFrame, pd.DataFrame]):\n\u001b[32m----> \u001b[39m\u001b[32m9\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mpy_base_sequence_quality\u001b[49m\u001b[43m(\u001b[49m\u001b[43mctx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdf\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[31mTypeError\u001b[39m: argument 'df_path_or_table': 'DataFrame' object cannot be converted to 'PyString'" - ] - } - ], + "outputs": [], "source": [ "df1 = pd.DataFrame(\n", " [[\"chr1\", 1, 5], [\"chr1\", 3, 8], [\"chr1\", 8, 10], [\"chr1\", 12, 14]],\n", @@ -144,7 +92,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "304f3aa6fcdc9650", "metadata": { "ExecuteTime": { @@ -152,22 +100,14 @@ "start_time": "2025-02-24T16:59:37.538707Z" } }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:polars_bio.operation:Running Overlap operation with algorithm Coitrees and 1 thread(s)...\n" - ] - } - ], + "outputs": [], "source": [ "overlapping_intervals = pb.overlap(df1, df2, output_type=\"pandas.DataFrame\")" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "61c9254622598622", "metadata": { "ExecuteTime": { @@ -175,76 +115,14 @@ "start_time": "2025-02-24T16:59:37.552440Z" } }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
chrom_1start_1end_1chrom_2start_2end_2
0chr115chr148
1chr138chr148
\n", - "
" - ], - "text/plain": [ - " chrom_1 start_1 end_1 chrom_2 start_2 end_2\n", - "0 chr1 1 5 chr1 4 8\n", - "1 chr1 3 8 chr1 4 8" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "display(overlapping_intervals)" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "e640901ec6e6ce11", "metadata": { "ExecuteTime": { @@ -252,28 +130,7 @@ "start_time": "2025-02-24T16:59:37.581481Z" } }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAZEUlEQVR4nO3dB5QdVf0H8BtIQgshBCQQJPTeiyBFooAUI1KkChIIRwXpKiIqhB6K1MChKAKKNKWDlCABQQgdpCg1hibtHyAsSBLI+5/f9bx1d7OBbNjNXPZ9Pue8ZN+8dmdm3879zi3To1ar1RIAAEABZqm6AAAAAHUCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKQEHuuOOO1KNHj/x/CY444ohcnu4i1iXWCYByCSgAMIPeeeedNMsss6Rbbrkl37/66qvTbLPNliZOnDjVc2PZIYcckgYOHJjmmGOOtM4666RRo0ZVUGqAsgkoAEzTL3/5y/Sf//wndRexLrFOneX+++/P/0fYCPfee29affXVc0hpa/fdd0+nnHJK2mWXXdLpp5+eZp111vSNb3wj3X333Z1WHoDuoGfVBQAgpQ8//DD17t07laZnz5751l3MPvvsn/qc999/P80111zTHVCWXXbZ1K9fv+aAUg8rbZ932WWXpZNOOin95Cc/yct22223tNJKK6Wf/vSn6Z577unwugB0V1pQgIb2yCOPpC222CL17ds39enTJ2288cZpzJgxzY8/+OCDedzCRRddNNVro1tPPHbDDTc0L3vllVfSsGHD0oABA/JZ9BVXXDH99re/bXecSVRY42z+wgsvnOacc840YcKEdst41113pe233z4NGjQov+ciiyySDjrooKlaNuIMfazDCy+8kDbbbLNcyY7uREcddVSq1WrNz/vXv/6VP/9Xv/pVOvXUU9Oiiy6auxwNHjw4PfHEE586BiXu77vvvumaa67JFez6et58881TlT3Wda211srBYMkll0znnnvudI9r+epXv5rf/6GHHkrrrbdeLuPiiy+ezjnnnFbPmzRpUjr88MPTmmuumeaZZ5683l/5ylfS6NGjP3UMSr0sTz31VPrOd76T5p133rTBBht8Yrnefffd9NZbb+VbBJJVV101//z666/nsi633HL5fjyv7k9/+lNuMfn+97/fvCy2yZ577pnf46WXXvrU7QHQKLrPaTGADnryySdzRTbCSZzF7tWrV65AR8X4zjvvzGfCo3K9xBJLpCuuuCINHTq01esvv/zyXKGNMBCigvrlL3+5uQL/hS98Id100025Ehrh48ADD2z1+qOPPjq3msQZ9RifMK0WlD/+8Y/pgw8+SHvvvXeab7758tn4kSNHppdffjk/1tLHH3+cNt9881yOE088MYeG4cOHp48++igHlZZ+97vfpffeey/ts88+uQUnuh1ttNFG6fHHH88B65NEt6Srrroq/fCHP0xzzz13OuOMM9K3v/3t9OKLL+Yy1sNflGWhhRZKRx55ZC5blCG2y/R6++23czeoHXbYIe288855P8R2iG0VQTDEtv3Nb36TH//e976X1+n888/P+yW21WqrrfapnxMBcOmll07HHXdcqzDXnq222ir/frT9XaiLbRK3CHz1yQ5iWyyzzDL5d62ltddeO///6KOP5uAJQErxhxigIW299da13r17155//vnmZa+++mpt7rnnrm244YbNyw499NBar169auPHj29eNnHixFq/fv1qw4YNa16255571hZaaKHaW2+91epzdtppp9o888xT++CDD/L90aNHRw24tsQSSzQvq6s/Fv/XtX1OGDFiRK1Hjx61cePGNS8bOnRofu1+++3XvGzKlCm1IUOG5PV8880387KxY8fm580xxxy1l19+ufm59913X15+0EEHNS8bPnx4XtZS3I/3e+6555qXPfbYY3n5yJEjm5dtueWWtTnnnLP2yiuvNC979tlnaz179pzqPdszePDg/LyTTz651XZfbbXVagsssEBt0qRJedlHH32Ul7f09ttv1wYMGNBq/9TLHuvUdv123nnn2vR68MEHa6NGjaqdddZZ+bUXX3xxvr/77rvXFllkkfxz3OJ5dSuuuGJto402muq9nnzyyfwe55xzznR/PkB3p4sX0JDibP6tt96att5669xCUhdn+6OrT7QQ1Ltc7bjjjmny5Mm5xaAuXhszOMVjIeq+V155Zdpyyy3zz/UuQHGLM/nR3efhhx9uVYZokYluS5+m5XNifES8Z3R5is+JM/NtRetNXb01J7pB3Xbbba2eF+se3ctans2PVqM///nPn1qmTTbZJHfZqltllVVy60B0L6tv3/i8+IzoZla31FJL5S510yvG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qmcfVM8+qJ590L22/wwNkgcAAOgKungBAADFEFAAAIBiCCgAAEAxBBQAAODzHVDOOuustNhii6XZZ589rbPOOun+++/v/JLRrhEjRqQvfelLae65504LLLBA2nrrrdPTTz9ddbEa1vHHH5969OiRDjzwwKqL0nBeeeWVtOuuu6b55psvzTHHHGnllVdODz74YNXFaggff/xxOuyww9Liiy+et/2SSy6Zjj766GTOla7117/+NW255ZZp4MCB+e/ONddc0+rx2P6HH354WmihhfJ+2WSTTdKzzz5bWXkbaftPnjw5HXLIIfnv0FxzzZWfs9tuu6VXX3210jI32negpb322is/57TTTpupZezu/jod++Af//hH+ta3vpWvLB/fh6i3vvjii10bUC6//PL0ox/9KE8l9vDDD6dVV101bbbZZumNN97o6FsxA+688860zz77pDFjxqRRo0blP4qbbrppev/996suWsN54IEH0rnnnptWWWWVqovScN5+++20/vrrp169eqWbbropPfXUU+nkk09O8847b9VFawgnnHBCOvvss9OZZ56ZD0Rx/8QTT0wjR46sumjdWvydj2NunCRsT+yDM844I51zzjnpvvvuyxWDOD5/+OGHM72sjbb9P/jgg1wniuAe/1911VX55GFU0ph534G6q6++OteTohLNzN0Hzz//fNpggw3Scsstl+64447097//PX8volGjQ2odtPbaa9f22Wef5vsff/xxbeDAgbURI0Z09K3oBG+88UacsqzdeeedVRelobz33nu1pZdeujZq1Kja4MGDawcccEDVRWoohxxySG2DDTaouhgNa8iQIbVhw4a1WrbtttvWdtlll8rK1Gji7/7VV1/dfH/KlCm1BRdcsHbSSSc1L3vnnXdqs802W+3SSy+tqJSNs/3bc//99+fnjRs3bqaVq5FMax+8/PLLtYUXXrj2xBNP1BZddNHaqaeeWkn5GnUf7LjjjrVdd931M793h1pQJk2alB566KHcbFw3yyyz5Pv33ntvx5IRneLdd9/N//fv37/qojSUaMUaMmRIq+8CM891112X1lprrbT99tvnro6rr756+vWvf111sRrGeuutl/7yl7+kZ555Jt9/7LHH0t1335222GKLqovWsMaOHZtee+21Vn+TontFdMN2fK7u+BxdYPr161d1URrGlClT0ne/+9108MEHpxVXXLHq4jTk9r/xxhvTMsssk1tv4/gcf4M+qSvetHQooLz11lu57/GAAQNaLY/78YeRmf+LEGMfoqvLSiutVHVxGsZll12Wm/BjPBDVeOGFF3IXo6WXXjrdcsstae+99077779/uuiii6ouWkP42c9+lnbaaafchB/d7CIgxt+iXXbZpeqiNaz6MdjxuQzRrS7GpOy8886pb9++VRenYUR30549e+bjATNfDPdoamrK43M333zzdOutt6ZtttkmbbvttnmIQkf07LJSMlPO4j/xxBP5zCUzx0svvZQOOOCAPP6nw/0p6dRwHi0oxx13XL4fFeT4LkTf+6FDh1ZdvG7viiuuSH/4wx/SJZdcks9SPvroozmgRH9v259GF2NDd9hhhzxpQZxIYeaIHj6nn356PoEYLVdUc2wOW221VTrooIPyz6uttlq655578vF58ODBXdOCMv/886dZZ501vf76662Wx/0FF1ywI2/FZ7TvvvumG264IY0ePTp98YtfrLo4DfUHMM4QrLHGGvksTdzirEAMTI2fo4WRrhezFK2wwgqtli2//PIdniWEGRPdJ+qtKDFrUXSpiIORVsXq1I/Bjs9lhJNx48blE1laT2aeu+66Kx+fBw0a1Hx8jv3w4x//OM88S9eLnBDbvTOOzx0KKL17905rrrlm7nvcMi3F/XXXXbdDH8yMiTMyEU5ihorbb789T/PJzLPxxhunxx9/PJ8xrt/iTH50bYmfI8DT9aJbY9vptWM8xKKLLlpZmRpJzFgU4w9bit/9+tkzZr44FkQQaXl8njBhQp7Ny/F55oaTmNr5tttuy1OgM/PEiZKYMarl8TladeOESnQFputFTogphTvj+NzhLl4xxXA04UelbO21187zS8eUY3vssUdH34oZ7NYV3SquvfbafC2Uet/iGAwZ897TtWKbtx3vE1N5xoHIOKCZJ87Wx0Dt6OIVFYK4FtN5552Xb3S9mAP/2GOPzWcqo4vXI488kk455ZQ0bNiwqovWrUXf7ueee67VwPiohMUkKbEvopvdMccck8dmRWCJqT2jghbXy6Jrt3+06m633Xa5e1H0bojW9PrxOR6Pihtd/x1oGwpjjFwE92WXXbaC0jbmPjj44IPTjjvumDbccMP0ta99Ld18883p+uuvz1MOd8iMTP01cuTI2qBBg2q9e/fO0w6PGTPmM08nxvSJXdbe7YILLqi6aA3LNMPVuP7662srrbRSnkZ1ueWWq5133nlVF6lhTJgwIf/Ox3Fg9tlnry2xxBK1X/ziF7WJEydWXbRubfTo0e3+/R86dGjzVMOHHXZYbcCAAfl7sfHGG9eefvrpqovdENt/7Nix0zw+x+uYOd+BtkwzXM0+OP/882tLLbVUPj6suuqqtWuuuabDn9Mj/un8fAUAANBxHb6SPAAAQFcRUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAAAgleL/ATwTEzjW7N/GAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAY4klEQVR4nO3dCbgd8/0/8G/IhogIlaASu9h3ak01ammqltZWKsSjpbFWVTdiTSxVS3iQUvRRa+3UEhpKiZ1Sak1jq+0XRKgkkvk/n+//Ofe59+aGe5N7MyPn9Xqek3tmzpxzvjOTc2be811Op6IoigQAAFAB85VdAAAAgBoBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBaBC7r333tSpU6f8twqOO+64XJ55RaxLrBMA1SWgAMBs+vDDD9N8882X7rzzzjx9ww03pG7duqUpU6Y0WW7y5Mlp+PDhabvttku9e/fOQenSSy8tqdQA1SagADBLv/3tb9P//ve/NK+IdYl1ai+PPPJI/rvxxhvnvw899FBad911c0hp7P33308nnHBCev7559Paa6/dbu8PMC/qXHYBAEjps88+S127dk1V07lz53ybV3Tv3v1Ll/nkk0/SQgst1OqAssoqq6RevXo1BJRaWGlsySWXTP/9739T375902OPPZY23HDD2Sg9QH1QgwLUtSeffDJtv/32qWfPnqlHjx5p0KBBady4cQ2Px8lkNMe57LLLZnpuNOuJx2699daGeW+++WYaOnRo6tOnT76Kvvrqq6c//vGPLfYzueqqq/LV/KWXXjotuOCCadKkSS2W8f7770+77rpr6tevX37NZZZZJh1xxBEz1Wzsu+++eR1effXVtO222+aT7KWWWipfuS+KomG5//znP/n9f/e736Uzzzwz9e/fPy2wwAJp4MCB6dlnn/3SPigxffDBB6cbb7wxrbHGGg3reccdd8xU9ljXDTbYIAeDFVZYIV144YWt7tfyzW9+M7/+448/njbddNNcxuWWWy5dcMEFTZabOnVqOvbYY9P666+fFllkkbzeW2yxRRo7duyX9kGpleW5555LP/zhD9Oiiy6aNt988y8s10cffZRrROIWgSRqROL+O++8k8s6YMCAPB3L1cQ2inACwJebdy6LAbTRv/71r3wiG+HkF7/4RerSpUs+gY4T4/vuuy9fCY+T6+WXXz5dc801aciQIU2ef/XVV+cT2ggDIU5Qv/GNbzScwH/ta19Lt99+e9p///1z+Dj88MObPP/EE0/MtSY///nPc5+FWdWgXHvttenTTz9NBx10UFpsscXyVftRo0alN954Iz/W2PTp03M/hyjHaaedlkND9H34/PPPc1Bp7E9/+lP6+OOP07Bhw3INztlnn52+9a1vpWeeeSYHrC/ywAMPpOuvvz799Kc/TQsvvHA655xz0ve///302muv5TLWwl+UJWoPjj/++Fy2KENsl9b64IMP0ne+85202267pT333DPvh9gOsa0iCIbYthdddFF+/IADDsjrdPHFF+f9EttqnXXW+dL3iQC40korpREjRjQJcy3Zcccd8/+P5v8XamKbxC0CX1UGOwD4SikA6tROO+1UdO3atXjllVca5r311lvFwgsvXGy55ZYN8371q18VXbp0KSZOnNgwb8qUKUWvXr2KoUOHNszbf//9iyWXXLJ4//33m7zPHnvsUSyyyCLFp59+mqfHjh0bZ8DF8ssv3zCvpvZY/K1pvkwYOXJk0alTp2LChAkN84YMGZKfe8ghhzTMmzFjRjF48OC8nu+9916eN378+LzcAgssULzxxhsNyz788MN5/hFHHNEwb/jw4XleYzEdr/fyyy83zHv66afz/FGjRjXM22GHHYoFF1ywePPNNxvmvfTSS0Xnzp1nes2WDBw4MC93xhlnNNnu66yzTrHEEksUU6dOzfM+//zzPL+xDz74oOjTp0+T/VMre6xT8/Xbc889i9Z67LHHijFjxhTnnXdefu7ll1+ep/fdd99imWWWyffjFsu15NFHH83Pu+SSS1r9ngD1RBMvoC7F1fy77ror7bTTTrmGpCau9kdTn6ghqDW52n333dO0adNyjUFNPDdGcIrHQpz7XnfddWmHHXbI92tNgOIWV/Kjuc8TTzzRpAxRIxPNlr5M42Wif0S8ZjR5iveJWormovamplabE82g7r777ibLxbpH87KajTbaKNca/fWvf/3SMm299da5yVbNWmutlWuionlZbfvG+8V7RDOzmhVXXDE3qWut6P/yk5/8pGE6ak5i+t13383NqcL888/fUPs0Y8aMNHHixFxjFLVfzbf5rBx44IGtLlM0JYv1j/eIddtrr73y9HvvvZebCMb9uMVy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VIaAAgAAfLUDynnnnZeWXXbZ1L1797TxxhunRx55pP1LRotGjhyZNtxww7TwwgunJZZYIu20007phRdeKLtYdeuUU05JnTp1SocffnjZRak7b775Ztp7773TYostlhZYYIG05pprpscee6zsYtWF6dOnp2OOOSYtt9xyeduvsMIK6cQTT0zGXOlYf//739MOO+yQllpqqfy9c+ONNzZ5PLb/sccem5Zccsm8X7beeuv00ksvlVbeetr+06ZNS0cffXT+HlpooYXyMvvss0966623Si1zvX0GGjvwwAPzMmedddZcLeO87u+t2AfPP/98+t73vpd/WT4+D3He+tprr3VsQLn66qvTz372szyU2BNPPJHWXnvttO2226Z33323rS/FbLjvvvvSsGHD0rhx49KYMWPyl+I222yTPvnkk7KLVnceffTRdOGFF6a11lqr7KLUnQ8++CBtttlmqUuXLun2229Pzz33XDrjjDPSoosuWnbR6sKpp56azj///HTuuefmA1FMn3baaWnUqFFlF22eFt/zccyNi4QtiX1wzjnnpAsuuCA9/PDD+cQgjs+fffbZXC9rvW3/Tz/9NJ8TRXCPv9dff32+eBgnacy9z0DNDTfckM+T4iSaubsPXnnllbT55punAQMGpHvvvTf985//zJ+LqNRok6KNNtpoo2LYsGEN09OnTy+WWmqpYuTIkW19KdrBu+++G5csi/vuu6/sotSVjz/+uFhppZWKMWPGFAMHDiwOO+ywsotUV44++uhi8803L7sYdWvw4MHF0KFDm8zbZZddir322qu0MtWb+N6/4YYbGqZnzJhR9O3btzj99NMb5n344YdFt27diiuvvLKkUtbP9m/JI488kpebMGHCXCtXPZnVPnjjjTeKpZdeunj22WeL/v37F2eeeWYp5avXfbD77rsXe++99xy/dptqUKZOnZoef/zxXG1cM9988+Xphx56qG3JiHbx0Ucf5b+9e/cuuyh1JWqxBg8e3OSzwNxz8803pw022CDtuuuuuanjuuuum/7whz+UXay6semmm6Z77rknvfjii3n66aefTg888EDafvvtyy5a3Ro/fnx6++23m3wnRfOKaIbt+Fze8TmawPTq1avsotSNGTNmpB/96EfpqKOOSquvvnrZxanL7X/bbbellVdeOdfexvE5voO+qCnerLQpoLz//vu57XGfPn2azI/p+GJk7v9HiL4P0dRljTXWKLs4deOqq67KVfjRH4hyvPrqq7mJ0UorrZTuvPPOdNBBB6VDDz00XXbZZWUXrS788pe/THvssUeuwo9mdhEQ47tor732Krtodat2DHZ8roZoVhd9Uvbcc8/Us2fPsotTN6K5aefOnfPxgLkvuntMnjw598/dbrvt0l133ZV23nnntMsuu+QuCm3RucNKyVy5iv/ss8/mK5fMHa+//no67LDDcv+fNrenpF3DedSgjBgxIk/HCXJ8FqLt/ZAhQ8ou3jzvmmuuSX/+85/TFVdcka9SPvXUUzmgRHtv2596F31Dd9tttzxoQVxIYe6IFj5nn312voAYNVeUc2wOO+64YzriiCPy/XXWWSc9+OCD+fg8cODAjqlBWXzxxdP888+f3nnnnSbzY7pv375teSnm0MEHH5xuvfXWNHbs2PT1r3+97OLU1RdgXCFYb7318lWauMVVgeiYGvejhpGOF6MUrbbaak3mrbrqqm0eJYTZE80narUoMWpRNKmIg5FaxfLUjsGOz9UIJxMmTMgXstSezD33339/Pj7369ev4fgc++HII4/MI8/S8SInxHZvj+NzmwJK165d0/rrr5/bHjdOSzG9ySabtOmNmT1xRSbCSYxQ8be//S0P88ncM2jQoPTMM8/kK8a1W1zJj6YtcT8CPB0vmjU2H147+kP079+/tDLVkxixKPofNhb/92tXz5j74lgQQaTx8XnSpEl5NC/H57kbTmJo57vvvjsPgc7cExdKYsSoxsfnqNWNCyrRFJiOFzkhhhRuj+Nzm5t4xRDDUYUfJ2UbbbRRHl86hhzbb7/92vpSzGazrmhWcdNNN+XfQqm1LY7OkDHuPR0rtnnz/j4xlGcciPQDmnvian101I4mXnFCEL/FNHr06Hyj48UY+CeffHK+UhlNvJ588sn0+9//Pg0dOrTsos3Tom33yy+/3KRjfJyExSApsS+imd1JJ52U+2ZFYImhPeMELX4vi47d/lGr+4Mf/CA3L4rWDVGbXjs+x+Nx4kbHfwaah8LoIxfBfZVVVimhtPW5D4466qi0++67py233DJttdVW6Y477ki33HJLHnK4TWZn6K9Ro0YV/fr1K7p27ZqHHR43btwcDydG68Qua+l2ySWXlF20umWY4XLccsstxRprrJGHUR0wYEAxevTosotUNyZNmpT/z8dxoHv37sXyyy9f/OY3vymmTJlSdtHmaWPHjm3x+3/IkCENQw0fc8wxRZ8+ffLnYtCgQcULL7xQdrHrYvuPHz9+lsfneB5z5zPQnGGGy9kHF198cbHiiivm48Paa69d3HjjjW1+n07xT/vnKwAAgLZr8y/JAwAAdBQBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAASFXx/wAOW0rnl+0oyQAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "visualize_intervals(overlapping_intervals)" ] @@ -288,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "bc0f8689c31221b3", "metadata": { "ExecuteTime": { @@ -296,22 +153,14 @@ "start_time": "2025-02-24T16:59:37.652480Z" } }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:polars_bio.operation:Running Nearest operation with algorithm Coitrees and 1 thread(s)...\n" - ] - } - ], + "outputs": [], "source": [ "nearest_intervals = pb.nearest(df1, df2, output_type=\"pandas.DataFrame\")" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "aad83ab53e1294fc", "metadata": { "ExecuteTime": { @@ -319,101 +168,14 @@ "start_time": "2025-02-24T16:59:37.665033Z" } }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
chrom_1start_1end_1chrom_2start_2end_2distance
0chr115chr1480
1chr138chr1480
2chr1810chr1480
3chr11214chr110111
\n", - "
" - ], - "text/plain": [ - " chrom_1 start_1 end_1 chrom_2 start_2 end_2 distance\n", - "0 chr1 1 5 chr1 4 8 0\n", - "1 chr1 3 8 chr1 4 8 0\n", - "2 chr1 8 10 chr1 4 8 0\n", - "3 chr1 12 14 chr1 10 11 1" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "display(nearest_intervals)" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "5f69f700b50f58e2", "metadata": { "ExecuteTime": { @@ -421,48 +183,7 @@ "start_time": "2025-02-24T16:59:37.673937Z" } }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAXGUlEQVR4nO3dCbRVZf0/4BdlUhEVTBANNHM2UVEyNcmFaWaZmmOaJLVSc0rNpQ2KMymZYznVQlc5VYpTOWDiUEpgakEaDiE4pKioeJ0gPf/1fX//c9e9CMLFy92vnOdZ63DPPnffs9+zN+fs97Pf4XSq1Wq1BAAAUIClqi4AAABAnYACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAJA8b71rW+lNdZYo+piANABBBQAPtRbb72VTjrppHT33XenJcluu+2W9t1333y/VqullVZaKV1++eXzXPemm25Km222WerevXvq379/GjFiRPrf//7XwSUGaAwCCgALDCgnn3xypQHlsssuS1OmTGnX55wwYULacsst8/3HHnssvfbaa83LLd16661p1113TSuuuGK64IIL8v3TTjstHX744e1aHgD+T+f//xOAJcSbb76ZlltuubQk6dKlywLXiRaN999/P3Xt2nWB6z777LPp+eefbw4kDzzwQFphhRXSuuuu+4F1f/CDH6SNN9443XHHHalz5/87bfbs2TOdccYZ6cgjj0zrrbfeIr0mAOZNCwrARxTdnzp16pSefPLJPFYirrRHZffAAw/MrQ9z++1vf5sGDRqUlllmmdSrV6+0zz77pGeeeabVOvfdd1/ac889c3eibt26pU9+8pPpqKOOSm+//Xar9WJ7PXr0SE899VT68pe/nJZffvm033775d9FZf3cc89NG264Ye6a1KdPn3TQQQelV199tdVzPPjgg2nHHXdMK6+8ci7TmmuumYYPH55/9/TTT6dPfOIT+X60osTrjFu85vmJblKxzr333pu317t371yhP+CAAz6w7RtvvDHtvPPOqV+/fvl1rrXWWunUU09N77333oeOQYlyxTZ+9rOf5dcYfxd//+ijj863XO+++256+eWX823cuHE59MR+jeUoa4SQV155JS/HvgvxfHH77ne/2xxOwve+973cLewPf/jDfLcHwKLRggLQTvbaa69cuR85cmR66KGH0q9+9au0yiqrpDPPPLN5ndNPPz2dcMIJed3vfOc76aWXXsrdhrbddtv08MMP53ATfv/73+dwc8ghh+QKfnRHivXiyn/8bu6WgwgY22yzTa6wL7vssvnxCAcRFiIoHXHEEWnq1KnpwgsvzNv561//mivoM2bMSDvssEMOIccff3zeflT+r7/++vwc8fhFF12UyxFjNnbffff8eFTmF+Swww7LzxdhJrpnxfNMmzYtdxWLcBGifBGwjj766PzzrrvuSieeeGKaNWtWGjVq1AK3MXr06PTOO+/kABEBJQLf/Fx99dV5X7S02mqrtVquh7HYVxGIYl+FzTffvNV6EahWX3315t8D0I5qAHwkI0aMqMXH6fDhw1s9vttuu9V69+7dvPz000/Xll566drpp5/ear1JkybVOnfu3Orxt9566wPbGTlyZK1Tp061adOmNT82bNiwvO3jjz++1br33XdffvzKK69s9fhtt93W6vExY8bk5YkTJ8739b300kt5nXidC2P06NF5/UGDBtVmz57d/PhZZ52VH7/xxhs/9HUedNBBtWWXXbb2zjvvtHqdAwYMaF6eOnVqfq6ePXvWZsyYsVDlev7552tjx47Nt3iuAw44IN+/+uqr83Odf/75zb9/++2389+MGjUq/2769OkfeL4tttiituWWWy7UtgFYeLp4AbSTgw8+uNXy5z//+dxlKFoDQrRKRNehaD2pdzWKW9++fdPaa6+dux3VRVerlmNKYr2tttoqdyua11X7aOFoKVpZopvZF7/4xVbbiq5l0VJR31a9xeaWW25Jc+bMadf9Ea0aLceORBmjm9Sf/vSneb7ON954I5cx9lu0Hv373/9e4Da+/vWvN7d6LMiqq66att9++9waEl3qoitcLEeZogtclDeW4xbLod6lLlpn5hbrzN3lDoCPThcvgHYS40VaimlrQ4y7iDEYTzzxRA4YEUbmpWVlfvr06bmrU0xvO/e4jddff73VclSwo7tRS7GtWC+6mM1LdO0KQ4YMyZX8GF9yzjnnpC984Qt5lqpvfOMb86yUt8XcrzOCUYSE6EJW969//Sv95Cc/yV276kFufq9zXqJL3cKI8FV/vttvvz0ttdRSeXB7BKJY3nTTTXNAilsEu/qxqAeoGL8yt+ha1jJgAdA+BBSAdrL00kvP8/EIJSFaT2LsRUxbO691owIfYoB4tHzMnDkzHXfccbkiHbNyPffcc3mweH0Ad10EiahwtxTrRDi58sor51mmeqtDlCcGeo8fPz7dfPPNubIeA+TPPvvs/Fi9TItDTOsbASnC2ymnnJIHukerRIzfidc99+ucl4UNCDHmZrvttmv12IABA+a5T6J1KYJaiEAV/vvf/+YB9S3FY4MHD16o7QOw8AQUgA4SFfAIK3HVf5111pnvepMmTUqPP/54uuKKK/LMV3Vjx45t07buvPPOtPXWWy9UJT6m241bDOK/6qqrcvena665Jg/krw9ob6toxWkZCpqamnKlPmYbCzFYPrrARde3mCSgLgaot7eBAwc277/oahavddiwYblVZY899kjnnXde2mCDDZrXrdtkk02aZzprGUZiiuKYsCC6hQHQvoxBAeggMQNWtJxEd6p6q0pdLEdlPdRbV1quE/ejEr2wYpxLtMTElL1zi1m/ovUiRPexuctSr5TXuzXVZwWr/83CuvTSS1uNa4lZvGLbO+2003xf5+zZs9Mvf/nL1N6iu12MLYmZzqL7XHRri+VomYpyfPvb324ef1LvmhdiiuZowYrX0nLq43gtEdwi3ADQvrSgAHSQaNWIbyD/4Q9/mMdhxFiP+N6SaDEYM2ZMvhofXwoYFeJYN+5Ht67oAnXdddd9YCzKh4muUzHNcEx5/Mgjj+SphGNcRbRqxAD6CDtRuY5WmggEMYVwbDPGYMS3tsc26y0d0QITrQvXXnttbvmJqXw32mijfPswETaGDh2aw1JMMxzbiYCwyy675N/HoP8IA9GSEdMgR4X/N7/5zQcCU3uKlpAoV2w73H///XnK5A/7YsuY7jjKHPswvrNm8uTJebrmaF1af/31F1tZARqVgALQgeK7RqKSHwPSoyUlxNiGqPzWK+4RJGI8SFTaI2DEuIwIEPG9Ii27Hy3IxRdfnGftuuSSS9KPfvSjPJg+vttj//33z12/6kEmvmMlunO9+OKLeYB4dGWKsSstB6DHd7ocfvjh+csio4I/YsSIBQaUqMTH88Rg/2hJ2XfffdP555/f3GUsvt8lZg875phj8kD5CCtRtgg18b0ui0OMRYkgVp88IL5Bvh5W5ucrX/lK7oYWxyv2QYxVif0ZrwuA9tcp5hpeDM8LQIOqfznkxIkTP/AFhwCwIMagAAAAxRBQAACAYggoAABAMYxBAQAAiqEFBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADF6Jwa2MyZM1NTU1PVxYBK9ejRI/Xq1avqYgAANHZAiXBy8smnpDlzZlddFKhUly5d04gRJwopAEARGjagRMtJhJPe2309dVnxE1UXByox57WX0ivjrsvvBwEFAChBwwaUuggnXVfuV3UxAAAAg+QBAICSCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBidE4Nbs5rL1VdBKiM//8AQGkaNqD06NEjdenSNb0y7rqqiwKVivdBvB8AAErQqVar1VKDmjlzZmpqaqq6GFCpCCe9evWquhgAAFlDBxQAAKAsBskDAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFKNz1QWAj7OZM2empqamqosBlerRo0fq1atX1cUAYAkhoMBHCCennHxymj1nTtVFgUp17dIlnThihJACQLsQUGARRctJhJNvbbpl6tujZ9XFgUq80DQrXf7w+Px+EFAAaA8CCnxEEU76r6hiBgDQHgySBwAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAitG56gLAx90LTbOqLgJUxv9/ANqbgAKLqEePHqlrly7p8ofHV10UqFS8D+L9AADtoVOtVqu1yzNBA5o5c2ZqamqquhhQqQgnvXr1qroYACwhBBQAAKAYBskDAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAAHy8A8q7776bTjrppPyTajgG1XMMqucYVM8xqJ5jUD3HoHqOwZK1/zvVarVaW/9o1qxZaYUVVkivv/566tmzZ7sUhLZxDKrnGFTPMaieY1A9x6B6jkH1HIMla//r4gUAABRDQAEAAIohoAAAAB/vgNKtW7c0YsSI/JNqOAbVcwyq5xhUzzGonmNQPcegeo7BkrX/F2mQPAAAwOKgixcAAFAMAQUAACiGgAIAABRDQAEAAD7eAeUXv/hFWmONNVL37t3TZz/72TRhwoT2LxnzNHLkyLTFFluk5ZdfPq2yyipp1113TVOmTKm6WA3rpz/9aerUqVP6/ve/X3VRGs5zzz2X9t9//9S7d++0zDLLpM985jPpwQcfrLpYDeG9995LJ5xwQlpzzTXzvl9rrbXSqaeemsy5snjde++96atf/Wrq169f/ty54YYbWv0+9v+JJ56YVl111Xxctt9++/TEE09UVt5G2v9z5sxJxx13XP4cWm655fI6BxxwQHr++ecrLXOjvQdaOvjgg/M65557boeWcUl370Icg8ceeyztsssu+Zvl4/0Q9dbp06cv3oBy7bXXpqOPPjpPJfbQQw+lgQMHph133DHNmDGjrU/FIrjnnnvSoYcemsaPH5/Gjh2bPxR32GGH9Oabb1ZdtIYzceLEdMkll6SNN9646qI0nFdffTVtvfXWqUuXLunWW29Njz76aDr77LPTSiutVHXRGsKZZ56ZLrroonThhRfmE1Esn3XWWemCCy6oumhLtPicj3NuXCSclzgG559/frr44ovT3/72t1wxiPPzO++80+FlbbT9/9Zbb+U6UQT3+Hn99dfni4dRSaPj3gN1Y8aMyfWkqETTscfgqaeeSttss01ab7310t13353++c9/5vdFNGq0Sa2NBg8eXDv00EObl997771av379aiNHjmzrU9EOZsyYEZcsa/fcc0/VRWkob7zxRm3ttdeujR07tjZkyJDakUceWXWRGspxxx1X22abbaouRsPaeeeda8OHD2/12O67717bb7/9KitTo4nP/TFjxjQvv//++7W+ffvWRo0a1fzYa6+9VuvWrVvt6quvrqiUjbP/52XChAl5vWnTpnVYuRrJ/I7Bs88+W1tttdVqkydPrg0YMKB2zjnnVFK+Rj0Ge++9d23//ff/yM/dphaU2bNnp7///e+52bhuqaWWyssPPPBA25IR7eL111/PP3v16lV1URpKtGLtvPPOrd4LdJybbropbb755mnPPffMXR033XTTdNlll1VdrIax1VZbpT//+c/p8ccfz8v/+Mc/0l/+8pe00047VV20hjV16tT0wgsvtPpMiu4V0Q3b+bm683N0gVlxxRWrLkrDeP/999M3v/nNdOyxx6YNN9yw6uI05P7/4x//mNZZZ53cehvn5/gM+rCuePPTpoDy8ssv577Hffr0afV4LMcHIx3/HyHGPkRXl4022qjq4jSMa665Jjfhx3ggqvGf//wndzFae+210+23354OOeSQdMQRR6Qrrrii6qI1hOOPPz7ts88+uQk/utlFQIzPov3226/qojWs+jnY+bkM0a0uxqTsu+++qWfPnlUXp2FEd9POnTvn8wEdL4Z7NDU15fG5X/rSl9Idd9yRdtttt7T77rvnIQpt0XmxlZIOuYo/efLkfOWSjvHMM8+kI488Mo//aXN/Sto1nEcLyhlnnJGXo4Ic74Xoez9s2LCqi7fE+93vfpeuvPLKdNVVV+WrlI888kgOKNHf2/6n0cXY0L322itPWhAXUugY0cPnvPPOyxcQo+WKas7N4Wtf+1o66qij8v1NNtkk3X///fn8PGTIkMXTgrLyyiunpZdeOr344outHo/lvn37tuWp+IgOO+ywdMstt6Rx48al1VdfveriNNQHYFwh2GyzzfJVmrjFVYEYmBr3o4WRxS9mKdpggw1aPbb++uu3eZYQFk10n6i3osSsRdGlIk5GWhWrUz8HOz+XEU6mTZuWL2RpPek49913Xz4/9+/fv/n8HMfhmGOOyTPPsvhFToj93h7n5zYFlK5du6ZBgwblvsct01Isf+5zn2vThlk0cUUmwknMUHHXXXflaT7pOEOHDk2TJk3KV4zrt7iSH11b4n4EeBa/6NY49/TaMR5iwIABlZWpkcSMRTH+sKX4v1+/ekbHi3NBBJGW5+dZs2bl2bycnzs2nMTUznfeeWeeAp2OExdKYsaolufnaNWNCyrRFZjFL3JCTCncHufnNnfxiimGowk/KmWDBw/O80vHlGMHHnhgW5+KRezWFd0qbrzxxvxdKPW+xTEYMua9Z/GKfT73eJ+YyjNORMYBdZy4Wh8DtaOLV1QI4ruYLr300nxj8Ys58E8//fR8pTK6eD388MPp5z//eRo+fHjVRVuiRd/uJ598stXA+KiExSQpcSyim91pp52Wx2ZFYImpPaOCFt+XxeLd/9Gqu8cee+TuRdG7IVrT6+fn+H1U3Fj874G5Q2GMkYvgvu6661ZQ2sY8Bscee2zae++907bbbpu22267dNttt6Wbb745TzncJosy9dcFF1xQ69+/f61r16552uHx48d/5OnEWDhxyOZ1Gz16dNVFa1imGa7GzTffXNtoo43yNKrrrbde7dJLL626SA1j1qxZ+f98nAe6d+9e+9SnPlX78Y9/XHv33XerLtoSbdy4cfP8/B82bFjzVMMnnHBCrU+fPvl9MXTo0NqUKVOqLnZD7P+pU6fO9/wcf0fHvAfmZprhao7Br3/969qnP/3pfH4YOHBg7YYbbmjzdjrFP+2frwAAANquzd8kDwAAsLgIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAACQSvH/AFFsXXBd2e9cAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAWgUlEQVR4nO3dC7AWZf0H8Ae5iIqoYIpooBlqYqJpVspfcjTNmEzIG0GS1KSOpqk52gXxRqRmXstbDTqFaKWIWGqYeCklMbU0zVuItxQVBY+okL7/+T0z75lzEJQD55x95Hw+My+c3bPsPu8u77v73eeynWq1Wi0BAAAUYLWqCwAAAFAnoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAFC8b3zjG2nTTTetuhgAtAMBBYD3tXDhwnTyySen2267La1Khg0blkaMGJF/rtVqab311kuXX375e5a7+uqr06hRo9KAAQNSp06d0uc///kKSgvQcQgoAHxgQDnllFMqDSiXXXZZevTRR1t1nffcc0/67Gc/m39+5JFH0muvvdY43dRFF12Upk6dmj760Y/mEANA2+rSxusHoJ298cYbaa211kqrkq5du37gMv/73//Su+++m7p16/aByz777LPp+eefbwwkd999d1pnnXXSlltu+Z5lf/3rX6eNN944rbbaammbbbZZwXcAwPJSgwKwkqL5UzT9eeKJJ3JfiXXXXTdf7B5yyCG59mFJv/nNb9IOO+yQ1lhjjdSrV6900EEHpWeeeabZMnfeeWfaf//9U79+/dLqq6+e794fc8wx6c0332y2XGyvR48e6cknn0xf+tKX0tprr51GjhyZfxcX6+eee24aOHBg6t69e9pwww3ToYceml599dVm67j33nvTXnvtldZff/1cps022yyNGTMm/+6pp55KH/nIR/LPUYsS7zNe8Z6XJZpJxTJ33HFH3l7v3r1Tz54908EHH/yebUfNxNChQ1Pfvn3z+9x8883Taaedlt5555337YMS5Ypt/PSnP83vMf5d/PuHH354meV6++2308svv5xfM2bMyKEn9mtMR1m33Xbb9Morr+Tp2Hd1sUyEEwDahxoUgFZywAEH5Iv7CRMmpPvuuy/98pe/TBtssEE644wzGpcZP358Gjt2bF72W9/6VnrppZfSBRdckHbdddd0//3353ATfve73+Vwc/jhh+cL/GiOFMvFnf/43ZI1BxEwBg8enC/Y11xzzTw/wkGEhQhKRx11VJo9e3a68MIL83b++te/5gv0uXPnpj333DOHkBNPPDFvPy7+r7322ryOmB9NnKIc0Wdj+PDheX5czH+QI488Mq8vwkw0z4r1zJkzJzcVi3ARonwRsI499tj896233ppOOumktGDBgnTWWWd94DYmTpyY3nrrrfTtb387B5QIfMsyefLkvC+aipqRpuphLPaVTvkAFakBsFLGjRtXi6/TMWPGNJs/bNiwWu/evRunn3rqqVrnzp1r48ePb7bcgw8+WOvSpUuz+QsXLnzPdiZMmFDr1KlTbc6cOY3zRo8enbd94oknNlv2zjvvzPMnTZrUbP5NN93UbP6UKVPy9KxZs5b5/l566aW8TLzP5TFx4sS8/A477FBbtGhR4/wzzzwzz586der7vs9DDz20tuaaa9beeuutZu+zf//+jdOzZ8/O6+rZs2dt7ty5y1Wu559/vjZ9+vT8inUdfPDB+efJkyfndZ1//vmNv3/zzTeXuo6BAwfWhgwZslzbA2DFqLMGaCWHHXZYs+n/+7//y02GojYgRK1ENB2K2pN6U6N49enTJ48QFc2O6qKpVdM+JbHczjvvnEebihqQJUUNR1NRyxLNzL7whS8021Y0LYuaivq26jU2N9xwQ1q8eHGr7o+o1WjadyTK2KVLl/THP/5xqe/z9ddfz2WM/Ra1R//+978/cBtf/epXG2s9PshGG22U9thjj7TjjjvmJnXRFC6mo0zRBC7KG9PximkAqqGJF0Arif4iTdVHfIp+F9EH4/HHH88BI8LI0jS9mH/66adzU6frr7/+Pf025s+f32w6LrA32WSTZvNiW7FcNDFbmmjaFYYMGZIv8qN/yTnnnJOH0N13333T1772tdxkamUs+T4jGEVIiCZkdf/617/Sj370o9y0qx7klvU+lyaa1C2PCF/19d188825T8lWW22VA1FMb7/99jkgxSuC3fJ0ygegbQgoAK2kc+fOS50foSRE7Un0vbjxxhuXumxcwIfoIB41H/PmzUsnnHBCvpCOUbmee+653Fm8aQfuEEFiyU7csUyEk0mTJi21TPVahyjP73//+zRz5sw0bdq0fLEeHeTPPvvsPK9eprYQw/pGQIrwduqpp+aO7lFz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UAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAPDhDihvv/12Ovnkk/PfVMMxqJ5jUD3HoHqOQfUcg+o5BtVzDFat/d+pVqvVWvqPFixYkNZZZ500f/781LNnz1YpCC3jGFTPMaieY1A9x6B6jkH1HIPqOQar1v7XxAsAACiGgAIAABRDQAEAAD7cAWX11VdP48aNy39TDcegeo5B9RyD6jkG1XMMqucYVM8xWLX2/wp1kgcAAGgLmngBAADFEFAAAIBiCCgAAEAxBBQAAODDHVB+/vOfp0033TR17949feYzn0n33HNP65eMpZowYUL69Kc/ndZee+20wQYbpH333Tc9+uijVRerw/rJT36SOnXqlL773e9WXZQO57nnnkujRo1KvXv3TmussUb65Cc/me69996qi9UhvPPOO2ns2LFps802y/t+8803T6eddloy5krbuuOOO9KXv/zl1Ldv3/y9c9111zX7fez/k046KW200Ub5uOyxxx7p8ccfr6y8HWn/L168OJ1wwgn5e2ittdbKyxx88MHp+eefr7TMHe0z0NRhhx2Wlzn33HPbtYyrujuW4xg88sgjaZ999slPlo/PQ1y3Pv30020bUK6++up07LHH5qHE7rvvvjRo0KC01157pblz57Z0VayA22+/PR1xxBFp5syZafr06flLcc8990xvvPFG1UXrcGbNmpUuueSStO2221ZdlA7n1VdfTbvsskvq2rVruvHGG9PDDz+czj777LTeeutVXbQO4YwzzkgXXXRRuvDCC/OJKKbPPPPMdMEFF1RdtFVafM/HOTduEi5NHIPzzz8/XXzxxelvf/tbvjCI8/Nbb73V7mXtaPt/4cKF+Zoognv8fe211+abh3GRRvt9BuqmTJmSr5PiIpr2PQZPPvlkGjx4cNpqq63Sbbfdlv75z3/mz0VUarRIrYV22mmn2hFHHNE4/c4779T69u1bmzBhQktXRSuYO3du3LKs3X777VUXpUN5/fXXawMGDKhNnz69NmTIkNrRRx9ddZE6lBNOOKE2ePDgqovRYQ0dOrQ2ZsyYZvOGDx9eGzlyZGVl6mjie3/KlCmN0++++26tT58+tbPOOqtx3muvvVZbffXVa5MnT66olB1n/y/NPffck5ebM2dOu5WrI1nWMXj22WdrG2+8ce2hhx6q9e/fv3bOOedUUr6OegwOPPDA2qhRo1Z63S2qQVm0aFH6+9//nquN61ZbbbU8fffdd7csGdEq5s+fn//u1atX1UXpUKIWa+jQoc0+C7Sf66+/Pu24445p//33z00dt99++3TZZZdVXawOY+edd05//vOf02OPPZan//GPf6S//OUvae+99666aB3W7Nmz0wsvvNDsOymaV0QzbOfn6s7P0QRm3XXXrbooHca7776bvv71r6fjjz8+DRw4sOridMj9/4c//CFtscUWufY2zs/xHfR+TfGWpUUB5eWXX85tjzfccMNm82M6vhhp//8I0fchmrpss802VRenw7jqqqtyFX70B6Ia//nPf3ITowEDBqSbb745HX744emoo45KV1xxRdVF6xBOPPHEdNBBB+Uq/GhmFwExvotGjhxZddE6rPo52Pm5DNGsLvqkjBgxIvXs2bPq4nQY0dy0S5cu+XxA+4vuHg0NDbl/7he/+MX0pz/9KQ0bNiwNHz48d1FoiS5tVkra5S7+Qw89lO9c0j6eeeaZdPTRR+f+Py1uT0mrhvOoQfnxj3+cp+MCOT4L0fZ+9OjRVRdvlffb3/42TZo0KV155ZX5LuUDDzyQA0q097b/6eiib+gBBxyQBy2IGym0j2jhc9555+UbiFFzRTXn5vCVr3wlHXPMMfnn7bbbLt111135/DxkyJC2qUFZf/31U+fOndOLL77YbH5M9+nTpyWrYiUdeeSR6YYbbkgzZsxIm2yySdXF6VBfgHGH4FOf+lS+SxOvuCsQHVPj56hhpO3FKEVbb711s3mf+MQnWjxKCCsmmk/Ua1Fi1KJoUhEnI7WK1amfg52fywgnc+bMyTey1J60nzvvvDOfn/v169d4fo7jcNxxx+WRZ2l7kRNiv7fG+blFAaVbt25phx12yG2Pm6almP7c5z7Xog2zYuKOTISTGKHi1ltvzcN80n5233339OCDD+Y7xvVX3MmPpi3xcwR42l40a1xyeO3oD9G/f//KytSRxIhF0f+wqfi/X797RvuLc0EEkabn5wULFuTRvJyf2zecxNDOt9xySx4CnfYTN0pixKim5+eo1Y0bKtEUmLYXOSGGFG6N83OLm3jFEMNRhR8XZTvttFMeXzqGHDvkkENauipWsFlXNKuYOnVqfhZKvW1xdIaMce9pW7HPl+zvE0N5xolIP6D2E3fro6N2NPGKC4J4FtOll16aX7S9GAN//Pjx+U5lNPG6//77089+9rM0ZsyYqou2Sou23U888USzjvFxERaDpMSxiGZ2p59+eu6bFYElhvaMC7R4XhZtu/+jVne//fbLzYuidUPUptfPz/H7uHCj7T8DS4bC6CMXwX3LLbesoLQd8xgcf/zx6cADD0y77rpr2m233dJNN92Upk2bloccbpEVGfrrggsuqPXr16/WrVu3POzwzJkzV3o4MZZPHLKlvSZOnFh10ToswwxXY9q0abVtttkmD6O61VZb1S699NKqi9RhLFiwIP+fj/NA9+7dax/72MdqP/zhD2tvv/121UVbpc2YMWOp3/+jR49uHGp47NixtQ033DB/Lnbffffao48+WnWxO8T+nz179jLPz/HvaJ/PwJIMM1zNMfjVr35V+/jHP57PD4MGDapdd911Ld5Op/ij9fMVAABAy7X4SfIAAABtRUABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgFSK/wf6+B9vMqhECAAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAXCUlEQVR4nO3dCbRd4/0/4DdkQgSJEqGJoSFFDY1qa0otStWqilkNqbSrKDVWpVViSmOomZraFdoS2hJTi0bF0JKiaKPUGDGVICSuKWmc//q+v//Jyo2E3OTeu1/3PM9ax7373J2z37O3c/b72e+wO9VqtVoCAAAowGJVFwAAAKBOQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAaB43/72t9Oqq65adTEAaAcCCgAf6Z133knHH398uuOOO1JHMmTIkLTnnnvm32u1WlpuueXSZZdd1myd119/PZ1++ulpiy22SJ/61KfSsssum770pS+lq6++uqJSA3R8AgoAHxtQTjjhhEoDyqWXXpoef/zxVn3N++67L4eN8Nhjj6U333xz9nLdvffem4455pjUq1ev9NOf/jSNHDkyLbnkkmmPPfZII0aMaNXyAPB/Ov//nwB0EG+//XZaaqmlUkfSpUuXj13nf//7X/rggw9S165dP3bdF154Ib300kuzA0kEkWWWWSattdZazdZbZ5110pNPPpn69+8/+7nvf//7aeutt06nnnpq+tGPftTh9jVA1bSgACyi6P7UqVOn9NRTT+WxEtENKCq7++23X259mNtvf/vbNGjQoLTEEkvkK/NxNf75559vts7dd9+ddt1119SvX7/UrVu39OlPfzodfvjh6d133222XmyvR48e6emnn05f//rX09JLL5322muv/LeorJ999tm5kt29e/e04oorpv333z+98cYbzV7jgQceSNtuu21afvnlc5lWW221NGzYsPy3Z599NndtCtGKEu8zHvGe5ye6ScU6d911V95e7969U8+ePdO+++77oW1ff/31afvtt099+/bN73ONNdZIJ510Upo1a9ZHjkGJcsU2fv7zn+f3GP8u/v2jjz4633K9//776bXXXsuP8ePH59AT+zWWo6zrrbde7tIVy7HvQuyLOcNJiO3uuOOO+fWeeeaZ+W4PgIWjBQWgley22265Qjtq1Kj04IMPpl/+8pdphRVWyFfa66KL0LHHHpvX/e53v5teffXVdN555+UxDg899FAON+H3v/99DjcHHnhgruBHd6RYL678x9/mbjmIgLHZZpvlCnt0QQoRDiIsRFA65JBD0qRJk9L555+ft/O3v/0tV9CnTJmSttlmmxxChg8fnrcflf9rr702v0Y8f+GFF+ZyxJiNnXbaKT8flfmPc/DBB+fXizAT3bPidSZPnpy7ikUlP0T5ImAdccQR+eftt9+ejjvuuDR9+vQ89uPjjB49Or333nvpe9/7Xg4oEfjmZ8yYMXlfzGnllVdutlwPY7GvPmpQ/ssvv5x/RqgDoJXVAFgkI0aMqMXX6bBhw5o9P2TIkFrv3r1nLz/77LO1xRdfvDZy5Mhm602cOLHWuXPnZs+/8847H9rOqFGjap06dapNnjx59nNDhw7N2x4+fHizde++++78/BVXXNHs+VtuuaXZ82PHjs3L999//3zf36uvvprXife5IEaPHp3XHzRoUG3GjBmznz/ttNPy89dff/1Hvs/999+/tuSSS9bee++9Zu+zf//+s5cnTZqUX6tnz561KVOmLFC5Xnrppdq4cePyI15r3333zb+PGTMmv9a55547++/vvvvufF/n9ddfr62wwgq1zTfffIG2C0DL6OIF0EoOOOCAZsubb7557jIUrQEhWiWi61C0ntS7GsWjT58+acCAAbnbUV10tZpzTEmst8kmm+TZpqIFZG7RwjGnaGWJbmZf/epXm20rupZFS0V9W/UWm5tuuinNnDmzVfdHtGrMOXYkyti5c+f0pz/9aZ7v86233spljP0WrUf/+c9/PnYbO++88+xWj4+z0kor5bEjG220Ue5SF13hYjnKFF3goryxHI9Ynpc4fvHvYkB9tGgB0Pp08QJoJTFeZE4xbW2IcRcxBiMGW0fAiDAyL3NW5p977rnc1emGG2740LiNadOmNVuOCvYqq6zS7LnYVqwXXczmJbp2hcGDB+dKfowvOeuss9JXvvKVPL7iW9/6Vu4ytSjmfp8RjCIkRBeyun//+995dqzo2lUPcvN7n/MSXeoWRISv+uvdeuutabHFFksDBw7MgSiWN9xwwxyQ4hHBbn6D8n/wgx+kW265Jf36179O66+//gJtG4CWEVAAWsniiy8+z+cjlNSvvsfYi5tvvnme60YFPsQA8Wj5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AMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAOCTHVDef//9dPzxx+efVMMxqJ5jUD3HoHqOQfUcg+o5BtVzDDrW/u9Uq9VqLf1H06dPT8sss0yaNm1a6tmzZ6sUhJZxDKrnGFTPMaieY1A9x6B6jkH1HIOOtf918QIAAIohoAAAAMUQUAAAgE92QOnWrVsaMWJE/kk1HIPqOQbVcwyq5xhUzzGonmNQPcegY+3/hRokDwAA0BZ08QIAAIohoAAAAMUQUAAAgGIIKAAAwCc7oFxwwQVp1VVXTd27d09f/OIX03333df6JWOeRo0alb7whS+kpZdeOq2wwgppxx13TI8//njVxWpYp5xySurUqVM67LDDqi5Kw3nxxRfT3nvvnXr37p2WWGKJ9LnPfS498MADVRerIcyaNSsde+yxabXVVsv7fo011kgnnXRSMudK27rrrrvSN77xjdS3b9/8vXPdddc1+3vs/+OOOy6ttNJK+bhsvfXW6cknn6ysvI20/2fOnJmOPvro/D201FJL5XX23Xff9NJLL1Va5kb7DMzpgAMOyOucffbZ7VrGju6uBTgGjz32WNphhx3yneXj8xD11ueee65tA8rVV1+djjjiiDyV2IMPPpjWX3/9tO2226YpU6a09KVYCHfeeWc66KCD0oQJE9K4cePyl+I222yT3n777aqL1nDuv//+dPHFF6f11luv6qI0nDfeeCNtuummqUuXLunmm29Ojz76aDrjjDPScsstV3XRGsKpp56aLrzwwnT++efnE1Esn3baaem8886rumgdWnzPxzk3LhLOSxyDc889N1100UXp73//e64YxPn5vffea/eyNtr+f+edd3KdKIJ7/Lz22mvzxcOopNF+n4G6sWPH5npSVKJp32Pw9NNPp8022ywNHDgw3XHHHelf//pX/lxEo0aL1Fpo4403rh100EGzl2fNmlXr27dvbdSoUS19KVrBlClT4pJl7c4776y6KA3lrbfeqg0YMKA2bty42uDBg2uHHnpo1UVqKEcffXRts802q7oYDWv77bevDRs2rNlzO+20U22vvfaqrEyNJr73x44dO3v5gw8+qPXp06d2+umnz37uzTffrHXr1q02ZsyYikrZOPt/Xu6777683uTJk9utXI1kfsfghRdeqK288sq1Rx55pNa/f//aWWedVUn5GvUY7L777rW99957kV+7RS0oM2bMSP/4xz9ys3HdYostlpfvvffeliUjWsW0adPyz169elVdlIYSrVjbb799s88C7eeGG25IG220Udp1111zV8cNN9wwXXrppVUXq2Fssskm6S9/+Ut64okn8vI///nP9Ne//jVtt912VRetYU2aNCm9/PLLzb6TontFdMN2fq7u/BxdYJZddtmqi9IwPvjgg7TPPvuko446Kq2zzjpVF6ch9/8f//jHtOaaa+bW2zg/x3fQR3XFm58WBZTXXnst9z1eccUVmz0fy/HFSPv/jxBjH6Kry7rrrlt1cRrGVVddlZvwYzwQ1XjmmWdyF6MBAwakW2+9NR144IHpkEMOSZdffnnVRWsIw4cPT3vssUduwo9udhEQ47tor732qrpoDat+DnZ+LkN0q4sxKXvuuWfq2bNn1cVpGNHdtHPnzvl8QPuL4R5NTU15fO7Xvva19Oc//zkNGTIk7bTTTnmIQkt0brNS0i5X8R955JF85ZL28fzzz6dDDz00j/9pcX9KWjWcRwvKz372s7wcFeT4LETf+6FDh1ZdvA7vd7/7XbriiivSlVdema9SPvzwwzmgRH9v+59GF2NDd9tttzxpQVxIoX1ED59zzjknX0CMliuqOTeHb37zm+nwww/Pv2+wwQbpnnvuyefnwYMHt00LyvLLL58WX3zx9MorrzR7Ppb79OnTkpdiER188MHppptuSuPHj0+rrLJK1cVpqC/AuELw+c9/Pl+liUdcFYiBqfF7tDDS9mKWorXXXrvZc5/97GdbPEsICye6T9RbUWLWouhSEScjrYrVqZ+DnZ/LCCeTJ0/OF7K0nrSfu+++O5+f+/XrN/v8HMfhyCOPzDPP0vYiJ8R+b43zc4sCSteuXdOgQYNy3+M501Isf/nLX27Rhlk4cUUmwknMUHH77bfnaT5pP1tttVWaOHFivmJcf8SV/OjaEr9HgKftRbfGuafXjvEQ/fv3r6xMjSRmLIrxh3OK//frV89of3EuiCAy5/l5+vTpeTYv5+f2DScxtfNtt92Wp0Cn/cSFkpgxas7zc7TqxgWV6ApM24ucEFMKt8b5ucVdvGKK4WjCj0rZxhtvnOeXjinH9ttvv5a+FAvZrSu6VVx//fX5Xij1vsUxGDLmvadtxT6fe7xPTOUZJyLjgNpPXK2PgdrRxSsqBHEvpksuuSQ/aHsxB/7IkSPzlcro4vXQQw+lM888Mw0bNqzqonVo0bf7qaeeajYwPiphMUlKHIvoZnfyySfnsVkRWGJqz6igxf2yaNv9H626u+yyS+5eFL0bojW9fn6Ov0fFjbb/DMwdCmOMXAT3tdZaq4LSNuYxOOqoo9Luu++etthii7TlllumW265Jd144415yuEWWZipv84777xav379al27ds3TDk+YMGGRpxNjwcQhm9dj9OjRVRetYZlmuBo33nhjbd11183TqA4cOLB2ySWXVF2khjF9+vT8/3ycB7p3715bffXVa8ccc0zt/fffr7poHdr48ePn+f0/dOjQ2VMNH3vssbUVV1wxfy622mqr2uOPP151sRti/0+aNGm+5+f4d7TPZ2Buphmu5hj86le/qn3mM5/J54f111+/dt1117V4O53iP62frwAAAFquxXeSBwAAaCsCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAACkUvw/PStWp8dTGfAAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAXCElEQVR4nO3dCbRVVf0H8I0CTogKJogGmqmoOJuV8pdcmGaunHIiEJJaqUvT1EwbECfCIXMsp1rqKqdKwaHUMFExJTG1NM0pxClFRcXnBOn9r99e67J4DMKT997Zj/v5rHV579x33j37nsO7Z3/PHk6nWq1WSwAAAAVYpuoCAAAA1AkoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAFO+b3/xmWmeddaouBgDtQEAB4GO9++676cQTT0x33nlnWprstddeaciQIfn7Wq2WVltttXT55ZfPt95RRx2Vttpqq9SjR4+04oorpo022ijvj6ampgpKDbD061x1AQAoP6CcdNJJ+fsvfelLlZTh0ksvTR999FGrvub999+ffvCDH+TvH3/88fTmm2+mL3zhC/OtN2XKlPR///d/6aCDDkrLL798euihh9Jpp52Wbr/99nT33XenZZZxrQ+gNQkoAEuZd955J6200kppadKlS5dFrvO///0vh5iuXbsuct0XXnghvfTSS3MCyX333ZdWWWWVtOGGG8637j333DPfc+utt176/ve/n0POgkINAJ+cyz4ASyi6+3Tq1Ck9/fTTeazEqquumiu7ccU9Wh/m9dvf/jZtvfXWaYUVVsjdhg444ID0/PPPN1tn0qRJad999019+/ZNyy23XPr0pz+duxq99957zdaL7XXr1i0988wz6atf/WpaeeWV09ChQ/PPorJ+zjnnpE022SRf+e/Vq1c6+OCD0xtvvNHsNR544IG0yy67pNVXXz2Xad11100jR47MP3v22WfTpz71qfx9tKLE+4xHvOeFiW5SsU60LsT2evbsmbp3756GDx8+37ZvuOGGtNtuu6U+ffrk9xkV/1NOOSV9+OGHHzsGJcoV2/jZz36W32P8Xvz+Y489ttByffDBB+m1117Lj4kTJ+bQE/s1lqOsm222WXr99dfz8qJaa+pliVYXAFqXFhSAVrLffvvlyv3YsWPTgw8+mH71q1+lNdZYI51++ulz1hkzZkwaNWpUXvfb3/52evXVV9P555+fdthhh9x1KMJN+P3vf5/DzaGHHpor+HGlPtaLK//xs3lbDiJgDBw4MFfYY5xEiHAQYSGC0hFHHJGmTp2aLrjggrydv/71r7mCPn369LTzzjvnEHL88cfn7Ufl//rrr8+vEc9feOGFuRwxZmPvvffOz0dlflEOP/zw/HoRZp544on8OtOmTctjWSJchChfBKyjjz46f73jjjvSCSeckGbOnJnOPPPMRW7jsssuS++//376zne+kwNKBL6Fufrqq/O+mNtaa63VbLkexmJfzR2IYh9HGJk1a1Z69NFH009+8pMcBrfddttFlhGAFqoBsERGjx5di4/TkSNHNnt+r732qvXs2XPO8rPPPltbdtlla2PGjGm23iOPPFLr3Llzs+fffffd+bYzduzYWqdOnWrTpk2b89yIESPyto8//vhm606aNCk/f+WVVzZ7/tZbb232/Lhx4/LylClTFvr+Xn311bxOvM/Fcdlll+X1t95669qsWbPmPH/GGWfk52+44YaPfZ8HH3xwbcUVV6y9//77zd5nv3795ixPnTo1v1b37t1r06dPX6xyvfTSS7UJEybkR7zW8OHD8/dXX311fq3zzjtvzs/fe++9Zr9733335XXqjw033LA2ceLExdouAC2jixdAKznkkEOaLcfA6ugyFK0BIVoloutQtJ7UuxrFo3fv3mn99dfP3Y7qoqvV3GNKYr3tttsuzzYVLSDzihaOuUUrS3Qz+/KXv9xsW9G1LFoq6tuqt9jcfPPNafbs2a26P6JVY+6xI1HGzp07pz/96U8LfJ9vv/12LmPst2g9+ve//73IbXz961+f0+qxKGuuuWbaaaed0jbbbJO71EVXuFiOMkUXuChvLMcjlue28cYbpwkTJqTx48fngfUxxscsXgBtQxcvgFYS40XmFtPWhhh3EWMwnnrqqRwwIowsyNyV+eeeey53dbrxxhvnG7fx1ltvNVuOCvbaa6/d7LnYVqwXXcwWJLp2hUGDBuVKfowvOfvss/MsXXvuuWf6xje+kbtMLYl532cEowgJ0YWs7l//+lfuLhVdu+pBbmHvc0GiS93iiPBVf73bbrstz7zVv3//HIhiecstt8wBKR4R7OYdlB/HL4JL2GOPPdJVV12Vv0ZXvs0333yxygDA4hFQAFrJ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YggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAA0LEDygcffJBOPPHE/JVqOAbVcwyq5xhUzzGonmNQPcegeo7B0rX/O9VqtVpLf2nmzJlplVVWSW+99Vbq3r17qxSElnEMqucYVM8xqJ5jUD3HoHqOQfUcg6Vr/+viBQAAFENAAQAAiiGgAAAAHTugLLfccmn06NH5K9VwDKrnGFTPMaieY1A9x6B6jkH1HIOla/9/okHyAAAAbUEXLwAAoBgCCgAAUAwBBQAAKIaAAgAAdOyA8otf/CKts846afnll0+f//zn0/3339/6JWOBxo4dmz73uc+llVdeOa2xxhppzz33TE888UTVxWpYp512WurUqVP63ve+V3VRGs6LL76Yhg0blnr27JlWWGGFtOmmm6YHHnig6mI1hA8//DCNGjUqrbvuunnfr7feeumUU05J5lxpW3fffXf62te+lvr06ZM/d8aPH9/s57H/TzjhhLTmmmvm47LTTjulp556qrLyNtL+nz17djruuOPy59BKK62U1xk+fHh66aWXKi1zo/0NzO2QQw7J65xzzjntWsal3d2LcQwef/zxtPvuu+c7y8ffQ9Rbn3vuubYNKNdee206+uij81RiDz74YNp8883TLrvskqZPn97Sl+ITuOuuu9Jhhx2WJk+enCZMmJA/FHfeeef0zjvvVF20hjNlypR08cUXp80226zqojScN954I22//fapS5cu6ZZbbkmPPfZYOuuss9Jqq61WddEawumnn54uvPDCdMEFF+QTUSyfccYZ6fzzz6+6aEu1+JyPc25cJFyQOAbnnXdeuuiii9Lf/va3XDGI8/P777/f7mVttP3/7rvv5jpRBPf4ev311+eLh1FJo/3+BurGjRuX60lRiaZ9j8EzzzyTBg4cmPr375/uvPPO9M9//jP/XUSjRovUWmjbbbetHXbYYXOWP/zww1qfPn1qY8eObelL0QqmT58elyxrd911V9VFaShvv/12bf31169NmDChNmjQoNqRRx5ZdZEaynHHHVcbOHBg1cVoWLvttltt5MiRzZ7be++9a0OHDq2sTI0mPvfHjRs3Z/mjjz6q9e7du3bmmWfOee7NN9+sLbfccrWrr766olI2zv5fkPvvvz+vN23atHYrVyNZ2DF44YUXamuttVbt0UcfrfXr16929tlnV1K+Rj0G+++/f23YsGFL/NotakGZNWtW+vvf/56bjeuWWWaZvHzfffe1LBnRKt566638tUePHlUXpaFEK9Zuu+3W7G+B9nPjjTembbbZJu277765q+OWW26ZLr300qqL1TC222679Je//CU9+eSTefkf//hHuueee9Kuu+5addEa1tSpU9PLL7/c7DMpuldEN2zn5+rOz9EFZtVVV626KA3jo48+SgceeGA69thj0yabbFJ1cRpy///xj39MG2ywQW69jfNzfAZ9XFe8hWlRQHnttddy3+NevXo1ez6W44OR9v+PEGMfoqvLgAEDqi5Ow7jmmmtyE36MB6Ia//nPf3IXo/XXXz/ddttt6dBDD01HHHFEuuKKK6ouWkM4/vjj0wEHHJCb8KObXQTE+CwaOnRo1UVrWPVzsPNzGaJbXYxJGTJkSOrevXvVxWkY0d20c+fO+XxA+4vhHk1NTXl87le+8pX05z//Oe21115p7733zkMUWqJzm5WSdrmK/+ijj+Yrl7SP559/Ph155JF5/E+L+1PSquE8WlB++tOf5uWoIMffQvS9HzFiRNXFW+r97ne/S1deeWW66qqr8lXKhx9+OAeU6O9t/9PoYmzofvvtlyctiAsptI/o4XPuuefmC4jRckU15+awxx57pKOOOip/v8UWW6R77703n58HDRrUNi0oq6++elp22WXTK6+80uz5WO7du3dLXooldPjhh6ebb745TZw4Ma299tpVF6ehPgDjCsFWW22Vr9LEI64KxMDU+D5aGGl7MUvRxhtv3Oy5jTbaqMWzhPDJRPeJeitKzFoUXSriZKRVsTr1c7DzcxnhZNq0aflCltaT9jNp0qR8fu7bt++c83Mch2OOOSbPPEvbi5wQ+701zs8tCihdu3ZNW2+9de57PHdaiuUvfvGLLdown0xckYlwEjNU3HHHHXmaT9rP4MGD0yOPPJKvGNcfcSU/urbE9xHgaXvRrXHe6bVjPES/fv0qK1MjiRmLYvzh3OL/fv3qGe0vzgURROY+P8+cOTPP5uX83L7hJKZ2vv322/MU6LSfuFASM0bNfX6OVt24oBJdgWl7kRNiSuHWOD+3uItXTDEcTfhRKdt2223z/NIx5dhBBx3U0pfiE3brim4VN9xwQ74XSr1vcQyGjHnvaVuxz+cd7xNTecaJyDig9hNX62OgdnTxigpB3IvpkksuyQ/aXsyBP2bMmHylMrp4PfTQQ+nnP/95GjlyZNVFW6pF3+6nn3662cD4qITFJClxLKKb3amnnprHZkVgiak9o4IW98uibfd/tOrus88+uXtR9G6I1vT6+Tl+HhU32v5vYN5QGGPkIrhvuOGGFZS2MY/Bsccem/bff/+0ww47pB133DHdeuut6aabbspTDrfIJ5n66/zzz6/17du31rVr1zzt8OTJk5d4OjEWTxyyBT0uu+yyqovWsEwzXI2bbrqpNmDAgDyNav/+/WuXXHJJ1UVqGDNnzsz/5+M8sPzyy9c+85nP1H784x/XPvjgg6qLtlSbOHHiAj//R4wYMWeq4VGjRtV69eqV/y4GDx5ce+KJJ6oudkPs/6lTpy70/By/R/v8DczLNMPVHINf//rXtc9+9rP5/LD55pvXxo8f3+LtdIp/Wj9fAQAAtFyL7yQPAADQVgQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAAEil+H91/GLN46PRBQAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "visualize_intervals(nearest_intervals, \"nearest pair\")" ] diff --git a/polars_bio/quality_stats.py b/polars_bio/quality_stats.py index 6cf85c46..c18ec841 100644 --- a/polars_bio/quality_stats.py +++ b/polars_bio/quality_stats.py @@ -4,17 +4,20 @@ import pandas as pd import pyarrow as pa from .context import ctx -from polars_bio.polars_bio import my_scan, my_frame +from polars_bio.polars_bio import ( + base_sequance_quality_scan, + base_sequance_quality_frame, +) def base_sequence_quality(df: Union[str, pl.DataFrame, pl.LazyFrame, pd.DataFrame]): if isinstance(df, str): - supported_exts = set([".parquet", ".csv", ".bed", ".vcf"]) + supported_exts = set([".parquet", ".csv", ".bed", ".vcf", ".fastq"]) ext = set(Path(df).suffixes) assert ( len(supported_exts.intersection(ext)) > 0 or len(ext) == 0 - ), "Dataframe1 must be a Parquet, a BED or CSV or VCF file" - return my_scan(ctx, df) + ), "Dataframe1 must be a Parquet, CSV, BED, VCF, or FASTQ file." + return base_sequance_quality_scan(ctx, df) else: if isinstance(df, pl.DataFrame): df = df.to_arrow().to_reader() @@ -22,4 +25,4 @@ def base_sequence_quality(df: Union[str, pl.DataFrame, pl.LazyFrame, pd.DataFram df = pa.Table.from_pandas(df) elif isinstance(df, pl.LazyFrame): df = df.collect().to_arrow().to_reader() - return my_frame(ctx, df) + return base_sequance_quality_frame(ctx, df) diff --git a/src/context.rs b/src/context.rs index 5f47f30e..afc02d4e 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,6 +1,9 @@ use std::collections::HashMap; +use std::sync::Arc; +use datafusion::arrow::datatypes::DataType; use datafusion::config::ConfigOptions; +use datafusion::logical_expr::{create_udaf, AggregateUDF, Volatility}; use datafusion::prelude::SessionConfig; use exon::config::ExonConfigExtension; use exon::ExonSession; @@ -8,6 +11,8 @@ use log::debug; use pyo3::{pyclass, pymethods, PyResult}; use sequila_core::session_context::SequilaConfig; +use crate::udaf::{base_quality_result_type, QualityScoresStats}; + #[pyclass(name = "BioSessionContext")] // #[derive(Clone)] pub struct PyBioSessionContext { @@ -25,7 +30,7 @@ impl PyBioSessionContext { pub fn new(seed: String, catalog_dir: String) -> PyResult { let ctx = create_context().unwrap(); let session_config: HashMap = HashMap::new(); - + ctx.session.register_udaf(make_base_sequence_quality_udaf()); Ok(PyBioSessionContext { ctx, session_config, @@ -87,3 +92,14 @@ fn create_context() -> exon::Result { ExonSession::with_config_exon(config) } + +pub fn make_base_sequence_quality_udaf() -> AggregateUDF { + create_udaf( + "base_sequence_quality", // nazwa funkcji w SQL + vec![DataType::Utf8], // typ wejściowy + Arc::new(base_quality_result_type()), + Volatility::Immutable, + Arc::new(|_| Ok(Box::new(QualityScoresStats::new()))), + Arc::new(vec![]), + ) +} diff --git a/src/lib.rs b/src/lib.rs index 629a9205..d92eb0c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,12 +4,14 @@ mod option; mod query; mod scan; mod streaming; +mod udaf; mod udtf; mod utils; use std::string::ToString; use std::sync::{Arc, Mutex}; +use arrow::array::*; use datafusion::arrow::ffi_stream::ArrowArrayStreamReader; use datafusion::arrow::pyarrow::PyArrowType; use datafusion::datasource::MemTable; @@ -21,6 +23,8 @@ use polars_lazy::prelude::{LazyFrame, ScanArgsAnonymous}; use polars_python::error::PyPolarsErr; use polars_python::lazyframe::PyLazyFrame; use pyo3::prelude::*; +use pyo3::types::{PyDict, PyList}; +use scan::deregister_table; use tokio::runtime::Runtime; use crate::context::PyBioSessionContext; @@ -32,11 +36,9 @@ use crate::scan::{maybe_register_table, register_frame, register_table}; use crate::streaming::RangeOperationScan; use crate::utils::convert_arrow_rb_schema_to_polars_df_schema; -use pyo3::types::PyString; -use serde_json::Value; - const LEFT_TABLE: &str = "s1"; const RIGHT_TABLE: &str = "s2"; +const DEFAULT_TABLE_NAME: &str = "unnamed_table"; const DEFAULT_COLUMN_NAMES: [&str; 3] = ["contig", "start", "end"]; #[pyfunction] @@ -407,34 +409,128 @@ fn py_from_polars( }) } -#[pyfunction] -#[pyo3(signature = (py_ctx, path))] -fn my_scan(py: Python<'_>, py_ctx: &PyBioSessionContext, path: String) -> PyResult { - let rt = Runtime::new()?; +fn struct_array_to_pydict(py: Python<'_>, struct_array: &StructArray) -> PyResult { + let warn_array = struct_array + .column_by_name("base_quality_warn") + .and_then(|a| a.as_any().downcast_ref::()) + .unwrap(); + + let base_per_pos_array = struct_array + .column_by_name("base_per_pos_data") + .and_then(|a| a.as_any().downcast_ref::()) + .unwrap(); + + let struct_array = base_per_pos_array + .values() + .as_any() + .downcast_ref::() + .unwrap(); + + let mut base_per_pos_data = Vec::new(); + for i in 0..base_per_pos_array.value_length(0) { + let mut row = std::collections::HashMap::new(); + + let pos = struct_array + .column_by_name("pos") + .and_then(|a| a.as_any().downcast_ref::()) + .unwrap() + .value(i as usize); + let average = struct_array + .column_by_name("average") + .and_then(|a| a.as_any().downcast_ref::()) + .unwrap() + .value(i as usize); + let median = struct_array + .column_by_name("median") + .and_then(|a| a.as_any().downcast_ref::()) + .unwrap() + .value(i as usize); + let q1 = struct_array + .column_by_name("q1") + .and_then(|a| a.as_any().downcast_ref::()) + .unwrap() + .value(i as usize); + let q3 = struct_array + .column_by_name("q3") + .and_then(|a| a.as_any().downcast_ref::()) + .unwrap() + .value(i as usize); + let lower = struct_array + .column_by_name("lower") + .and_then(|a| a.as_any().downcast_ref::()) + .unwrap() + .value(i as usize); + let upper = struct_array + .column_by_name("upper") + .and_then(|a| a.as_any().downcast_ref::()) + .unwrap() + .value(i as usize); + + row.insert("pos", pos.into_py(py)); + row.insert("average", average.into_py(py)); + row.insert("median", median.into_py(py)); + row.insert("q1", q1.into_py(py)); + row.insert("q3", q3.into_py(py)); + row.insert("lower", lower.into_py(py)); + row.insert("upper", upper.into_py(py)); + + base_per_pos_data.push(row.into_py(py).to_object(py)); + } + + let result_dict = PyDict::new_bound(py); + result_dict.set_item("base_quality_warn", warn_array.value(0))?; + result_dict.set_item( + "base_per_pos_data", + PyList::new_bound(py, base_per_pos_data), + )?; + + Ok(result_dict.to_object(py)) +} + +fn handle_base_sequence_quality<'a, F>( + py: Python<'a>, + py_ctx: &PyBioSessionContext, + table_name: &str, + register_fn: F, +) -> PyResult +where + F: FnOnce(&PyBioSessionContext, &str, &Runtime), +{ let ctx = &py_ctx.ctx; - let _table = maybe_register_table(path, &LEFT_TABLE.to_string(), None, ctx, &rt); - let result: Value = rt.block_on(do_base_sequence_quality(ctx, LEFT_TABLE.to_string())); + let rt = Runtime::new().unwrap(); + register_fn(py_ctx, table_name, &rt); + let result_opt = rt.block_on(do_base_sequence_quality(ctx, &table_name.to_string())); + deregister_table(ctx, table_name); + if let Some(struct_array) = result_opt { + struct_array_to_pydict(py, &struct_array) + } else { + Ok(py.None()) + } +} - let json_str = serde_json::to_string(&result).unwrap(); - let py_str = PyString::new_bound(py, &json_str); - Ok(py_str.into_py(py)) +#[pyfunction] +#[pyo3(signature = (py_ctx, path))] +fn base_sequance_quality_scan( + py: Python<'_>, + py_ctx: &PyBioSessionContext, + path: String, +) -> PyResult { + handle_base_sequence_quality(py, py_ctx, DEFAULT_TABLE_NAME, |py_ctx, table_name, rt| { + let ctx = &py_ctx.ctx; + maybe_register_table(path, &table_name.to_string(), None, ctx, rt); + }) } #[pyfunction] #[pyo3(signature = (py_ctx, df))] -fn my_frame( +fn base_sequance_quality_frame( py: Python<'_>, py_ctx: &PyBioSessionContext, df: PyArrowType, ) -> PyResult { - let rt = Runtime::new().unwrap(); - let ctx = &py_ctx.ctx; - register_frame(py_ctx, df, LEFT_TABLE.to_string()); - let result: Value = rt.block_on(do_base_sequence_quality(ctx, LEFT_TABLE.to_string())); - - let json_str = serde_json::to_string(&result).unwrap(); - let py_str = PyString::new_bound(py, &json_str); - Ok(py_str.into_py(py)) + handle_base_sequence_quality(py, py_ctx, DEFAULT_TABLE_NAME, |py_ctx, table_name, _rt| { + register_frame(py_ctx, df, table_name.to_string()); + }) } #[pymodule] @@ -451,9 +547,8 @@ fn polars_bio(_py: Python, m: &Bound) -> PyResult<()> { m.add_function(wrap_pyfunction!(py_describe_vcf, m)?)?; m.add_function(wrap_pyfunction!(py_register_view, m)?)?; m.add_function(wrap_pyfunction!(py_from_polars, m)?)?; - m.add_function(wrap_pyfunction!(my_frame, m)?)?; - m.add_function(wrap_pyfunction!(my_scan, m)?)?; - // m.add_function(wrap_pyfunction!(unary_operation_scan, m)?)?; + m.add_function(wrap_pyfunction!(base_sequance_quality_frame, m)?)?; + m.add_function(wrap_pyfunction!(base_sequance_quality_scan, m)?)?; m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/src/operation.rs b/src/operation.rs index 9e5c8cdf..808c55a9 100644 --- a/src/operation.rs +++ b/src/operation.rs @@ -1,10 +1,10 @@ use std::sync::Arc; +use arrow_array::{Array, StructArray}; use datafusion::catalog_common::TableReference; use exon::ExonSession; use log::{debug, info}; use sequila_core::session_context::{Algorithm, SequilaConfig}; -use serde_json::json; use tokio::runtime::Runtime; use crate::context::set_option_internal; @@ -194,134 +194,33 @@ async fn do_count_overlaps_coverage_naive( pub(crate) async fn do_base_sequence_quality( ctx: &ExonSession, - table: String, -) -> serde_json::Value { - let query = format!("SELECT quality_scores FROM {}", table); + table: &String, +) -> Option { + let query = format!( + "SELECT base_sequence_quality(quality_scores) as result FROM {}", + table + ); debug!("Query: {}", query); let batches = ctx.sql(&query).await.unwrap().collect().await.unwrap(); - let mut base_quality_count: std::collections::HashMap> = - std::collections::HashMap::new(); - - use std::any::type_name_of_val; - - for batch in batches { + if let Some(batch) = batches.get(0) { let col_idx = batch .schema() .fields() .iter() - .position(|f| f.name() == "quality_scores") - .expect("Column 'quality_scores' not found"); + .position(|f| f.name() == "result") + .expect("Column 'result' not found"); let array = batch.column(col_idx); - for i in 0..array.len() { - if array.is_null(i) { - continue; - } - let quality_str = if let Some(string_array) = - array.as_any().downcast_ref::() - { - string_array.value(i) - } else if let Some(large_string_array) = array - .as_any() - .downcast_ref::() - { - large_string_array.value(i) - } else if let Some(generic_string_array_i64) = array - .as_any() - .downcast_ref::>( - ) { - generic_string_array_i64.value(i) - } else if let Some(generic_string_array_i32) = array - .as_any() - .downcast_ref::>( - ) { - generic_string_array_i32.value(i) - } else if let Some(string_view_array) = array - .as_any() - .downcast_ref::() - { - string_view_array.value(i) - } else { - panic!( - "Column 'quality_scores' has unsupported array type: {:?} (concrete Rust type: {})", - array.data_type(), - type_name_of_val(array) - ); - }; - - for (pos, qchar) in quality_str.chars().enumerate() { - let qscore = qchar as usize - 33; - let rec = base_quality_count - .entry(pos) - .or_insert_with(|| vec![0_usize; 94]); - if qscore < 94 { - rec[qscore] += 1; - } - } - } - } - fn quartiles(counts: &[usize]) -> Vec { - let mut expanded = Vec::new(); - for (q, &c) in counts.iter().enumerate() { - for _ in 0..c { - expanded.push(q as f32 + 33.0); + if array.len() > 0 && !array.is_null(0) { + if let Some(struct_array) = array.as_any().downcast_ref::() { + return Some(struct_array.clone()); + } else { + panic!("Unsupported result type: {:?}", array.data_type()); } } - if expanded.is_empty() { - return vec![0.0; 5]; - } - expanded.sort_by(|a, b| a.partial_cmp(b).unwrap()); - let n = expanded.len(); - let q = |p: f32| { - let idx = (p * (n - 1) as f32).round() as usize; - expanded[idx] - }; - vec![ - q(0.0), // min - q(0.25), // Q1 - q(0.5), // median - q(0.75), // Q3 - q(1.0), // max - ] - } - - let mut base_quality_warn = "pass"; - let mut base_per_pos_data = Vec::new(); - for (position, qualities) in base_quality_count.iter() { - let (sum, len) = qualities - .iter() - .enumerate() - .fold((0_usize, 0_usize), |(s, l), (q, c)| { - (s + (q + 33) * c, l + c) - }); - let avg = if len > 0 { - sum as f64 / len as f64 - } else { - 0.0 - }; - let values = quartiles(qualities); - let median = values[2]; - if median <= 20.0 { - base_quality_warn = "fail"; - } else if median <= 25.0 && base_quality_warn != "fail" { - base_quality_warn = "warn"; - } - base_per_pos_data.push(json!({ - "pos": position, - "average": avg, - "upper": values[4], - "lower": values[0], - "q1": values[1], - "q3": values[3], - "median": values[2], - })); } - - json!({ - "base_quality_warn": base_quality_warn, - "base_per_pos_data": base_per_pos_data - }) + None } async fn get_non_join_columns( diff --git a/src/scan.rs b/src/scan.rs index 4d5b288e..e7795a99 100644 --- a/src/scan.rs +++ b/src/scan.rs @@ -61,6 +61,8 @@ pub(crate) fn get_input_format(path: &str) -> InputFormat { InputFormat::Bed } else if path.ends_with(".vcf") || path.ends_with(".vcf.gz") || path.ends_with(".vcf.bgz") { InputFormat::Vcf + } else if path.ends_with(".fastq") { + InputFormat::Fastq } else { panic!("Unsupported format") } @@ -154,3 +156,7 @@ pub(crate) fn maybe_register_table( } .to_string() } + +pub(crate) fn deregister_table(ctx: &ExonSession, table_name: &str) { + let _ = ctx.session.deregister_table(table_name); +} diff --git a/src/udaf.rs b/src/udaf.rs new file mode 100644 index 00000000..a26ac237 --- /dev/null +++ b/src/udaf.rs @@ -0,0 +1,210 @@ +use std::collections::HashMap; +use std::sync::Arc; + +use arrow::buffer::OffsetBuffer; +use arrow_array::{Array, ArrayRef, Float64Array, Int64Array, ListArray, StringArray, StructArray}; +use arrow_schema::{DataType, Field, Fields}; +use datafusion::error::{DataFusionError, Result}; +use datafusion::physical_plan::Accumulator; +use datafusion::scalar::ScalarValue; + +#[derive(Debug)] +pub(crate) struct QualityScoresStats { + values_per_pos: HashMap>, // key: position, value: decoded quality scores +} + +impl QualityScoresStats { + pub fn new() -> Self { + Self { + values_per_pos: HashMap::new(), + } + } + + fn decode_score(c: char) -> Option { + let ascii = c as u8; + if ascii >= 33 { + Some(ascii - 33) + } else { + None + } + } + + fn calc_stats(values: &mut Vec) -> (f64, f64, f64, f64, f64, f64) { + values.sort_unstable(); + let n = values.len(); + let average = values.iter().map(|&v| v as f64).sum::() / n as f64; + let median = if n % 2 == 0 { + (values[n / 2 - 1] as f64 + values[n / 2] as f64) / 2.0 + } else { + values[n / 2] as f64 + }; + let q1 = values[n / 4] as f64; + let q3 = values[(3 * n) / 4] as f64; + let iqr = q3 - q1; + let lower = q1 - 1.5 * iqr; + let upper = q3 + 1.5 * iqr; + (average, median, q1, q3, lower, upper) + } +} + +impl Accumulator for QualityScoresStats { + fn state(&mut self) -> Result> { + Ok(vec![]) + } + + fn evaluate(&mut self) -> Result { + #[derive(Default)] + struct StatColumns { + pos: Vec, + avg: Vec, + median: Vec, + q1: Vec, + q3: Vec, + lower: Vec, + upper: Vec, + } + + let mut cols = StatColumns::default(); + let mut base_quality_warn = "pass"; + + for (&pos, values) in &mut self.values_per_pos { + if values.is_empty() { + continue; + } + + let (avg, median, q1, q3, lower, upper) = Self::calc_stats(values); + + cols.pos.push(pos as i64); + cols.avg.push(avg); + cols.median.push(median); + cols.q1.push(q1); + cols.q3.push(q3); + cols.lower.push(lower); + cols.upper.push(upper); + + base_quality_warn = match (q1 <= 20.0, q1 <= 25.0, base_quality_warn) { + (true, _, _) => "fail", + (false, true, "pass") => "warn", + _ => base_quality_warn, + }; + } + + let result_type = base_quality_result_type(); + + let fields = match result_type { + DataType::Struct(ref fields) => fields.clone(), + _ => { + return Err(DataFusionError::Execution( + "Unexpected result type".to_string(), + )) + }, + }; + + let base_quality_warn_field = fields[0].clone(); + let base_per_pos_data_field = fields[1].clone(); + + let base_per_pos_data_element_field = match base_per_pos_data_field.data_type() { + DataType::List(inner_field) => inner_field.as_ref().clone(), + _ => return Err(DataFusionError::Execution("Expected List type".to_string())), + }; + + let struct_fields = match base_per_pos_data_element_field.data_type() { + DataType::Struct(inner_fields) => inner_fields.clone(), + _ => { + return Err(DataFusionError::Execution( + "Expected Struct type inside list".to_string(), + )) + }, + }; + + let to_array = |vec: Vec| Arc::new(Float64Array::from(vec)) as ArrayRef; + + let struct_array = Arc::new(StructArray::new( + struct_fields.clone(), + vec![ + Arc::new(Int64Array::from(cols.pos)) as ArrayRef, + to_array(cols.avg), + to_array(cols.median), + to_array(cols.q1), + to_array(cols.q3), + to_array(cols.lower), + to_array(cols.upper), + ], + None, + )) as ArrayRef; + + let list_array = Arc::new(ListArray::new( + Arc::new(base_per_pos_data_element_field), + OffsetBuffer::new(vec![0, struct_array.len() as i32].into()), + struct_array, + None, + )); + + Ok(ScalarValue::Struct(Arc::new(StructArray::from(vec![ + ( + base_quality_warn_field, + Arc::new(StringArray::from(vec![base_quality_warn])) as ArrayRef, + ), + (base_per_pos_data_field, list_array), + ])))) + } + + fn update_batch(&mut self, values: &[ArrayRef]) -> Result<()> { + let arr = values[0] + .as_any() + .downcast_ref::() + .ok_or_else(|| { + datafusion::error::DataFusionError::Internal("Expected StringArray".to_string()) + })?; + + for i in 0..arr.len() { + if arr.is_null(i) { + continue; + } + let val = arr.value(i); + + for (j, c) in val.chars().enumerate() { + if let Some(decoded) = Self::decode_score(c) { + self.values_per_pos.entry(j).or_default().push(decoded); + } + } + } + + Ok(()) + } + + fn merge_batch(&mut self, _states: &[ArrayRef]) -> Result<()> { + Ok(()) + } + + fn size(&self) -> usize { + std::mem::size_of_val(self) + } +} + +pub fn base_quality_result_type() -> DataType { + let per_pos_fields = Fields::from(vec![ + Field::new("pos", DataType::Int64, false), + Field::new("average", DataType::Float64, false), + Field::new("median", DataType::Float64, false), + Field::new("q1", DataType::Float64, false), + Field::new("q3", DataType::Float64, false), + Field::new("lower", DataType::Float64, false), + Field::new("upper", DataType::Float64, false), + ]); + + let base_per_pos_element_field = Field::new( + "base_per_pos_data_element", + DataType::Struct(per_pos_fields), + false, + ); + + DataType::Struct(Fields::from(vec![ + Field::new("base_quality_warn", DataType::Utf8, false), + Field::new( + "base_per_pos_data", + DataType::List(Arc::new(base_per_pos_element_field)), + false, + ), + ])) +} From 5a64fe13c7219ace43e83997e233d5a1f2169ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20=C5=9Acise=C5=82?= Date: Fri, 30 May 2025 21:46:33 +0200 Subject: [PATCH 3/6] Remove serde_json dependency from Cargo files --- Cargo.lock | 1 - Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2527967b..946f46a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5424,7 +5424,6 @@ dependencies = [ "pyo3-log", "rand", "sequila-core", - "serde_json", "tokio", "tracing", ] diff --git a/Cargo.toml b/Cargo.toml index 919b38d5..47d326b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,4 +43,3 @@ coitrees = "0.4.0" fnv = "1.0.7" async-stream = "0.3.6" rand = "0.8.5" -serde_json = "1.0.140" From dbc09494a94f0e6c4de961aef0396f65dd0e13b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20=C5=9Acise=C5=82?= Date: Tue, 3 Jun 2025 14:47:09 +0200 Subject: [PATCH 4/6] Added examples of using the base_sequence_quality function --- docs/notebooks/base_sequence_quality.ipynb | 4587 ++++++++++++++++++++ 1 file changed, 4587 insertions(+) create mode 100644 docs/notebooks/base_sequence_quality.ipynb diff --git a/docs/notebooks/base_sequence_quality.ipynb b/docs/notebooks/base_sequence_quality.ipynb new file mode 100644 index 00000000..35d8bed5 --- /dev/null +++ b/docs/notebooks/base_sequence_quality.ipynb @@ -0,0 +1,4587 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "83d7ccd7", + "metadata": {}, + "source": [ + "### Import dependencies" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "58b40aa6", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/user/.pyenv/versions/3.12.9/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n", + "INFO:polars_bio:Creating BioSessionContext\n" + ] + } + ], + "source": [ + "import polars_bio as pb\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "id": "2e29cd0a", + "metadata": {}, + "source": [ + "### Usage examples" + ] + }, + { + "cell_type": "markdown", + "id": "f9aedeb9", + "metadata": {}, + "source": [ + "#### Usage example - calling UDAF directly in SQL" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5f6fccf3", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:polars_bio:Table: example registered for path: ./example.fastq\n", + "1rows [00:00, 327.48rows/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'base_quality_warn': 'pass', 'base_per_pos_data': [{'pos': 89, 'average': 32.44, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 84, 'average': 32.415, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 96, 'average': 31.315, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 31, 'average': 38.795, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 49, 'average': 37.21, 'median': 39.0, 'q1': 36.0, 'q3': 40.0, 'lower': 30.0, 'upper': 46.0}, {'pos': 69, 'average': 33.7, 'median': 36.0, 'q1': 34.0, 'q3': 39.0, 'lower': 26.5, 'upper': 46.5}, {'pos': 63, 'average': 36.25, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 65, 'average': 35.995, 'median': 37.0, 'q1': 35.0, 'q3': 39.0, 'lower': 29.0, 'upper': 45.0}, {'pos': 70, 'average': 33.565, 'median': 35.0, 'q1': 34.0, 'q3': 38.0, 'lower': 28.0, 'upper': 44.0}, {'pos': 68, 'average': 35.91, 'median': 36.0, 'q1': 34.0, 'q3': 39.0, 'lower': 26.5, 'upper': 46.5}, {'pos': 55, 'average': 37.55, 'median': 39.0, 'q1': 36.0, 'q3': 40.0, 'lower': 30.0, 'upper': 46.0}, {'pos': 24, 'average': 38.265, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 21, 'average': 38.445, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 60, 'average': 35.985, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 45, 'average': 37.45, 'median': 40.0, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 30, 'average': 38.245, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 20, 'average': 38.625, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 82, 'average': 31.525, 'median': 35.0, 'q1': 33.0, 'q3': 36.0, 'lower': 28.5, 'upper': 40.5}, {'pos': 85, 'average': 32.195, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 35, 'average': 38.385, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 57, 'average': 37.35, 'median': 39.0, 'q1': 36.0, 'q3': 40.0, 'lower': 30.0, 'upper': 46.0}, {'pos': 66, 'average': 35.875, 'median': 37.0, 'q1': 35.0, 'q3': 39.0, 'lower': 29.0, 'upper': 45.0}, {'pos': 74, 'average': 30.83, 'median': 35.0, 'q1': 32.0, 'q3': 37.0, 'lower': 24.5, 'upper': 44.5}, {'pos': 86, 'average': 31.815, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 87, 'average': 31.915, 'median': 35.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 88, 'average': 32.065, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 42, 'average': 37.78, 'median': 40.0, 'q1': 37.0, 'q3': 40.0, 'lower': 32.5, 'upper': 44.5}, {'pos': 51, 'average': 37.53, 'median': 39.0, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 71, 'average': 33.005, 'median': 35.0, 'q1': 33.0, 'q3': 38.0, 'lower': 25.5, 'upper': 45.5}, {'pos': 72, 'average': 33.265, 'median': 35.0, 'q1': 33.0, 'q3': 37.0, 'lower': 27.0, 'upper': 43.0}, {'pos': 90, 'average': 32.275, 'median': 34.5, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 23, 'average': 38.635, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 32, 'average': 38.29, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 11, 'average': 37.71, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 43, 'average': 37.775, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 91, 'average': 32.665, 'median': 35.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 6, 'average': 35.145, 'median': 35.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 67, 'average': 35.96, 'median': 36.5, 'q1': 34.0, 'q3': 39.0, 'lower': 26.5, 'upper': 46.5}, {'pos': 76, 'average': 30.265, 'median': 35.0, 'q1': 31.0, 'q3': 37.0, 'lower': 22.0, 'upper': 46.0}, {'pos': 52, 'average': 37.77, 'median': 39.0, 'q1': 37.0, 'q3': 40.0, 'lower': 32.5, 'upper': 44.5}, {'pos': 73, 'average': 32.68, 'median': 35.0, 'q1': 33.0, 'q3': 37.0, 'lower': 27.0, 'upper': 43.0}, {'pos': 29, 'average': 38.595, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 17, 'average': 38.505, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 53, 'average': 37.845, 'median': 39.0, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 77, 'average': 30.805, 'median': 35.0, 'q1': 30.0, 'q3': 36.0, 'lower': 21.0, 'upper': 45.0}, {'pos': 12, 'average': 37.5, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 37, 'average': 38.0, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 83, 'average': 32.03, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 99, 'average': 31.25, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 48, 'average': 37.61, 'median': 40.0, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 4, 'average': 35.68, 'median': 37.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 56, 'average': 37.59, 'median': 39.0, 'q1': 36.0, 'q3': 40.0, 'lower': 30.0, 'upper': 46.0}, {'pos': 8, 'average': 37.625, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 18, 'average': 38.47, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 38, 'average': 37.64, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 39, 'average': 37.895, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 41, 'average': 37.87, 'median': 40.0, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 19, 'average': 38.425, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 15, 'average': 38.725, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 78, 'average': 31.46, 'median': 35.0, 'q1': 31.0, 'q3': 36.0, 'lower': 23.5, 'upper': 43.5}, {'pos': 62, 'average': 36.145, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 13, 'average': 38.94, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 28, 'average': 38.445, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 93, 'average': 31.05, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 94, 'average': 30.775, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 100, 'average': 31.105, 'median': 34.0, 'q1': 31.0, 'q3': 35.0, 'lower': 25.0, 'upper': 41.0}, {'pos': 64, 'average': 36.095, 'median': 37.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 61, 'average': 35.99, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 44, 'average': 37.565, 'median': 40.0, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 40, 'average': 37.95, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 92, 'average': 31.835, 'median': 35.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 46, 'average': 37.79, 'median': 39.5, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 10, 'average': 37.675, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 36, 'average': 38.11, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 0, 'average': 30.135, 'median': 33.0, 'q1': 31.0, 'q3': 34.0, 'lower': 26.5, 'upper': 38.5}, {'pos': 33, 'average': 38.245, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 26, 'average': 37.855, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 95, 'average': 31.425, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 98, 'average': 31.55, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 81, 'average': 32.76, 'median': 35.0, 'q1': 33.0, 'q3': 36.0, 'lower': 28.5, 'upper': 40.5}, {'pos': 14, 'average': 38.965, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 75, 'average': 31.06, 'median': 35.0, 'q1': 31.0, 'q3': 37.0, 'lower': 22.0, 'upper': 46.0}, {'pos': 5, 'average': 35.095, 'median': 35.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 16, 'average': 38.48, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 3, 'average': 35.69, 'median': 37.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 27, 'average': 38.44, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 54, 'average': 37.59, 'median': 39.5, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 9, 'average': 37.36, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 97, 'average': 30.67, 'median': 34.0, 'q1': 31.0, 'q3': 35.0, 'lower': 25.0, 'upper': 41.0}, {'pos': 7, 'average': 35.4, 'median': 36.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 22, 'average': 38.41, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 47, 'average': 37.665, 'median': 39.0, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 59, 'average': 36.08, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 79, 'average': 32.46, 'median': 35.0, 'q1': 32.0, 'q3': 36.0, 'lower': 26.0, 'upper': 42.0}, {'pos': 50, 'average': 37.425, 'median': 39.0, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 34, 'average': 38.205, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 58, 'average': 36.77, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 25, 'average': 38.2, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 2, 'average': 32.015, 'median': 34.0, 'q1': 31.0, 'q3': 34.0, 'lower': 26.5, 'upper': 38.5}, {'pos': 1, 'average': 31.21, 'median': 34.0, 'q1': 31.0, 'q3': 34.0, 'lower': 26.5, 'upper': 38.5}, {'pos': 80, 'average': 32.61, 'median': 35.0, 'q1': 32.0, 'q3': 36.0, 'lower': 26.0, 'upper': 42.0}]}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", + "result = pb.sql(\"SELECT base_sequence_quality(quality_scores) FROM example\").collect()\n", + "print(result.item())" + ] + }, + { + "cell_type": "markdown", + "id": "b238193d", + "metadata": {}, + "source": [ + "#### Usage example - .fastq file" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0420c240", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'base_quality_warn': 'pass',\n", + " 'base_per_pos_data': [{'lower': 33.5,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0,\n", + " 'median': 40.0,\n", + " 'average': 38.205,\n", + " 'upper': 45.5,\n", + " 'pos': 34},\n", + " {'average': 38.47,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'pos': 18,\n", + " 'upper': 45.5},\n", + " {'q3': 35.0,\n", + " 'average': 31.815,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'pos': 86,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0},\n", + " {'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'pos': 21,\n", + " 'average': 38.445,\n", + " 'q1': 38.0,\n", + " 'median': 40.0},\n", + " {'lower': 27.5,\n", + " 'average': 31.835,\n", + " 'q3': 35.0,\n", + " 'median': 35.0,\n", + " 'q1': 32.0,\n", + " 'upper': 39.5,\n", + " 'pos': 92},\n", + " {'q3': 35.0,\n", + " 'lower': 27.5,\n", + " 'pos': 95,\n", + " 'upper': 39.5,\n", + " 'median': 34.0,\n", + " 'q1': 32.0,\n", + " 'average': 31.425},\n", + " {'average': 35.91,\n", + " 'q3': 39.0,\n", + " 'lower': 26.5,\n", + " 'median': 36.0,\n", + " 'pos': 68,\n", + " 'upper': 46.5,\n", + " 'q1': 34.0},\n", + " {'pos': 61,\n", + " 'average': 35.99,\n", + " 'median': 38.0,\n", + " 'q3': 40.0,\n", + " 'q1': 35.0,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5},\n", + " {'median': 39.0,\n", + " 'lower': 30.0,\n", + " 'upper': 46.0,\n", + " 'average': 37.59,\n", + " 'q1': 36.0,\n", + " 'pos': 56,\n", + " 'q3': 40.0},\n", + " {'q3': 35.0,\n", + " 'upper': 38.0,\n", + " 'q1': 33.0,\n", + " 'pos': 89,\n", + " 'average': 32.44,\n", + " 'median': 35.0,\n", + " 'lower': 30.0},\n", + " {'lower': 35.0,\n", + " 'median': 40.0,\n", + " 'upper': 43.0,\n", + " 'pos': 37,\n", + " 'q1': 38.0,\n", + " 'average': 38.0,\n", + " 'q3': 40.0},\n", + " {'average': 37.71,\n", + " 'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'pos': 11,\n", + " 'lower': 34.0,\n", + " 'q3': 39.0,\n", + " 'upper': 42.0},\n", + " {'average': 32.015,\n", + " 'median': 34.0,\n", + " 'lower': 26.5,\n", + " 'pos': 2,\n", + " 'q1': 31.0,\n", + " 'q3': 34.0,\n", + " 'upper': 38.5},\n", + " {'upper': 41.0,\n", + " 'q1': 31.0,\n", + " 'average': 30.67,\n", + " 'lower': 25.0,\n", + " 'pos': 97,\n", + " 'q3': 35.0,\n", + " 'median': 34.0},\n", + " {'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.595,\n", + " 'upper': 45.5,\n", + " 'pos': 29},\n", + " {'pos': 39,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'q3': 40.0,\n", + " 'q1': 38.0,\n", + " 'median': 40.0,\n", + " 'average': 37.895},\n", + " {'upper': 39.5,\n", + " 'average': 31.25,\n", + " 'median': 34.0,\n", + " 'pos': 99,\n", + " 'q3': 35.0,\n", + " 'q1': 32.0,\n", + " 'lower': 27.5},\n", + " {'average': 37.425,\n", + " 'upper': 48.5,\n", + " 'pos': 50,\n", + " 'q1': 36.0,\n", + " 'lower': 28.5,\n", + " 'q3': 41.0,\n", + " 'median': 39.0},\n", + " {'median': 37.0,\n", + " 'pos': 66,\n", + " 'q3': 39.0,\n", + " 'upper': 45.0,\n", + " 'q1': 35.0,\n", + " 'lower': 29.0,\n", + " 'average': 35.875},\n", + " {'average': 38.94,\n", + " 'pos': 13,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'q1': 32.0,\n", + " 'average': 32.61,\n", + " 'median': 35.0,\n", + " 'pos': 80,\n", + " 'q3': 36.0,\n", + " 'lower': 26.0,\n", + " 'upper': 42.0},\n", + " {'lower': 27.5,\n", + " 'q1': 35.0,\n", + " 'upper': 47.5,\n", + " 'median': 38.0,\n", + " 'pos': 59,\n", + " 'average': 36.08,\n", + " 'q3': 40.0},\n", + " {'average': 31.55,\n", + " 'q3': 35.0,\n", + " 'pos': 98,\n", + " 'lower': 27.5,\n", + " 'median': 34.0,\n", + " 'upper': 39.5,\n", + " 'q1': 32.0},\n", + " {'average': 38.505,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 17,\n", + " 'median': 40.0,\n", + " 'q3': 41.0},\n", + " {'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'pos': 20,\n", + " 'lower': 33.5,\n", + " 'average': 38.625,\n", + " 'q1': 38.0},\n", + " {'upper': 47.0,\n", + " 'average': 37.87,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'q1': 37.0,\n", + " 'lower': 31.0,\n", + " 'pos': 41},\n", + " {'q1': 38.0,\n", + " 'upper': 43.0,\n", + " 'lower': 35.0,\n", + " 'average': 37.775,\n", + " 'median': 40.0,\n", + " 'q3': 40.0,\n", + " 'pos': 43},\n", + " {'q1': 33.0,\n", + " 'average': 33.265,\n", + " 'pos': 72,\n", + " 'median': 35.0,\n", + " 'lower': 27.0,\n", + " 'upper': 43.0,\n", + " 'q3': 37.0},\n", + " {'median': 35.0,\n", + " 'average': 31.525,\n", + " 'q1': 33.0,\n", + " 'q3': 36.0,\n", + " 'pos': 82,\n", + " 'upper': 40.5,\n", + " 'lower': 28.5},\n", + " {'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'pos': 8,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'average': 37.625,\n", + " 'upper': 42.0},\n", + " {'median': 39.0,\n", + " 'q3': 39.0,\n", + " 'upper': 42.0,\n", + " 'lower': 34.0,\n", + " 'average': 37.5,\n", + " 'q1': 37.0,\n", + " 'pos': 12},\n", + " {'pos': 40,\n", + " 'lower': 35.0,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'upper': 43.0,\n", + " 'average': 37.95,\n", + " 'q3': 40.0},\n", + " {'q1': 36.0,\n", + " 'median': 39.0,\n", + " 'lower': 30.0,\n", + " 'q3': 40.0,\n", + " 'average': 37.35,\n", + " 'pos': 57,\n", + " 'upper': 46.0},\n", + " {'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'pos': 7,\n", + " 'q3': 37.0,\n", + " 'median': 36.0,\n", + " 'q1': 35.0,\n", + " 'average': 35.4},\n", + " {'median': 35.0,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'average': 32.03,\n", + " 'pos': 83,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0},\n", + " {'pos': 6,\n", + " 'q3': 37.0,\n", + " 'q1': 35.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'median': 35.0,\n", + " 'average': 35.145},\n", + " {'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'median': 39.0,\n", + " 'upper': 42.0,\n", + " 'average': 37.675,\n", + " 'q1': 37.0,\n", + " 'pos': 10},\n", + " {'q1': 31.0,\n", + " 'q3': 34.0,\n", + " 'median': 33.0,\n", + " 'lower': 26.5,\n", + " 'pos': 0,\n", + " 'average': 30.135,\n", + " 'upper': 38.5},\n", + " {'pos': 1,\n", + " 'lower': 26.5,\n", + " 'average': 31.21,\n", + " 'q3': 34.0,\n", + " 'q1': 31.0,\n", + " 'median': 34.0,\n", + " 'upper': 38.5},\n", + " {'upper': 47.5,\n", + " 'average': 36.095,\n", + " 'q1': 35.0,\n", + " 'pos': 64,\n", + " 'median': 37.0,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5},\n", + " {'average': 37.55,\n", + " 'q3': 40.0,\n", + " 'pos': 55,\n", + " 'lower': 30.0,\n", + " 'q1': 36.0,\n", + " 'median': 39.0,\n", + " 'upper': 46.0},\n", + " {'average': 30.83,\n", + " 'q3': 37.0,\n", + " 'lower': 24.5,\n", + " 'upper': 44.5,\n", + " 'q1': 32.0,\n", + " 'median': 35.0,\n", + " 'pos': 74},\n", + " {'lower': 28.5,\n", + " 'upper': 48.5,\n", + " 'average': 37.61,\n", + " 'pos': 48,\n", + " 'q1': 36.0,\n", + " 'median': 40.0,\n", + " 'q3': 41.0},\n", + " {'pos': 23,\n", + " 'q1': 38.0,\n", + " 'average': 38.635,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'upper': 45.5},\n", + " {'pos': 32,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'average': 38.29,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0},\n", + " {'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'pos': 38,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'average': 37.64},\n", + " {'pos': 16,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5,\n", + " 'average': 38.48,\n", + " 'q3': 41.0,\n", + " 'median': 40.0},\n", + " {'median': 39.0,\n", + " 'upper': 42.0,\n", + " 'q1': 37.0,\n", + " 'pos': 9,\n", + " 'q3': 39.0,\n", + " 'average': 37.36,\n", + " 'lower': 34.0},\n", + " {'upper': 43.0,\n", + " 'average': 38.11,\n", + " 'q3': 40.0,\n", + " 'pos': 36,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'lower': 35.0},\n", + " {'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'average': 37.855,\n", + " 'pos': 26},\n", + " {'upper': 46.0,\n", + " 'pos': 75,\n", + " 'q1': 31.0,\n", + " 'average': 31.06,\n", + " 'median': 35.0,\n", + " 'lower': 22.0,\n", + " 'q3': 37.0},\n", + " {'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'lower': 33.5,\n", + " 'pos': 24,\n", + " 'average': 38.265},\n", + " {'pos': 30,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'upper': 43.0,\n", + " 'lower': 35.0,\n", + " 'average': 38.245},\n", + " {'pos': 69,\n", + " 'q1': 34.0,\n", + " 'q3': 39.0,\n", + " 'lower': 26.5,\n", + " 'upper': 46.5,\n", + " 'average': 33.7,\n", + " 'median': 36.0},\n", + " {'pos': 77,\n", + " 'q1': 30.0,\n", + " 'q3': 36.0,\n", + " 'lower': 21.0,\n", + " 'upper': 45.0,\n", + " 'median': 35.0,\n", + " 'average': 30.805},\n", + " {'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'pos': 28,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.445},\n", + " {'q1': 38.0,\n", + " 'average': 38.44,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 27},\n", + " {'q3': 37.0,\n", + " 'pos': 3,\n", + " 'average': 35.69,\n", + " 'q1': 35.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'median': 37.0},\n", + " {'median': 36.5,\n", + " 'lower': 26.5,\n", + " 'upper': 46.5,\n", + " 'average': 35.96,\n", + " 'q3': 39.0,\n", + " 'pos': 67,\n", + " 'q1': 34.0},\n", + " {'q3': 38.0,\n", + " 'lower': 28.0,\n", + " 'upper': 44.0,\n", + " 'average': 33.565,\n", + " 'median': 35.0,\n", + " 'pos': 70,\n", + " 'q1': 34.0},\n", + " {'upper': 39.5,\n", + " 'lower': 27.5,\n", + " 'pos': 87,\n", + " 'median': 35.0,\n", + " 'average': 31.915,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0},\n", + " {'lower': 30.0,\n", + " 'pos': 88,\n", + " 'average': 32.065,\n", + " 'upper': 38.0,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0},\n", + " {'q3': 35.0,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'median': 34.0,\n", + " 'average': 31.05,\n", + " 'q1': 32.0,\n", + " 'pos': 93},\n", + " {'upper': 47.0,\n", + " 'median': 39.5,\n", + " 'q3': 41.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.79,\n", + " 'lower': 31.0,\n", + " 'pos': 46},\n", + " {'pos': 96,\n", + " 'average': 31.315,\n", + " 'median': 34.0,\n", + " 'q1': 32.0,\n", + " 'upper': 39.5,\n", + " 'lower': 27.5,\n", + " 'q3': 35.0},\n", + " {'average': 31.105,\n", + " 'upper': 41.0,\n", + " 'pos': 100,\n", + " 'median': 34.0,\n", + " 'q1': 31.0,\n", + " 'q3': 35.0,\n", + " 'lower': 25.0},\n", + " {'q3': 37.0,\n", + " 'average': 32.68,\n", + " 'q1': 33.0,\n", + " 'pos': 73,\n", + " 'lower': 27.0,\n", + " 'upper': 43.0,\n", + " 'median': 35.0},\n", + " {'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.2,\n", + " 'upper': 45.5,\n", + " 'pos': 25,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0},\n", + " {'upper': 47.0,\n", + " 'q3': 41.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.845,\n", + " 'median': 39.0,\n", + " 'pos': 53,\n", + " 'lower': 31.0},\n", + " {'q3': 39.0,\n", + " 'upper': 45.0,\n", + " 'lower': 29.0,\n", + " 'pos': 65,\n", + " 'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'average': 35.995},\n", + " {'upper': 38.0,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'lower': 30.0,\n", + " 'q3': 35.0,\n", + " 'pos': 84,\n", + " 'average': 32.415},\n", + " {'median': 39.5,\n", + " 'pos': 54,\n", + " 'q1': 36.0,\n", + " 'upper': 48.5,\n", + " 'average': 37.59,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5},\n", + " {'average': 37.77,\n", + " 'q1': 37.0,\n", + " 'lower': 32.5,\n", + " 'upper': 44.5,\n", + " 'q3': 40.0,\n", + " 'pos': 52,\n", + " 'median': 39.0},\n", + " {'upper': 47.5,\n", + " 'pos': 58,\n", + " 'median': 38.0,\n", + " 'average': 36.77,\n", + " 'q1': 35.0,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5},\n", + " {'average': 36.25,\n", + " 'q3': 40.0,\n", + " 'q1': 35.0,\n", + " 'lower': 27.5,\n", + " 'median': 38.0,\n", + " 'pos': 63,\n", + " 'upper': 47.5},\n", + " {'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 15,\n", + " 'average': 38.725,\n", + " 'median': 40.0},\n", + " {'pos': 94,\n", + " 'q3': 35.0,\n", + " 'q1': 32.0,\n", + " 'upper': 39.5,\n", + " 'average': 30.775,\n", + " 'median': 34.0,\n", + " 'lower': 27.5},\n", + " {'median': 39.0,\n", + " 'q1': 36.0,\n", + " 'q3': 41.0,\n", + " 'pos': 51,\n", + " 'lower': 28.5,\n", + " 'upper': 48.5,\n", + " 'average': 37.53},\n", + " {'q1': 33.0,\n", + " 'upper': 40.5,\n", + " 'median': 35.0,\n", + " 'average': 32.76,\n", + " 'pos': 81,\n", + " 'lower': 28.5,\n", + " 'q3': 36.0},\n", + " {'average': 37.78,\n", + " 'q3': 40.0,\n", + " 'lower': 32.5,\n", + " 'median': 40.0,\n", + " 'upper': 44.5,\n", + " 'pos': 42,\n", + " 'q1': 37.0},\n", + " {'upper': 42.0,\n", + " 'q1': 32.0,\n", + " 'lower': 26.0,\n", + " 'median': 35.0,\n", + " 'pos': 79,\n", + " 'average': 32.46,\n", + " 'q3': 36.0},\n", + " {'q1': 36.0,\n", + " 'pos': 49,\n", + " 'average': 37.21,\n", + " 'lower': 30.0,\n", + " 'upper': 46.0,\n", + " 'median': 39.0,\n", + " 'q3': 40.0},\n", + " {'upper': 47.5,\n", + " 'pos': 62,\n", + " 'q1': 35.0,\n", + " 'q3': 40.0,\n", + " 'median': 38.0,\n", + " 'lower': 27.5,\n", + " 'average': 36.145},\n", + " {'q3': 36.0,\n", + " 'average': 31.46,\n", + " 'pos': 78,\n", + " 'median': 35.0,\n", + " 'lower': 23.5,\n", + " 'upper': 43.5,\n", + " 'q1': 31.0},\n", + " {'median': 40.0,\n", + " 'average': 38.245,\n", + " 'q3': 41.0,\n", + " 'pos': 33,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0},\n", + " {'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5,\n", + " 'pos': 14,\n", + " 'average': 38.965,\n", + " 'median': 40.0},\n", + " {'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.41,\n", + " 'upper': 45.5,\n", + " 'pos': 22},\n", + " {'q3': 35.0,\n", + " 'median': 34.5,\n", + " 'upper': 38.0,\n", + " 'pos': 90,\n", + " 'q1': 33.0,\n", + " 'lower': 30.0,\n", + " 'average': 32.275},\n", + " {'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'pos': 19,\n", + " 'average': 38.425,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5},\n", + " {'average': 38.385,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5,\n", + " 'pos': 35,\n", + " 'q3': 41.0},\n", + " {'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'average': 38.795,\n", + " 'pos': 31,\n", + " 'median': 40.0},\n", + " {'upper': 48.5,\n", + " 'pos': 45,\n", + " 'average': 37.45,\n", + " 'median': 40.0,\n", + " 'q1': 36.0,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5},\n", + " {'upper': 46.0,\n", + " 'pos': 76,\n", + " 'q1': 31.0,\n", + " 'median': 35.0,\n", + " 'q3': 37.0,\n", + " 'average': 30.265,\n", + " 'lower': 22.0},\n", + " {'pos': 44,\n", + " 'q1': 37.0,\n", + " 'upper': 47.0,\n", + " 'average': 37.565,\n", + " 'lower': 31.0,\n", + " 'q3': 41.0,\n", + " 'median': 40.0},\n", + " {'upper': 45.5,\n", + " 'q3': 38.0,\n", + " 'q1': 33.0,\n", + " 'lower': 25.5,\n", + " 'median': 35.0,\n", + " 'average': 33.005,\n", + " 'pos': 71},\n", + " {'pos': 47,\n", + " 'average': 37.665,\n", + " 'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'q3': 41.0},\n", + " {'q3': 37.0,\n", + " 'pos': 5,\n", + " 'average': 35.095,\n", + " 'median': 35.0,\n", + " 'q1': 35.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0},\n", + " {'pos': 4,\n", + " 'average': 35.68,\n", + " 'median': 37.0,\n", + " 'q3': 37.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'q1': 35.0},\n", + " {'upper': 47.5,\n", + " 'pos': 60,\n", + " 'median': 38.0,\n", + " 'average': 35.985,\n", + " 'q1': 35.0,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5},\n", + " {'q1': 32.0,\n", + " 'average': 32.665,\n", + " 'q3': 35.0,\n", + " 'lower': 27.5,\n", + " 'median': 35.0,\n", + " 'pos': 91,\n", + " 'upper': 39.5},\n", + " {'average': 32.195,\n", + " 'median': 35.0,\n", + " 'pos': 85,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0}]}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pb.base_sequence_quality(\"example.fastq\")" + ] + }, + { + "cell_type": "markdown", + "id": "9886c394", + "metadata": {}, + "source": [ + "#### Usage example - .csv file" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "66c3af24", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'base_quality_warn': 'pass',\n", + " 'base_per_pos_data': [{'average': 32.195,\n", + " 'pos': 85,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'median': 35.0,\n", + " 'q1': 33.0},\n", + " {'average': 38.245,\n", + " 'median': 40.0,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'pos': 30,\n", + " 'upper': 43.0,\n", + " 'q1': 38.0},\n", + " {'pos': 2,\n", + " 'average': 32.015,\n", + " 'q3': 34.0,\n", + " 'lower': 26.5,\n", + " 'upper': 38.5,\n", + " 'q1': 31.0,\n", + " 'median': 34.0},\n", + " {'lower': 30.0,\n", + " 'pos': 89,\n", + " 'upper': 38.0,\n", + " 'average': 32.44,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0},\n", + " {'q3': 39.0,\n", + " 'average': 37.5,\n", + " 'q1': 37.0,\n", + " 'pos': 12,\n", + " 'median': 39.0,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0},\n", + " {'median': 40.0,\n", + " 'pos': 23,\n", + " 'lower': 33.5,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5,\n", + " 'average': 38.635},\n", + " {'average': 38.595,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'pos': 29,\n", + " 'upper': 45.5},\n", + " {'average': 37.35,\n", + " 'pos': 57,\n", + " 'q1': 36.0,\n", + " 'median': 39.0,\n", + " 'lower': 30.0,\n", + " 'upper': 46.0,\n", + " 'q3': 40.0},\n", + " {'pos': 56,\n", + " 'average': 37.59,\n", + " 'upper': 46.0,\n", + " 'median': 39.0,\n", + " 'q1': 36.0,\n", + " 'q3': 40.0,\n", + " 'lower': 30.0},\n", + " {'average': 36.08,\n", + " 'q3': 40.0,\n", + " 'q1': 35.0,\n", + " 'median': 38.0,\n", + " 'upper': 47.5,\n", + " 'pos': 59,\n", + " 'lower': 27.5},\n", + " {'q1': 32.0,\n", + " 'median': 35.0,\n", + " 'average': 31.835,\n", + " 'q3': 35.0,\n", + " 'pos': 92,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5},\n", + " {'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 24,\n", + " 'median': 40.0,\n", + " 'average': 38.265,\n", + " 'q1': 38.0},\n", + " {'lower': 30.0,\n", + " 'upper': 46.0,\n", + " 'pos': 49,\n", + " 'median': 39.0,\n", + " 'average': 37.21,\n", + " 'q1': 36.0,\n", + " 'q3': 40.0},\n", + " {'upper': 38.0,\n", + " 'pos': 90,\n", + " 'q1': 33.0,\n", + " 'average': 32.275,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'median': 34.5},\n", + " {'q1': 34.0,\n", + " 'pos': 70,\n", + " 'lower': 28.0,\n", + " 'average': 33.565,\n", + " 'median': 35.0,\n", + " 'q3': 38.0,\n", + " 'upper': 44.0},\n", + " {'upper': 45.5,\n", + " 'pos': 27,\n", + " 'q1': 38.0,\n", + " 'average': 38.44,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5},\n", + " {'upper': 42.0,\n", + " 'average': 37.675,\n", + " 'q3': 39.0,\n", + " 'pos': 10,\n", + " 'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'lower': 34.0},\n", + " {'q1': 32.0,\n", + " 'upper': 39.5,\n", + " 'q3': 35.0,\n", + " 'pos': 98,\n", + " 'average': 31.55,\n", + " 'lower': 27.5,\n", + " 'median': 34.0},\n", + " {'median': 40.0,\n", + " 'pos': 13,\n", + " 'average': 38.94,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0},\n", + " {'upper': 43.0,\n", + " 'q3': 40.0,\n", + " 'median': 40.0,\n", + " 'pos': 21,\n", + " 'average': 38.445,\n", + " 'q1': 38.0,\n", + " 'lower': 35.0},\n", + " {'lower': 27.5,\n", + " 'median': 34.0,\n", + " 'pos': 99,\n", + " 'average': 31.25,\n", + " 'q3': 35.0,\n", + " 'q1': 32.0,\n", + " 'upper': 39.5},\n", + " {'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'pos': 31,\n", + " 'average': 38.795,\n", + " 'q1': 38.0,\n", + " 'median': 40.0},\n", + " {'average': 37.855,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'pos': 26,\n", + " 'q3': 40.0,\n", + " 'q1': 38.0,\n", + " 'median': 40.0},\n", + " {'pos': 33,\n", + " 'upper': 45.5,\n", + " 'average': 38.245,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'median': 40.0},\n", + " {'average': 37.665,\n", + " 'pos': 47,\n", + " 'q3': 41.0,\n", + " 'lower': 31.0,\n", + " 'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'upper': 47.0},\n", + " {'average': 38.505,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 17,\n", + " 'median': 40.0},\n", + " {'q3': 40.0,\n", + " 'median': 39.0,\n", + " 'upper': 44.5,\n", + " 'average': 37.77,\n", + " 'pos': 52,\n", + " 'q1': 37.0,\n", + " 'lower': 32.5},\n", + " {'q3': 35.0,\n", + " 'upper': 39.5,\n", + " 'median': 35.0,\n", + " 'q1': 32.0,\n", + " 'lower': 27.5,\n", + " 'pos': 87,\n", + " 'average': 31.915},\n", + " {'upper': 48.5,\n", + " 'pos': 48,\n", + " 'q3': 41.0,\n", + " 'average': 37.61,\n", + " 'q1': 36.0,\n", + " 'median': 40.0,\n", + " 'lower': 28.5},\n", + " {'median': 40.0,\n", + " 'upper': 43.0,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'q1': 38.0,\n", + " 'average': 37.895,\n", + " 'pos': 39},\n", + " {'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'average': 38.2,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'pos': 25,\n", + " 'median': 40.0},\n", + " {'pos': 63,\n", + " 'q1': 35.0,\n", + " 'average': 36.25,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'median': 38.0},\n", + " {'pos': 80,\n", + " 'average': 32.61,\n", + " 'upper': 42.0,\n", + " 'q1': 32.0,\n", + " 'median': 35.0,\n", + " 'q3': 36.0,\n", + " 'lower': 26.0},\n", + " {'q3': 41.0,\n", + " 'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'q1': 37.0,\n", + " 'median': 39.0,\n", + " 'average': 37.845,\n", + " 'pos': 53},\n", + " {'upper': 45.5,\n", + " 'pos': 16,\n", + " 'median': 40.0,\n", + " 'average': 38.48,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5},\n", + " {'q1': 38.0,\n", + " 'pos': 14,\n", + " 'average': 38.965,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'pos': 55,\n", + " 'q3': 40.0,\n", + " 'median': 39.0,\n", + " 'lower': 30.0,\n", + " 'q1': 36.0,\n", + " 'upper': 46.0,\n", + " 'average': 37.55},\n", + " {'average': 37.78,\n", + " 'median': 40.0,\n", + " 'q3': 40.0,\n", + " 'pos': 42,\n", + " 'q1': 37.0,\n", + " 'lower': 32.5,\n", + " 'upper': 44.5},\n", + " {'average': 37.425,\n", + " 'q1': 36.0,\n", + " 'upper': 48.5,\n", + " 'pos': 50,\n", + " 'median': 39.0,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5},\n", + " {'lower': 25.0,\n", + " 'upper': 41.0,\n", + " 'q1': 31.0,\n", + " 'average': 31.105,\n", + " 'median': 34.0,\n", + " 'q3': 35.0,\n", + " 'pos': 100},\n", + " {'upper': 38.5,\n", + " 'q1': 31.0,\n", + " 'q3': 34.0,\n", + " 'lower': 26.5,\n", + " 'average': 30.135,\n", + " 'median': 33.0,\n", + " 'pos': 0},\n", + " {'lower': 26.5,\n", + " 'q1': 31.0,\n", + " 'median': 34.0,\n", + " 'upper': 38.5,\n", + " 'pos': 1,\n", + " 'q3': 34.0,\n", + " 'average': 31.21},\n", + " {'q3': 37.0,\n", + " 'q1': 32.0,\n", + " 'upper': 44.5,\n", + " 'pos': 74,\n", + " 'average': 30.83,\n", + " 'median': 35.0,\n", + " 'lower': 24.5},\n", + " {'upper': 38.0,\n", + " 'q3': 35.0,\n", + " 'median': 35.0,\n", + " 'pos': 84,\n", + " 'average': 32.415,\n", + " 'q1': 33.0,\n", + " 'lower': 30.0},\n", + " {'median': 35.0,\n", + " 'q1': 35.0,\n", + " 'q3': 37.0,\n", + " 'lower': 32.0,\n", + " 'average': 35.095,\n", + " 'pos': 5,\n", + " 'upper': 40.0},\n", + " {'pos': 3,\n", + " 'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'q3': 37.0,\n", + " 'lower': 32.0,\n", + " 'average': 35.69,\n", + " 'upper': 40.0},\n", + " {'pos': 40,\n", + " 'q1': 38.0,\n", + " 'average': 37.95,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'median': 40.0,\n", + " 'upper': 43.0},\n", + " {'pos': 58,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'median': 38.0,\n", + " 'q1': 35.0,\n", + " 'average': 36.77},\n", + " {'median': 37.0,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5,\n", + " 'q1': 35.0,\n", + " 'upper': 47.5,\n", + " 'pos': 64,\n", + " 'average': 36.095},\n", + " {'pos': 41,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.87},\n", + " {'average': 35.99,\n", + " 'median': 38.0,\n", + " 'q1': 35.0,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'pos': 61},\n", + " {'q3': 39.0,\n", + " 'median': 39.0,\n", + " 'average': 37.625,\n", + " 'pos': 8,\n", + " 'lower': 34.0,\n", + " 'q1': 37.0,\n", + " 'upper': 42.0},\n", + " {'upper': 48.5,\n", + " 'q3': 41.0,\n", + " 'average': 37.45,\n", + " 'pos': 45,\n", + " 'q1': 36.0,\n", + " 'median': 40.0,\n", + " 'lower': 28.5},\n", + " {'pos': 71,\n", + " 'average': 33.005,\n", + " 'q1': 33.0,\n", + " 'median': 35.0,\n", + " 'upper': 45.5,\n", + " 'lower': 25.5,\n", + " 'q3': 38.0},\n", + " {'median': 35.0,\n", + " 'average': 32.03,\n", + " 'pos': 83,\n", + " 'q1': 33.0,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'q3': 35.0},\n", + " {'pos': 36,\n", + " 'upper': 43.0,\n", + " 'median': 40.0,\n", + " 'average': 38.11,\n", + " 'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0},\n", + " {'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'pos': 86,\n", + " 'q1': 33.0,\n", + " 'average': 31.815,\n", + " 'q3': 35.0,\n", + " 'median': 35.0},\n", + " {'lower': 35.0,\n", + " 'pos': 37,\n", + " 'upper': 43.0,\n", + " 'q3': 40.0,\n", + " 'q1': 38.0,\n", + " 'average': 38.0,\n", + " 'median': 40.0},\n", + " {'lower': 34.0,\n", + " 'upper': 42.0,\n", + " 'average': 37.36,\n", + " 'q3': 39.0,\n", + " 'q1': 37.0,\n", + " 'median': 39.0,\n", + " 'pos': 9},\n", + " {'q3': 36.0,\n", + " 'lower': 28.5,\n", + " 'median': 35.0,\n", + " 'upper': 40.5,\n", + " 'q1': 33.0,\n", + " 'average': 32.76,\n", + " 'pos': 81},\n", + " {'pos': 38,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'average': 37.64,\n", + " 'q1': 38.0,\n", + " 'median': 40.0},\n", + " {'average': 32.065,\n", + " 'q3': 35.0,\n", + " 'upper': 38.0,\n", + " 'lower': 30.0,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'pos': 88},\n", + " {'average': 31.525,\n", + " 'q3': 36.0,\n", + " 'pos': 82,\n", + " 'lower': 28.5,\n", + " 'median': 35.0,\n", + " 'upper': 40.5,\n", + " 'q1': 33.0},\n", + " {'pos': 91,\n", + " 'average': 32.665,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0,\n", + " 'median': 35.0,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5},\n", + " {'q1': 34.0,\n", + " 'q3': 39.0,\n", + " 'pos': 69,\n", + " 'upper': 46.5,\n", + " 'lower': 26.5,\n", + " 'median': 36.0,\n", + " 'average': 33.7},\n", + " {'median': 35.0,\n", + " 'lower': 27.0,\n", + " 'average': 32.68,\n", + " 'pos': 73,\n", + " 'q1': 33.0,\n", + " 'q3': 37.0,\n", + " 'upper': 43.0},\n", + " {'q1': 36.0,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5,\n", + " 'average': 37.53,\n", + " 'upper': 48.5,\n", + " 'pos': 51,\n", + " 'median': 39.0},\n", + " {'pos': 43,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'average': 37.775},\n", + " {'q3': 39.0,\n", + " 'median': 39.0,\n", + " 'pos': 11,\n", + " 'upper': 42.0,\n", + " 'lower': 34.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.71},\n", + " {'q1': 38.0,\n", + " 'pos': 28,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.445,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5},\n", + " {'average': 38.47,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'pos': 18,\n", + " 'median': 40.0},\n", + " {'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'pos': 44,\n", + " 'q1': 37.0,\n", + " 'average': 37.565,\n", + " 'upper': 47.0,\n", + " 'lower': 31.0},\n", + " {'q1': 35.0,\n", + " 'pos': 6,\n", + " 'q3': 37.0,\n", + " 'median': 35.0,\n", + " 'upper': 40.0,\n", + " 'average': 35.145,\n", + " 'lower': 32.0},\n", + " {'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 35,\n", + " 'q1': 38.0,\n", + " 'average': 38.385},\n", + " {'pos': 60,\n", + " 'lower': 27.5,\n", + " 'median': 38.0,\n", + " 'average': 35.985,\n", + " 'upper': 47.5,\n", + " 'q1': 35.0,\n", + " 'q3': 40.0},\n", + " {'q3': 37.0,\n", + " 'average': 35.4,\n", + " 'q1': 35.0,\n", + " 'median': 36.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'pos': 7},\n", + " {'q3': 37.0,\n", + " 'lower': 27.0,\n", + " 'upper': 43.0,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'pos': 72,\n", + " 'average': 33.265},\n", + " {'average': 30.265,\n", + " 'pos': 76,\n", + " 'median': 35.0,\n", + " 'q3': 37.0,\n", + " 'lower': 22.0,\n", + " 'upper': 46.0,\n", + " 'q1': 31.0},\n", + " {'q1': 35.0,\n", + " 'average': 35.875,\n", + " 'q3': 39.0,\n", + " 'upper': 45.0,\n", + " 'pos': 66,\n", + " 'lower': 29.0,\n", + " 'median': 37.0},\n", + " {'average': 36.145,\n", + " 'pos': 62,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5,\n", + " 'q1': 35.0,\n", + " 'upper': 47.5,\n", + " 'median': 38.0},\n", + " {'pos': 93,\n", + " 'median': 34.0,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0,\n", + " 'average': 31.05},\n", + " {'average': 35.68,\n", + " 'median': 37.0,\n", + " 'q3': 37.0,\n", + " 'upper': 40.0,\n", + " 'lower': 32.0,\n", + " 'pos': 4,\n", + " 'q1': 35.0},\n", + " {'pos': 46,\n", + " 'lower': 31.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.79,\n", + " 'q3': 41.0,\n", + " 'median': 39.5,\n", + " 'upper': 47.0},\n", + " {'pos': 20,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'average': 38.625,\n", + " 'q1': 38.0},\n", + " {'q1': 36.0,\n", + " 'upper': 48.5,\n", + " 'pos': 54,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5,\n", + " 'average': 37.59,\n", + " 'median': 39.5},\n", + " {'pos': 95,\n", + " 'q3': 35.0,\n", + " 'q1': 32.0,\n", + " 'average': 31.425,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'median': 34.0},\n", + " {'upper': 42.0,\n", + " 'lower': 26.0,\n", + " 'pos': 79,\n", + " 'q3': 36.0,\n", + " 'average': 32.46,\n", + " 'median': 35.0,\n", + " 'q1': 32.0},\n", + " {'average': 31.46,\n", + " 'lower': 23.5,\n", + " 'q3': 36.0,\n", + " 'pos': 78,\n", + " 'q1': 31.0,\n", + " 'upper': 43.5,\n", + " 'median': 35.0},\n", + " {'q1': 32.0,\n", + " 'lower': 27.5,\n", + " 'median': 34.0,\n", + " 'average': 30.775,\n", + " 'pos': 94,\n", + " 'q3': 35.0,\n", + " 'upper': 39.5},\n", + " {'q3': 35.0,\n", + " 'lower': 27.5,\n", + " 'q1': 32.0,\n", + " 'upper': 39.5,\n", + " 'pos': 96,\n", + " 'average': 31.315,\n", + " 'median': 34.0},\n", + " {'pos': 75,\n", + " 'average': 31.06,\n", + " 'q1': 31.0,\n", + " 'q3': 37.0,\n", + " 'lower': 22.0,\n", + " 'upper': 46.0,\n", + " 'median': 35.0},\n", + " {'q3': 39.0,\n", + " 'pos': 67,\n", + " 'lower': 26.5,\n", + " 'upper': 46.5,\n", + " 'median': 36.5,\n", + " 'average': 35.96,\n", + " 'q1': 34.0},\n", + " {'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'pos': 19,\n", + " 'average': 38.425,\n", + " 'q1': 38.0},\n", + " {'average': 38.725,\n", + " 'q1': 38.0,\n", + " 'pos': 15,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'upper': 45.5,\n", + " 'pos': 34,\n", + " 'average': 38.205,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'median': 40.0},\n", + " {'average': 38.41,\n", + " 'q3': 41.0,\n", + " 'pos': 22,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5},\n", + " {'average': 38.29,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5,\n", + " 'pos': 32,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5},\n", + " {'median': 35.0,\n", + " 'q1': 30.0,\n", + " 'upper': 45.0,\n", + " 'average': 30.805,\n", + " 'q3': 36.0,\n", + " 'pos': 77,\n", + " 'lower': 21.0},\n", + " {'average': 35.91,\n", + " 'q1': 34.0,\n", + " 'q3': 39.0,\n", + " 'median': 36.0,\n", + " 'lower': 26.5,\n", + " 'upper': 46.5,\n", + " 'pos': 68},\n", + " {'lower': 25.0,\n", + " 'median': 34.0,\n", + " 'upper': 41.0,\n", + " 'pos': 97,\n", + " 'q3': 35.0,\n", + " 'q1': 31.0,\n", + " 'average': 30.67},\n", + " {'lower': 29.0,\n", + " 'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'q3': 39.0,\n", + " 'average': 35.995,\n", + " 'upper': 45.0,\n", + " 'pos': 65}]}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pb.base_sequence_quality(\"example.csv\")" + ] + }, + { + "cell_type": "markdown", + "id": "5ab1da41", + "metadata": {}, + "source": [ + "#### Usage example - .parquet file" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a2cb9c97", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'base_quality_warn': 'pass',\n", + " 'base_per_pos_data': [{'average': 35.69,\n", + " 'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'q3': 37.0,\n", + " 'pos': 3},\n", + " {'pos': 39,\n", + " 'average': 37.895,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'upper': 43.0},\n", + " {'pos': 20,\n", + " 'average': 38.625,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0},\n", + " {'pos': 28,\n", + " 'q1': 38.0,\n", + " 'average': 38.445,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'median': 40.0},\n", + " {'pos': 49,\n", + " 'average': 37.21,\n", + " 'q1': 36.0,\n", + " 'q3': 40.0,\n", + " 'lower': 30.0,\n", + " 'median': 39.0,\n", + " 'upper': 46.0},\n", + " {'q1': 35.0,\n", + " 'pos': 59,\n", + " 'upper': 47.5,\n", + " 'median': 38.0,\n", + " 'average': 36.08,\n", + " 'lower': 27.5,\n", + " 'q3': 40.0},\n", + " {'pos': 67,\n", + " 'average': 35.96,\n", + " 'lower': 26.5,\n", + " 'q1': 34.0,\n", + " 'upper': 46.5,\n", + " 'q3': 39.0,\n", + " 'median': 36.5},\n", + " {'average': 37.45,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'q1': 36.0,\n", + " 'lower': 28.5,\n", + " 'pos': 45,\n", + " 'upper': 48.5},\n", + " {'lower': 35.0,\n", + " 'q3': 40.0,\n", + " 'average': 38.0,\n", + " 'pos': 37,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'upper': 43.0},\n", + " {'pos': 22,\n", + " 'average': 38.41,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'pos': 15,\n", + " 'average': 38.725,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5,\n", + " 'median': 40.0},\n", + " {'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'pos': 19,\n", + " 'upper': 45.5,\n", + " 'average': 38.425,\n", + " 'median': 40.0,\n", + " 'q1': 38.0},\n", + " {'median': 35.0,\n", + " 'pos': 74,\n", + " 'q3': 37.0,\n", + " 'average': 30.83,\n", + " 'upper': 44.5,\n", + " 'q1': 32.0,\n", + " 'lower': 24.5},\n", + " {'q3': 37.0,\n", + " 'pos': 76,\n", + " 'q1': 31.0,\n", + " 'upper': 46.0,\n", + " 'average': 30.265,\n", + " 'median': 35.0,\n", + " 'lower': 22.0},\n", + " {'pos': 31,\n", + " 'average': 38.795,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5},\n", + " {'pos': 23,\n", + " 'average': 38.635,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0},\n", + " {'q3': 41.0,\n", + " 'median': 39.0,\n", + " 'upper': 48.5,\n", + " 'pos': 51,\n", + " 'q1': 36.0,\n", + " 'lower': 28.5,\n", + " 'average': 37.53},\n", + " {'upper': 40.0,\n", + " 'median': 37.0,\n", + " 'average': 35.68,\n", + " 'q1': 35.0,\n", + " 'q3': 37.0,\n", + " 'pos': 4,\n", + " 'lower': 32.0},\n", + " {'average': 32.46,\n", + " 'upper': 42.0,\n", + " 'median': 35.0,\n", + " 'q1': 32.0,\n", + " 'pos': 79,\n", + " 'q3': 36.0,\n", + " 'lower': 26.0},\n", + " {'average': 32.61,\n", + " 'q1': 32.0,\n", + " 'pos': 80,\n", + " 'median': 35.0,\n", + " 'q3': 36.0,\n", + " 'upper': 42.0,\n", + " 'lower': 26.0},\n", + " {'q1': 35.0,\n", + " 'median': 38.0,\n", + " 'q3': 40.0,\n", + " 'upper': 47.5,\n", + " 'lower': 27.5,\n", + " 'pos': 58,\n", + " 'average': 36.77},\n", + " {'average': 32.68,\n", + " 'median': 35.0,\n", + " 'lower': 27.0,\n", + " 'q1': 33.0,\n", + " 'q3': 37.0,\n", + " 'upper': 43.0,\n", + " 'pos': 73},\n", + " {'median': 34.0,\n", + " 'pos': 97,\n", + " 'q1': 31.0,\n", + " 'upper': 41.0,\n", + " 'q3': 35.0,\n", + " 'lower': 25.0,\n", + " 'average': 30.67},\n", + " {'median': 34.0,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'average': 31.55,\n", + " 'pos': 98,\n", + " 'q3': 35.0,\n", + " 'q1': 32.0},\n", + " {'upper': 42.0,\n", + " 'median': 39.0,\n", + " 'pos': 8,\n", + " 'q1': 37.0,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'average': 37.625},\n", + " {'q1': 38.0,\n", + " 'pos': 29,\n", + " 'lower': 33.5,\n", + " 'average': 38.595,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'upper': 45.5},\n", + " {'pos': 38,\n", + " 'q3': 41.0,\n", + " 'average': 37.64,\n", + " 'median': 40.0,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5},\n", + " {'q3': 41.0,\n", + " 'pos': 18,\n", + " 'q1': 38.0,\n", + " 'average': 38.47,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'lower': 30.0,\n", + " 'average': 37.35,\n", + " 'q1': 36.0,\n", + " 'q3': 40.0,\n", + " 'upper': 46.0,\n", + " 'pos': 57,\n", + " 'median': 39.0},\n", + " {'q3': 34.0,\n", + " 'upper': 38.5,\n", + " 'q1': 31.0,\n", + " 'average': 30.135,\n", + " 'lower': 26.5,\n", + " 'pos': 0,\n", + " 'median': 33.0},\n", + " {'pos': 71,\n", + " 'q3': 38.0,\n", + " 'lower': 25.5,\n", + " 'upper': 45.5,\n", + " 'average': 33.005,\n", + " 'median': 35.0,\n", + " 'q1': 33.0},\n", + " {'upper': 39.5,\n", + " 'q3': 35.0,\n", + " 'q1': 32.0,\n", + " 'lower': 27.5,\n", + " 'average': 32.665,\n", + " 'pos': 91,\n", + " 'median': 35.0},\n", + " {'q3': 35.0,\n", + " 'pos': 89,\n", + " 'upper': 38.0,\n", + " 'q1': 33.0,\n", + " 'lower': 30.0,\n", + " 'median': 35.0,\n", + " 'average': 32.44},\n", + " {'median': 39.5,\n", + " 'q1': 36.0,\n", + " 'average': 37.59,\n", + " 'pos': 54,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5,\n", + " 'upper': 48.5},\n", + " {'median': 35.0,\n", + " 'pos': 82,\n", + " 'q3': 36.0,\n", + " 'q1': 33.0,\n", + " 'lower': 28.5,\n", + " 'upper': 40.5,\n", + " 'average': 31.525},\n", + " {'pos': 85,\n", + " 'lower': 30.0,\n", + " 'q3': 35.0,\n", + " 'upper': 38.0,\n", + " 'average': 32.195,\n", + " 'median': 35.0,\n", + " 'q1': 33.0},\n", + " {'lower': 30.0,\n", + " 'pos': 83,\n", + " 'upper': 38.0,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'average': 32.03,\n", + " 'q3': 35.0},\n", + " {'median': 35.0,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0,\n", + " 'upper': 39.5,\n", + " 'average': 31.835,\n", + " 'lower': 27.5,\n", + " 'pos': 92},\n", + " {'average': 35.995,\n", + " 'lower': 29.0,\n", + " 'pos': 65,\n", + " 'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'upper': 45.0,\n", + " 'q3': 39.0},\n", + " {'pos': 34,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'average': 38.205,\n", + " 'median': 40.0},\n", + " {'upper': 43.0,\n", + " 'median': 40.0,\n", + " 'q3': 40.0,\n", + " 'q1': 38.0,\n", + " 'pos': 43,\n", + " 'average': 37.775,\n", + " 'lower': 35.0},\n", + " {'pos': 68,\n", + " 'q3': 39.0,\n", + " 'lower': 26.5,\n", + " 'upper': 46.5,\n", + " 'q1': 34.0,\n", + " 'median': 36.0,\n", + " 'average': 35.91},\n", + " {'q3': 40.0,\n", + " 'median': 40.0,\n", + " 'lower': 35.0,\n", + " 'pos': 26,\n", + " 'q1': 38.0,\n", + " 'upper': 43.0,\n", + " 'average': 37.855},\n", + " {'median': 35.0,\n", + " 'pos': 70,\n", + " 'q3': 38.0,\n", + " 'lower': 28.0,\n", + " 'q1': 34.0,\n", + " 'upper': 44.0,\n", + " 'average': 33.565},\n", + " {'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'pos': 13,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.94,\n", + " 'upper': 45.5},\n", + " {'pos': 88,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0,\n", + " 'upper': 38.0,\n", + " 'average': 32.065,\n", + " 'lower': 30.0,\n", + " 'median': 35.0},\n", + " {'median': 34.5,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0,\n", + " 'upper': 38.0,\n", + " 'average': 32.275,\n", + " 'pos': 90,\n", + " 'lower': 30.0},\n", + " {'q1': 30.0,\n", + " 'upper': 45.0,\n", + " 'q3': 36.0,\n", + " 'pos': 77,\n", + " 'average': 30.805,\n", + " 'median': 35.0,\n", + " 'lower': 21.0},\n", + " {'q1': 37.0,\n", + " 'median': 39.0,\n", + " 'average': 37.77,\n", + " 'upper': 44.5,\n", + " 'pos': 52,\n", + " 'q3': 40.0,\n", + " 'lower': 32.5},\n", + " {'average': 37.565,\n", + " 'q1': 37.0,\n", + " 'pos': 44,\n", + " 'lower': 31.0,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'upper': 47.0},\n", + " {'lower': 28.5,\n", + " 'average': 37.425,\n", + " 'median': 39.0,\n", + " 'q1': 36.0,\n", + " 'pos': 50,\n", + " 'upper': 48.5,\n", + " 'q3': 41.0},\n", + " {'upper': 46.0,\n", + " 'q1': 36.0,\n", + " 'lower': 30.0,\n", + " 'pos': 56,\n", + " 'average': 37.59,\n", + " 'median': 39.0,\n", + " 'q3': 40.0},\n", + " {'median': 38.0,\n", + " 'pos': 63,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'q1': 35.0,\n", + " 'average': 36.25,\n", + " 'q3': 40.0},\n", + " {'lower': 31.0,\n", + " 'median': 39.0,\n", + " 'average': 37.665,\n", + " 'q1': 37.0,\n", + " 'q3': 41.0,\n", + " 'upper': 47.0,\n", + " 'pos': 47},\n", + " {'median': 39.0,\n", + " 'q3': 39.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.675,\n", + " 'lower': 34.0,\n", + " 'pos': 10,\n", + " 'upper': 42.0},\n", + " {'average': 37.5,\n", + " 'q1': 37.0,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0,\n", + " 'pos': 12,\n", + " 'median': 39.0},\n", + " {'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0,\n", + " 'pos': 25,\n", + " 'average': 38.2,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'lower': 23.5,\n", + " 'pos': 78,\n", + " 'q1': 31.0,\n", + " 'upper': 43.5,\n", + " 'average': 31.46,\n", + " 'q3': 36.0,\n", + " 'median': 35.0},\n", + " {'q3': 35.0,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'pos': 95,\n", + " 'q1': 32.0,\n", + " 'median': 34.0,\n", + " 'average': 31.425},\n", + " {'q3': 40.0,\n", + " 'upper': 47.5,\n", + " 'lower': 27.5,\n", + " 'average': 36.145,\n", + " 'pos': 62,\n", + " 'q1': 35.0,\n", + " 'median': 38.0},\n", + " {'pos': 21,\n", + " 'q3': 40.0,\n", + " 'median': 40.0,\n", + " 'lower': 35.0,\n", + " 'q1': 38.0,\n", + " 'average': 38.445,\n", + " 'upper': 43.0},\n", + " {'q1': 38.0,\n", + " 'lower': 35.0,\n", + " 'pos': 36,\n", + " 'q3': 40.0,\n", + " 'average': 38.11,\n", + " 'median': 40.0,\n", + " 'upper': 43.0},\n", + " {'lower': 27.5,\n", + " 'median': 38.0,\n", + " 'q1': 35.0,\n", + " 'average': 35.985,\n", + " 'upper': 47.5,\n", + " 'pos': 60,\n", + " 'q3': 40.0},\n", + " {'pos': 24,\n", + " 'average': 38.265,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'lower': 33.5},\n", + " {'q1': 37.0,\n", + " 'q3': 39.0,\n", + " 'median': 39.0,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0,\n", + " 'average': 37.36,\n", + " 'pos': 9},\n", + " {'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'median': 40.0,\n", + " 'pos': 30,\n", + " 'average': 38.245,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0},\n", + " {'average': 37.78,\n", + " 'q3': 40.0,\n", + " 'q1': 37.0,\n", + " 'lower': 32.5,\n", + " 'upper': 44.5,\n", + " 'pos': 42,\n", + " 'median': 40.0},\n", + " {'pos': 53,\n", + " 'q1': 37.0,\n", + " 'q3': 41.0,\n", + " 'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'median': 39.0,\n", + " 'average': 37.845},\n", + " {'q3': 37.0,\n", + " 'upper': 40.0,\n", + " 'median': 36.0,\n", + " 'average': 35.4,\n", + " 'q1': 35.0,\n", + " 'pos': 7,\n", + " 'lower': 32.0},\n", + " {'q1': 38.0,\n", + " 'upper': 45.5,\n", + " 'pos': 16,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.48},\n", + " {'pos': 72,\n", + " 'median': 35.0,\n", + " 'upper': 43.0,\n", + " 'average': 33.265,\n", + " 'q1': 33.0,\n", + " 'lower': 27.0,\n", + " 'q3': 37.0},\n", + " {'q1': 31.0,\n", + " 'lower': 22.0,\n", + " 'pos': 75,\n", + " 'average': 31.06,\n", + " 'q3': 37.0,\n", + " 'upper': 46.0,\n", + " 'median': 35.0},\n", + " {'average': 37.95,\n", + " 'median': 40.0,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'pos': 40,\n", + " 'upper': 43.0,\n", + " 'q1': 38.0},\n", + " {'pos': 5,\n", + " 'median': 35.0,\n", + " 'q3': 37.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'average': 35.095,\n", + " 'q1': 35.0},\n", + " {'upper': 40.0,\n", + " 'pos': 6,\n", + " 'median': 35.0,\n", + " 'average': 35.145,\n", + " 'q3': 37.0,\n", + " 'lower': 32.0,\n", + " 'q1': 35.0},\n", + " {'pos': 86,\n", + " 'q1': 33.0,\n", + " 'average': 31.815,\n", + " 'median': 35.0,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0},\n", + " {'lower': 30.0,\n", + " 'pos': 55,\n", + " 'average': 37.55,\n", + " 'q3': 40.0,\n", + " 'upper': 46.0,\n", + " 'median': 39.0,\n", + " 'q1': 36.0},\n", + " {'median': 34.0,\n", + " 'q1': 31.0,\n", + " 'q3': 34.0,\n", + " 'pos': 1,\n", + " 'lower': 26.5,\n", + " 'upper': 38.5,\n", + " 'average': 31.21},\n", + " {'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'average': 38.44,\n", + " 'q1': 38.0,\n", + " 'pos': 27,\n", + " 'upper': 45.5,\n", + " 'lower': 33.5},\n", + " {'upper': 42.0,\n", + " 'average': 37.71,\n", + " 'lower': 34.0,\n", + " 'q3': 39.0,\n", + " 'pos': 11,\n", + " 'q1': 37.0,\n", + " 'median': 39.0},\n", + " {'median': 37.0,\n", + " 'pos': 66,\n", + " 'average': 35.875,\n", + " 'q3': 39.0,\n", + " 'q1': 35.0,\n", + " 'lower': 29.0,\n", + " 'upper': 45.0},\n", + " {'upper': 39.5,\n", + " 'q3': 35.0,\n", + " 'lower': 27.5,\n", + " 'average': 31.05,\n", + " 'median': 34.0,\n", + " 'pos': 93,\n", + " 'q1': 32.0},\n", + " {'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'pos': 32,\n", + " 'average': 38.29,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5},\n", + " {'median': 36.0,\n", + " 'upper': 46.5,\n", + " 'q1': 34.0,\n", + " 'pos': 69,\n", + " 'q3': 39.0,\n", + " 'lower': 26.5,\n", + " 'average': 33.7},\n", + " {'lower': 33.5,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'pos': 14,\n", + " 'average': 38.965,\n", + " 'median': 40.0},\n", + " {'q1': 32.0,\n", + " 'median': 34.0,\n", + " 'average': 30.775,\n", + " 'q3': 35.0,\n", + " 'pos': 94,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5},\n", + " {'q1': 37.0,\n", + " 'q3': 41.0,\n", + " 'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'average': 37.87,\n", + " 'pos': 41,\n", + " 'median': 40.0},\n", + " {'pos': 96,\n", + " 'q3': 35.0,\n", + " 'upper': 39.5,\n", + " 'q1': 32.0,\n", + " 'lower': 27.5,\n", + " 'median': 34.0,\n", + " 'average': 31.315},\n", + " {'pos': 17,\n", + " 'q1': 38.0,\n", + " 'median': 40.0,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.505},\n", + " {'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'average': 38.245,\n", + " 'q1': 38.0,\n", + " 'pos': 33},\n", + " {'average': 36.095,\n", + " 'q1': 35.0,\n", + " 'lower': 27.5,\n", + " 'pos': 64,\n", + " 'q3': 40.0,\n", + " 'upper': 47.5,\n", + " 'median': 37.0},\n", + " {'pos': 35,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'average': 38.385,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0},\n", + " {'lower': 28.5,\n", + " 'q1': 36.0,\n", + " 'pos': 48,\n", + " 'median': 40.0,\n", + " 'average': 37.61,\n", + " 'q3': 41.0,\n", + " 'upper': 48.5},\n", + " {'average': 31.915,\n", + " 'median': 35.0,\n", + " 'pos': 87,\n", + " 'q1': 32.0,\n", + " 'upper': 39.5,\n", + " 'lower': 27.5,\n", + " 'q3': 35.0},\n", + " {'upper': 47.5,\n", + " 'median': 38.0,\n", + " 'average': 35.99,\n", + " 'pos': 61,\n", + " 'q1': 35.0,\n", + " 'lower': 27.5,\n", + " 'q3': 40.0},\n", + " {'average': 37.79,\n", + " 'q3': 41.0,\n", + " 'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'q1': 37.0,\n", + " 'median': 39.5,\n", + " 'pos': 46},\n", + " {'q3': 36.0,\n", + " 'average': 32.76,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'upper': 40.5,\n", + " 'pos': 81,\n", + " 'lower': 28.5},\n", + " {'pos': 2,\n", + " 'average': 32.015,\n", + " 'median': 34.0,\n", + " 'q1': 31.0,\n", + " 'lower': 26.5,\n", + " 'upper': 38.5,\n", + " 'q3': 34.0},\n", + " {'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'median': 34.0,\n", + " 'average': 31.25,\n", + " 'q3': 35.0,\n", + " 'pos': 99,\n", + " 'q1': 32.0},\n", + " {'q1': 33.0,\n", + " 'average': 32.415,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'pos': 84,\n", + " 'q3': 35.0,\n", + " 'median': 35.0},\n", + " {'upper': 41.0,\n", + " 'q3': 35.0,\n", + " 'pos': 100,\n", + " 'average': 31.105,\n", + " 'q1': 31.0,\n", + " 'lower': 25.0,\n", + " 'median': 34.0}]}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pb.base_sequence_quality(\"example.parquet\")" + ] + }, + { + "cell_type": "markdown", + "id": "b519abbd", + "metadata": {}, + "source": [ + "#### Usage example - `polars.lazyframe.frame.LazyFrame` object" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "1899ca01", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:polars_bio:Table: example registered for path: ./example.fastq\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200rows [00:00, 126946.25rows/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "{'base_quality_warn': 'pass',\n", + " 'base_per_pos_data': [{'average': 38.505,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'upper': 45.5,\n", + " 'pos': 17,\n", + " 'q1': 38.0},\n", + " {'median': 33.0,\n", + " 'average': 30.135,\n", + " 'lower': 26.5,\n", + " 'q1': 31.0,\n", + " 'q3': 34.0,\n", + " 'pos': 0,\n", + " 'upper': 38.5},\n", + " {'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'median': 35.0,\n", + " 'pos': 5,\n", + " 'average': 35.095,\n", + " 'q1': 35.0,\n", + " 'q3': 37.0},\n", + " {'pos': 20,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.625,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'pos': 10,\n", + " 'lower': 34.0,\n", + " 'q3': 39.0,\n", + " 'upper': 42.0,\n", + " 'average': 37.675,\n", + " 'q1': 37.0,\n", + " 'median': 39.0},\n", + " {'lower': 31.0,\n", + " 'average': 37.87,\n", + " 'upper': 47.0,\n", + " 'q1': 37.0,\n", + " 'pos': 41,\n", + " 'median': 40.0,\n", + " 'q3': 41.0},\n", + " {'pos': 56,\n", + " 'q1': 36.0,\n", + " 'lower': 30.0,\n", + " 'median': 39.0,\n", + " 'upper': 46.0,\n", + " 'q3': 40.0,\n", + " 'average': 37.59},\n", + " {'q1': 38.0,\n", + " 'upper': 43.0,\n", + " 'average': 37.855,\n", + " 'pos': 26,\n", + " 'median': 40.0,\n", + " 'lower': 35.0,\n", + " 'q3': 40.0},\n", + " {'average': 37.565,\n", + " 'pos': 44,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'q1': 37.0},\n", + " {'average': 37.59,\n", + " 'upper': 48.5,\n", + " 'pos': 54,\n", + " 'q1': 36.0,\n", + " 'lower': 28.5,\n", + " 'median': 39.5,\n", + " 'q3': 41.0},\n", + " {'median': 38.0,\n", + " 'q3': 40.0,\n", + " 'upper': 47.5,\n", + " 'lower': 27.5,\n", + " 'q1': 35.0,\n", + " 'pos': 58,\n", + " 'average': 36.77},\n", + " {'average': 36.08,\n", + " 'lower': 27.5,\n", + " 'pos': 59,\n", + " 'q1': 35.0,\n", + " 'q3': 40.0,\n", + " 'upper': 47.5,\n", + " 'median': 38.0},\n", + " {'average': 37.625,\n", + " 'median': 39.0,\n", + " 'pos': 8,\n", + " 'q1': 37.0,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0},\n", + " {'average': 38.205,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 34,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0},\n", + " {'upper': 46.5,\n", + " 'pos': 67,\n", + " 'q1': 34.0,\n", + " 'q3': 39.0,\n", + " 'lower': 26.5,\n", + " 'average': 35.96,\n", + " 'median': 36.5},\n", + " {'upper': 44.5,\n", + " 'q1': 32.0,\n", + " 'pos': 74,\n", + " 'median': 35.0,\n", + " 'average': 30.83,\n", + " 'q3': 37.0,\n", + " 'lower': 24.5},\n", + " {'average': 31.46,\n", + " 'upper': 43.5,\n", + " 'pos': 78,\n", + " 'lower': 23.5,\n", + " 'median': 35.0,\n", + " 'q3': 36.0,\n", + " 'q1': 31.0},\n", + " {'pos': 28,\n", + " 'median': 40.0,\n", + " 'average': 38.445,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'pos': 32,\n", + " 'average': 38.29,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'median': 40.0},\n", + " {'pos': 2,\n", + " 'median': 34.0,\n", + " 'q3': 34.0,\n", + " 'average': 32.015,\n", + " 'lower': 26.5,\n", + " 'upper': 38.5,\n", + " 'q1': 31.0},\n", + " {'lower': 30.0,\n", + " 'pos': 83,\n", + " 'median': 35.0,\n", + " 'q3': 35.0,\n", + " 'upper': 38.0,\n", + " 'average': 32.03,\n", + " 'q1': 33.0},\n", + " {'q3': 35.0,\n", + " 'average': 32.195,\n", + " 'median': 35.0,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'pos': 85,\n", + " 'q1': 33.0},\n", + " {'q3': 38.0,\n", + " 'lower': 28.0,\n", + " 'upper': 44.0,\n", + " 'q1': 34.0,\n", + " 'median': 35.0,\n", + " 'average': 33.565,\n", + " 'pos': 70},\n", + " {'q1': 35.0,\n", + " 'lower': 27.5,\n", + " 'pos': 64,\n", + " 'q3': 40.0,\n", + " 'upper': 47.5,\n", + " 'median': 37.0,\n", + " 'average': 36.095},\n", + " {'median': 35.0,\n", + " 'q3': 35.0,\n", + " 'average': 32.665,\n", + " 'upper': 39.5,\n", + " 'pos': 91,\n", + " 'q1': 32.0,\n", + " 'lower': 27.5},\n", + " {'q3': 39.0,\n", + " 'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'lower': 29.0,\n", + " 'upper': 45.0,\n", + " 'average': 35.995,\n", + " 'pos': 65},\n", + " {'q1': 33.0,\n", + " 'median': 35.0,\n", + " 'average': 32.76,\n", + " 'lower': 28.5,\n", + " 'upper': 40.5,\n", + " 'pos': 81,\n", + " 'q3': 36.0},\n", + " {'pos': 66,\n", + " 'median': 37.0,\n", + " 'q3': 39.0,\n", + " 'average': 35.875,\n", + " 'q1': 35.0,\n", + " 'lower': 29.0,\n", + " 'upper': 45.0},\n", + " {'upper': 42.0,\n", + " 'median': 35.0,\n", + " 'lower': 26.0,\n", + " 'average': 32.46,\n", + " 'pos': 79,\n", + " 'q1': 32.0,\n", + " 'q3': 36.0},\n", + " {'q3': 37.0,\n", + " 'pos': 7,\n", + " 'average': 35.4,\n", + " 'median': 36.0,\n", + " 'q1': 35.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0},\n", + " {'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'q1': 38.0,\n", + " 'average': 38.245,\n", + " 'upper': 43.0,\n", + " 'pos': 30,\n", + " 'median': 40.0},\n", + " {'lower': 35.0,\n", + " 'q3': 40.0,\n", + " 'upper': 43.0,\n", + " 'average': 37.895,\n", + " 'q1': 38.0,\n", + " 'pos': 39,\n", + " 'median': 40.0},\n", + " {'q1': 36.0,\n", + " 'upper': 48.5,\n", + " 'average': 37.45,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5,\n", + " 'median': 40.0,\n", + " 'pos': 45},\n", + " {'average': 37.21,\n", + " 'median': 39.0,\n", + " 'upper': 46.0,\n", + " 'lower': 30.0,\n", + " 'pos': 49,\n", + " 'q1': 36.0,\n", + " 'q3': 40.0},\n", + " {'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'lower': 30.0,\n", + " 'pos': 86,\n", + " 'upper': 38.0,\n", + " 'average': 31.815,\n", + " 'q3': 35.0},\n", + " {'pos': 6,\n", + " 'q1': 35.0,\n", + " 'lower': 32.0,\n", + " 'q3': 37.0,\n", + " 'upper': 40.0,\n", + " 'average': 35.145,\n", + " 'median': 35.0},\n", + " {'q3': 40.0,\n", + " 'lower': 27.5,\n", + " 'pos': 60,\n", + " 'average': 35.985,\n", + " 'upper': 47.5,\n", + " 'median': 38.0,\n", + " 'q1': 35.0},\n", + " {'lower': 27.5,\n", + " 'average': 31.425,\n", + " 'q3': 35.0,\n", + " 'median': 34.0,\n", + " 'q1': 32.0,\n", + " 'pos': 95,\n", + " 'upper': 39.5},\n", + " {'median': 40.0,\n", + " 'pos': 13,\n", + " 'lower': 33.5,\n", + " 'q3': 41.0,\n", + " 'average': 38.94,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5},\n", + " {'q1': 33.0,\n", + " 'upper': 38.0,\n", + " 'average': 32.275,\n", + " 'pos': 90,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'median': 34.5},\n", + " {'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'pos': 33,\n", + " 'average': 38.245,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5},\n", + " {'upper': 39.5,\n", + " 'pos': 87,\n", + " 'average': 31.915,\n", + " 'q1': 32.0,\n", + " 'median': 35.0,\n", + " 'q3': 35.0,\n", + " 'lower': 27.5},\n", + " {'pos': 42,\n", + " 'median': 40.0,\n", + " 'average': 37.78,\n", + " 'q3': 40.0,\n", + " 'lower': 32.5,\n", + " 'q1': 37.0,\n", + " 'upper': 44.5},\n", + " {'q3': 40.0,\n", + " 'pos': 63,\n", + " 'average': 36.25,\n", + " 'median': 38.0,\n", + " 'q1': 35.0,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5},\n", + " {'q1': 36.0,\n", + " 'pos': 57,\n", + " 'median': 39.0,\n", + " 'q3': 40.0,\n", + " 'upper': 46.0,\n", + " 'average': 37.35,\n", + " 'lower': 30.0},\n", + " {'upper': 42.0,\n", + " 'average': 37.71,\n", + " 'q1': 37.0,\n", + " 'median': 39.0,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'pos': 11},\n", + " {'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'average': 38.425,\n", + " 'pos': 19,\n", + " 'q3': 41.0},\n", + " {'pos': 88,\n", + " 'upper': 38.0,\n", + " 'q1': 33.0,\n", + " 'average': 32.065,\n", + " 'median': 35.0,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0},\n", + " {'upper': 39.5,\n", + " 'average': 31.315,\n", + " 'q1': 32.0,\n", + " 'pos': 96,\n", + " 'median': 34.0,\n", + " 'q3': 35.0,\n", + " 'lower': 27.5},\n", + " {'q3': 41.0,\n", + " 'lower': 28.5,\n", + " 'upper': 48.5,\n", + " 'average': 37.61,\n", + " 'median': 40.0,\n", + " 'pos': 48,\n", + " 'q1': 36.0},\n", + " {'q3': 37.0,\n", + " 'average': 35.68,\n", + " 'upper': 40.0,\n", + " 'lower': 32.0,\n", + " 'pos': 4,\n", + " 'median': 37.0,\n", + " 'q1': 35.0},\n", + " {'q1': 33.0,\n", + " 'pos': 89,\n", + " 'average': 32.44,\n", + " 'median': 35.0,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'q3': 35.0},\n", + " {'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'average': 37.5,\n", + " 'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'upper': 42.0,\n", + " 'pos': 12},\n", + " {'lower': 25.0,\n", + " 'q3': 35.0,\n", + " 'upper': 41.0,\n", + " 'pos': 97,\n", + " 'average': 30.67,\n", + " 'median': 34.0,\n", + " 'q1': 31.0},\n", + " {'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'pos': 27,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'average': 38.44},\n", + " {'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'average': 37.845,\n", + " 'q1': 37.0,\n", + " 'median': 39.0,\n", + " 'pos': 53,\n", + " 'q3': 41.0},\n", + " {'pos': 100,\n", + " 'q3': 35.0,\n", + " 'lower': 25.0,\n", + " 'average': 31.105,\n", + " 'upper': 41.0,\n", + " 'median': 34.0,\n", + " 'q1': 31.0},\n", + " {'q1': 37.0,\n", + " 'lower': 32.5,\n", + " 'upper': 44.5,\n", + " 'q3': 40.0,\n", + " 'pos': 52,\n", + " 'average': 37.77,\n", + " 'median': 39.0},\n", + " {'q3': 41.0,\n", + " 'pos': 24,\n", + " 'average': 38.265,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'upper': 42.0,\n", + " 'median': 39.0,\n", + " 'q3': 39.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.36,\n", + " 'pos': 9,\n", + " 'lower': 34.0},\n", + " {'pos': 15,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'average': 38.725,\n", + " 'q1': 38.0},\n", + " {'pos': 55,\n", + " 'average': 37.55,\n", + " 'lower': 30.0,\n", + " 'q1': 36.0,\n", + " 'median': 39.0,\n", + " 'q3': 40.0,\n", + " 'upper': 46.0},\n", + " {'median': 35.0,\n", + " 'q1': 31.0,\n", + " 'q3': 37.0,\n", + " 'pos': 75,\n", + " 'lower': 22.0,\n", + " 'upper': 46.0,\n", + " 'average': 31.06},\n", + " {'lower': 33.5,\n", + " 'pos': 29,\n", + " 'average': 38.595,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'q1': 38.0},\n", + " {'q1': 34.0,\n", + " 'pos': 69,\n", + " 'lower': 26.5,\n", + " 'average': 33.7,\n", + " 'upper': 46.5,\n", + " 'median': 36.0,\n", + " 'q3': 39.0},\n", + " {'q3': 41.0,\n", + " 'average': 37.79,\n", + " 'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'pos': 46,\n", + " 'median': 39.5,\n", + " 'q1': 37.0},\n", + " {'upper': 39.5,\n", + " 'pos': 93,\n", + " 'average': 31.05,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0,\n", + " 'median': 34.0,\n", + " 'lower': 27.5},\n", + " {'average': 37.775,\n", + " 'pos': 43,\n", + " 'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'median': 40.0},\n", + " {'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'pos': 23,\n", + " 'average': 38.635,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5},\n", + " {'q3': 37.0,\n", + " 'median': 35.0,\n", + " 'pos': 73,\n", + " 'average': 32.68,\n", + " 'q1': 33.0,\n", + " 'lower': 27.0,\n", + " 'upper': 43.0},\n", + " {'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 14,\n", + " 'average': 38.965,\n", + " 'q1': 38.0,\n", + " 'median': 40.0},\n", + " {'median': 40.0,\n", + " 'q3': 40.0,\n", + " 'q1': 38.0,\n", + " 'pos': 37,\n", + " 'upper': 43.0,\n", + " 'lower': 35.0,\n", + " 'average': 38.0},\n", + " {'pos': 76,\n", + " 'median': 35.0,\n", + " 'lower': 22.0,\n", + " 'upper': 46.0,\n", + " 'q3': 37.0,\n", + " 'average': 30.265,\n", + " 'q1': 31.0},\n", + " {'q3': 36.0,\n", + " 'lower': 26.0,\n", + " 'upper': 42.0,\n", + " 'median': 35.0,\n", + " 'average': 32.61,\n", + " 'pos': 80,\n", + " 'q1': 32.0},\n", + " {'average': 37.665,\n", + " 'q3': 41.0,\n", + " 'pos': 47,\n", + " 'q1': 37.0,\n", + " 'lower': 31.0,\n", + " 'median': 39.0,\n", + " 'upper': 47.0},\n", + " {'average': 33.265,\n", + " 'median': 35.0,\n", + " 'pos': 72,\n", + " 'q1': 33.0,\n", + " 'q3': 37.0,\n", + " 'lower': 27.0,\n", + " 'upper': 43.0},\n", + " {'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'pos': 18,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'average': 38.47},\n", + " {'q1': 33.0,\n", + " 'lower': 28.5,\n", + " 'pos': 82,\n", + " 'q3': 36.0,\n", + " 'upper': 40.5,\n", + " 'median': 35.0,\n", + " 'average': 31.525},\n", + " {'average': 35.69,\n", + " 'median': 37.0,\n", + " 'lower': 32.0,\n", + " 'pos': 3,\n", + " 'q3': 37.0,\n", + " 'upper': 40.0,\n", + " 'q1': 35.0},\n", + " {'average': 35.99,\n", + " 'q1': 35.0,\n", + " 'upper': 47.5,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5,\n", + " 'pos': 61,\n", + " 'median': 38.0},\n", + " {'upper': 48.5,\n", + " 'lower': 28.5,\n", + " 'pos': 50,\n", + " 'q1': 36.0,\n", + " 'q3': 41.0,\n", + " 'median': 39.0,\n", + " 'average': 37.425},\n", + " {'average': 36.145,\n", + " 'upper': 47.5,\n", + " 'q3': 40.0,\n", + " 'pos': 62,\n", + " 'median': 38.0,\n", + " 'q1': 35.0,\n", + " 'lower': 27.5},\n", + " {'pos': 51,\n", + " 'average': 37.53,\n", + " 'lower': 28.5,\n", + " 'median': 39.0,\n", + " 'upper': 48.5,\n", + " 'q3': 41.0,\n", + " 'q1': 36.0},\n", + " {'upper': 43.0,\n", + " 'average': 37.95,\n", + " 'q1': 38.0,\n", + " 'median': 40.0,\n", + " 'lower': 35.0,\n", + " 'pos': 40,\n", + " 'q3': 40.0},\n", + " {'upper': 46.5,\n", + " 'average': 35.91,\n", + " 'q1': 34.0,\n", + " 'q3': 39.0,\n", + " 'lower': 26.5,\n", + " 'median': 36.0,\n", + " 'pos': 68},\n", + " {'median': 35.0,\n", + " 'q1': 30.0,\n", + " 'q3': 36.0,\n", + " 'lower': 21.0,\n", + " 'pos': 77,\n", + " 'average': 30.805,\n", + " 'upper': 45.0},\n", + " {'average': 33.005,\n", + " 'pos': 71,\n", + " 'q1': 33.0,\n", + " 'q3': 38.0,\n", + " 'lower': 25.5,\n", + " 'median': 35.0,\n", + " 'upper': 45.5},\n", + " {'q3': 35.0,\n", + " 'pos': 98,\n", + " 'average': 31.55,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'median': 34.0,\n", + " 'q1': 32.0},\n", + " {'average': 31.25,\n", + " 'median': 34.0,\n", + " 'upper': 39.5,\n", + " 'pos': 99,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0,\n", + " 'lower': 27.5},\n", + " {'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'upper': 45.5,\n", + " 'pos': 38,\n", + " 'average': 37.64,\n", + " 'q1': 38.0},\n", + " {'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'pos': 25,\n", + " 'q3': 41.0,\n", + " 'average': 38.2},\n", + " {'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'pos': 31,\n", + " 'average': 38.795,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5},\n", + " {'average': 38.385,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'pos': 35,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0},\n", + " {'q1': 33.0,\n", + " 'q3': 35.0,\n", + " 'pos': 84,\n", + " 'lower': 30.0,\n", + " 'median': 35.0,\n", + " 'upper': 38.0,\n", + " 'average': 32.415},\n", + " {'pos': 92,\n", + " 'median': 35.0,\n", + " 'upper': 39.5,\n", + " 'average': 31.835,\n", + " 'lower': 27.5,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0},\n", + " {'q1': 32.0,\n", + " 'lower': 27.5,\n", + " 'median': 34.0,\n", + " 'pos': 94,\n", + " 'upper': 39.5,\n", + " 'average': 30.775,\n", + " 'q3': 35.0},\n", + " {'pos': 1,\n", + " 'median': 34.0,\n", + " 'q3': 34.0,\n", + " 'average': 31.21,\n", + " 'lower': 26.5,\n", + " 'q1': 31.0,\n", + " 'upper': 38.5},\n", + " {'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'average': 38.41,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'q3': 41.0,\n", + " 'pos': 22},\n", + " {'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'pos': 36,\n", + " 'average': 38.11,\n", + " 'q1': 38.0,\n", + " 'median': 40.0},\n", + " {'lower': 35.0,\n", + " 'average': 38.445,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'upper': 43.0,\n", + " 'pos': 21},\n", + " {'q1': 38.0,\n", + " 'pos': 16,\n", + " 'q3': 41.0,\n", + " 'average': 38.48,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'median': 40.0}]}" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", + "print(type(a_lazyframe))\n", + "pb.base_sequence_quality(a_lazyframe)" + ] + }, + { + "cell_type": "markdown", + "id": "cdb4aad6", + "metadata": {}, + "source": [ + "#### Usage example - `polars.dataframe.frame.DataFrame` object" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "7830b8aa", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:polars_bio:Table: example registered for path: ./example.fastq\n", + "200rows [00:00, 80924.25rows/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "{'base_quality_warn': 'pass',\n", + " 'base_per_pos_data': [{'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'average': 38.265,\n", + " 'pos': 24,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0},\n", + " {'median': 35.0,\n", + " 'average': 30.83,\n", + " 'pos': 74,\n", + " 'q1': 32.0,\n", + " 'lower': 24.5,\n", + " 'q3': 37.0,\n", + " 'upper': 44.5},\n", + " {'pos': 93,\n", + " 'upper': 39.5,\n", + " 'average': 31.05,\n", + " 'median': 34.0,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0,\n", + " 'lower': 27.5},\n", + " {'q1': 37.0,\n", + " 'pos': 10,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0,\n", + " 'median': 39.0,\n", + " 'average': 37.675},\n", + " {'lower': 28.5,\n", + " 'upper': 48.5,\n", + " 'median': 39.0,\n", + " 'average': 37.425,\n", + " 'pos': 50,\n", + " 'q1': 36.0,\n", + " 'q3': 41.0},\n", + " {'q1': 36.0,\n", + " 'lower': 30.0,\n", + " 'pos': 55,\n", + " 'average': 37.55,\n", + " 'q3': 40.0,\n", + " 'upper': 46.0,\n", + " 'median': 39.0},\n", + " {'average': 32.195,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'pos': 85,\n", + " 'upper': 38.0,\n", + " 'median': 35.0},\n", + " {'pos': 91,\n", + " 'q1': 32.0,\n", + " 'upper': 39.5,\n", + " 'q3': 35.0,\n", + " 'average': 32.665,\n", + " 'lower': 27.5,\n", + " 'median': 35.0},\n", + " {'pos': 92,\n", + " 'q1': 32.0,\n", + " 'median': 35.0,\n", + " 'upper': 39.5,\n", + " 'q3': 35.0,\n", + " 'average': 31.835,\n", + " 'lower': 27.5},\n", + " {'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'q1': 37.0,\n", + " 'median': 39.5,\n", + " 'average': 37.79,\n", + " 'pos': 46,\n", + " 'q3': 41.0},\n", + " {'q3': 40.0,\n", + " 'q1': 36.0,\n", + " 'upper': 46.0,\n", + " 'pos': 57,\n", + " 'average': 37.35,\n", + " 'median': 39.0,\n", + " 'lower': 30.0},\n", + " {'pos': 66,\n", + " 'average': 35.875,\n", + " 'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'q3': 39.0,\n", + " 'lower': 29.0,\n", + " 'upper': 45.0},\n", + " {'pos': 69,\n", + " 'q3': 39.0,\n", + " 'lower': 26.5,\n", + " 'average': 33.7,\n", + " 'upper': 46.5,\n", + " 'q1': 34.0,\n", + " 'median': 36.0},\n", + " {'median': 38.0,\n", + " 'pos': 59,\n", + " 'q3': 40.0,\n", + " 'average': 36.08,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'q1': 35.0},\n", + " {'q3': 35.0,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'q1': 32.0,\n", + " 'pos': 99,\n", + " 'average': 31.25,\n", + " 'median': 34.0},\n", + " {'upper': 43.0,\n", + " 'q3': 40.0,\n", + " 'pos': 39,\n", + " 'q1': 38.0,\n", + " 'average': 37.895,\n", + " 'median': 40.0,\n", + " 'lower': 35.0},\n", + " {'upper': 43.0,\n", + " 'average': 37.95,\n", + " 'q1': 38.0,\n", + " 'pos': 40,\n", + " 'q3': 40.0,\n", + " 'median': 40.0,\n", + " 'lower': 35.0},\n", + " {'pos': 28,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5,\n", + " 'average': 38.445},\n", + " {'q1': 37.0,\n", + " 'q3': 39.0,\n", + " 'average': 37.5,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0,\n", + " 'pos': 12,\n", + " 'median': 39.0},\n", + " {'q3': 41.0,\n", + " 'pos': 23,\n", + " 'upper': 45.5,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'median': 40.0,\n", + " 'average': 38.635},\n", + " {'pos': 0,\n", + " 'average': 30.135,\n", + " 'median': 33.0,\n", + " 'q3': 34.0,\n", + " 'lower': 26.5,\n", + " 'upper': 38.5,\n", + " 'q1': 31.0},\n", + " {'lower': 34.0,\n", + " 'pos': 8,\n", + " 'upper': 42.0,\n", + " 'average': 37.625,\n", + " 'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'q3': 39.0},\n", + " {'median': 40.0,\n", + " 'lower': 28.5,\n", + " 'pos': 48,\n", + " 'q3': 41.0,\n", + " 'q1': 36.0,\n", + " 'average': 37.61,\n", + " 'upper': 48.5},\n", + " {'q1': 33.0,\n", + " 'pos': 82,\n", + " 'median': 35.0,\n", + " 'q3': 36.0,\n", + " 'lower': 28.5,\n", + " 'average': 31.525,\n", + " 'upper': 40.5},\n", + " {'pos': 96,\n", + " 'average': 31.315,\n", + " 'median': 34.0,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5},\n", + " {'upper': 47.0,\n", + " 'pos': 53,\n", + " 'median': 39.0,\n", + " 'average': 37.845,\n", + " 'q1': 37.0,\n", + " 'q3': 41.0,\n", + " 'lower': 31.0},\n", + " {'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'median': 38.0,\n", + " 'pos': 62,\n", + " 'q3': 40.0,\n", + " 'average': 36.145,\n", + " 'q1': 35.0},\n", + " {'upper': 38.0,\n", + " 'median': 34.5,\n", + " 'average': 32.275,\n", + " 'q3': 35.0,\n", + " 'pos': 90,\n", + " 'q1': 33.0,\n", + " 'lower': 30.0},\n", + " {'q1': 35.0,\n", + " 'average': 35.145,\n", + " 'pos': 6,\n", + " 'q3': 37.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'median': 35.0},\n", + " {'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'average': 38.245,\n", + " 'pos': 30,\n", + " 'q3': 40.0,\n", + " 'median': 40.0,\n", + " 'q1': 38.0},\n", + " {'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'average': 38.725,\n", + " 'median': 40.0,\n", + " 'pos': 15},\n", + " {'median': 40.0,\n", + " 'upper': 45.5,\n", + " 'average': 38.245,\n", + " 'pos': 33,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5},\n", + " {'pos': 42,\n", + " 'average': 37.78,\n", + " 'median': 40.0,\n", + " 'q1': 37.0,\n", + " 'lower': 32.5,\n", + " 'upper': 44.5,\n", + " 'q3': 40.0},\n", + " {'pos': 44,\n", + " 'upper': 47.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.565,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'lower': 31.0},\n", + " {'q3': 41.0,\n", + " 'upper': 48.5,\n", + " 'lower': 28.5,\n", + " 'average': 37.59,\n", + " 'median': 39.5,\n", + " 'q1': 36.0,\n", + " 'pos': 54},\n", + " {'average': 32.68,\n", + " 'pos': 73,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'q3': 37.0,\n", + " 'lower': 27.0,\n", + " 'upper': 43.0},\n", + " {'pos': 37,\n", + " 'average': 38.0,\n", + " 'q1': 38.0,\n", + " 'median': 40.0,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0},\n", + " {'average': 38.625,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5,\n", + " 'lower': 33.5,\n", + " 'pos': 20,\n", + " 'q3': 41.0,\n", + " 'median': 40.0},\n", + " {'q3': 41.0,\n", + " 'lower': 31.0,\n", + " 'upper': 47.0,\n", + " 'pos': 47,\n", + " 'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.665},\n", + " {'average': 32.44,\n", + " 'lower': 30.0,\n", + " 'q1': 33.0,\n", + " 'upper': 38.0,\n", + " 'pos': 89,\n", + " 'median': 35.0,\n", + " 'q3': 35.0},\n", + " {'upper': 43.5,\n", + " 'q3': 36.0,\n", + " 'average': 31.46,\n", + " 'median': 35.0,\n", + " 'pos': 78,\n", + " 'q1': 31.0,\n", + " 'lower': 23.5},\n", + " {'upper': 40.0,\n", + " 'q3': 37.0,\n", + " 'median': 36.0,\n", + " 'average': 35.4,\n", + " 'q1': 35.0,\n", + " 'pos': 7,\n", + " 'lower': 32.0},\n", + " {'median': 39.0,\n", + " 'pos': 9,\n", + " 'average': 37.36,\n", + " 'q1': 37.0,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0},\n", + " {'upper': 48.5,\n", + " 'pos': 51,\n", + " 'q1': 36.0,\n", + " 'average': 37.53,\n", + " 'median': 39.0,\n", + " 'lower': 28.5,\n", + " 'q3': 41.0},\n", + " {'median': 34.0,\n", + " 'lower': 25.0,\n", + " 'pos': 97,\n", + " 'upper': 41.0,\n", + " 'q1': 31.0,\n", + " 'q3': 35.0,\n", + " 'average': 30.67},\n", + " {'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'pos': 26,\n", + " 'average': 37.855,\n", + " 'median': 40.0},\n", + " {'pos': 76,\n", + " 'median': 35.0,\n", + " 'q3': 37.0,\n", + " 'lower': 22.0,\n", + " 'upper': 46.0,\n", + " 'average': 30.265,\n", + " 'q1': 31.0},\n", + " {'q3': 36.0,\n", + " 'lower': 26.0,\n", + " 'pos': 80,\n", + " 'average': 32.61,\n", + " 'upper': 42.0,\n", + " 'median': 35.0,\n", + " 'q1': 32.0},\n", + " {'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'average': 38.47,\n", + " 'upper': 45.5,\n", + " 'pos': 18},\n", + " {'pos': 35,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.385,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'upper': 38.0,\n", + " 'lower': 30.0,\n", + " 'average': 32.03,\n", + " 'q3': 35.0,\n", + " 'pos': 83,\n", + " 'median': 35.0,\n", + " 'q1': 33.0},\n", + " {'pos': 31,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.795,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'pos': 3,\n", + " 'median': 37.0,\n", + " 'upper': 40.0,\n", + " 'average': 35.69,\n", + " 'lower': 32.0,\n", + " 'q3': 37.0,\n", + " 'q1': 35.0},\n", + " {'pos': 56,\n", + " 'average': 37.59,\n", + " 'q1': 36.0,\n", + " 'q3': 40.0,\n", + " 'lower': 30.0,\n", + " 'median': 39.0,\n", + " 'upper': 46.0},\n", + " {'upper': 47.5,\n", + " 'pos': 58,\n", + " 'average': 36.77,\n", + " 'median': 38.0,\n", + " 'q1': 35.0,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5},\n", + " {'q3': 40.0,\n", + " 'average': 35.99,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'pos': 61,\n", + " 'median': 38.0,\n", + " 'q1': 35.0},\n", + " {'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'average': 36.095,\n", + " 'q3': 40.0,\n", + " 'upper': 47.5,\n", + " 'lower': 27.5,\n", + " 'pos': 64},\n", + " {'q3': 37.0,\n", + " 'pos': 5,\n", + " 'lower': 32.0,\n", + " 'median': 35.0,\n", + " 'average': 35.095,\n", + " 'q1': 35.0,\n", + " 'upper': 40.0},\n", + " {'q1': 34.0,\n", + " 'pos': 68,\n", + " 'lower': 26.5,\n", + " 'q3': 39.0,\n", + " 'average': 35.91,\n", + " 'upper': 46.5,\n", + " 'median': 36.0},\n", + " {'pos': 87,\n", + " 'q1': 32.0,\n", + " 'lower': 27.5,\n", + " 'average': 31.915,\n", + " 'upper': 39.5,\n", + " 'q3': 35.0,\n", + " 'median': 35.0},\n", + " {'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'median': 34.0,\n", + " 'pos': 95,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0,\n", + " 'average': 31.425},\n", + " {'average': 38.94,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'pos': 13,\n", + " 'median': 40.0,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0},\n", + " {'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'pos': 22,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'average': 38.41},\n", + " {'pos': 70,\n", + " 'q3': 38.0,\n", + " 'average': 33.565,\n", + " 'q1': 34.0,\n", + " 'lower': 28.0,\n", + " 'median': 35.0,\n", + " 'upper': 44.0},\n", + " {'pos': 45,\n", + " 'q1': 36.0,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5,\n", + " 'upper': 48.5,\n", + " 'average': 37.45},\n", + " {'upper': 46.0,\n", + " 'average': 31.06,\n", + " 'median': 35.0,\n", + " 'pos': 75,\n", + " 'q1': 31.0,\n", + " 'q3': 37.0,\n", + " 'lower': 22.0},\n", + " {'pos': 94,\n", + " 'median': 34.0,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0,\n", + " 'average': 30.775,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5},\n", + " {'median': 40.0,\n", + " 'upper': 43.0,\n", + " 'pos': 21,\n", + " 'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'lower': 35.0,\n", + " 'average': 38.445},\n", + " {'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'pos': 16,\n", + " 'average': 38.48,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5},\n", + " {'average': 38.11,\n", + " 'median': 40.0,\n", + " 'lower': 35.0,\n", + " 'q1': 38.0,\n", + " 'upper': 43.0,\n", + " 'q3': 40.0,\n", + " 'pos': 36},\n", + " {'lower': 27.0,\n", + " 'average': 33.265,\n", + " 'median': 35.0,\n", + " 'q3': 37.0,\n", + " 'upper': 43.0,\n", + " 'pos': 72,\n", + " 'q1': 33.0},\n", + " {'average': 32.065,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'pos': 88,\n", + " 'upper': 38.0,\n", + " 'median': 35.0,\n", + " 'q1': 33.0},\n", + " {'upper': 47.0,\n", + " 'q3': 41.0,\n", + " 'pos': 41,\n", + " 'q1': 37.0,\n", + " 'median': 40.0,\n", + " 'lower': 31.0,\n", + " 'average': 37.87},\n", + " {'pos': 43,\n", + " 'upper': 43.0,\n", + " 'q1': 38.0,\n", + " 'lower': 35.0,\n", + " 'median': 40.0,\n", + " 'q3': 40.0,\n", + " 'average': 37.775},\n", + " {'pos': 100,\n", + " 'average': 31.105,\n", + " 'q1': 31.0,\n", + " 'median': 34.0,\n", + " 'upper': 41.0,\n", + " 'q3': 35.0,\n", + " 'lower': 25.0},\n", + " {'pos': 32,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'average': 38.29,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0},\n", + " {'average': 37.64,\n", + " 'pos': 38,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'median': 40.0},\n", + " {'pos': 67,\n", + " 'median': 36.5,\n", + " 'q1': 34.0,\n", + " 'q3': 39.0,\n", + " 'lower': 26.5,\n", + " 'upper': 46.5,\n", + " 'average': 35.96},\n", + " {'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'average': 38.205,\n", + " 'pos': 34,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'upper': 38.0,\n", + " 'q3': 35.0,\n", + " 'q1': 33.0,\n", + " 'average': 32.415,\n", + " 'pos': 84,\n", + " 'median': 35.0,\n", + " 'lower': 30.0},\n", + " {'upper': 40.0,\n", + " 'pos': 4,\n", + " 'average': 35.68,\n", + " 'q1': 35.0,\n", + " 'median': 37.0,\n", + " 'q3': 37.0,\n", + " 'lower': 32.0},\n", + " {'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 27,\n", + " 'average': 38.44,\n", + " 'median': 40.0,\n", + " 'q1': 38.0},\n", + " {'lower': 30.0,\n", + " 'average': 37.21,\n", + " 'q3': 40.0,\n", + " 'pos': 49,\n", + " 'upper': 46.0,\n", + " 'median': 39.0,\n", + " 'q1': 36.0},\n", + " {'q3': 39.0,\n", + " 'upper': 45.0,\n", + " 'average': 35.995,\n", + " 'lower': 29.0,\n", + " 'q1': 35.0,\n", + " 'pos': 65,\n", + " 'median': 37.0},\n", + " {'upper': 40.5,\n", + " 'average': 32.76,\n", + " 'q1': 33.0,\n", + " 'q3': 36.0,\n", + " 'median': 35.0,\n", + " 'pos': 81,\n", + " 'lower': 28.5},\n", + " {'pos': 17,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'lower': 33.5,\n", + " 'average': 38.505,\n", + " 'q1': 38.0,\n", + " 'median': 40.0},\n", + " {'lower': 33.5,\n", + " 'pos': 25,\n", + " 'upper': 45.5,\n", + " 'average': 38.2,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0},\n", + " {'upper': 45.5,\n", + " 'q3': 38.0,\n", + " 'pos': 71,\n", + " 'average': 33.005,\n", + " 'q1': 33.0,\n", + " 'lower': 25.5,\n", + " 'median': 35.0},\n", + " {'pos': 14,\n", + " 'average': 38.965,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'median': 40.0},\n", + " {'q1': 31.0,\n", + " 'upper': 38.5,\n", + " 'q3': 34.0,\n", + " 'lower': 26.5,\n", + " 'median': 34.0,\n", + " 'average': 31.21,\n", + " 'pos': 1},\n", + " {'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'q3': 40.0,\n", + " 'median': 38.0,\n", + " 'q1': 35.0,\n", + " 'pos': 63,\n", + " 'average': 36.25},\n", + " {'average': 30.805,\n", + " 'q1': 30.0,\n", + " 'lower': 21.0,\n", + " 'upper': 45.0,\n", + " 'pos': 77,\n", + " 'median': 35.0,\n", + " 'q3': 36.0},\n", + " {'q1': 32.0,\n", + " 'pos': 79,\n", + " 'median': 35.0,\n", + " 'q3': 36.0,\n", + " 'average': 32.46,\n", + " 'lower': 26.0,\n", + " 'upper': 42.0},\n", + " {'average': 32.015,\n", + " 'q1': 31.0,\n", + " 'lower': 26.5,\n", + " 'pos': 2,\n", + " 'q3': 34.0,\n", + " 'upper': 38.5,\n", + " 'median': 34.0},\n", + " {'upper': 44.5,\n", + " 'lower': 32.5,\n", + " 'q1': 37.0,\n", + " 'pos': 52,\n", + " 'median': 39.0,\n", + " 'average': 37.77,\n", + " 'q3': 40.0},\n", + " {'average': 35.985,\n", + " 'pos': 60,\n", + " 'q1': 35.0,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'q3': 40.0,\n", + " 'median': 38.0},\n", + " {'lower': 30.0,\n", + " 'average': 31.815,\n", + " 'median': 35.0,\n", + " 'upper': 38.0,\n", + " 'pos': 86,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0},\n", + " {'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'pos': 29,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.595},\n", + " {'average': 31.55,\n", + " 'median': 34.0,\n", + " 'q1': 32.0,\n", + " 'upper': 39.5,\n", + " 'pos': 98,\n", + " 'lower': 27.5,\n", + " 'q3': 35.0},\n", + " {'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'pos': 19,\n", + " 'upper': 45.5,\n", + " 'average': 38.425},\n", + " {'pos': 11,\n", + " 'average': 37.71,\n", + " 'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0}]}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", + "a_dataframe = a_lazyframe.collect()\n", + "print(type(a_dataframe))\n", + "pb.base_sequence_quality(a_dataframe)" + ] + }, + { + "cell_type": "markdown", + "id": "ddf5da9d", + "metadata": {}, + "source": [ + "#### Usage example - `pandas.core.frame.DataFrame` object" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "56817174", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:polars_bio:Table: example registered for path: ./example.fastq\n", + "200rows [00:00, 120508.66rows/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "{'base_quality_warn': 'pass',\n", + " 'base_per_pos_data': [{'upper': 41.0,\n", + " 'q3': 35.0,\n", + " 'lower': 25.0,\n", + " 'pos': 97,\n", + " 'average': 30.67,\n", + " 'median': 34.0,\n", + " 'q1': 31.0},\n", + " {'q1': 38.0,\n", + " 'pos': 14,\n", + " 'average': 38.965,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0},\n", + " {'pos': 23,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.635,\n", + " 'lower': 33.5,\n", + " 'median': 40.0},\n", + " {'q1': 37.0,\n", + " 'lower': 34.0,\n", + " 'average': 37.71,\n", + " 'upper': 42.0,\n", + " 'q3': 39.0,\n", + " 'median': 39.0,\n", + " 'pos': 11},\n", + " {'average': 38.425,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'pos': 19},\n", + " {'q3': 34.0,\n", + " 'upper': 38.5,\n", + " 'average': 32.015,\n", + " 'q1': 31.0,\n", + " 'lower': 26.5,\n", + " 'pos': 2,\n", + " 'median': 34.0},\n", + " {'upper': 48.5,\n", + " 'q1': 36.0,\n", + " 'average': 37.45,\n", + " 'median': 40.0,\n", + " 'pos': 45,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5},\n", + " {'average': 37.61,\n", + " 'pos': 48,\n", + " 'median': 40.0,\n", + " 'q1': 36.0,\n", + " 'upper': 48.5,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5},\n", + " {'q1': 38.0,\n", + " 'median': 40.0,\n", + " 'lower': 35.0,\n", + " 'pos': 37,\n", + " 'q3': 40.0,\n", + " 'upper': 43.0,\n", + " 'average': 38.0},\n", + " {'pos': 74,\n", + " 'median': 35.0,\n", + " 'q3': 37.0,\n", + " 'q1': 32.0,\n", + " 'average': 30.83,\n", + " 'lower': 24.5,\n", + " 'upper': 44.5},\n", + " {'average': 33.565,\n", + " 'pos': 70,\n", + " 'q1': 34.0,\n", + " 'q3': 38.0,\n", + " 'lower': 28.0,\n", + " 'upper': 44.0,\n", + " 'median': 35.0},\n", + " {'upper': 45.5,\n", + " 'pos': 31,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.795},\n", + " {'average': 32.195,\n", + " 'median': 35.0,\n", + " 'upper': 38.0,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'pos': 85},\n", + " {'pos': 15,\n", + " 'upper': 45.5,\n", + " 'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0,\n", + " 'average': 38.725},\n", + " {'q1': 32.0,\n", + " 'median': 35.0,\n", + " 'lower': 27.5,\n", + " 'pos': 91,\n", + " 'q3': 35.0,\n", + " 'upper': 39.5,\n", + " 'average': 32.665},\n", + " {'median': 34.0,\n", + " 'pos': 1,\n", + " 'q1': 31.0,\n", + " 'lower': 26.5,\n", + " 'average': 31.21,\n", + " 'q3': 34.0,\n", + " 'upper': 38.5},\n", + " {'median': 34.0,\n", + " 'q3': 35.0,\n", + " 'upper': 39.5,\n", + " 'q1': 32.0,\n", + " 'pos': 96,\n", + " 'average': 31.315,\n", + " 'lower': 27.5},\n", + " {'upper': 39.5,\n", + " 'median': 34.0,\n", + " 'lower': 27.5,\n", + " 'pos': 99,\n", + " 'q1': 32.0,\n", + " 'average': 31.25,\n", + " 'q3': 35.0},\n", + " {'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'average': 38.595,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'pos': 29,\n", + " 'lower': 33.5},\n", + " {'median': 40.0,\n", + " 'upper': 43.0,\n", + " 'q1': 38.0,\n", + " 'average': 38.245,\n", + " 'pos': 30,\n", + " 'lower': 35.0,\n", + " 'q3': 40.0},\n", + " {'q3': 35.0,\n", + " 'q1': 32.0,\n", + " 'average': 31.55,\n", + " 'median': 34.0,\n", + " 'upper': 39.5,\n", + " 'lower': 27.5,\n", + " 'pos': 98},\n", + " {'pos': 52,\n", + " 'q1': 37.0,\n", + " 'q3': 40.0,\n", + " 'upper': 44.5,\n", + " 'lower': 32.5,\n", + " 'median': 39.0,\n", + " 'average': 37.77},\n", + " {'lower': 32.0,\n", + " 'pos': 4,\n", + " 'q1': 35.0,\n", + " 'average': 35.68,\n", + " 'q3': 37.0,\n", + " 'median': 37.0,\n", + " 'upper': 40.0},\n", + " {'average': 35.69,\n", + " 'q3': 37.0,\n", + " 'lower': 32.0,\n", + " 'upper': 40.0,\n", + " 'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'pos': 3},\n", + " {'median': 40.0,\n", + " 'pos': 38,\n", + " 'average': 37.64,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'pos': 46,\n", + " 'upper': 47.0,\n", + " 'q3': 41.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.79,\n", + " 'median': 39.5,\n", + " 'lower': 31.0},\n", + " {'pos': 82,\n", + " 'average': 31.525,\n", + " 'lower': 28.5,\n", + " 'upper': 40.5,\n", + " 'median': 35.0,\n", + " 'q3': 36.0,\n", + " 'q1': 33.0},\n", + " {'upper': 40.0,\n", + " 'lower': 32.0,\n", + " 'average': 35.095,\n", + " 'pos': 5,\n", + " 'median': 35.0,\n", + " 'q1': 35.0,\n", + " 'q3': 37.0},\n", + " {'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'median': 40.0,\n", + " 'average': 38.2,\n", + " 'pos': 25,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5},\n", + " {'pos': 33,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'upper': 45.5,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.245},\n", + " {'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'upper': 45.5,\n", + " 'pos': 24,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.265},\n", + " {'pos': 43,\n", + " 'average': 37.775,\n", + " 'q1': 38.0,\n", + " 'lower': 35.0,\n", + " 'q3': 40.0,\n", + " 'upper': 43.0,\n", + " 'median': 40.0},\n", + " {'median': 39.0,\n", + " 'q3': 40.0,\n", + " 'pos': 56,\n", + " 'lower': 30.0,\n", + " 'q1': 36.0,\n", + " 'upper': 46.0,\n", + " 'average': 37.59},\n", + " {'median': 37.0,\n", + " 'q3': 39.0,\n", + " 'lower': 29.0,\n", + " 'average': 35.875,\n", + " 'pos': 66,\n", + " 'q1': 35.0,\n", + " 'upper': 45.0},\n", + " {'upper': 45.5,\n", + " 'median': 35.0,\n", + " 'q3': 38.0,\n", + " 'pos': 71,\n", + " 'q1': 33.0,\n", + " 'average': 33.005,\n", + " 'lower': 25.5},\n", + " {'pos': 34,\n", + " 'median': 40.0,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.205,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'pos': 68,\n", + " 'upper': 46.5,\n", + " 'lower': 26.5,\n", + " 'median': 36.0,\n", + " 'q1': 34.0,\n", + " 'q3': 39.0,\n", + " 'average': 35.91},\n", + " {'average': 31.425,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'median': 34.0,\n", + " 'pos': 95,\n", + " 'q1': 32.0,\n", + " 'q3': 35.0},\n", + " {'median': 39.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.665,\n", + " 'q3': 41.0,\n", + " 'lower': 31.0,\n", + " 'pos': 47,\n", + " 'upper': 47.0},\n", + " {'median': 38.0,\n", + " 'q3': 40.0,\n", + " 'upper': 47.5,\n", + " 'average': 36.145,\n", + " 'lower': 27.5,\n", + " 'pos': 62,\n", + " 'q1': 35.0},\n", + " {'upper': 46.0,\n", + " 'median': 39.0,\n", + " 'q1': 36.0,\n", + " 'lower': 30.0,\n", + " 'q3': 40.0,\n", + " 'pos': 49,\n", + " 'average': 37.21},\n", + " {'upper': 44.5,\n", + " 'q3': 40.0,\n", + " 'q1': 37.0,\n", + " 'average': 37.78,\n", + " 'pos': 42,\n", + " 'median': 40.0,\n", + " 'lower': 32.5},\n", + " {'pos': 10,\n", + " 'average': 37.675,\n", + " 'lower': 34.0,\n", + " 'median': 39.0,\n", + " 'q3': 39.0,\n", + " 'q1': 37.0,\n", + " 'upper': 42.0},\n", + " {'median': 39.0,\n", + " 'q3': 40.0,\n", + " 'lower': 30.0,\n", + " 'average': 37.55,\n", + " 'q1': 36.0,\n", + " 'pos': 55,\n", + " 'upper': 46.0},\n", + " {'median': 34.5,\n", + " 'q3': 35.0,\n", + " 'average': 32.275,\n", + " 'pos': 90,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'q1': 33.0},\n", + " {'q1': 36.0,\n", + " 'average': 37.425,\n", + " 'upper': 48.5,\n", + " 'pos': 50,\n", + " 'lower': 28.5,\n", + " 'q3': 41.0,\n", + " 'median': 39.0},\n", + " {'average': 38.48,\n", + " 'q3': 41.0,\n", + " 'median': 40.0,\n", + " 'pos': 16,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5},\n", + " {'lower': 33.5,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'pos': 18,\n", + " 'average': 38.47,\n", + " 'q1': 38.0},\n", + " {'median': 40.0,\n", + " 'pos': 28,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'q3': 41.0,\n", + " 'q1': 38.0,\n", + " 'average': 38.445},\n", + " {'upper': 48.5,\n", + " 'q3': 41.0,\n", + " 'q1': 36.0,\n", + " 'average': 37.53,\n", + " 'median': 39.0,\n", + " 'pos': 51,\n", + " 'lower': 28.5},\n", + " {'pos': 100,\n", + " 'q3': 35.0,\n", + " 'upper': 41.0,\n", + " 'q1': 31.0,\n", + " 'lower': 25.0,\n", + " 'average': 31.105,\n", + " 'median': 34.0},\n", + " {'median': 40.0,\n", + " 'average': 37.95,\n", + " 'q1': 38.0,\n", + " 'pos': 40,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'q3': 40.0},\n", + " {'q1': 37.0,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0,\n", + " 'median': 39.0,\n", + " 'average': 37.36,\n", + " 'pos': 9},\n", + " {'pos': 69,\n", + " 'q3': 39.0,\n", + " 'lower': 26.5,\n", + " 'upper': 46.5,\n", + " 'q1': 34.0,\n", + " 'median': 36.0,\n", + " 'average': 33.7},\n", + " {'pos': 89,\n", + " 'average': 32.44,\n", + " 'median': 35.0,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0},\n", + " {'average': 32.03,\n", + " 'pos': 83,\n", + " 'q1': 33.0,\n", + " 'q3': 35.0,\n", + " 'median': 35.0,\n", + " 'upper': 38.0,\n", + " 'lower': 30.0},\n", + " {'q3': 34.0,\n", + " 'lower': 26.5,\n", + " 'average': 30.135,\n", + " 'pos': 0,\n", + " 'upper': 38.5,\n", + " 'q1': 31.0,\n", + " 'median': 33.0},\n", + " {'average': 36.08,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'median': 38.0,\n", + " 'pos': 59,\n", + " 'q1': 35.0,\n", + " 'q3': 40.0},\n", + " {'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.385,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 35},\n", + " {'pos': 39,\n", + " 'average': 37.895,\n", + " 'q1': 38.0,\n", + " 'lower': 35.0,\n", + " 'q3': 40.0,\n", + " 'upper': 43.0,\n", + " 'median': 40.0},\n", + " {'median': 40.0,\n", + " 'average': 38.505,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'pos': 17,\n", + " 'q3': 41.0},\n", + " {'pos': 20,\n", + " 'median': 40.0,\n", + " 'q3': 41.0,\n", + " 'average': 38.625,\n", + " 'lower': 33.5,\n", + " 'q1': 38.0,\n", + " 'upper': 45.5},\n", + " {'q3': 37.0,\n", + " 'q1': 35.0,\n", + " 'upper': 40.0,\n", + " 'pos': 7,\n", + " 'median': 36.0,\n", + " 'average': 35.4,\n", + " 'lower': 32.0},\n", + " {'average': 32.415,\n", + " 'q1': 33.0,\n", + " 'median': 35.0,\n", + " 'q3': 35.0,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'pos': 84},\n", + " {'pos': 67,\n", + " 'q1': 34.0,\n", + " 'average': 35.96,\n", + " 'median': 36.5,\n", + " 'q3': 39.0,\n", + " 'upper': 46.5,\n", + " 'lower': 26.5},\n", + " {'q1': 38.0,\n", + " 'average': 38.11,\n", + " 'pos': 36,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'q3': 40.0,\n", + " 'median': 40.0},\n", + " {'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'average': 38.41,\n", + " 'pos': 22,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0},\n", + " {'q1': 35.0,\n", + " 'lower': 27.5,\n", + " 'average': 36.77,\n", + " 'median': 38.0,\n", + " 'pos': 58,\n", + " 'q3': 40.0,\n", + " 'upper': 47.5},\n", + " {'q1': 33.0,\n", + " 'lower': 27.0,\n", + " 'average': 32.68,\n", + " 'pos': 73,\n", + " 'upper': 43.0,\n", + " 'median': 35.0,\n", + " 'q3': 37.0},\n", + " {'median': 40.0,\n", + " 'pos': 32,\n", + " 'q1': 38.0,\n", + " 'lower': 33.5,\n", + " 'average': 38.29,\n", + " 'q3': 41.0,\n", + " 'upper': 45.5},\n", + " {'pos': 72,\n", + " 'average': 33.265,\n", + " 'q3': 37.0,\n", + " 'q1': 33.0,\n", + " 'lower': 27.0,\n", + " 'upper': 43.0,\n", + " 'median': 35.0},\n", + " {'average': 35.99,\n", + " 'q1': 35.0,\n", + " 'pos': 61,\n", + " 'q3': 40.0,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'median': 38.0},\n", + " {'pos': 76,\n", + " 'average': 30.265,\n", + " 'median': 35.0,\n", + " 'q3': 37.0,\n", + " 'lower': 22.0,\n", + " 'upper': 46.0,\n", + " 'q1': 31.0},\n", + " {'pos': 79,\n", + " 'q1': 32.0,\n", + " 'lower': 26.0,\n", + " 'average': 32.46,\n", + " 'upper': 42.0,\n", + " 'median': 35.0,\n", + " 'q3': 36.0},\n", + " {'pos': 26,\n", + " 'average': 37.855,\n", + " 'median': 40.0,\n", + " 'lower': 35.0,\n", + " 'upper': 43.0,\n", + " 'q1': 38.0,\n", + " 'q3': 40.0},\n", + " {'pos': 93,\n", + " 'q3': 35.0,\n", + " 'upper': 39.5,\n", + " 'lower': 27.5,\n", + " 'q1': 32.0,\n", + " 'median': 34.0,\n", + " 'average': 31.05},\n", + " {'pos': 75,\n", + " 'q3': 37.0,\n", + " 'lower': 22.0,\n", + " 'median': 35.0,\n", + " 'q1': 31.0,\n", + " 'average': 31.06,\n", + " 'upper': 46.0},\n", + " {'average': 37.35,\n", + " 'q3': 40.0,\n", + " 'q1': 36.0,\n", + " 'lower': 30.0,\n", + " 'upper': 46.0,\n", + " 'pos': 57,\n", + " 'median': 39.0},\n", + " {'lower': 27.5,\n", + " 'average': 35.985,\n", + " 'pos': 60,\n", + " 'q1': 35.0,\n", + " 'q3': 40.0,\n", + " 'upper': 47.5,\n", + " 'median': 38.0},\n", + " {'upper': 47.0,\n", + " 'lower': 31.0,\n", + " 'q1': 37.0,\n", + " 'pos': 44,\n", + " 'average': 37.565,\n", + " 'median': 40.0,\n", + " 'q3': 41.0},\n", + " {'median': 35.0,\n", + " 'q1': 32.0,\n", + " 'lower': 27.5,\n", + " 'average': 31.915,\n", + " 'pos': 87,\n", + " 'upper': 39.5,\n", + " 'q3': 35.0},\n", + " {'average': 32.065,\n", + " 'median': 35.0,\n", + " 'q3': 35.0,\n", + " 'pos': 88,\n", + " 'lower': 30.0,\n", + " 'upper': 38.0,\n", + " 'q1': 33.0},\n", + " {'upper': 47.0,\n", + " 'pos': 53,\n", + " 'q1': 37.0,\n", + " 'average': 37.845,\n", + " 'q3': 41.0,\n", + " 'median': 39.0,\n", + " 'lower': 31.0},\n", + " {'median': 35.0,\n", + " 'q3': 36.0,\n", + " 'pos': 81,\n", + " 'q1': 33.0,\n", + " 'lower': 28.5,\n", + " 'upper': 40.5,\n", + " 'average': 32.76},\n", + " {'pos': 8,\n", + " 'lower': 34.0,\n", + " 'upper': 42.0,\n", + " 'average': 37.625,\n", + " 'median': 39.0,\n", + " 'q3': 39.0,\n", + " 'q1': 37.0},\n", + " {'pos': 12,\n", + " 'average': 37.5,\n", + " 'upper': 42.0,\n", + " 'q1': 37.0,\n", + " 'median': 39.0,\n", + " 'q3': 39.0,\n", + " 'lower': 34.0},\n", + " {'q1': 36.0,\n", + " 'average': 37.59,\n", + " 'q3': 41.0,\n", + " 'lower': 28.5,\n", + " 'upper': 48.5,\n", + " 'pos': 54,\n", + " 'median': 39.5},\n", + " {'average': 36.25,\n", + " 'median': 38.0,\n", + " 'q1': 35.0,\n", + " 'lower': 27.5,\n", + " 'upper': 47.5,\n", + " 'pos': 63,\n", + " 'q3': 40.0},\n", + " {'q1': 32.0,\n", + " 'pos': 80,\n", + " 'average': 32.61,\n", + " 'median': 35.0,\n", + " 'upper': 42.0,\n", + " 'q3': 36.0,\n", + " 'lower': 26.0},\n", + " {'lower': 27.5,\n", + " 'median': 35.0,\n", + " 'q1': 32.0,\n", + " 'average': 31.835,\n", + " 'q3': 35.0,\n", + " 'upper': 39.5,\n", + " 'pos': 92},\n", + " {'upper': 38.0,\n", + " 'median': 35.0,\n", + " 'lower': 30.0,\n", + " 'q3': 35.0,\n", + " 'average': 31.815,\n", + " 'pos': 86,\n", + " 'q1': 33.0},\n", + " {'q3': 41.0,\n", + " 'upper': 45.5,\n", + " 'lower': 33.5,\n", + " 'pos': 27,\n", + " 'average': 38.44,\n", + " 'median': 40.0,\n", + " 'q1': 38.0},\n", + " {'pos': 94,\n", + " 'q1': 32.0,\n", + " 'lower': 27.5,\n", + " 'upper': 39.5,\n", + " 'average': 30.775,\n", + " 'median': 34.0,\n", + " 'q3': 35.0},\n", + " {'pos': 65,\n", + " 'upper': 45.0,\n", + " 'median': 37.0,\n", + " 'q1': 35.0,\n", + " 'q3': 39.0,\n", + " 'lower': 29.0,\n", + " 'average': 35.995},\n", + " {'average': 37.87,\n", + " 'q3': 41.0,\n", + " 'upper': 47.0,\n", + " 'q1': 37.0,\n", + " 'lower': 31.0,\n", + " 'pos': 41,\n", + " 'median': 40.0},\n", + " {'pos': 77,\n", + " 'average': 30.805,\n", + " 'upper': 45.0,\n", + " 'median': 35.0,\n", + " 'q3': 36.0,\n", + " 'q1': 30.0,\n", + " 'lower': 21.0},\n", + " {'pos': 13,\n", + " 'q1': 38.0,\n", + " 'q3': 41.0,\n", + " 'lower': 33.5,\n", + " 'upper': 45.5,\n", + " 'median': 40.0,\n", + " 'average': 38.94},\n", + " {'lower': 35.0,\n", + " 'q1': 38.0,\n", + " 'q3': 40.0,\n", + " 'upper': 43.0,\n", + " 'pos': 21,\n", + " 'average': 38.445,\n", + " 'median': 40.0},\n", + " {'q3': 36.0,\n", + " 'median': 35.0,\n", + " 'average': 31.46,\n", + " 'q1': 31.0,\n", + " 'pos': 78,\n", + " 'lower': 23.5,\n", + " 'upper': 43.5},\n", + " {'q3': 37.0,\n", + " 'lower': 32.0,\n", + " 'pos': 6,\n", + " 'upper': 40.0,\n", + " 'median': 35.0,\n", + " 'q1': 35.0,\n", + " 'average': 35.145},\n", + " {'pos': 64,\n", + " 'q3': 40.0,\n", + " 'median': 37.0,\n", + " 'lower': 27.5,\n", + " 'q1': 35.0,\n", + " 'upper': 47.5,\n", + " 'average': 36.095}]}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", + "a_pandas_dataframe = a_lazyframe.collect().to_pandas()\n", + "print(type(a_pandas_dataframe))\n", + "pb.base_sequence_quality(a_pandas_dataframe)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "3.12.9", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a982f0e144743d13483359d4f4cd3cc7e94e5b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20=C5=9Acise=C5=82?= Date: Wed, 4 Jun 2025 21:20:54 +0200 Subject: [PATCH 5/6] Refactor base sequence quality computation and integrate DataFusion - Updated `base_sequence_quality` function to accept a quality scores column and output type. - Introduced `BaseSequenceQualityProvider` and `BaseSequenceQualityExec` in Rust for efficient execution plans. - Removed the custom UDAF for quality scores and replaced it with a DataFusion table provider. - Simplified data handling by directly using DataFrames from DataFusion. - Cleaned up unnecessary code and files related to UDAF implementation. - Enhanced error handling and type checking for input data. --- docs/notebooks/base_sequence_quality.ipynb | 4461 +------------------- docs/notebooks/tutorial.ipynb | 336 +- polars_bio/quality_stats.py | 48 +- src/base_sequence_quality.rs | 247 ++ src/context.rs | 17 - src/lib.rs | 138 +- src/operation.rs | 41 +- src/scan.rs | 4 - src/udaf.rs | 210 - 9 files changed, 776 insertions(+), 4726 deletions(-) create mode 100644 src/base_sequence_quality.rs delete mode 100644 src/udaf.rs diff --git a/docs/notebooks/base_sequence_quality.ipynb b/docs/notebooks/base_sequence_quality.ipynb index 35d8bed5..cac9a2ce 100644 --- a/docs/notebooks/base_sequence_quality.ipynb +++ b/docs/notebooks/base_sequence_quality.ipynb @@ -47,37 +47,15 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "5f6fccf3", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:polars_bio:Table: example registered for path: ./example.fastq\n", - "1rows [00:00, 327.48rows/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'base_quality_warn': 'pass', 'base_per_pos_data': [{'pos': 89, 'average': 32.44, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 84, 'average': 32.415, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 96, 'average': 31.315, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 31, 'average': 38.795, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 49, 'average': 37.21, 'median': 39.0, 'q1': 36.0, 'q3': 40.0, 'lower': 30.0, 'upper': 46.0}, {'pos': 69, 'average': 33.7, 'median': 36.0, 'q1': 34.0, 'q3': 39.0, 'lower': 26.5, 'upper': 46.5}, {'pos': 63, 'average': 36.25, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 65, 'average': 35.995, 'median': 37.0, 'q1': 35.0, 'q3': 39.0, 'lower': 29.0, 'upper': 45.0}, {'pos': 70, 'average': 33.565, 'median': 35.0, 'q1': 34.0, 'q3': 38.0, 'lower': 28.0, 'upper': 44.0}, {'pos': 68, 'average': 35.91, 'median': 36.0, 'q1': 34.0, 'q3': 39.0, 'lower': 26.5, 'upper': 46.5}, {'pos': 55, 'average': 37.55, 'median': 39.0, 'q1': 36.0, 'q3': 40.0, 'lower': 30.0, 'upper': 46.0}, {'pos': 24, 'average': 38.265, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 21, 'average': 38.445, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 60, 'average': 35.985, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 45, 'average': 37.45, 'median': 40.0, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 30, 'average': 38.245, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 20, 'average': 38.625, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 82, 'average': 31.525, 'median': 35.0, 'q1': 33.0, 'q3': 36.0, 'lower': 28.5, 'upper': 40.5}, {'pos': 85, 'average': 32.195, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 35, 'average': 38.385, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 57, 'average': 37.35, 'median': 39.0, 'q1': 36.0, 'q3': 40.0, 'lower': 30.0, 'upper': 46.0}, {'pos': 66, 'average': 35.875, 'median': 37.0, 'q1': 35.0, 'q3': 39.0, 'lower': 29.0, 'upper': 45.0}, {'pos': 74, 'average': 30.83, 'median': 35.0, 'q1': 32.0, 'q3': 37.0, 'lower': 24.5, 'upper': 44.5}, {'pos': 86, 'average': 31.815, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 87, 'average': 31.915, 'median': 35.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 88, 'average': 32.065, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 42, 'average': 37.78, 'median': 40.0, 'q1': 37.0, 'q3': 40.0, 'lower': 32.5, 'upper': 44.5}, {'pos': 51, 'average': 37.53, 'median': 39.0, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 71, 'average': 33.005, 'median': 35.0, 'q1': 33.0, 'q3': 38.0, 'lower': 25.5, 'upper': 45.5}, {'pos': 72, 'average': 33.265, 'median': 35.0, 'q1': 33.0, 'q3': 37.0, 'lower': 27.0, 'upper': 43.0}, {'pos': 90, 'average': 32.275, 'median': 34.5, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 23, 'average': 38.635, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 32, 'average': 38.29, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 11, 'average': 37.71, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 43, 'average': 37.775, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 91, 'average': 32.665, 'median': 35.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 6, 'average': 35.145, 'median': 35.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 67, 'average': 35.96, 'median': 36.5, 'q1': 34.0, 'q3': 39.0, 'lower': 26.5, 'upper': 46.5}, {'pos': 76, 'average': 30.265, 'median': 35.0, 'q1': 31.0, 'q3': 37.0, 'lower': 22.0, 'upper': 46.0}, {'pos': 52, 'average': 37.77, 'median': 39.0, 'q1': 37.0, 'q3': 40.0, 'lower': 32.5, 'upper': 44.5}, {'pos': 73, 'average': 32.68, 'median': 35.0, 'q1': 33.0, 'q3': 37.0, 'lower': 27.0, 'upper': 43.0}, {'pos': 29, 'average': 38.595, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 17, 'average': 38.505, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 53, 'average': 37.845, 'median': 39.0, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 77, 'average': 30.805, 'median': 35.0, 'q1': 30.0, 'q3': 36.0, 'lower': 21.0, 'upper': 45.0}, {'pos': 12, 'average': 37.5, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 37, 'average': 38.0, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 83, 'average': 32.03, 'median': 35.0, 'q1': 33.0, 'q3': 35.0, 'lower': 30.0, 'upper': 38.0}, {'pos': 99, 'average': 31.25, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 48, 'average': 37.61, 'median': 40.0, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 4, 'average': 35.68, 'median': 37.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 56, 'average': 37.59, 'median': 39.0, 'q1': 36.0, 'q3': 40.0, 'lower': 30.0, 'upper': 46.0}, {'pos': 8, 'average': 37.625, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 18, 'average': 38.47, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 38, 'average': 37.64, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 39, 'average': 37.895, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 41, 'average': 37.87, 'median': 40.0, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 19, 'average': 38.425, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 15, 'average': 38.725, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 78, 'average': 31.46, 'median': 35.0, 'q1': 31.0, 'q3': 36.0, 'lower': 23.5, 'upper': 43.5}, {'pos': 62, 'average': 36.145, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 13, 'average': 38.94, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 28, 'average': 38.445, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 93, 'average': 31.05, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 94, 'average': 30.775, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 100, 'average': 31.105, 'median': 34.0, 'q1': 31.0, 'q3': 35.0, 'lower': 25.0, 'upper': 41.0}, {'pos': 64, 'average': 36.095, 'median': 37.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 61, 'average': 35.99, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 44, 'average': 37.565, 'median': 40.0, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 40, 'average': 37.95, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 92, 'average': 31.835, 'median': 35.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 46, 'average': 37.79, 'median': 39.5, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 10, 'average': 37.675, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 36, 'average': 38.11, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 0, 'average': 30.135, 'median': 33.0, 'q1': 31.0, 'q3': 34.0, 'lower': 26.5, 'upper': 38.5}, {'pos': 33, 'average': 38.245, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 26, 'average': 37.855, 'median': 40.0, 'q1': 38.0, 'q3': 40.0, 'lower': 35.0, 'upper': 43.0}, {'pos': 95, 'average': 31.425, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 98, 'average': 31.55, 'median': 34.0, 'q1': 32.0, 'q3': 35.0, 'lower': 27.5, 'upper': 39.5}, {'pos': 81, 'average': 32.76, 'median': 35.0, 'q1': 33.0, 'q3': 36.0, 'lower': 28.5, 'upper': 40.5}, {'pos': 14, 'average': 38.965, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 75, 'average': 31.06, 'median': 35.0, 'q1': 31.0, 'q3': 37.0, 'lower': 22.0, 'upper': 46.0}, {'pos': 5, 'average': 35.095, 'median': 35.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 16, 'average': 38.48, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 3, 'average': 35.69, 'median': 37.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 27, 'average': 38.44, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 54, 'average': 37.59, 'median': 39.5, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 9, 'average': 37.36, 'median': 39.0, 'q1': 37.0, 'q3': 39.0, 'lower': 34.0, 'upper': 42.0}, {'pos': 97, 'average': 30.67, 'median': 34.0, 'q1': 31.0, 'q3': 35.0, 'lower': 25.0, 'upper': 41.0}, {'pos': 7, 'average': 35.4, 'median': 36.0, 'q1': 35.0, 'q3': 37.0, 'lower': 32.0, 'upper': 40.0}, {'pos': 22, 'average': 38.41, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 47, 'average': 37.665, 'median': 39.0, 'q1': 37.0, 'q3': 41.0, 'lower': 31.0, 'upper': 47.0}, {'pos': 59, 'average': 36.08, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 79, 'average': 32.46, 'median': 35.0, 'q1': 32.0, 'q3': 36.0, 'lower': 26.0, 'upper': 42.0}, {'pos': 50, 'average': 37.425, 'median': 39.0, 'q1': 36.0, 'q3': 41.0, 'lower': 28.5, 'upper': 48.5}, {'pos': 34, 'average': 38.205, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 58, 'average': 36.77, 'median': 38.0, 'q1': 35.0, 'q3': 40.0, 'lower': 27.5, 'upper': 47.5}, {'pos': 25, 'average': 38.2, 'median': 40.0, 'q1': 38.0, 'q3': 41.0, 'lower': 33.5, 'upper': 45.5}, {'pos': 2, 'average': 32.015, 'median': 34.0, 'q1': 31.0, 'q3': 34.0, 'lower': 26.5, 'upper': 38.5}, {'pos': 1, 'average': 31.21, 'median': 34.0, 'q1': 31.0, 'q3': 34.0, 'lower': 26.5, 'upper': 38.5}, {'pos': 80, 'average': 32.61, 'median': 35.0, 'q1': 32.0, 'q3': 36.0, 'lower': 26.0, 'upper': 42.0}]}\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], + "outputs": [], "source": [ "a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", - "result = pb.sql(\"SELECT base_sequence_quality(quality_scores) FROM example\").collect()\n", - "print(result.item())" + "# not implemented yet\n", + "result = pb.sql(\"???\").collect()\n", + "print(result)" ] }, { @@ -95,725 +73,29 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "{'base_quality_warn': 'pass',\n", - " 'base_per_pos_data': [{'lower': 33.5,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0,\n", - " 'median': 40.0,\n", - " 'average': 38.205,\n", - " 'upper': 45.5,\n", - " 'pos': 34},\n", - " {'average': 38.47,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'pos': 18,\n", - " 'upper': 45.5},\n", - " {'q3': 35.0,\n", - " 'average': 31.815,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'pos': 86,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0},\n", - " {'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'pos': 21,\n", - " 'average': 38.445,\n", - " 'q1': 38.0,\n", - " 'median': 40.0},\n", - " {'lower': 27.5,\n", - " 'average': 31.835,\n", - " 'q3': 35.0,\n", - " 'median': 35.0,\n", - " 'q1': 32.0,\n", - " 'upper': 39.5,\n", - " 'pos': 92},\n", - " {'q3': 35.0,\n", - " 'lower': 27.5,\n", - " 'pos': 95,\n", - " 'upper': 39.5,\n", - " 'median': 34.0,\n", - " 'q1': 32.0,\n", - " 'average': 31.425},\n", - " {'average': 35.91,\n", - " 'q3': 39.0,\n", - " 'lower': 26.5,\n", - " 'median': 36.0,\n", - " 'pos': 68,\n", - " 'upper': 46.5,\n", - " 'q1': 34.0},\n", - " {'pos': 61,\n", - " 'average': 35.99,\n", - " 'median': 38.0,\n", - " 'q3': 40.0,\n", - " 'q1': 35.0,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5},\n", - " {'median': 39.0,\n", - " 'lower': 30.0,\n", - " 'upper': 46.0,\n", - " 'average': 37.59,\n", - " 'q1': 36.0,\n", - " 'pos': 56,\n", - " 'q3': 40.0},\n", - " {'q3': 35.0,\n", - " 'upper': 38.0,\n", - " 'q1': 33.0,\n", - " 'pos': 89,\n", - " 'average': 32.44,\n", - " 'median': 35.0,\n", - " 'lower': 30.0},\n", - " {'lower': 35.0,\n", - " 'median': 40.0,\n", - " 'upper': 43.0,\n", - " 'pos': 37,\n", - " 'q1': 38.0,\n", - " 'average': 38.0,\n", - " 'q3': 40.0},\n", - " {'average': 37.71,\n", - " 'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'pos': 11,\n", - " 'lower': 34.0,\n", - " 'q3': 39.0,\n", - " 'upper': 42.0},\n", - " {'average': 32.015,\n", - " 'median': 34.0,\n", - " 'lower': 26.5,\n", - " 'pos': 2,\n", - " 'q1': 31.0,\n", - " 'q3': 34.0,\n", - " 'upper': 38.5},\n", - " {'upper': 41.0,\n", - " 'q1': 31.0,\n", - " 'average': 30.67,\n", - " 'lower': 25.0,\n", - " 'pos': 97,\n", - " 'q3': 35.0,\n", - " 'median': 34.0},\n", - " {'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.595,\n", - " 'upper': 45.5,\n", - " 'pos': 29},\n", - " {'pos': 39,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'q3': 40.0,\n", - " 'q1': 38.0,\n", - " 'median': 40.0,\n", - " 'average': 37.895},\n", - " {'upper': 39.5,\n", - " 'average': 31.25,\n", - " 'median': 34.0,\n", - " 'pos': 99,\n", - " 'q3': 35.0,\n", - " 'q1': 32.0,\n", - " 'lower': 27.5},\n", - " {'average': 37.425,\n", - " 'upper': 48.5,\n", - " 'pos': 50,\n", - " 'q1': 36.0,\n", - " 'lower': 28.5,\n", - " 'q3': 41.0,\n", - " 'median': 39.0},\n", - " {'median': 37.0,\n", - " 'pos': 66,\n", - " 'q3': 39.0,\n", - " 'upper': 45.0,\n", - " 'q1': 35.0,\n", - " 'lower': 29.0,\n", - " 'average': 35.875},\n", - " {'average': 38.94,\n", - " 'pos': 13,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'q1': 32.0,\n", - " 'average': 32.61,\n", - " 'median': 35.0,\n", - " 'pos': 80,\n", - " 'q3': 36.0,\n", - " 'lower': 26.0,\n", - " 'upper': 42.0},\n", - " {'lower': 27.5,\n", - " 'q1': 35.0,\n", - " 'upper': 47.5,\n", - " 'median': 38.0,\n", - " 'pos': 59,\n", - " 'average': 36.08,\n", - " 'q3': 40.0},\n", - " {'average': 31.55,\n", - " 'q3': 35.0,\n", - " 'pos': 98,\n", - " 'lower': 27.5,\n", - " 'median': 34.0,\n", - " 'upper': 39.5,\n", - " 'q1': 32.0},\n", - " {'average': 38.505,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 17,\n", - " 'median': 40.0,\n", - " 'q3': 41.0},\n", - " {'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'pos': 20,\n", - " 'lower': 33.5,\n", - " 'average': 38.625,\n", - " 'q1': 38.0},\n", - " {'upper': 47.0,\n", - " 'average': 37.87,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'q1': 37.0,\n", - " 'lower': 31.0,\n", - " 'pos': 41},\n", - " {'q1': 38.0,\n", - " 'upper': 43.0,\n", - " 'lower': 35.0,\n", - " 'average': 37.775,\n", - " 'median': 40.0,\n", - " 'q3': 40.0,\n", - " 'pos': 43},\n", - " {'q1': 33.0,\n", - " 'average': 33.265,\n", - " 'pos': 72,\n", - " 'median': 35.0,\n", - " 'lower': 27.0,\n", - " 'upper': 43.0,\n", - " 'q3': 37.0},\n", - " {'median': 35.0,\n", - " 'average': 31.525,\n", - " 'q1': 33.0,\n", - " 'q3': 36.0,\n", - " 'pos': 82,\n", - " 'upper': 40.5,\n", - " 'lower': 28.5},\n", - " {'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'pos': 8,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'average': 37.625,\n", - " 'upper': 42.0},\n", - " {'median': 39.0,\n", - " 'q3': 39.0,\n", - " 'upper': 42.0,\n", - " 'lower': 34.0,\n", - " 'average': 37.5,\n", - " 'q1': 37.0,\n", - " 'pos': 12},\n", - " {'pos': 40,\n", - " 'lower': 35.0,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'upper': 43.0,\n", - " 'average': 37.95,\n", - " 'q3': 40.0},\n", - " {'q1': 36.0,\n", - " 'median': 39.0,\n", - " 'lower': 30.0,\n", - " 'q3': 40.0,\n", - " 'average': 37.35,\n", - " 'pos': 57,\n", - " 'upper': 46.0},\n", - " {'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'pos': 7,\n", - " 'q3': 37.0,\n", - " 'median': 36.0,\n", - " 'q1': 35.0,\n", - " 'average': 35.4},\n", - " {'median': 35.0,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'average': 32.03,\n", - " 'pos': 83,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0},\n", - " {'pos': 6,\n", - " 'q3': 37.0,\n", - " 'q1': 35.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'median': 35.0,\n", - " 'average': 35.145},\n", - " {'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'median': 39.0,\n", - " 'upper': 42.0,\n", - " 'average': 37.675,\n", - " 'q1': 37.0,\n", - " 'pos': 10},\n", - " {'q1': 31.0,\n", - " 'q3': 34.0,\n", - " 'median': 33.0,\n", - " 'lower': 26.5,\n", - " 'pos': 0,\n", - " 'average': 30.135,\n", - " 'upper': 38.5},\n", - " {'pos': 1,\n", - " 'lower': 26.5,\n", - " 'average': 31.21,\n", - " 'q3': 34.0,\n", - " 'q1': 31.0,\n", - " 'median': 34.0,\n", - " 'upper': 38.5},\n", - " {'upper': 47.5,\n", - " 'average': 36.095,\n", - " 'q1': 35.0,\n", - " 'pos': 64,\n", - " 'median': 37.0,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5},\n", - " {'average': 37.55,\n", - " 'q3': 40.0,\n", - " 'pos': 55,\n", - " 'lower': 30.0,\n", - " 'q1': 36.0,\n", - " 'median': 39.0,\n", - " 'upper': 46.0},\n", - " {'average': 30.83,\n", - " 'q3': 37.0,\n", - " 'lower': 24.5,\n", - " 'upper': 44.5,\n", - " 'q1': 32.0,\n", - " 'median': 35.0,\n", - " 'pos': 74},\n", - " {'lower': 28.5,\n", - " 'upper': 48.5,\n", - " 'average': 37.61,\n", - " 'pos': 48,\n", - " 'q1': 36.0,\n", - " 'median': 40.0,\n", - " 'q3': 41.0},\n", - " {'pos': 23,\n", - " 'q1': 38.0,\n", - " 'average': 38.635,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'upper': 45.5},\n", - " {'pos': 32,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'average': 38.29,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0},\n", - " {'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'pos': 38,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'average': 37.64},\n", - " {'pos': 16,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5,\n", - " 'average': 38.48,\n", - " 'q3': 41.0,\n", - " 'median': 40.0},\n", - " {'median': 39.0,\n", - " 'upper': 42.0,\n", - " 'q1': 37.0,\n", - " 'pos': 9,\n", - " 'q3': 39.0,\n", - " 'average': 37.36,\n", - " 'lower': 34.0},\n", - " {'upper': 43.0,\n", - " 'average': 38.11,\n", - " 'q3': 40.0,\n", - " 'pos': 36,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'lower': 35.0},\n", - " {'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'average': 37.855,\n", - " 'pos': 26},\n", - " {'upper': 46.0,\n", - " 'pos': 75,\n", - " 'q1': 31.0,\n", - " 'average': 31.06,\n", - " 'median': 35.0,\n", - " 'lower': 22.0,\n", - " 'q3': 37.0},\n", - " {'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'lower': 33.5,\n", - " 'pos': 24,\n", - " 'average': 38.265},\n", - " {'pos': 30,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'upper': 43.0,\n", - " 'lower': 35.0,\n", - " 'average': 38.245},\n", - " {'pos': 69,\n", - " 'q1': 34.0,\n", - " 'q3': 39.0,\n", - " 'lower': 26.5,\n", - " 'upper': 46.5,\n", - " 'average': 33.7,\n", - " 'median': 36.0},\n", - " {'pos': 77,\n", - " 'q1': 30.0,\n", - " 'q3': 36.0,\n", - " 'lower': 21.0,\n", - " 'upper': 45.0,\n", - " 'median': 35.0,\n", - " 'average': 30.805},\n", - " {'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'pos': 28,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.445},\n", - " {'q1': 38.0,\n", - " 'average': 38.44,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 27},\n", - " {'q3': 37.0,\n", - " 'pos': 3,\n", - " 'average': 35.69,\n", - " 'q1': 35.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'median': 37.0},\n", - " {'median': 36.5,\n", - " 'lower': 26.5,\n", - " 'upper': 46.5,\n", - " 'average': 35.96,\n", - " 'q3': 39.0,\n", - " 'pos': 67,\n", - " 'q1': 34.0},\n", - " {'q3': 38.0,\n", - " 'lower': 28.0,\n", - " 'upper': 44.0,\n", - " 'average': 33.565,\n", - " 'median': 35.0,\n", - " 'pos': 70,\n", - " 'q1': 34.0},\n", - " {'upper': 39.5,\n", - " 'lower': 27.5,\n", - " 'pos': 87,\n", - " 'median': 35.0,\n", - " 'average': 31.915,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0},\n", - " {'lower': 30.0,\n", - " 'pos': 88,\n", - " 'average': 32.065,\n", - " 'upper': 38.0,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0},\n", - " {'q3': 35.0,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'median': 34.0,\n", - " 'average': 31.05,\n", - " 'q1': 32.0,\n", - " 'pos': 93},\n", - " {'upper': 47.0,\n", - " 'median': 39.5,\n", - " 'q3': 41.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.79,\n", - " 'lower': 31.0,\n", - " 'pos': 46},\n", - " {'pos': 96,\n", - " 'average': 31.315,\n", - " 'median': 34.0,\n", - " 'q1': 32.0,\n", - " 'upper': 39.5,\n", - " 'lower': 27.5,\n", - " 'q3': 35.0},\n", - " {'average': 31.105,\n", - " 'upper': 41.0,\n", - " 'pos': 100,\n", - " 'median': 34.0,\n", - " 'q1': 31.0,\n", - " 'q3': 35.0,\n", - " 'lower': 25.0},\n", - " {'q3': 37.0,\n", - " 'average': 32.68,\n", - " 'q1': 33.0,\n", - " 'pos': 73,\n", - " 'lower': 27.0,\n", - " 'upper': 43.0,\n", - " 'median': 35.0},\n", - " {'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.2,\n", - " 'upper': 45.5,\n", - " 'pos': 25,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0},\n", - " {'upper': 47.0,\n", - " 'q3': 41.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.845,\n", - " 'median': 39.0,\n", - " 'pos': 53,\n", - " 'lower': 31.0},\n", - " {'q3': 39.0,\n", - " 'upper': 45.0,\n", - " 'lower': 29.0,\n", - " 'pos': 65,\n", - " 'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'average': 35.995},\n", - " {'upper': 38.0,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'lower': 30.0,\n", - " 'q3': 35.0,\n", - " 'pos': 84,\n", - " 'average': 32.415},\n", - " {'median': 39.5,\n", - " 'pos': 54,\n", - " 'q1': 36.0,\n", - " 'upper': 48.5,\n", - " 'average': 37.59,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5},\n", - " {'average': 37.77,\n", - " 'q1': 37.0,\n", - " 'lower': 32.5,\n", - " 'upper': 44.5,\n", - " 'q3': 40.0,\n", - " 'pos': 52,\n", - " 'median': 39.0},\n", - " {'upper': 47.5,\n", - " 'pos': 58,\n", - " 'median': 38.0,\n", - " 'average': 36.77,\n", - " 'q1': 35.0,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5},\n", - " {'average': 36.25,\n", - " 'q3': 40.0,\n", - " 'q1': 35.0,\n", - " 'lower': 27.5,\n", - " 'median': 38.0,\n", - " 'pos': 63,\n", - " 'upper': 47.5},\n", - " {'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 15,\n", - " 'average': 38.725,\n", - " 'median': 40.0},\n", - " {'pos': 94,\n", - " 'q3': 35.0,\n", - " 'q1': 32.0,\n", - " 'upper': 39.5,\n", - " 'average': 30.775,\n", - " 'median': 34.0,\n", - " 'lower': 27.5},\n", - " {'median': 39.0,\n", - " 'q1': 36.0,\n", - " 'q3': 41.0,\n", - " 'pos': 51,\n", - " 'lower': 28.5,\n", - " 'upper': 48.5,\n", - " 'average': 37.53},\n", - " {'q1': 33.0,\n", - " 'upper': 40.5,\n", - " 'median': 35.0,\n", - " 'average': 32.76,\n", - " 'pos': 81,\n", - " 'lower': 28.5,\n", - " 'q3': 36.0},\n", - " {'average': 37.78,\n", - " 'q3': 40.0,\n", - " 'lower': 32.5,\n", - " 'median': 40.0,\n", - " 'upper': 44.5,\n", - " 'pos': 42,\n", - " 'q1': 37.0},\n", - " {'upper': 42.0,\n", - " 'q1': 32.0,\n", - " 'lower': 26.0,\n", - " 'median': 35.0,\n", - " 'pos': 79,\n", - " 'average': 32.46,\n", - " 'q3': 36.0},\n", - " {'q1': 36.0,\n", - " 'pos': 49,\n", - " 'average': 37.21,\n", - " 'lower': 30.0,\n", - " 'upper': 46.0,\n", - " 'median': 39.0,\n", - " 'q3': 40.0},\n", - " {'upper': 47.5,\n", - " 'pos': 62,\n", - " 'q1': 35.0,\n", - " 'q3': 40.0,\n", - " 'median': 38.0,\n", - " 'lower': 27.5,\n", - " 'average': 36.145},\n", - " {'q3': 36.0,\n", - " 'average': 31.46,\n", - " 'pos': 78,\n", - " 'median': 35.0,\n", - " 'lower': 23.5,\n", - " 'upper': 43.5,\n", - " 'q1': 31.0},\n", - " {'median': 40.0,\n", - " 'average': 38.245,\n", - " 'q3': 41.0,\n", - " 'pos': 33,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0},\n", - " {'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5,\n", - " 'pos': 14,\n", - " 'average': 38.965,\n", - " 'median': 40.0},\n", - " {'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.41,\n", - " 'upper': 45.5,\n", - " 'pos': 22},\n", - " {'q3': 35.0,\n", - " 'median': 34.5,\n", - " 'upper': 38.0,\n", - " 'pos': 90,\n", - " 'q1': 33.0,\n", - " 'lower': 30.0,\n", - " 'average': 32.275},\n", - " {'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'pos': 19,\n", - " 'average': 38.425,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5},\n", - " {'average': 38.385,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5,\n", - " 'pos': 35,\n", - " 'q3': 41.0},\n", - " {'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'average': 38.795,\n", - " 'pos': 31,\n", - " 'median': 40.0},\n", - " {'upper': 48.5,\n", - " 'pos': 45,\n", - " 'average': 37.45,\n", - " 'median': 40.0,\n", - " 'q1': 36.0,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5},\n", - " {'upper': 46.0,\n", - " 'pos': 76,\n", - " 'q1': 31.0,\n", - " 'median': 35.0,\n", - " 'q3': 37.0,\n", - " 'average': 30.265,\n", - " 'lower': 22.0},\n", - " {'pos': 44,\n", - " 'q1': 37.0,\n", - " 'upper': 47.0,\n", - " 'average': 37.565,\n", - " 'lower': 31.0,\n", - " 'q3': 41.0,\n", - " 'median': 40.0},\n", - " {'upper': 45.5,\n", - " 'q3': 38.0,\n", - " 'q1': 33.0,\n", - " 'lower': 25.5,\n", - " 'median': 35.0,\n", - " 'average': 33.005,\n", - " 'pos': 71},\n", - " {'pos': 47,\n", - " 'average': 37.665,\n", - " 'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'q3': 41.0},\n", - " {'q3': 37.0,\n", - " 'pos': 5,\n", - " 'average': 35.095,\n", - " 'median': 35.0,\n", - " 'q1': 35.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0},\n", - " {'pos': 4,\n", - " 'average': 35.68,\n", - " 'median': 37.0,\n", - " 'q3': 37.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'q1': 35.0},\n", - " {'upper': 47.5,\n", - " 'pos': 60,\n", - " 'median': 38.0,\n", - " 'average': 35.985,\n", - " 'q1': 35.0,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5},\n", - " {'q1': 32.0,\n", - " 'average': 32.665,\n", - " 'q3': 35.0,\n", - " 'lower': 27.5,\n", - " 'median': 35.0,\n", - " 'pos': 91,\n", - " 'upper': 39.5},\n", - " {'average': 32.195,\n", - " 'median': 35.0,\n", - " 'pos': 85,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0}]}" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + " pos score\n", + "0 0 2\n", + "1 1 19\n", + "2 2 33\n", + "3 3 35\n", + "4 4 37\n", + "... ... ...\n", + "20195 96 35\n", + "20196 97 32\n", + "20197 98 35\n", + "20198 99 35\n", + "20199 100 33\n", + "\n", + "[20200 rows x 2 columns]\n" + ] } ], "source": [ - "pb.base_sequence_quality(\"example.fastq\")" + "result = pb.base_sequence_quality(\"example.fastq\", output_type=\"pandas.DataFrame\")\n", + "print(result)" ] }, { @@ -832,715 +114,35 @@ "outputs": [ { "data": { + "text/html": [ + "
\n", + "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + ], "text/plain": [ - "{'base_quality_warn': 'pass',\n", - " 'base_per_pos_data': [{'average': 32.195,\n", - " 'pos': 85,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'median': 35.0,\n", - " 'q1': 33.0},\n", - " {'average': 38.245,\n", - " 'median': 40.0,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'pos': 30,\n", - " 'upper': 43.0,\n", - " 'q1': 38.0},\n", - " {'pos': 2,\n", - " 'average': 32.015,\n", - " 'q3': 34.0,\n", - " 'lower': 26.5,\n", - " 'upper': 38.5,\n", - " 'q1': 31.0,\n", - " 'median': 34.0},\n", - " {'lower': 30.0,\n", - " 'pos': 89,\n", - " 'upper': 38.0,\n", - " 'average': 32.44,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0},\n", - " {'q3': 39.0,\n", - " 'average': 37.5,\n", - " 'q1': 37.0,\n", - " 'pos': 12,\n", - " 'median': 39.0,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0},\n", - " {'median': 40.0,\n", - " 'pos': 23,\n", - " 'lower': 33.5,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5,\n", - " 'average': 38.635},\n", - " {'average': 38.595,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'pos': 29,\n", - " 'upper': 45.5},\n", - " {'average': 37.35,\n", - " 'pos': 57,\n", - " 'q1': 36.0,\n", - " 'median': 39.0,\n", - " 'lower': 30.0,\n", - " 'upper': 46.0,\n", - " 'q3': 40.0},\n", - " {'pos': 56,\n", - " 'average': 37.59,\n", - " 'upper': 46.0,\n", - " 'median': 39.0,\n", - " 'q1': 36.0,\n", - " 'q3': 40.0,\n", - " 'lower': 30.0},\n", - " {'average': 36.08,\n", - " 'q3': 40.0,\n", - " 'q1': 35.0,\n", - " 'median': 38.0,\n", - " 'upper': 47.5,\n", - " 'pos': 59,\n", - " 'lower': 27.5},\n", - " {'q1': 32.0,\n", - " 'median': 35.0,\n", - " 'average': 31.835,\n", - " 'q3': 35.0,\n", - " 'pos': 92,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5},\n", - " {'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 24,\n", - " 'median': 40.0,\n", - " 'average': 38.265,\n", - " 'q1': 38.0},\n", - " {'lower': 30.0,\n", - " 'upper': 46.0,\n", - " 'pos': 49,\n", - " 'median': 39.0,\n", - " 'average': 37.21,\n", - " 'q1': 36.0,\n", - " 'q3': 40.0},\n", - " {'upper': 38.0,\n", - " 'pos': 90,\n", - " 'q1': 33.0,\n", - " 'average': 32.275,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'median': 34.5},\n", - " {'q1': 34.0,\n", - " 'pos': 70,\n", - " 'lower': 28.0,\n", - " 'average': 33.565,\n", - " 'median': 35.0,\n", - " 'q3': 38.0,\n", - " 'upper': 44.0},\n", - " {'upper': 45.5,\n", - " 'pos': 27,\n", - " 'q1': 38.0,\n", - " 'average': 38.44,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5},\n", - " {'upper': 42.0,\n", - " 'average': 37.675,\n", - " 'q3': 39.0,\n", - " 'pos': 10,\n", - " 'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'lower': 34.0},\n", - " {'q1': 32.0,\n", - " 'upper': 39.5,\n", - " 'q3': 35.0,\n", - " 'pos': 98,\n", - " 'average': 31.55,\n", - " 'lower': 27.5,\n", - " 'median': 34.0},\n", - " {'median': 40.0,\n", - " 'pos': 13,\n", - " 'average': 38.94,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0},\n", - " {'upper': 43.0,\n", - " 'q3': 40.0,\n", - " 'median': 40.0,\n", - " 'pos': 21,\n", - " 'average': 38.445,\n", - " 'q1': 38.0,\n", - " 'lower': 35.0},\n", - " {'lower': 27.5,\n", - " 'median': 34.0,\n", - " 'pos': 99,\n", - " 'average': 31.25,\n", - " 'q3': 35.0,\n", - " 'q1': 32.0,\n", - " 'upper': 39.5},\n", - " {'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'pos': 31,\n", - " 'average': 38.795,\n", - " 'q1': 38.0,\n", - " 'median': 40.0},\n", - " {'average': 37.855,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'pos': 26,\n", - " 'q3': 40.0,\n", - " 'q1': 38.0,\n", - " 'median': 40.0},\n", - " {'pos': 33,\n", - " 'upper': 45.5,\n", - " 'average': 38.245,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'median': 40.0},\n", - " {'average': 37.665,\n", - " 'pos': 47,\n", - " 'q3': 41.0,\n", - " 'lower': 31.0,\n", - " 'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'upper': 47.0},\n", - " {'average': 38.505,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 17,\n", - " 'median': 40.0},\n", - " {'q3': 40.0,\n", - " 'median': 39.0,\n", - " 'upper': 44.5,\n", - " 'average': 37.77,\n", - " 'pos': 52,\n", - " 'q1': 37.0,\n", - " 'lower': 32.5},\n", - " {'q3': 35.0,\n", - " 'upper': 39.5,\n", - " 'median': 35.0,\n", - " 'q1': 32.0,\n", - " 'lower': 27.5,\n", - " 'pos': 87,\n", - " 'average': 31.915},\n", - " {'upper': 48.5,\n", - " 'pos': 48,\n", - " 'q3': 41.0,\n", - " 'average': 37.61,\n", - " 'q1': 36.0,\n", - " 'median': 40.0,\n", - " 'lower': 28.5},\n", - " {'median': 40.0,\n", - " 'upper': 43.0,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'q1': 38.0,\n", - " 'average': 37.895,\n", - " 'pos': 39},\n", - " {'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'average': 38.2,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'pos': 25,\n", - " 'median': 40.0},\n", - " {'pos': 63,\n", - " 'q1': 35.0,\n", - " 'average': 36.25,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'median': 38.0},\n", - " {'pos': 80,\n", - " 'average': 32.61,\n", - " 'upper': 42.0,\n", - " 'q1': 32.0,\n", - " 'median': 35.0,\n", - " 'q3': 36.0,\n", - " 'lower': 26.0},\n", - " {'q3': 41.0,\n", - " 'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'q1': 37.0,\n", - " 'median': 39.0,\n", - " 'average': 37.845,\n", - " 'pos': 53},\n", - " {'upper': 45.5,\n", - " 'pos': 16,\n", - " 'median': 40.0,\n", - " 'average': 38.48,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5},\n", - " {'q1': 38.0,\n", - " 'pos': 14,\n", - " 'average': 38.965,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'pos': 55,\n", - " 'q3': 40.0,\n", - " 'median': 39.0,\n", - " 'lower': 30.0,\n", - " 'q1': 36.0,\n", - " 'upper': 46.0,\n", - " 'average': 37.55},\n", - " {'average': 37.78,\n", - " 'median': 40.0,\n", - " 'q3': 40.0,\n", - " 'pos': 42,\n", - " 'q1': 37.0,\n", - " 'lower': 32.5,\n", - " 'upper': 44.5},\n", - " {'average': 37.425,\n", - " 'q1': 36.0,\n", - " 'upper': 48.5,\n", - " 'pos': 50,\n", - " 'median': 39.0,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5},\n", - " {'lower': 25.0,\n", - " 'upper': 41.0,\n", - " 'q1': 31.0,\n", - " 'average': 31.105,\n", - " 'median': 34.0,\n", - " 'q3': 35.0,\n", - " 'pos': 100},\n", - " {'upper': 38.5,\n", - " 'q1': 31.0,\n", - " 'q3': 34.0,\n", - " 'lower': 26.5,\n", - " 'average': 30.135,\n", - " 'median': 33.0,\n", - " 'pos': 0},\n", - " {'lower': 26.5,\n", - " 'q1': 31.0,\n", - " 'median': 34.0,\n", - " 'upper': 38.5,\n", - " 'pos': 1,\n", - " 'q3': 34.0,\n", - " 'average': 31.21},\n", - " {'q3': 37.0,\n", - " 'q1': 32.0,\n", - " 'upper': 44.5,\n", - " 'pos': 74,\n", - " 'average': 30.83,\n", - " 'median': 35.0,\n", - " 'lower': 24.5},\n", - " {'upper': 38.0,\n", - " 'q3': 35.0,\n", - " 'median': 35.0,\n", - " 'pos': 84,\n", - " 'average': 32.415,\n", - " 'q1': 33.0,\n", - " 'lower': 30.0},\n", - " {'median': 35.0,\n", - " 'q1': 35.0,\n", - " 'q3': 37.0,\n", - " 'lower': 32.0,\n", - " 'average': 35.095,\n", - " 'pos': 5,\n", - " 'upper': 40.0},\n", - " {'pos': 3,\n", - " 'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'q3': 37.0,\n", - " 'lower': 32.0,\n", - " 'average': 35.69,\n", - " 'upper': 40.0},\n", - " {'pos': 40,\n", - " 'q1': 38.0,\n", - " 'average': 37.95,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'median': 40.0,\n", - " 'upper': 43.0},\n", - " {'pos': 58,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'median': 38.0,\n", - " 'q1': 35.0,\n", - " 'average': 36.77},\n", - " {'median': 37.0,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5,\n", - " 'q1': 35.0,\n", - " 'upper': 47.5,\n", - " 'pos': 64,\n", - " 'average': 36.095},\n", - " {'pos': 41,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.87},\n", - " {'average': 35.99,\n", - " 'median': 38.0,\n", - " 'q1': 35.0,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'pos': 61},\n", - " {'q3': 39.0,\n", - " 'median': 39.0,\n", - " 'average': 37.625,\n", - " 'pos': 8,\n", - " 'lower': 34.0,\n", - " 'q1': 37.0,\n", - " 'upper': 42.0},\n", - " {'upper': 48.5,\n", - " 'q3': 41.0,\n", - " 'average': 37.45,\n", - " 'pos': 45,\n", - " 'q1': 36.0,\n", - " 'median': 40.0,\n", - " 'lower': 28.5},\n", - " {'pos': 71,\n", - " 'average': 33.005,\n", - " 'q1': 33.0,\n", - " 'median': 35.0,\n", - " 'upper': 45.5,\n", - " 'lower': 25.5,\n", - " 'q3': 38.0},\n", - " {'median': 35.0,\n", - " 'average': 32.03,\n", - " 'pos': 83,\n", - " 'q1': 33.0,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'q3': 35.0},\n", - " {'pos': 36,\n", - " 'upper': 43.0,\n", - " 'median': 40.0,\n", - " 'average': 38.11,\n", - " 'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0},\n", - " {'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'pos': 86,\n", - " 'q1': 33.0,\n", - " 'average': 31.815,\n", - " 'q3': 35.0,\n", - " 'median': 35.0},\n", - " {'lower': 35.0,\n", - " 'pos': 37,\n", - " 'upper': 43.0,\n", - " 'q3': 40.0,\n", - " 'q1': 38.0,\n", - " 'average': 38.0,\n", - " 'median': 40.0},\n", - " {'lower': 34.0,\n", - " 'upper': 42.0,\n", - " 'average': 37.36,\n", - " 'q3': 39.0,\n", - " 'q1': 37.0,\n", - " 'median': 39.0,\n", - " 'pos': 9},\n", - " {'q3': 36.0,\n", - " 'lower': 28.5,\n", - " 'median': 35.0,\n", - " 'upper': 40.5,\n", - " 'q1': 33.0,\n", - " 'average': 32.76,\n", - " 'pos': 81},\n", - " {'pos': 38,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'average': 37.64,\n", - " 'q1': 38.0,\n", - " 'median': 40.0},\n", - " {'average': 32.065,\n", - " 'q3': 35.0,\n", - " 'upper': 38.0,\n", - " 'lower': 30.0,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'pos': 88},\n", - " {'average': 31.525,\n", - " 'q3': 36.0,\n", - " 'pos': 82,\n", - " 'lower': 28.5,\n", - " 'median': 35.0,\n", - " 'upper': 40.5,\n", - " 'q1': 33.0},\n", - " {'pos': 91,\n", - " 'average': 32.665,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0,\n", - " 'median': 35.0,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5},\n", - " {'q1': 34.0,\n", - " 'q3': 39.0,\n", - " 'pos': 69,\n", - " 'upper': 46.5,\n", - " 'lower': 26.5,\n", - " 'median': 36.0,\n", - " 'average': 33.7},\n", - " {'median': 35.0,\n", - " 'lower': 27.0,\n", - " 'average': 32.68,\n", - " 'pos': 73,\n", - " 'q1': 33.0,\n", - " 'q3': 37.0,\n", - " 'upper': 43.0},\n", - " {'q1': 36.0,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5,\n", - " 'average': 37.53,\n", - " 'upper': 48.5,\n", - " 'pos': 51,\n", - " 'median': 39.0},\n", - " {'pos': 43,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'average': 37.775},\n", - " {'q3': 39.0,\n", - " 'median': 39.0,\n", - " 'pos': 11,\n", - " 'upper': 42.0,\n", - " 'lower': 34.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.71},\n", - " {'q1': 38.0,\n", - " 'pos': 28,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.445,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5},\n", - " {'average': 38.47,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'pos': 18,\n", - " 'median': 40.0},\n", - " {'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'pos': 44,\n", - " 'q1': 37.0,\n", - " 'average': 37.565,\n", - " 'upper': 47.0,\n", - " 'lower': 31.0},\n", - " {'q1': 35.0,\n", - " 'pos': 6,\n", - " 'q3': 37.0,\n", - " 'median': 35.0,\n", - " 'upper': 40.0,\n", - " 'average': 35.145,\n", - " 'lower': 32.0},\n", - " {'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 35,\n", - " 'q1': 38.0,\n", - " 'average': 38.385},\n", - " {'pos': 60,\n", - " 'lower': 27.5,\n", - " 'median': 38.0,\n", - " 'average': 35.985,\n", - " 'upper': 47.5,\n", - " 'q1': 35.0,\n", - " 'q3': 40.0},\n", - " {'q3': 37.0,\n", - " 'average': 35.4,\n", - " 'q1': 35.0,\n", - " 'median': 36.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'pos': 7},\n", - " {'q3': 37.0,\n", - " 'lower': 27.0,\n", - " 'upper': 43.0,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'pos': 72,\n", - " 'average': 33.265},\n", - " {'average': 30.265,\n", - " 'pos': 76,\n", - " 'median': 35.0,\n", - " 'q3': 37.0,\n", - " 'lower': 22.0,\n", - " 'upper': 46.0,\n", - " 'q1': 31.0},\n", - " {'q1': 35.0,\n", - " 'average': 35.875,\n", - " 'q3': 39.0,\n", - " 'upper': 45.0,\n", - " 'pos': 66,\n", - " 'lower': 29.0,\n", - " 'median': 37.0},\n", - " {'average': 36.145,\n", - " 'pos': 62,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5,\n", - " 'q1': 35.0,\n", - " 'upper': 47.5,\n", - " 'median': 38.0},\n", - " {'pos': 93,\n", - " 'median': 34.0,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0,\n", - " 'average': 31.05},\n", - " {'average': 35.68,\n", - " 'median': 37.0,\n", - " 'q3': 37.0,\n", - " 'upper': 40.0,\n", - " 'lower': 32.0,\n", - " 'pos': 4,\n", - " 'q1': 35.0},\n", - " {'pos': 46,\n", - " 'lower': 31.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.79,\n", - " 'q3': 41.0,\n", - " 'median': 39.5,\n", - " 'upper': 47.0},\n", - " {'pos': 20,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'average': 38.625,\n", - " 'q1': 38.0},\n", - " {'q1': 36.0,\n", - " 'upper': 48.5,\n", - " 'pos': 54,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5,\n", - " 'average': 37.59,\n", - " 'median': 39.5},\n", - " {'pos': 95,\n", - " 'q3': 35.0,\n", - " 'q1': 32.0,\n", - " 'average': 31.425,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'median': 34.0},\n", - " {'upper': 42.0,\n", - " 'lower': 26.0,\n", - " 'pos': 79,\n", - " 'q3': 36.0,\n", - " 'average': 32.46,\n", - " 'median': 35.0,\n", - " 'q1': 32.0},\n", - " {'average': 31.46,\n", - " 'lower': 23.5,\n", - " 'q3': 36.0,\n", - " 'pos': 78,\n", - " 'q1': 31.0,\n", - " 'upper': 43.5,\n", - " 'median': 35.0},\n", - " {'q1': 32.0,\n", - " 'lower': 27.5,\n", - " 'median': 34.0,\n", - " 'average': 30.775,\n", - " 'pos': 94,\n", - " 'q3': 35.0,\n", - " 'upper': 39.5},\n", - " {'q3': 35.0,\n", - " 'lower': 27.5,\n", - " 'q1': 32.0,\n", - " 'upper': 39.5,\n", - " 'pos': 96,\n", - " 'average': 31.315,\n", - " 'median': 34.0},\n", - " {'pos': 75,\n", - " 'average': 31.06,\n", - " 'q1': 31.0,\n", - " 'q3': 37.0,\n", - " 'lower': 22.0,\n", - " 'upper': 46.0,\n", - " 'median': 35.0},\n", - " {'q3': 39.0,\n", - " 'pos': 67,\n", - " 'lower': 26.5,\n", - " 'upper': 46.5,\n", - " 'median': 36.5,\n", - " 'average': 35.96,\n", - " 'q1': 34.0},\n", - " {'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'pos': 19,\n", - " 'average': 38.425,\n", - " 'q1': 38.0},\n", - " {'average': 38.725,\n", - " 'q1': 38.0,\n", - " 'pos': 15,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'upper': 45.5,\n", - " 'pos': 34,\n", - " 'average': 38.205,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'median': 40.0},\n", - " {'average': 38.41,\n", - " 'q3': 41.0,\n", - " 'pos': 22,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5},\n", - " {'average': 38.29,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5,\n", - " 'pos': 32,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5},\n", - " {'median': 35.0,\n", - " 'q1': 30.0,\n", - " 'upper': 45.0,\n", - " 'average': 30.805,\n", - " 'q3': 36.0,\n", - " 'pos': 77,\n", - " 'lower': 21.0},\n", - " {'average': 35.91,\n", - " 'q1': 34.0,\n", - " 'q3': 39.0,\n", - " 'median': 36.0,\n", - " 'lower': 26.5,\n", - " 'upper': 46.5,\n", - " 'pos': 68},\n", - " {'lower': 25.0,\n", - " 'median': 34.0,\n", - " 'upper': 41.0,\n", - " 'pos': 97,\n", - " 'q3': 35.0,\n", - " 'q1': 31.0,\n", - " 'average': 30.67},\n", - " {'lower': 29.0,\n", - " 'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'q3': 39.0,\n", - " 'average': 35.995,\n", - " 'upper': 45.0,\n", - " 'pos': 65}]}" + "shape: (20_200, 2)\n", + "┌─────┬───────┐\n", + "│ pos ┆ score │\n", + "│ --- ┆ --- │\n", + "│ i64 ┆ i8 │\n", + "╞═════╪═══════╡\n", + "│ 0 ┆ 2 │\n", + "│ 1 ┆ 19 │\n", + "│ 2 ┆ 33 │\n", + "│ 3 ┆ 35 │\n", + "│ 4 ┆ 37 │\n", + "│ … ┆ … │\n", + "│ 96 ┆ 35 │\n", + "│ 97 ┆ 32 │\n", + "│ 98 ┆ 35 │\n", + "│ 99 ┆ 35 │\n", + "│ 100 ┆ 33 │\n", + "└─────┴───────┘" ] }, "execution_count": 4, @@ -1568,715 +170,35 @@ "outputs": [ { "data": { + "text/html": [ + "
\n", + "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + ], "text/plain": [ - "{'base_quality_warn': 'pass',\n", - " 'base_per_pos_data': [{'average': 35.69,\n", - " 'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'q3': 37.0,\n", - " 'pos': 3},\n", - " {'pos': 39,\n", - " 'average': 37.895,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'upper': 43.0},\n", - " {'pos': 20,\n", - " 'average': 38.625,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0},\n", - " {'pos': 28,\n", - " 'q1': 38.0,\n", - " 'average': 38.445,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'median': 40.0},\n", - " {'pos': 49,\n", - " 'average': 37.21,\n", - " 'q1': 36.0,\n", - " 'q3': 40.0,\n", - " 'lower': 30.0,\n", - " 'median': 39.0,\n", - " 'upper': 46.0},\n", - " {'q1': 35.0,\n", - " 'pos': 59,\n", - " 'upper': 47.5,\n", - " 'median': 38.0,\n", - " 'average': 36.08,\n", - " 'lower': 27.5,\n", - " 'q3': 40.0},\n", - " {'pos': 67,\n", - " 'average': 35.96,\n", - " 'lower': 26.5,\n", - " 'q1': 34.0,\n", - " 'upper': 46.5,\n", - " 'q3': 39.0,\n", - " 'median': 36.5},\n", - " {'average': 37.45,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'q1': 36.0,\n", - " 'lower': 28.5,\n", - " 'pos': 45,\n", - " 'upper': 48.5},\n", - " {'lower': 35.0,\n", - " 'q3': 40.0,\n", - " 'average': 38.0,\n", - " 'pos': 37,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'upper': 43.0},\n", - " {'pos': 22,\n", - " 'average': 38.41,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'pos': 15,\n", - " 'average': 38.725,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5,\n", - " 'median': 40.0},\n", - " {'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'pos': 19,\n", - " 'upper': 45.5,\n", - " 'average': 38.425,\n", - " 'median': 40.0,\n", - " 'q1': 38.0},\n", - " {'median': 35.0,\n", - " 'pos': 74,\n", - " 'q3': 37.0,\n", - " 'average': 30.83,\n", - " 'upper': 44.5,\n", - " 'q1': 32.0,\n", - " 'lower': 24.5},\n", - " {'q3': 37.0,\n", - " 'pos': 76,\n", - " 'q1': 31.0,\n", - " 'upper': 46.0,\n", - " 'average': 30.265,\n", - " 'median': 35.0,\n", - " 'lower': 22.0},\n", - " {'pos': 31,\n", - " 'average': 38.795,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5},\n", - " {'pos': 23,\n", - " 'average': 38.635,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0},\n", - " {'q3': 41.0,\n", - " 'median': 39.0,\n", - " 'upper': 48.5,\n", - " 'pos': 51,\n", - " 'q1': 36.0,\n", - " 'lower': 28.5,\n", - " 'average': 37.53},\n", - " {'upper': 40.0,\n", - " 'median': 37.0,\n", - " 'average': 35.68,\n", - " 'q1': 35.0,\n", - " 'q3': 37.0,\n", - " 'pos': 4,\n", - " 'lower': 32.0},\n", - " {'average': 32.46,\n", - " 'upper': 42.0,\n", - " 'median': 35.0,\n", - " 'q1': 32.0,\n", - " 'pos': 79,\n", - " 'q3': 36.0,\n", - " 'lower': 26.0},\n", - " {'average': 32.61,\n", - " 'q1': 32.0,\n", - " 'pos': 80,\n", - " 'median': 35.0,\n", - " 'q3': 36.0,\n", - " 'upper': 42.0,\n", - " 'lower': 26.0},\n", - " {'q1': 35.0,\n", - " 'median': 38.0,\n", - " 'q3': 40.0,\n", - " 'upper': 47.5,\n", - " 'lower': 27.5,\n", - " 'pos': 58,\n", - " 'average': 36.77},\n", - " {'average': 32.68,\n", - " 'median': 35.0,\n", - " 'lower': 27.0,\n", - " 'q1': 33.0,\n", - " 'q3': 37.0,\n", - " 'upper': 43.0,\n", - " 'pos': 73},\n", - " {'median': 34.0,\n", - " 'pos': 97,\n", - " 'q1': 31.0,\n", - " 'upper': 41.0,\n", - " 'q3': 35.0,\n", - " 'lower': 25.0,\n", - " 'average': 30.67},\n", - " {'median': 34.0,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'average': 31.55,\n", - " 'pos': 98,\n", - " 'q3': 35.0,\n", - " 'q1': 32.0},\n", - " {'upper': 42.0,\n", - " 'median': 39.0,\n", - " 'pos': 8,\n", - " 'q1': 37.0,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'average': 37.625},\n", - " {'q1': 38.0,\n", - " 'pos': 29,\n", - " 'lower': 33.5,\n", - " 'average': 38.595,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'upper': 45.5},\n", - " {'pos': 38,\n", - " 'q3': 41.0,\n", - " 'average': 37.64,\n", - " 'median': 40.0,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5},\n", - " {'q3': 41.0,\n", - " 'pos': 18,\n", - " 'q1': 38.0,\n", - " 'average': 38.47,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'lower': 30.0,\n", - " 'average': 37.35,\n", - " 'q1': 36.0,\n", - " 'q3': 40.0,\n", - " 'upper': 46.0,\n", - " 'pos': 57,\n", - " 'median': 39.0},\n", - " {'q3': 34.0,\n", - " 'upper': 38.5,\n", - " 'q1': 31.0,\n", - " 'average': 30.135,\n", - " 'lower': 26.5,\n", - " 'pos': 0,\n", - " 'median': 33.0},\n", - " {'pos': 71,\n", - " 'q3': 38.0,\n", - " 'lower': 25.5,\n", - " 'upper': 45.5,\n", - " 'average': 33.005,\n", - " 'median': 35.0,\n", - " 'q1': 33.0},\n", - " {'upper': 39.5,\n", - " 'q3': 35.0,\n", - " 'q1': 32.0,\n", - " 'lower': 27.5,\n", - " 'average': 32.665,\n", - " 'pos': 91,\n", - " 'median': 35.0},\n", - " {'q3': 35.0,\n", - " 'pos': 89,\n", - " 'upper': 38.0,\n", - " 'q1': 33.0,\n", - " 'lower': 30.0,\n", - " 'median': 35.0,\n", - " 'average': 32.44},\n", - " {'median': 39.5,\n", - " 'q1': 36.0,\n", - " 'average': 37.59,\n", - " 'pos': 54,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5,\n", - " 'upper': 48.5},\n", - " {'median': 35.0,\n", - " 'pos': 82,\n", - " 'q3': 36.0,\n", - " 'q1': 33.0,\n", - " 'lower': 28.5,\n", - " 'upper': 40.5,\n", - " 'average': 31.525},\n", - " {'pos': 85,\n", - " 'lower': 30.0,\n", - " 'q3': 35.0,\n", - " 'upper': 38.0,\n", - " 'average': 32.195,\n", - " 'median': 35.0,\n", - " 'q1': 33.0},\n", - " {'lower': 30.0,\n", - " 'pos': 83,\n", - " 'upper': 38.0,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'average': 32.03,\n", - " 'q3': 35.0},\n", - " {'median': 35.0,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0,\n", - " 'upper': 39.5,\n", - " 'average': 31.835,\n", - " 'lower': 27.5,\n", - " 'pos': 92},\n", - " {'average': 35.995,\n", - " 'lower': 29.0,\n", - " 'pos': 65,\n", - " 'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'upper': 45.0,\n", - " 'q3': 39.0},\n", - " {'pos': 34,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'average': 38.205,\n", - " 'median': 40.0},\n", - " {'upper': 43.0,\n", - " 'median': 40.0,\n", - " 'q3': 40.0,\n", - " 'q1': 38.0,\n", - " 'pos': 43,\n", - " 'average': 37.775,\n", - " 'lower': 35.0},\n", - " {'pos': 68,\n", - " 'q3': 39.0,\n", - " 'lower': 26.5,\n", - " 'upper': 46.5,\n", - " 'q1': 34.0,\n", - " 'median': 36.0,\n", - " 'average': 35.91},\n", - " {'q3': 40.0,\n", - " 'median': 40.0,\n", - " 'lower': 35.0,\n", - " 'pos': 26,\n", - " 'q1': 38.0,\n", - " 'upper': 43.0,\n", - " 'average': 37.855},\n", - " {'median': 35.0,\n", - " 'pos': 70,\n", - " 'q3': 38.0,\n", - " 'lower': 28.0,\n", - " 'q1': 34.0,\n", - " 'upper': 44.0,\n", - " 'average': 33.565},\n", - " {'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'pos': 13,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.94,\n", - " 'upper': 45.5},\n", - " {'pos': 88,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0,\n", - " 'upper': 38.0,\n", - " 'average': 32.065,\n", - " 'lower': 30.0,\n", - " 'median': 35.0},\n", - " {'median': 34.5,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0,\n", - " 'upper': 38.0,\n", - " 'average': 32.275,\n", - " 'pos': 90,\n", - " 'lower': 30.0},\n", - " {'q1': 30.0,\n", - " 'upper': 45.0,\n", - " 'q3': 36.0,\n", - " 'pos': 77,\n", - " 'average': 30.805,\n", - " 'median': 35.0,\n", - " 'lower': 21.0},\n", - " {'q1': 37.0,\n", - " 'median': 39.0,\n", - " 'average': 37.77,\n", - " 'upper': 44.5,\n", - " 'pos': 52,\n", - " 'q3': 40.0,\n", - " 'lower': 32.5},\n", - " {'average': 37.565,\n", - " 'q1': 37.0,\n", - " 'pos': 44,\n", - " 'lower': 31.0,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'upper': 47.0},\n", - " {'lower': 28.5,\n", - " 'average': 37.425,\n", - " 'median': 39.0,\n", - " 'q1': 36.0,\n", - " 'pos': 50,\n", - " 'upper': 48.5,\n", - " 'q3': 41.0},\n", - " {'upper': 46.0,\n", - " 'q1': 36.0,\n", - " 'lower': 30.0,\n", - " 'pos': 56,\n", - " 'average': 37.59,\n", - " 'median': 39.0,\n", - " 'q3': 40.0},\n", - " {'median': 38.0,\n", - " 'pos': 63,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'q1': 35.0,\n", - " 'average': 36.25,\n", - " 'q3': 40.0},\n", - " {'lower': 31.0,\n", - " 'median': 39.0,\n", - " 'average': 37.665,\n", - " 'q1': 37.0,\n", - " 'q3': 41.0,\n", - " 'upper': 47.0,\n", - " 'pos': 47},\n", - " {'median': 39.0,\n", - " 'q3': 39.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.675,\n", - " 'lower': 34.0,\n", - " 'pos': 10,\n", - " 'upper': 42.0},\n", - " {'average': 37.5,\n", - " 'q1': 37.0,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0,\n", - " 'pos': 12,\n", - " 'median': 39.0},\n", - " {'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0,\n", - " 'pos': 25,\n", - " 'average': 38.2,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'lower': 23.5,\n", - " 'pos': 78,\n", - " 'q1': 31.0,\n", - " 'upper': 43.5,\n", - " 'average': 31.46,\n", - " 'q3': 36.0,\n", - " 'median': 35.0},\n", - " {'q3': 35.0,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'pos': 95,\n", - " 'q1': 32.0,\n", - " 'median': 34.0,\n", - " 'average': 31.425},\n", - " {'q3': 40.0,\n", - " 'upper': 47.5,\n", - " 'lower': 27.5,\n", - " 'average': 36.145,\n", - " 'pos': 62,\n", - " 'q1': 35.0,\n", - " 'median': 38.0},\n", - " {'pos': 21,\n", - " 'q3': 40.0,\n", - " 'median': 40.0,\n", - " 'lower': 35.0,\n", - " 'q1': 38.0,\n", - " 'average': 38.445,\n", - " 'upper': 43.0},\n", - " {'q1': 38.0,\n", - " 'lower': 35.0,\n", - " 'pos': 36,\n", - " 'q3': 40.0,\n", - " 'average': 38.11,\n", - " 'median': 40.0,\n", - " 'upper': 43.0},\n", - " {'lower': 27.5,\n", - " 'median': 38.0,\n", - " 'q1': 35.0,\n", - " 'average': 35.985,\n", - " 'upper': 47.5,\n", - " 'pos': 60,\n", - " 'q3': 40.0},\n", - " {'pos': 24,\n", - " 'average': 38.265,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'lower': 33.5},\n", - " {'q1': 37.0,\n", - " 'q3': 39.0,\n", - " 'median': 39.0,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0,\n", - " 'average': 37.36,\n", - " 'pos': 9},\n", - " {'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'median': 40.0,\n", - " 'pos': 30,\n", - " 'average': 38.245,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0},\n", - " {'average': 37.78,\n", - " 'q3': 40.0,\n", - " 'q1': 37.0,\n", - " 'lower': 32.5,\n", - " 'upper': 44.5,\n", - " 'pos': 42,\n", - " 'median': 40.0},\n", - " {'pos': 53,\n", - " 'q1': 37.0,\n", - " 'q3': 41.0,\n", - " 'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'median': 39.0,\n", - " 'average': 37.845},\n", - " {'q3': 37.0,\n", - " 'upper': 40.0,\n", - " 'median': 36.0,\n", - " 'average': 35.4,\n", - " 'q1': 35.0,\n", - " 'pos': 7,\n", - " 'lower': 32.0},\n", - " {'q1': 38.0,\n", - " 'upper': 45.5,\n", - " 'pos': 16,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.48},\n", - " {'pos': 72,\n", - " 'median': 35.0,\n", - " 'upper': 43.0,\n", - " 'average': 33.265,\n", - " 'q1': 33.0,\n", - " 'lower': 27.0,\n", - " 'q3': 37.0},\n", - " {'q1': 31.0,\n", - " 'lower': 22.0,\n", - " 'pos': 75,\n", - " 'average': 31.06,\n", - " 'q3': 37.0,\n", - " 'upper': 46.0,\n", - " 'median': 35.0},\n", - " {'average': 37.95,\n", - " 'median': 40.0,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'pos': 40,\n", - " 'upper': 43.0,\n", - " 'q1': 38.0},\n", - " {'pos': 5,\n", - " 'median': 35.0,\n", - " 'q3': 37.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'average': 35.095,\n", - " 'q1': 35.0},\n", - " {'upper': 40.0,\n", - " 'pos': 6,\n", - " 'median': 35.0,\n", - " 'average': 35.145,\n", - " 'q3': 37.0,\n", - " 'lower': 32.0,\n", - " 'q1': 35.0},\n", - " {'pos': 86,\n", - " 'q1': 33.0,\n", - " 'average': 31.815,\n", - " 'median': 35.0,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0},\n", - " {'lower': 30.0,\n", - " 'pos': 55,\n", - " 'average': 37.55,\n", - " 'q3': 40.0,\n", - " 'upper': 46.0,\n", - " 'median': 39.0,\n", - " 'q1': 36.0},\n", - " {'median': 34.0,\n", - " 'q1': 31.0,\n", - " 'q3': 34.0,\n", - " 'pos': 1,\n", - " 'lower': 26.5,\n", - " 'upper': 38.5,\n", - " 'average': 31.21},\n", - " {'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'average': 38.44,\n", - " 'q1': 38.0,\n", - " 'pos': 27,\n", - " 'upper': 45.5,\n", - " 'lower': 33.5},\n", - " {'upper': 42.0,\n", - " 'average': 37.71,\n", - " 'lower': 34.0,\n", - " 'q3': 39.0,\n", - " 'pos': 11,\n", - " 'q1': 37.0,\n", - " 'median': 39.0},\n", - " {'median': 37.0,\n", - " 'pos': 66,\n", - " 'average': 35.875,\n", - " 'q3': 39.0,\n", - " 'q1': 35.0,\n", - " 'lower': 29.0,\n", - " 'upper': 45.0},\n", - " {'upper': 39.5,\n", - " 'q3': 35.0,\n", - " 'lower': 27.5,\n", - " 'average': 31.05,\n", - " 'median': 34.0,\n", - " 'pos': 93,\n", - " 'q1': 32.0},\n", - " {'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'pos': 32,\n", - " 'average': 38.29,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5},\n", - " {'median': 36.0,\n", - " 'upper': 46.5,\n", - " 'q1': 34.0,\n", - " 'pos': 69,\n", - " 'q3': 39.0,\n", - " 'lower': 26.5,\n", - " 'average': 33.7},\n", - " {'lower': 33.5,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'pos': 14,\n", - " 'average': 38.965,\n", - " 'median': 40.0},\n", - " {'q1': 32.0,\n", - " 'median': 34.0,\n", - " 'average': 30.775,\n", - " 'q3': 35.0,\n", - " 'pos': 94,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5},\n", - " {'q1': 37.0,\n", - " 'q3': 41.0,\n", - " 'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'average': 37.87,\n", - " 'pos': 41,\n", - " 'median': 40.0},\n", - " {'pos': 96,\n", - " 'q3': 35.0,\n", - " 'upper': 39.5,\n", - " 'q1': 32.0,\n", - " 'lower': 27.5,\n", - " 'median': 34.0,\n", - " 'average': 31.315},\n", - " {'pos': 17,\n", - " 'q1': 38.0,\n", - " 'median': 40.0,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.505},\n", - " {'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'average': 38.245,\n", - " 'q1': 38.0,\n", - " 'pos': 33},\n", - " {'average': 36.095,\n", - " 'q1': 35.0,\n", - " 'lower': 27.5,\n", - " 'pos': 64,\n", - " 'q3': 40.0,\n", - " 'upper': 47.5,\n", - " 'median': 37.0},\n", - " {'pos': 35,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'average': 38.385,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0},\n", - " {'lower': 28.5,\n", - " 'q1': 36.0,\n", - " 'pos': 48,\n", - " 'median': 40.0,\n", - " 'average': 37.61,\n", - " 'q3': 41.0,\n", - " 'upper': 48.5},\n", - " {'average': 31.915,\n", - " 'median': 35.0,\n", - " 'pos': 87,\n", - " 'q1': 32.0,\n", - " 'upper': 39.5,\n", - " 'lower': 27.5,\n", - " 'q3': 35.0},\n", - " {'upper': 47.5,\n", - " 'median': 38.0,\n", - " 'average': 35.99,\n", - " 'pos': 61,\n", - " 'q1': 35.0,\n", - " 'lower': 27.5,\n", - " 'q3': 40.0},\n", - " {'average': 37.79,\n", - " 'q3': 41.0,\n", - " 'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'q1': 37.0,\n", - " 'median': 39.5,\n", - " 'pos': 46},\n", - " {'q3': 36.0,\n", - " 'average': 32.76,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'upper': 40.5,\n", - " 'pos': 81,\n", - " 'lower': 28.5},\n", - " {'pos': 2,\n", - " 'average': 32.015,\n", - " 'median': 34.0,\n", - " 'q1': 31.0,\n", - " 'lower': 26.5,\n", - " 'upper': 38.5,\n", - " 'q3': 34.0},\n", - " {'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'median': 34.0,\n", - " 'average': 31.25,\n", - " 'q3': 35.0,\n", - " 'pos': 99,\n", - " 'q1': 32.0},\n", - " {'q1': 33.0,\n", - " 'average': 32.415,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'pos': 84,\n", - " 'q3': 35.0,\n", - " 'median': 35.0},\n", - " {'upper': 41.0,\n", - " 'q3': 35.0,\n", - " 'pos': 100,\n", - " 'average': 31.105,\n", - " 'q1': 31.0,\n", - " 'lower': 25.0,\n", - " 'median': 34.0}]}" + "shape: (20_200, 2)\n", + "┌─────┬───────┐\n", + "│ pos ┆ score │\n", + "│ --- ┆ --- │\n", + "│ i64 ┆ i8 │\n", + "╞═════╪═══════╡\n", + "│ 0 ┆ 2 │\n", + "│ 1 ┆ 19 │\n", + "│ 2 ┆ 33 │\n", + "│ 3 ┆ 35 │\n", + "│ 4 ┆ 37 │\n", + "│ … ┆ … │\n", + "│ 96 ┆ 35 │\n", + "│ 97 ┆ 32 │\n", + "│ 98 ┆ 35 │\n", + "│ 99 ┆ 35 │\n", + "│ 100 ┆ 33 │\n", + "└─────┴───────┘" ] }, "execution_count": 5, @@ -2320,720 +242,40 @@ "name": "stderr", "output_type": "stream", "text": [ - "200rows [00:00, 126946.25rows/s]\n" + "200rows [00:00, 85580.58rows/s]\n" ] }, { "data": { + "text/html": [ + "
\n", + "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + ], "text/plain": [ - "{'base_quality_warn': 'pass',\n", - " 'base_per_pos_data': [{'average': 38.505,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'upper': 45.5,\n", - " 'pos': 17,\n", - " 'q1': 38.0},\n", - " {'median': 33.0,\n", - " 'average': 30.135,\n", - " 'lower': 26.5,\n", - " 'q1': 31.0,\n", - " 'q3': 34.0,\n", - " 'pos': 0,\n", - " 'upper': 38.5},\n", - " {'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'median': 35.0,\n", - " 'pos': 5,\n", - " 'average': 35.095,\n", - " 'q1': 35.0,\n", - " 'q3': 37.0},\n", - " {'pos': 20,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.625,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'pos': 10,\n", - " 'lower': 34.0,\n", - " 'q3': 39.0,\n", - " 'upper': 42.0,\n", - " 'average': 37.675,\n", - " 'q1': 37.0,\n", - " 'median': 39.0},\n", - " {'lower': 31.0,\n", - " 'average': 37.87,\n", - " 'upper': 47.0,\n", - " 'q1': 37.0,\n", - " 'pos': 41,\n", - " 'median': 40.0,\n", - " 'q3': 41.0},\n", - " {'pos': 56,\n", - " 'q1': 36.0,\n", - " 'lower': 30.0,\n", - " 'median': 39.0,\n", - " 'upper': 46.0,\n", - " 'q3': 40.0,\n", - " 'average': 37.59},\n", - " {'q1': 38.0,\n", - " 'upper': 43.0,\n", - " 'average': 37.855,\n", - " 'pos': 26,\n", - " 'median': 40.0,\n", - " 'lower': 35.0,\n", - " 'q3': 40.0},\n", - " {'average': 37.565,\n", - " 'pos': 44,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'q1': 37.0},\n", - " {'average': 37.59,\n", - " 'upper': 48.5,\n", - " 'pos': 54,\n", - " 'q1': 36.0,\n", - " 'lower': 28.5,\n", - " 'median': 39.5,\n", - " 'q3': 41.0},\n", - " {'median': 38.0,\n", - " 'q3': 40.0,\n", - " 'upper': 47.5,\n", - " 'lower': 27.5,\n", - " 'q1': 35.0,\n", - " 'pos': 58,\n", - " 'average': 36.77},\n", - " {'average': 36.08,\n", - " 'lower': 27.5,\n", - " 'pos': 59,\n", - " 'q1': 35.0,\n", - " 'q3': 40.0,\n", - " 'upper': 47.5,\n", - " 'median': 38.0},\n", - " {'average': 37.625,\n", - " 'median': 39.0,\n", - " 'pos': 8,\n", - " 'q1': 37.0,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0},\n", - " {'average': 38.205,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 34,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0},\n", - " {'upper': 46.5,\n", - " 'pos': 67,\n", - " 'q1': 34.0,\n", - " 'q3': 39.0,\n", - " 'lower': 26.5,\n", - " 'average': 35.96,\n", - " 'median': 36.5},\n", - " {'upper': 44.5,\n", - " 'q1': 32.0,\n", - " 'pos': 74,\n", - " 'median': 35.0,\n", - " 'average': 30.83,\n", - " 'q3': 37.0,\n", - " 'lower': 24.5},\n", - " {'average': 31.46,\n", - " 'upper': 43.5,\n", - " 'pos': 78,\n", - " 'lower': 23.5,\n", - " 'median': 35.0,\n", - " 'q3': 36.0,\n", - " 'q1': 31.0},\n", - " {'pos': 28,\n", - " 'median': 40.0,\n", - " 'average': 38.445,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'pos': 32,\n", - " 'average': 38.29,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'median': 40.0},\n", - " {'pos': 2,\n", - " 'median': 34.0,\n", - " 'q3': 34.0,\n", - " 'average': 32.015,\n", - " 'lower': 26.5,\n", - " 'upper': 38.5,\n", - " 'q1': 31.0},\n", - " {'lower': 30.0,\n", - " 'pos': 83,\n", - " 'median': 35.0,\n", - " 'q3': 35.0,\n", - " 'upper': 38.0,\n", - " 'average': 32.03,\n", - " 'q1': 33.0},\n", - " {'q3': 35.0,\n", - " 'average': 32.195,\n", - " 'median': 35.0,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'pos': 85,\n", - " 'q1': 33.0},\n", - " {'q3': 38.0,\n", - " 'lower': 28.0,\n", - " 'upper': 44.0,\n", - " 'q1': 34.0,\n", - " 'median': 35.0,\n", - " 'average': 33.565,\n", - " 'pos': 70},\n", - " {'q1': 35.0,\n", - " 'lower': 27.5,\n", - " 'pos': 64,\n", - " 'q3': 40.0,\n", - " 'upper': 47.5,\n", - " 'median': 37.0,\n", - " 'average': 36.095},\n", - " {'median': 35.0,\n", - " 'q3': 35.0,\n", - " 'average': 32.665,\n", - " 'upper': 39.5,\n", - " 'pos': 91,\n", - " 'q1': 32.0,\n", - " 'lower': 27.5},\n", - " {'q3': 39.0,\n", - " 'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'lower': 29.0,\n", - " 'upper': 45.0,\n", - " 'average': 35.995,\n", - " 'pos': 65},\n", - " {'q1': 33.0,\n", - " 'median': 35.0,\n", - " 'average': 32.76,\n", - " 'lower': 28.5,\n", - " 'upper': 40.5,\n", - " 'pos': 81,\n", - " 'q3': 36.0},\n", - " {'pos': 66,\n", - " 'median': 37.0,\n", - " 'q3': 39.0,\n", - " 'average': 35.875,\n", - " 'q1': 35.0,\n", - " 'lower': 29.0,\n", - " 'upper': 45.0},\n", - " {'upper': 42.0,\n", - " 'median': 35.0,\n", - " 'lower': 26.0,\n", - " 'average': 32.46,\n", - " 'pos': 79,\n", - " 'q1': 32.0,\n", - " 'q3': 36.0},\n", - " {'q3': 37.0,\n", - " 'pos': 7,\n", - " 'average': 35.4,\n", - " 'median': 36.0,\n", - " 'q1': 35.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0},\n", - " {'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'q1': 38.0,\n", - " 'average': 38.245,\n", - " 'upper': 43.0,\n", - " 'pos': 30,\n", - " 'median': 40.0},\n", - " {'lower': 35.0,\n", - " 'q3': 40.0,\n", - " 'upper': 43.0,\n", - " 'average': 37.895,\n", - " 'q1': 38.0,\n", - " 'pos': 39,\n", - " 'median': 40.0},\n", - " {'q1': 36.0,\n", - " 'upper': 48.5,\n", - " 'average': 37.45,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5,\n", - " 'median': 40.0,\n", - " 'pos': 45},\n", - " {'average': 37.21,\n", - " 'median': 39.0,\n", - " 'upper': 46.0,\n", - " 'lower': 30.0,\n", - " 'pos': 49,\n", - " 'q1': 36.0,\n", - " 'q3': 40.0},\n", - " {'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'lower': 30.0,\n", - " 'pos': 86,\n", - " 'upper': 38.0,\n", - " 'average': 31.815,\n", - " 'q3': 35.0},\n", - " {'pos': 6,\n", - " 'q1': 35.0,\n", - " 'lower': 32.0,\n", - " 'q3': 37.0,\n", - " 'upper': 40.0,\n", - " 'average': 35.145,\n", - " 'median': 35.0},\n", - " {'q3': 40.0,\n", - " 'lower': 27.5,\n", - " 'pos': 60,\n", - " 'average': 35.985,\n", - " 'upper': 47.5,\n", - " 'median': 38.0,\n", - " 'q1': 35.0},\n", - " {'lower': 27.5,\n", - " 'average': 31.425,\n", - " 'q3': 35.0,\n", - " 'median': 34.0,\n", - " 'q1': 32.0,\n", - " 'pos': 95,\n", - " 'upper': 39.5},\n", - " {'median': 40.0,\n", - " 'pos': 13,\n", - " 'lower': 33.5,\n", - " 'q3': 41.0,\n", - " 'average': 38.94,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5},\n", - " {'q1': 33.0,\n", - " 'upper': 38.0,\n", - " 'average': 32.275,\n", - " 'pos': 90,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'median': 34.5},\n", - " {'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'pos': 33,\n", - " 'average': 38.245,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5},\n", - " {'upper': 39.5,\n", - " 'pos': 87,\n", - " 'average': 31.915,\n", - " 'q1': 32.0,\n", - " 'median': 35.0,\n", - " 'q3': 35.0,\n", - " 'lower': 27.5},\n", - " {'pos': 42,\n", - " 'median': 40.0,\n", - " 'average': 37.78,\n", - " 'q3': 40.0,\n", - " 'lower': 32.5,\n", - " 'q1': 37.0,\n", - " 'upper': 44.5},\n", - " {'q3': 40.0,\n", - " 'pos': 63,\n", - " 'average': 36.25,\n", - " 'median': 38.0,\n", - " 'q1': 35.0,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5},\n", - " {'q1': 36.0,\n", - " 'pos': 57,\n", - " 'median': 39.0,\n", - " 'q3': 40.0,\n", - " 'upper': 46.0,\n", - " 'average': 37.35,\n", - " 'lower': 30.0},\n", - " {'upper': 42.0,\n", - " 'average': 37.71,\n", - " 'q1': 37.0,\n", - " 'median': 39.0,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'pos': 11},\n", - " {'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'average': 38.425,\n", - " 'pos': 19,\n", - " 'q3': 41.0},\n", - " {'pos': 88,\n", - " 'upper': 38.0,\n", - " 'q1': 33.0,\n", - " 'average': 32.065,\n", - " 'median': 35.0,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0},\n", - " {'upper': 39.5,\n", - " 'average': 31.315,\n", - " 'q1': 32.0,\n", - " 'pos': 96,\n", - " 'median': 34.0,\n", - " 'q3': 35.0,\n", - " 'lower': 27.5},\n", - " {'q3': 41.0,\n", - " 'lower': 28.5,\n", - " 'upper': 48.5,\n", - " 'average': 37.61,\n", - " 'median': 40.0,\n", - " 'pos': 48,\n", - " 'q1': 36.0},\n", - " {'q3': 37.0,\n", - " 'average': 35.68,\n", - " 'upper': 40.0,\n", - " 'lower': 32.0,\n", - " 'pos': 4,\n", - " 'median': 37.0,\n", - " 'q1': 35.0},\n", - " {'q1': 33.0,\n", - " 'pos': 89,\n", - " 'average': 32.44,\n", - " 'median': 35.0,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'q3': 35.0},\n", - " {'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'average': 37.5,\n", - " 'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'upper': 42.0,\n", - " 'pos': 12},\n", - " {'lower': 25.0,\n", - " 'q3': 35.0,\n", - " 'upper': 41.0,\n", - " 'pos': 97,\n", - " 'average': 30.67,\n", - " 'median': 34.0,\n", - " 'q1': 31.0},\n", - " {'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'pos': 27,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'average': 38.44},\n", - " {'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'average': 37.845,\n", - " 'q1': 37.0,\n", - " 'median': 39.0,\n", - " 'pos': 53,\n", - " 'q3': 41.0},\n", - " {'pos': 100,\n", - " 'q3': 35.0,\n", - " 'lower': 25.0,\n", - " 'average': 31.105,\n", - " 'upper': 41.0,\n", - " 'median': 34.0,\n", - " 'q1': 31.0},\n", - " {'q1': 37.0,\n", - " 'lower': 32.5,\n", - " 'upper': 44.5,\n", - " 'q3': 40.0,\n", - " 'pos': 52,\n", - " 'average': 37.77,\n", - " 'median': 39.0},\n", - " {'q3': 41.0,\n", - " 'pos': 24,\n", - " 'average': 38.265,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'upper': 42.0,\n", - " 'median': 39.0,\n", - " 'q3': 39.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.36,\n", - " 'pos': 9,\n", - " 'lower': 34.0},\n", - " {'pos': 15,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'average': 38.725,\n", - " 'q1': 38.0},\n", - " {'pos': 55,\n", - " 'average': 37.55,\n", - " 'lower': 30.0,\n", - " 'q1': 36.0,\n", - " 'median': 39.0,\n", - " 'q3': 40.0,\n", - " 'upper': 46.0},\n", - " {'median': 35.0,\n", - " 'q1': 31.0,\n", - " 'q3': 37.0,\n", - " 'pos': 75,\n", - " 'lower': 22.0,\n", - " 'upper': 46.0,\n", - " 'average': 31.06},\n", - " {'lower': 33.5,\n", - " 'pos': 29,\n", - " 'average': 38.595,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'q1': 38.0},\n", - " {'q1': 34.0,\n", - " 'pos': 69,\n", - " 'lower': 26.5,\n", - " 'average': 33.7,\n", - " 'upper': 46.5,\n", - " 'median': 36.0,\n", - " 'q3': 39.0},\n", - " {'q3': 41.0,\n", - " 'average': 37.79,\n", - " 'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'pos': 46,\n", - " 'median': 39.5,\n", - " 'q1': 37.0},\n", - " {'upper': 39.5,\n", - " 'pos': 93,\n", - " 'average': 31.05,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0,\n", - " 'median': 34.0,\n", - " 'lower': 27.5},\n", - " {'average': 37.775,\n", - " 'pos': 43,\n", - " 'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'median': 40.0},\n", - " {'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'pos': 23,\n", - " 'average': 38.635,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5},\n", - " {'q3': 37.0,\n", - " 'median': 35.0,\n", - " 'pos': 73,\n", - " 'average': 32.68,\n", - " 'q1': 33.0,\n", - " 'lower': 27.0,\n", - " 'upper': 43.0},\n", - " {'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 14,\n", - " 'average': 38.965,\n", - " 'q1': 38.0,\n", - " 'median': 40.0},\n", - " {'median': 40.0,\n", - " 'q3': 40.0,\n", - " 'q1': 38.0,\n", - " 'pos': 37,\n", - " 'upper': 43.0,\n", - " 'lower': 35.0,\n", - " 'average': 38.0},\n", - " {'pos': 76,\n", - " 'median': 35.0,\n", - " 'lower': 22.0,\n", - " 'upper': 46.0,\n", - " 'q3': 37.0,\n", - " 'average': 30.265,\n", - " 'q1': 31.0},\n", - " {'q3': 36.0,\n", - " 'lower': 26.0,\n", - " 'upper': 42.0,\n", - " 'median': 35.0,\n", - " 'average': 32.61,\n", - " 'pos': 80,\n", - " 'q1': 32.0},\n", - " {'average': 37.665,\n", - " 'q3': 41.0,\n", - " 'pos': 47,\n", - " 'q1': 37.0,\n", - " 'lower': 31.0,\n", - " 'median': 39.0,\n", - " 'upper': 47.0},\n", - " {'average': 33.265,\n", - " 'median': 35.0,\n", - " 'pos': 72,\n", - " 'q1': 33.0,\n", - " 'q3': 37.0,\n", - " 'lower': 27.0,\n", - " 'upper': 43.0},\n", - " {'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'pos': 18,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'average': 38.47},\n", - " {'q1': 33.0,\n", - " 'lower': 28.5,\n", - " 'pos': 82,\n", - " 'q3': 36.0,\n", - " 'upper': 40.5,\n", - " 'median': 35.0,\n", - " 'average': 31.525},\n", - " {'average': 35.69,\n", - " 'median': 37.0,\n", - " 'lower': 32.0,\n", - " 'pos': 3,\n", - " 'q3': 37.0,\n", - " 'upper': 40.0,\n", - " 'q1': 35.0},\n", - " {'average': 35.99,\n", - " 'q1': 35.0,\n", - " 'upper': 47.5,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5,\n", - " 'pos': 61,\n", - " 'median': 38.0},\n", - " {'upper': 48.5,\n", - " 'lower': 28.5,\n", - " 'pos': 50,\n", - " 'q1': 36.0,\n", - " 'q3': 41.0,\n", - " 'median': 39.0,\n", - " 'average': 37.425},\n", - " {'average': 36.145,\n", - " 'upper': 47.5,\n", - " 'q3': 40.0,\n", - " 'pos': 62,\n", - " 'median': 38.0,\n", - " 'q1': 35.0,\n", - " 'lower': 27.5},\n", - " {'pos': 51,\n", - " 'average': 37.53,\n", - " 'lower': 28.5,\n", - " 'median': 39.0,\n", - " 'upper': 48.5,\n", - " 'q3': 41.0,\n", - " 'q1': 36.0},\n", - " {'upper': 43.0,\n", - " 'average': 37.95,\n", - " 'q1': 38.0,\n", - " 'median': 40.0,\n", - " 'lower': 35.0,\n", - " 'pos': 40,\n", - " 'q3': 40.0},\n", - " {'upper': 46.5,\n", - " 'average': 35.91,\n", - " 'q1': 34.0,\n", - " 'q3': 39.0,\n", - " 'lower': 26.5,\n", - " 'median': 36.0,\n", - " 'pos': 68},\n", - " {'median': 35.0,\n", - " 'q1': 30.0,\n", - " 'q3': 36.0,\n", - " 'lower': 21.0,\n", - " 'pos': 77,\n", - " 'average': 30.805,\n", - " 'upper': 45.0},\n", - " {'average': 33.005,\n", - " 'pos': 71,\n", - " 'q1': 33.0,\n", - " 'q3': 38.0,\n", - " 'lower': 25.5,\n", - " 'median': 35.0,\n", - " 'upper': 45.5},\n", - " {'q3': 35.0,\n", - " 'pos': 98,\n", - " 'average': 31.55,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'median': 34.0,\n", - " 'q1': 32.0},\n", - " {'average': 31.25,\n", - " 'median': 34.0,\n", - " 'upper': 39.5,\n", - " 'pos': 99,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0,\n", - " 'lower': 27.5},\n", - " {'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'upper': 45.5,\n", - " 'pos': 38,\n", - " 'average': 37.64,\n", - " 'q1': 38.0},\n", - " {'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'pos': 25,\n", - " 'q3': 41.0,\n", - " 'average': 38.2},\n", - " {'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'pos': 31,\n", - " 'average': 38.795,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5},\n", - " {'average': 38.385,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'pos': 35,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0},\n", - " {'q1': 33.0,\n", - " 'q3': 35.0,\n", - " 'pos': 84,\n", - " 'lower': 30.0,\n", - " 'median': 35.0,\n", - " 'upper': 38.0,\n", - " 'average': 32.415},\n", - " {'pos': 92,\n", - " 'median': 35.0,\n", - " 'upper': 39.5,\n", - " 'average': 31.835,\n", - " 'lower': 27.5,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0},\n", - " {'q1': 32.0,\n", - " 'lower': 27.5,\n", - " 'median': 34.0,\n", - " 'pos': 94,\n", - " 'upper': 39.5,\n", - " 'average': 30.775,\n", - " 'q3': 35.0},\n", - " {'pos': 1,\n", - " 'median': 34.0,\n", - " 'q3': 34.0,\n", - " 'average': 31.21,\n", - " 'lower': 26.5,\n", - " 'q1': 31.0,\n", - " 'upper': 38.5},\n", - " {'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'average': 38.41,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'q3': 41.0,\n", - " 'pos': 22},\n", - " {'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'pos': 36,\n", - " 'average': 38.11,\n", - " 'q1': 38.0,\n", - " 'median': 40.0},\n", - " {'lower': 35.0,\n", - " 'average': 38.445,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'upper': 43.0,\n", - " 'pos': 21},\n", - " {'q1': 38.0,\n", - " 'pos': 16,\n", - " 'q3': 41.0,\n", - " 'average': 38.48,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'median': 40.0}]}" + "shape: (20_200, 2)\n", + "┌─────┬───────┐\n", + "│ pos ┆ score │\n", + "│ --- ┆ --- │\n", + "│ i64 ┆ i8 │\n", + "╞═════╪═══════╡\n", + "│ 0 ┆ 2 │\n", + "│ 1 ┆ 19 │\n", + "│ 2 ┆ 33 │\n", + "│ 3 ┆ 35 │\n", + "│ 4 ┆ 37 │\n", + "│ … ┆ … │\n", + "│ 96 ┆ 35 │\n", + "│ 97 ┆ 32 │\n", + "│ 98 ┆ 35 │\n", + "│ 99 ┆ 35 │\n", + "│ 100 ┆ 33 │\n", + "└─────┴───────┘" ] }, "execution_count": 6, @@ -3066,7 +308,7 @@ "output_type": "stream", "text": [ "INFO:polars_bio:Table: example registered for path: ./example.fastq\n", - "200rows [00:00, 80924.25rows/s]\n" + "200rows [00:00, 99332.24rows/s]" ] }, { @@ -3076,717 +318,44 @@ "\n" ] }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, { "data": { + "text/html": [ + "
\n", + "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + ], "text/plain": [ - "{'base_quality_warn': 'pass',\n", - " 'base_per_pos_data': [{'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'average': 38.265,\n", - " 'pos': 24,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0},\n", - " {'median': 35.0,\n", - " 'average': 30.83,\n", - " 'pos': 74,\n", - " 'q1': 32.0,\n", - " 'lower': 24.5,\n", - " 'q3': 37.0,\n", - " 'upper': 44.5},\n", - " {'pos': 93,\n", - " 'upper': 39.5,\n", - " 'average': 31.05,\n", - " 'median': 34.0,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0,\n", - " 'lower': 27.5},\n", - " {'q1': 37.0,\n", - " 'pos': 10,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0,\n", - " 'median': 39.0,\n", - " 'average': 37.675},\n", - " {'lower': 28.5,\n", - " 'upper': 48.5,\n", - " 'median': 39.0,\n", - " 'average': 37.425,\n", - " 'pos': 50,\n", - " 'q1': 36.0,\n", - " 'q3': 41.0},\n", - " {'q1': 36.0,\n", - " 'lower': 30.0,\n", - " 'pos': 55,\n", - " 'average': 37.55,\n", - " 'q3': 40.0,\n", - " 'upper': 46.0,\n", - " 'median': 39.0},\n", - " {'average': 32.195,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'pos': 85,\n", - " 'upper': 38.0,\n", - " 'median': 35.0},\n", - " {'pos': 91,\n", - " 'q1': 32.0,\n", - " 'upper': 39.5,\n", - " 'q3': 35.0,\n", - " 'average': 32.665,\n", - " 'lower': 27.5,\n", - " 'median': 35.0},\n", - " {'pos': 92,\n", - " 'q1': 32.0,\n", - " 'median': 35.0,\n", - " 'upper': 39.5,\n", - " 'q3': 35.0,\n", - " 'average': 31.835,\n", - " 'lower': 27.5},\n", - " {'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'q1': 37.0,\n", - " 'median': 39.5,\n", - " 'average': 37.79,\n", - " 'pos': 46,\n", - " 'q3': 41.0},\n", - " {'q3': 40.0,\n", - " 'q1': 36.0,\n", - " 'upper': 46.0,\n", - " 'pos': 57,\n", - " 'average': 37.35,\n", - " 'median': 39.0,\n", - " 'lower': 30.0},\n", - " {'pos': 66,\n", - " 'average': 35.875,\n", - " 'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'q3': 39.0,\n", - " 'lower': 29.0,\n", - " 'upper': 45.0},\n", - " {'pos': 69,\n", - " 'q3': 39.0,\n", - " 'lower': 26.5,\n", - " 'average': 33.7,\n", - " 'upper': 46.5,\n", - " 'q1': 34.0,\n", - " 'median': 36.0},\n", - " {'median': 38.0,\n", - " 'pos': 59,\n", - " 'q3': 40.0,\n", - " 'average': 36.08,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'q1': 35.0},\n", - " {'q3': 35.0,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'q1': 32.0,\n", - " 'pos': 99,\n", - " 'average': 31.25,\n", - " 'median': 34.0},\n", - " {'upper': 43.0,\n", - " 'q3': 40.0,\n", - " 'pos': 39,\n", - " 'q1': 38.0,\n", - " 'average': 37.895,\n", - " 'median': 40.0,\n", - " 'lower': 35.0},\n", - " {'upper': 43.0,\n", - " 'average': 37.95,\n", - " 'q1': 38.0,\n", - " 'pos': 40,\n", - " 'q3': 40.0,\n", - " 'median': 40.0,\n", - " 'lower': 35.0},\n", - " {'pos': 28,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5,\n", - " 'average': 38.445},\n", - " {'q1': 37.0,\n", - " 'q3': 39.0,\n", - " 'average': 37.5,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0,\n", - " 'pos': 12,\n", - " 'median': 39.0},\n", - " {'q3': 41.0,\n", - " 'pos': 23,\n", - " 'upper': 45.5,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'median': 40.0,\n", - " 'average': 38.635},\n", - " {'pos': 0,\n", - " 'average': 30.135,\n", - " 'median': 33.0,\n", - " 'q3': 34.0,\n", - " 'lower': 26.5,\n", - " 'upper': 38.5,\n", - " 'q1': 31.0},\n", - " {'lower': 34.0,\n", - " 'pos': 8,\n", - " 'upper': 42.0,\n", - " 'average': 37.625,\n", - " 'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'q3': 39.0},\n", - " {'median': 40.0,\n", - " 'lower': 28.5,\n", - " 'pos': 48,\n", - " 'q3': 41.0,\n", - " 'q1': 36.0,\n", - " 'average': 37.61,\n", - " 'upper': 48.5},\n", - " {'q1': 33.0,\n", - " 'pos': 82,\n", - " 'median': 35.0,\n", - " 'q3': 36.0,\n", - " 'lower': 28.5,\n", - " 'average': 31.525,\n", - " 'upper': 40.5},\n", - " {'pos': 96,\n", - " 'average': 31.315,\n", - " 'median': 34.0,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5},\n", - " {'upper': 47.0,\n", - " 'pos': 53,\n", - " 'median': 39.0,\n", - " 'average': 37.845,\n", - " 'q1': 37.0,\n", - " 'q3': 41.0,\n", - " 'lower': 31.0},\n", - " {'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'median': 38.0,\n", - " 'pos': 62,\n", - " 'q3': 40.0,\n", - " 'average': 36.145,\n", - " 'q1': 35.0},\n", - " {'upper': 38.0,\n", - " 'median': 34.5,\n", - " 'average': 32.275,\n", - " 'q3': 35.0,\n", - " 'pos': 90,\n", - " 'q1': 33.0,\n", - " 'lower': 30.0},\n", - " {'q1': 35.0,\n", - " 'average': 35.145,\n", - " 'pos': 6,\n", - " 'q3': 37.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'median': 35.0},\n", - " {'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'average': 38.245,\n", - " 'pos': 30,\n", - " 'q3': 40.0,\n", - " 'median': 40.0,\n", - " 'q1': 38.0},\n", - " {'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'average': 38.725,\n", - " 'median': 40.0,\n", - " 'pos': 15},\n", - " {'median': 40.0,\n", - " 'upper': 45.5,\n", - " 'average': 38.245,\n", - " 'pos': 33,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5},\n", - " {'pos': 42,\n", - " 'average': 37.78,\n", - " 'median': 40.0,\n", - " 'q1': 37.0,\n", - " 'lower': 32.5,\n", - " 'upper': 44.5,\n", - " 'q3': 40.0},\n", - " {'pos': 44,\n", - " 'upper': 47.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.565,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'lower': 31.0},\n", - " {'q3': 41.0,\n", - " 'upper': 48.5,\n", - " 'lower': 28.5,\n", - " 'average': 37.59,\n", - " 'median': 39.5,\n", - " 'q1': 36.0,\n", - " 'pos': 54},\n", - " {'average': 32.68,\n", - " 'pos': 73,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'q3': 37.0,\n", - " 'lower': 27.0,\n", - " 'upper': 43.0},\n", - " {'pos': 37,\n", - " 'average': 38.0,\n", - " 'q1': 38.0,\n", - " 'median': 40.0,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0},\n", - " {'average': 38.625,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5,\n", - " 'lower': 33.5,\n", - " 'pos': 20,\n", - " 'q3': 41.0,\n", - " 'median': 40.0},\n", - " {'q3': 41.0,\n", - " 'lower': 31.0,\n", - " 'upper': 47.0,\n", - " 'pos': 47,\n", - " 'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.665},\n", - " {'average': 32.44,\n", - " 'lower': 30.0,\n", - " 'q1': 33.0,\n", - " 'upper': 38.0,\n", - " 'pos': 89,\n", - " 'median': 35.0,\n", - " 'q3': 35.0},\n", - " {'upper': 43.5,\n", - " 'q3': 36.0,\n", - " 'average': 31.46,\n", - " 'median': 35.0,\n", - " 'pos': 78,\n", - " 'q1': 31.0,\n", - " 'lower': 23.5},\n", - " {'upper': 40.0,\n", - " 'q3': 37.0,\n", - " 'median': 36.0,\n", - " 'average': 35.4,\n", - " 'q1': 35.0,\n", - " 'pos': 7,\n", - " 'lower': 32.0},\n", - " {'median': 39.0,\n", - " 'pos': 9,\n", - " 'average': 37.36,\n", - " 'q1': 37.0,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0},\n", - " {'upper': 48.5,\n", - " 'pos': 51,\n", - " 'q1': 36.0,\n", - " 'average': 37.53,\n", - " 'median': 39.0,\n", - " 'lower': 28.5,\n", - " 'q3': 41.0},\n", - " {'median': 34.0,\n", - " 'lower': 25.0,\n", - " 'pos': 97,\n", - " 'upper': 41.0,\n", - " 'q1': 31.0,\n", - " 'q3': 35.0,\n", - " 'average': 30.67},\n", - " {'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'pos': 26,\n", - " 'average': 37.855,\n", - " 'median': 40.0},\n", - " {'pos': 76,\n", - " 'median': 35.0,\n", - " 'q3': 37.0,\n", - " 'lower': 22.0,\n", - " 'upper': 46.0,\n", - " 'average': 30.265,\n", - " 'q1': 31.0},\n", - " {'q3': 36.0,\n", - " 'lower': 26.0,\n", - " 'pos': 80,\n", - " 'average': 32.61,\n", - " 'upper': 42.0,\n", - " 'median': 35.0,\n", - " 'q1': 32.0},\n", - " {'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'average': 38.47,\n", - " 'upper': 45.5,\n", - " 'pos': 18},\n", - " {'pos': 35,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.385,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'upper': 38.0,\n", - " 'lower': 30.0,\n", - " 'average': 32.03,\n", - " 'q3': 35.0,\n", - " 'pos': 83,\n", - " 'median': 35.0,\n", - " 'q1': 33.0},\n", - " {'pos': 31,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.795,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'pos': 3,\n", - " 'median': 37.0,\n", - " 'upper': 40.0,\n", - " 'average': 35.69,\n", - " 'lower': 32.0,\n", - " 'q3': 37.0,\n", - " 'q1': 35.0},\n", - " {'pos': 56,\n", - " 'average': 37.59,\n", - " 'q1': 36.0,\n", - " 'q3': 40.0,\n", - " 'lower': 30.0,\n", - " 'median': 39.0,\n", - " 'upper': 46.0},\n", - " {'upper': 47.5,\n", - " 'pos': 58,\n", - " 'average': 36.77,\n", - " 'median': 38.0,\n", - " 'q1': 35.0,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5},\n", - " {'q3': 40.0,\n", - " 'average': 35.99,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'pos': 61,\n", - " 'median': 38.0,\n", - " 'q1': 35.0},\n", - " {'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'average': 36.095,\n", - " 'q3': 40.0,\n", - " 'upper': 47.5,\n", - " 'lower': 27.5,\n", - " 'pos': 64},\n", - " {'q3': 37.0,\n", - " 'pos': 5,\n", - " 'lower': 32.0,\n", - " 'median': 35.0,\n", - " 'average': 35.095,\n", - " 'q1': 35.0,\n", - " 'upper': 40.0},\n", - " {'q1': 34.0,\n", - " 'pos': 68,\n", - " 'lower': 26.5,\n", - " 'q3': 39.0,\n", - " 'average': 35.91,\n", - " 'upper': 46.5,\n", - " 'median': 36.0},\n", - " {'pos': 87,\n", - " 'q1': 32.0,\n", - " 'lower': 27.5,\n", - " 'average': 31.915,\n", - " 'upper': 39.5,\n", - " 'q3': 35.0,\n", - " 'median': 35.0},\n", - " {'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'median': 34.0,\n", - " 'pos': 95,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0,\n", - " 'average': 31.425},\n", - " {'average': 38.94,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'pos': 13,\n", - " 'median': 40.0,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0},\n", - " {'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'pos': 22,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'average': 38.41},\n", - " {'pos': 70,\n", - " 'q3': 38.0,\n", - " 'average': 33.565,\n", - " 'q1': 34.0,\n", - " 'lower': 28.0,\n", - " 'median': 35.0,\n", - " 'upper': 44.0},\n", - " {'pos': 45,\n", - " 'q1': 36.0,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5,\n", - " 'upper': 48.5,\n", - " 'average': 37.45},\n", - " {'upper': 46.0,\n", - " 'average': 31.06,\n", - " 'median': 35.0,\n", - " 'pos': 75,\n", - " 'q1': 31.0,\n", - " 'q3': 37.0,\n", - " 'lower': 22.0},\n", - " {'pos': 94,\n", - " 'median': 34.0,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0,\n", - " 'average': 30.775,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5},\n", - " {'median': 40.0,\n", - " 'upper': 43.0,\n", - " 'pos': 21,\n", - " 'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'lower': 35.0,\n", - " 'average': 38.445},\n", - " {'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'pos': 16,\n", - " 'average': 38.48,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5},\n", - " {'average': 38.11,\n", - " 'median': 40.0,\n", - " 'lower': 35.0,\n", - " 'q1': 38.0,\n", - " 'upper': 43.0,\n", - " 'q3': 40.0,\n", - " 'pos': 36},\n", - " {'lower': 27.0,\n", - " 'average': 33.265,\n", - " 'median': 35.0,\n", - " 'q3': 37.0,\n", - " 'upper': 43.0,\n", - " 'pos': 72,\n", - " 'q1': 33.0},\n", - " {'average': 32.065,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'pos': 88,\n", - " 'upper': 38.0,\n", - " 'median': 35.0,\n", - " 'q1': 33.0},\n", - " {'upper': 47.0,\n", - " 'q3': 41.0,\n", - " 'pos': 41,\n", - " 'q1': 37.0,\n", - " 'median': 40.0,\n", - " 'lower': 31.0,\n", - " 'average': 37.87},\n", - " {'pos': 43,\n", - " 'upper': 43.0,\n", - " 'q1': 38.0,\n", - " 'lower': 35.0,\n", - " 'median': 40.0,\n", - " 'q3': 40.0,\n", - " 'average': 37.775},\n", - " {'pos': 100,\n", - " 'average': 31.105,\n", - " 'q1': 31.0,\n", - " 'median': 34.0,\n", - " 'upper': 41.0,\n", - " 'q3': 35.0,\n", - " 'lower': 25.0},\n", - " {'pos': 32,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'average': 38.29,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0},\n", - " {'average': 37.64,\n", - " 'pos': 38,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'median': 40.0},\n", - " {'pos': 67,\n", - " 'median': 36.5,\n", - " 'q1': 34.0,\n", - " 'q3': 39.0,\n", - " 'lower': 26.5,\n", - " 'upper': 46.5,\n", - " 'average': 35.96},\n", - " {'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'average': 38.205,\n", - " 'pos': 34,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'upper': 38.0,\n", - " 'q3': 35.0,\n", - " 'q1': 33.0,\n", - " 'average': 32.415,\n", - " 'pos': 84,\n", - " 'median': 35.0,\n", - " 'lower': 30.0},\n", - " {'upper': 40.0,\n", - " 'pos': 4,\n", - " 'average': 35.68,\n", - " 'q1': 35.0,\n", - " 'median': 37.0,\n", - " 'q3': 37.0,\n", - " 'lower': 32.0},\n", - " {'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 27,\n", - " 'average': 38.44,\n", - " 'median': 40.0,\n", - " 'q1': 38.0},\n", - " {'lower': 30.0,\n", - " 'average': 37.21,\n", - " 'q3': 40.0,\n", - " 'pos': 49,\n", - " 'upper': 46.0,\n", - " 'median': 39.0,\n", - " 'q1': 36.0},\n", - " {'q3': 39.0,\n", - " 'upper': 45.0,\n", - " 'average': 35.995,\n", - " 'lower': 29.0,\n", - " 'q1': 35.0,\n", - " 'pos': 65,\n", - " 'median': 37.0},\n", - " {'upper': 40.5,\n", - " 'average': 32.76,\n", - " 'q1': 33.0,\n", - " 'q3': 36.0,\n", - " 'median': 35.0,\n", - " 'pos': 81,\n", - " 'lower': 28.5},\n", - " {'pos': 17,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'lower': 33.5,\n", - " 'average': 38.505,\n", - " 'q1': 38.0,\n", - " 'median': 40.0},\n", - " {'lower': 33.5,\n", - " 'pos': 25,\n", - " 'upper': 45.5,\n", - " 'average': 38.2,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0},\n", - " {'upper': 45.5,\n", - " 'q3': 38.0,\n", - " 'pos': 71,\n", - " 'average': 33.005,\n", - " 'q1': 33.0,\n", - " 'lower': 25.5,\n", - " 'median': 35.0},\n", - " {'pos': 14,\n", - " 'average': 38.965,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'median': 40.0},\n", - " {'q1': 31.0,\n", - " 'upper': 38.5,\n", - " 'q3': 34.0,\n", - " 'lower': 26.5,\n", - " 'median': 34.0,\n", - " 'average': 31.21,\n", - " 'pos': 1},\n", - " {'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'q3': 40.0,\n", - " 'median': 38.0,\n", - " 'q1': 35.0,\n", - " 'pos': 63,\n", - " 'average': 36.25},\n", - " {'average': 30.805,\n", - " 'q1': 30.0,\n", - " 'lower': 21.0,\n", - " 'upper': 45.0,\n", - " 'pos': 77,\n", - " 'median': 35.0,\n", - " 'q3': 36.0},\n", - " {'q1': 32.0,\n", - " 'pos': 79,\n", - " 'median': 35.0,\n", - " 'q3': 36.0,\n", - " 'average': 32.46,\n", - " 'lower': 26.0,\n", - " 'upper': 42.0},\n", - " {'average': 32.015,\n", - " 'q1': 31.0,\n", - " 'lower': 26.5,\n", - " 'pos': 2,\n", - " 'q3': 34.0,\n", - " 'upper': 38.5,\n", - " 'median': 34.0},\n", - " {'upper': 44.5,\n", - " 'lower': 32.5,\n", - " 'q1': 37.0,\n", - " 'pos': 52,\n", - " 'median': 39.0,\n", - " 'average': 37.77,\n", - " 'q3': 40.0},\n", - " {'average': 35.985,\n", - " 'pos': 60,\n", - " 'q1': 35.0,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'q3': 40.0,\n", - " 'median': 38.0},\n", - " {'lower': 30.0,\n", - " 'average': 31.815,\n", - " 'median': 35.0,\n", - " 'upper': 38.0,\n", - " 'pos': 86,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0},\n", - " {'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'pos': 29,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.595},\n", - " {'average': 31.55,\n", - " 'median': 34.0,\n", - " 'q1': 32.0,\n", - " 'upper': 39.5,\n", - " 'pos': 98,\n", - " 'lower': 27.5,\n", - " 'q3': 35.0},\n", - " {'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'pos': 19,\n", - " 'upper': 45.5,\n", - " 'average': 38.425},\n", - " {'pos': 11,\n", - " 'average': 37.71,\n", - " 'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0}]}" + "shape: (20_200, 2)\n", + "┌─────┬───────┐\n", + "│ pos ┆ score │\n", + "│ --- ┆ --- │\n", + "│ i64 ┆ i8 │\n", + "╞═════╪═══════╡\n", + "│ 0 ┆ 2 │\n", + "│ 1 ┆ 19 │\n", + "│ 2 ┆ 33 │\n", + "│ 3 ┆ 35 │\n", + "│ 4 ┆ 37 │\n", + "│ … ┆ … │\n", + "│ 96 ┆ 35 │\n", + "│ 97 ┆ 32 │\n", + "│ 98 ┆ 35 │\n", + "│ 99 ┆ 35 │\n", + "│ 100 ┆ 33 │\n", + "└─────┴───────┘" ] }, "execution_count": 7, @@ -3820,7 +389,7 @@ "output_type": "stream", "text": [ "INFO:polars_bio:Table: example registered for path: ./example.fastq\n", - "200rows [00:00, 120508.66rows/s]" + "200rows [00:00, 91638.72rows/s]" ] }, { @@ -3839,715 +408,35 @@ }, { "data": { + "text/html": [ + "
\n", + "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + ], "text/plain": [ - "{'base_quality_warn': 'pass',\n", - " 'base_per_pos_data': [{'upper': 41.0,\n", - " 'q3': 35.0,\n", - " 'lower': 25.0,\n", - " 'pos': 97,\n", - " 'average': 30.67,\n", - " 'median': 34.0,\n", - " 'q1': 31.0},\n", - " {'q1': 38.0,\n", - " 'pos': 14,\n", - " 'average': 38.965,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0},\n", - " {'pos': 23,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.635,\n", - " 'lower': 33.5,\n", - " 'median': 40.0},\n", - " {'q1': 37.0,\n", - " 'lower': 34.0,\n", - " 'average': 37.71,\n", - " 'upper': 42.0,\n", - " 'q3': 39.0,\n", - " 'median': 39.0,\n", - " 'pos': 11},\n", - " {'average': 38.425,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'pos': 19},\n", - " {'q3': 34.0,\n", - " 'upper': 38.5,\n", - " 'average': 32.015,\n", - " 'q1': 31.0,\n", - " 'lower': 26.5,\n", - " 'pos': 2,\n", - " 'median': 34.0},\n", - " {'upper': 48.5,\n", - " 'q1': 36.0,\n", - " 'average': 37.45,\n", - " 'median': 40.0,\n", - " 'pos': 45,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5},\n", - " {'average': 37.61,\n", - " 'pos': 48,\n", - " 'median': 40.0,\n", - " 'q1': 36.0,\n", - " 'upper': 48.5,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5},\n", - " {'q1': 38.0,\n", - " 'median': 40.0,\n", - " 'lower': 35.0,\n", - " 'pos': 37,\n", - " 'q3': 40.0,\n", - " 'upper': 43.0,\n", - " 'average': 38.0},\n", - " {'pos': 74,\n", - " 'median': 35.0,\n", - " 'q3': 37.0,\n", - " 'q1': 32.0,\n", - " 'average': 30.83,\n", - " 'lower': 24.5,\n", - " 'upper': 44.5},\n", - " {'average': 33.565,\n", - " 'pos': 70,\n", - " 'q1': 34.0,\n", - " 'q3': 38.0,\n", - " 'lower': 28.0,\n", - " 'upper': 44.0,\n", - " 'median': 35.0},\n", - " {'upper': 45.5,\n", - " 'pos': 31,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.795},\n", - " {'average': 32.195,\n", - " 'median': 35.0,\n", - " 'upper': 38.0,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'pos': 85},\n", - " {'pos': 15,\n", - " 'upper': 45.5,\n", - " 'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0,\n", - " 'average': 38.725},\n", - " {'q1': 32.0,\n", - " 'median': 35.0,\n", - " 'lower': 27.5,\n", - " 'pos': 91,\n", - " 'q3': 35.0,\n", - " 'upper': 39.5,\n", - " 'average': 32.665},\n", - " {'median': 34.0,\n", - " 'pos': 1,\n", - " 'q1': 31.0,\n", - " 'lower': 26.5,\n", - " 'average': 31.21,\n", - " 'q3': 34.0,\n", - " 'upper': 38.5},\n", - " {'median': 34.0,\n", - " 'q3': 35.0,\n", - " 'upper': 39.5,\n", - " 'q1': 32.0,\n", - " 'pos': 96,\n", - " 'average': 31.315,\n", - " 'lower': 27.5},\n", - " {'upper': 39.5,\n", - " 'median': 34.0,\n", - " 'lower': 27.5,\n", - " 'pos': 99,\n", - " 'q1': 32.0,\n", - " 'average': 31.25,\n", - " 'q3': 35.0},\n", - " {'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'average': 38.595,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'pos': 29,\n", - " 'lower': 33.5},\n", - " {'median': 40.0,\n", - " 'upper': 43.0,\n", - " 'q1': 38.0,\n", - " 'average': 38.245,\n", - " 'pos': 30,\n", - " 'lower': 35.0,\n", - " 'q3': 40.0},\n", - " {'q3': 35.0,\n", - " 'q1': 32.0,\n", - " 'average': 31.55,\n", - " 'median': 34.0,\n", - " 'upper': 39.5,\n", - " 'lower': 27.5,\n", - " 'pos': 98},\n", - " {'pos': 52,\n", - " 'q1': 37.0,\n", - " 'q3': 40.0,\n", - " 'upper': 44.5,\n", - " 'lower': 32.5,\n", - " 'median': 39.0,\n", - " 'average': 37.77},\n", - " {'lower': 32.0,\n", - " 'pos': 4,\n", - " 'q1': 35.0,\n", - " 'average': 35.68,\n", - " 'q3': 37.0,\n", - " 'median': 37.0,\n", - " 'upper': 40.0},\n", - " {'average': 35.69,\n", - " 'q3': 37.0,\n", - " 'lower': 32.0,\n", - " 'upper': 40.0,\n", - " 'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'pos': 3},\n", - " {'median': 40.0,\n", - " 'pos': 38,\n", - " 'average': 37.64,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'pos': 46,\n", - " 'upper': 47.0,\n", - " 'q3': 41.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.79,\n", - " 'median': 39.5,\n", - " 'lower': 31.0},\n", - " {'pos': 82,\n", - " 'average': 31.525,\n", - " 'lower': 28.5,\n", - " 'upper': 40.5,\n", - " 'median': 35.0,\n", - " 'q3': 36.0,\n", - " 'q1': 33.0},\n", - " {'upper': 40.0,\n", - " 'lower': 32.0,\n", - " 'average': 35.095,\n", - " 'pos': 5,\n", - " 'median': 35.0,\n", - " 'q1': 35.0,\n", - " 'q3': 37.0},\n", - " {'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'median': 40.0,\n", - " 'average': 38.2,\n", - " 'pos': 25,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5},\n", - " {'pos': 33,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'upper': 45.5,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.245},\n", - " {'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'upper': 45.5,\n", - " 'pos': 24,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.265},\n", - " {'pos': 43,\n", - " 'average': 37.775,\n", - " 'q1': 38.0,\n", - " 'lower': 35.0,\n", - " 'q3': 40.0,\n", - " 'upper': 43.0,\n", - " 'median': 40.0},\n", - " {'median': 39.0,\n", - " 'q3': 40.0,\n", - " 'pos': 56,\n", - " 'lower': 30.0,\n", - " 'q1': 36.0,\n", - " 'upper': 46.0,\n", - " 'average': 37.59},\n", - " {'median': 37.0,\n", - " 'q3': 39.0,\n", - " 'lower': 29.0,\n", - " 'average': 35.875,\n", - " 'pos': 66,\n", - " 'q1': 35.0,\n", - " 'upper': 45.0},\n", - " {'upper': 45.5,\n", - " 'median': 35.0,\n", - " 'q3': 38.0,\n", - " 'pos': 71,\n", - " 'q1': 33.0,\n", - " 'average': 33.005,\n", - " 'lower': 25.5},\n", - " {'pos': 34,\n", - " 'median': 40.0,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.205,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'pos': 68,\n", - " 'upper': 46.5,\n", - " 'lower': 26.5,\n", - " 'median': 36.0,\n", - " 'q1': 34.0,\n", - " 'q3': 39.0,\n", - " 'average': 35.91},\n", - " {'average': 31.425,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'median': 34.0,\n", - " 'pos': 95,\n", - " 'q1': 32.0,\n", - " 'q3': 35.0},\n", - " {'median': 39.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.665,\n", - " 'q3': 41.0,\n", - " 'lower': 31.0,\n", - " 'pos': 47,\n", - " 'upper': 47.0},\n", - " {'median': 38.0,\n", - " 'q3': 40.0,\n", - " 'upper': 47.5,\n", - " 'average': 36.145,\n", - " 'lower': 27.5,\n", - " 'pos': 62,\n", - " 'q1': 35.0},\n", - " {'upper': 46.0,\n", - " 'median': 39.0,\n", - " 'q1': 36.0,\n", - " 'lower': 30.0,\n", - " 'q3': 40.0,\n", - " 'pos': 49,\n", - " 'average': 37.21},\n", - " {'upper': 44.5,\n", - " 'q3': 40.0,\n", - " 'q1': 37.0,\n", - " 'average': 37.78,\n", - " 'pos': 42,\n", - " 'median': 40.0,\n", - " 'lower': 32.5},\n", - " {'pos': 10,\n", - " 'average': 37.675,\n", - " 'lower': 34.0,\n", - " 'median': 39.0,\n", - " 'q3': 39.0,\n", - " 'q1': 37.0,\n", - " 'upper': 42.0},\n", - " {'median': 39.0,\n", - " 'q3': 40.0,\n", - " 'lower': 30.0,\n", - " 'average': 37.55,\n", - " 'q1': 36.0,\n", - " 'pos': 55,\n", - " 'upper': 46.0},\n", - " {'median': 34.5,\n", - " 'q3': 35.0,\n", - " 'average': 32.275,\n", - " 'pos': 90,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'q1': 33.0},\n", - " {'q1': 36.0,\n", - " 'average': 37.425,\n", - " 'upper': 48.5,\n", - " 'pos': 50,\n", - " 'lower': 28.5,\n", - " 'q3': 41.0,\n", - " 'median': 39.0},\n", - " {'average': 38.48,\n", - " 'q3': 41.0,\n", - " 'median': 40.0,\n", - " 'pos': 16,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5},\n", - " {'lower': 33.5,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'pos': 18,\n", - " 'average': 38.47,\n", - " 'q1': 38.0},\n", - " {'median': 40.0,\n", - " 'pos': 28,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'q3': 41.0,\n", - " 'q1': 38.0,\n", - " 'average': 38.445},\n", - " {'upper': 48.5,\n", - " 'q3': 41.0,\n", - " 'q1': 36.0,\n", - " 'average': 37.53,\n", - " 'median': 39.0,\n", - " 'pos': 51,\n", - " 'lower': 28.5},\n", - " {'pos': 100,\n", - " 'q3': 35.0,\n", - " 'upper': 41.0,\n", - " 'q1': 31.0,\n", - " 'lower': 25.0,\n", - " 'average': 31.105,\n", - " 'median': 34.0},\n", - " {'median': 40.0,\n", - " 'average': 37.95,\n", - " 'q1': 38.0,\n", - " 'pos': 40,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'q3': 40.0},\n", - " {'q1': 37.0,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0,\n", - " 'median': 39.0,\n", - " 'average': 37.36,\n", - " 'pos': 9},\n", - " {'pos': 69,\n", - " 'q3': 39.0,\n", - " 'lower': 26.5,\n", - " 'upper': 46.5,\n", - " 'q1': 34.0,\n", - " 'median': 36.0,\n", - " 'average': 33.7},\n", - " {'pos': 89,\n", - " 'average': 32.44,\n", - " 'median': 35.0,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0},\n", - " {'average': 32.03,\n", - " 'pos': 83,\n", - " 'q1': 33.0,\n", - " 'q3': 35.0,\n", - " 'median': 35.0,\n", - " 'upper': 38.0,\n", - " 'lower': 30.0},\n", - " {'q3': 34.0,\n", - " 'lower': 26.5,\n", - " 'average': 30.135,\n", - " 'pos': 0,\n", - " 'upper': 38.5,\n", - " 'q1': 31.0,\n", - " 'median': 33.0},\n", - " {'average': 36.08,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'median': 38.0,\n", - " 'pos': 59,\n", - " 'q1': 35.0,\n", - " 'q3': 40.0},\n", - " {'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.385,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 35},\n", - " {'pos': 39,\n", - " 'average': 37.895,\n", - " 'q1': 38.0,\n", - " 'lower': 35.0,\n", - " 'q3': 40.0,\n", - " 'upper': 43.0,\n", - " 'median': 40.0},\n", - " {'median': 40.0,\n", - " 'average': 38.505,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'pos': 17,\n", - " 'q3': 41.0},\n", - " {'pos': 20,\n", - " 'median': 40.0,\n", - " 'q3': 41.0,\n", - " 'average': 38.625,\n", - " 'lower': 33.5,\n", - " 'q1': 38.0,\n", - " 'upper': 45.5},\n", - " {'q3': 37.0,\n", - " 'q1': 35.0,\n", - " 'upper': 40.0,\n", - " 'pos': 7,\n", - " 'median': 36.0,\n", - " 'average': 35.4,\n", - " 'lower': 32.0},\n", - " {'average': 32.415,\n", - " 'q1': 33.0,\n", - " 'median': 35.0,\n", - " 'q3': 35.0,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'pos': 84},\n", - " {'pos': 67,\n", - " 'q1': 34.0,\n", - " 'average': 35.96,\n", - " 'median': 36.5,\n", - " 'q3': 39.0,\n", - " 'upper': 46.5,\n", - " 'lower': 26.5},\n", - " {'q1': 38.0,\n", - " 'average': 38.11,\n", - " 'pos': 36,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'q3': 40.0,\n", - " 'median': 40.0},\n", - " {'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'average': 38.41,\n", - " 'pos': 22,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0},\n", - " {'q1': 35.0,\n", - " 'lower': 27.5,\n", - " 'average': 36.77,\n", - " 'median': 38.0,\n", - " 'pos': 58,\n", - " 'q3': 40.0,\n", - " 'upper': 47.5},\n", - " {'q1': 33.0,\n", - " 'lower': 27.0,\n", - " 'average': 32.68,\n", - " 'pos': 73,\n", - " 'upper': 43.0,\n", - " 'median': 35.0,\n", - " 'q3': 37.0},\n", - " {'median': 40.0,\n", - " 'pos': 32,\n", - " 'q1': 38.0,\n", - " 'lower': 33.5,\n", - " 'average': 38.29,\n", - " 'q3': 41.0,\n", - " 'upper': 45.5},\n", - " {'pos': 72,\n", - " 'average': 33.265,\n", - " 'q3': 37.0,\n", - " 'q1': 33.0,\n", - " 'lower': 27.0,\n", - " 'upper': 43.0,\n", - " 'median': 35.0},\n", - " {'average': 35.99,\n", - " 'q1': 35.0,\n", - " 'pos': 61,\n", - " 'q3': 40.0,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'median': 38.0},\n", - " {'pos': 76,\n", - " 'average': 30.265,\n", - " 'median': 35.0,\n", - " 'q3': 37.0,\n", - " 'lower': 22.0,\n", - " 'upper': 46.0,\n", - " 'q1': 31.0},\n", - " {'pos': 79,\n", - " 'q1': 32.0,\n", - " 'lower': 26.0,\n", - " 'average': 32.46,\n", - " 'upper': 42.0,\n", - " 'median': 35.0,\n", - " 'q3': 36.0},\n", - " {'pos': 26,\n", - " 'average': 37.855,\n", - " 'median': 40.0,\n", - " 'lower': 35.0,\n", - " 'upper': 43.0,\n", - " 'q1': 38.0,\n", - " 'q3': 40.0},\n", - " {'pos': 93,\n", - " 'q3': 35.0,\n", - " 'upper': 39.5,\n", - " 'lower': 27.5,\n", - " 'q1': 32.0,\n", - " 'median': 34.0,\n", - " 'average': 31.05},\n", - " {'pos': 75,\n", - " 'q3': 37.0,\n", - " 'lower': 22.0,\n", - " 'median': 35.0,\n", - " 'q1': 31.0,\n", - " 'average': 31.06,\n", - " 'upper': 46.0},\n", - " {'average': 37.35,\n", - " 'q3': 40.0,\n", - " 'q1': 36.0,\n", - " 'lower': 30.0,\n", - " 'upper': 46.0,\n", - " 'pos': 57,\n", - " 'median': 39.0},\n", - " {'lower': 27.5,\n", - " 'average': 35.985,\n", - " 'pos': 60,\n", - " 'q1': 35.0,\n", - " 'q3': 40.0,\n", - " 'upper': 47.5,\n", - " 'median': 38.0},\n", - " {'upper': 47.0,\n", - " 'lower': 31.0,\n", - " 'q1': 37.0,\n", - " 'pos': 44,\n", - " 'average': 37.565,\n", - " 'median': 40.0,\n", - " 'q3': 41.0},\n", - " {'median': 35.0,\n", - " 'q1': 32.0,\n", - " 'lower': 27.5,\n", - " 'average': 31.915,\n", - " 'pos': 87,\n", - " 'upper': 39.5,\n", - " 'q3': 35.0},\n", - " {'average': 32.065,\n", - " 'median': 35.0,\n", - " 'q3': 35.0,\n", - " 'pos': 88,\n", - " 'lower': 30.0,\n", - " 'upper': 38.0,\n", - " 'q1': 33.0},\n", - " {'upper': 47.0,\n", - " 'pos': 53,\n", - " 'q1': 37.0,\n", - " 'average': 37.845,\n", - " 'q3': 41.0,\n", - " 'median': 39.0,\n", - " 'lower': 31.0},\n", - " {'median': 35.0,\n", - " 'q3': 36.0,\n", - " 'pos': 81,\n", - " 'q1': 33.0,\n", - " 'lower': 28.5,\n", - " 'upper': 40.5,\n", - " 'average': 32.76},\n", - " {'pos': 8,\n", - " 'lower': 34.0,\n", - " 'upper': 42.0,\n", - " 'average': 37.625,\n", - " 'median': 39.0,\n", - " 'q3': 39.0,\n", - " 'q1': 37.0},\n", - " {'pos': 12,\n", - " 'average': 37.5,\n", - " 'upper': 42.0,\n", - " 'q1': 37.0,\n", - " 'median': 39.0,\n", - " 'q3': 39.0,\n", - " 'lower': 34.0},\n", - " {'q1': 36.0,\n", - " 'average': 37.59,\n", - " 'q3': 41.0,\n", - " 'lower': 28.5,\n", - " 'upper': 48.5,\n", - " 'pos': 54,\n", - " 'median': 39.5},\n", - " {'average': 36.25,\n", - " 'median': 38.0,\n", - " 'q1': 35.0,\n", - " 'lower': 27.5,\n", - " 'upper': 47.5,\n", - " 'pos': 63,\n", - " 'q3': 40.0},\n", - " {'q1': 32.0,\n", - " 'pos': 80,\n", - " 'average': 32.61,\n", - " 'median': 35.0,\n", - " 'upper': 42.0,\n", - " 'q3': 36.0,\n", - " 'lower': 26.0},\n", - " {'lower': 27.5,\n", - " 'median': 35.0,\n", - " 'q1': 32.0,\n", - " 'average': 31.835,\n", - " 'q3': 35.0,\n", - " 'upper': 39.5,\n", - " 'pos': 92},\n", - " {'upper': 38.0,\n", - " 'median': 35.0,\n", - " 'lower': 30.0,\n", - " 'q3': 35.0,\n", - " 'average': 31.815,\n", - " 'pos': 86,\n", - " 'q1': 33.0},\n", - " {'q3': 41.0,\n", - " 'upper': 45.5,\n", - " 'lower': 33.5,\n", - " 'pos': 27,\n", - " 'average': 38.44,\n", - " 'median': 40.0,\n", - " 'q1': 38.0},\n", - " {'pos': 94,\n", - " 'q1': 32.0,\n", - " 'lower': 27.5,\n", - " 'upper': 39.5,\n", - " 'average': 30.775,\n", - " 'median': 34.0,\n", - " 'q3': 35.0},\n", - " {'pos': 65,\n", - " 'upper': 45.0,\n", - " 'median': 37.0,\n", - " 'q1': 35.0,\n", - " 'q3': 39.0,\n", - " 'lower': 29.0,\n", - " 'average': 35.995},\n", - " {'average': 37.87,\n", - " 'q3': 41.0,\n", - " 'upper': 47.0,\n", - " 'q1': 37.0,\n", - " 'lower': 31.0,\n", - " 'pos': 41,\n", - " 'median': 40.0},\n", - " {'pos': 77,\n", - " 'average': 30.805,\n", - " 'upper': 45.0,\n", - " 'median': 35.0,\n", - " 'q3': 36.0,\n", - " 'q1': 30.0,\n", - " 'lower': 21.0},\n", - " {'pos': 13,\n", - " 'q1': 38.0,\n", - " 'q3': 41.0,\n", - " 'lower': 33.5,\n", - " 'upper': 45.5,\n", - " 'median': 40.0,\n", - " 'average': 38.94},\n", - " {'lower': 35.0,\n", - " 'q1': 38.0,\n", - " 'q3': 40.0,\n", - " 'upper': 43.0,\n", - " 'pos': 21,\n", - " 'average': 38.445,\n", - " 'median': 40.0},\n", - " {'q3': 36.0,\n", - " 'median': 35.0,\n", - " 'average': 31.46,\n", - " 'q1': 31.0,\n", - " 'pos': 78,\n", - " 'lower': 23.5,\n", - " 'upper': 43.5},\n", - " {'q3': 37.0,\n", - " 'lower': 32.0,\n", - " 'pos': 6,\n", - " 'upper': 40.0,\n", - " 'median': 35.0,\n", - " 'q1': 35.0,\n", - " 'average': 35.145},\n", - " {'pos': 64,\n", - " 'q3': 40.0,\n", - " 'median': 37.0,\n", - " 'lower': 27.5,\n", - " 'q1': 35.0,\n", - " 'upper': 47.5,\n", - " 'average': 36.095}]}" + "shape: (20_200, 2)\n", + "┌─────┬───────┐\n", + "│ pos ┆ score │\n", + "│ --- ┆ --- │\n", + "│ i64 ┆ i8 │\n", + "╞═════╪═══════╡\n", + "│ 0 ┆ 2 │\n", + "│ 1 ┆ 19 │\n", + "│ 2 ┆ 33 │\n", + "│ 3 ┆ 35 │\n", + "│ 4 ┆ 37 │\n", + "│ … ┆ … │\n", + "│ 96 ┆ 35 │\n", + "│ 97 ┆ 32 │\n", + "│ 98 ┆ 35 │\n", + "│ 99 ┆ 35 │\n", + "│ 100 ┆ 33 │\n", + "└─────┴───────┘" ] }, "execution_count": 8, diff --git a/docs/notebooks/tutorial.ipynb b/docs/notebooks/tutorial.ipynb index 5b98a620..acd8b329 100644 --- a/docs/notebooks/tutorial.ipynb +++ b/docs/notebooks/tutorial.ipynb @@ -4,13 +4,10 @@ "cell_type": "markdown", "id": "947f441f13ced60a", "metadata": {}, - "source": [ - "### Import dependencies" - ] + "source": "### Import dependencies" }, { "cell_type": "code", - "execution_count": null, "id": "7b173024d3e8f76", "metadata": { "ExecuteTime": { @@ -18,49 +15,30 @@ "start_time": "2025-02-24T16:59:36.960817Z" } }, - "outputs": [], "source": [ "import polars_bio as pb\n", "import pandas as pd\n", - "\n", - "# print(type(a_lazyframe))\n", - "# # display types of columns\n", - "# print(a_lazyframe.dtypes)\n", - "# print(type(a_dataframe))\n", - "# print(type(a_pandas_dataframe))\n", - "# print(pb.sql(\"SHOW TABLES\").collect())\n", - "print(pb.sql(\"SHOW TABLES\").collect())\n", - "\n", - "# a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", - "# a_dataframe = a_lazyframe.collect()\n", - "# a_pandas_dataframe = a_lazyframe.collect().to_pandas()\n", - "# print(pb.base_sequence_quality(a_lazyframe))\n", - "# print(pb.base_sequence_quality(a_dataframe))\n", - "# print(pb.base_sequence_quality(a_pandas_dataframe))\n", - "\n", - "# result = pb.sql(\"SELECT base_sequence_quality(quality_scores) FROM example\").collect()\n", - "# print(result.item())\n", - "# print(pb.base_sequence_quality(\"./example.csv\"))\n", - "print(pb.base_sequence_quality(\"./example.fastq\"))\n", - "# print(pb.base_sequence_quality(\"./example.parquet\"))\n", - "\n", - "# sql display all tables and print it\n", - "print(pb.sql(\"SHOW TABLES\").collect())\n", - "# use sql and display result (it is aggregate function that returns string)\n", - "# print(result.item())\n" - ] + "from polars_bio.range_viz import visualize_intervals" + ], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:polars_bio:Creating BioSessionContext\n" + ] + } + ], + "execution_count": 1 }, { "cell_type": "markdown", "id": "d2bb8c193890f27f", "metadata": {}, - "source": [ - "### Sample data" - ] + "source": "### Sample data" }, { "cell_type": "code", - "execution_count": null, "id": "86fe039c3780140e", "metadata": { "ExecuteTime": { @@ -68,31 +46,27 @@ "start_time": "2025-02-24T16:59:37.452650Z" } }, - "outputs": [], "source": [ "df1 = pd.DataFrame(\n", " [[\"chr1\", 1, 5], [\"chr1\", 3, 8], [\"chr1\", 8, 10], [\"chr1\", 12, 14]],\n", " columns=[\"chrom\", \"start\", \"end\"],\n", ")\n", "\n", - "pb.base_sequence_quality(df1)\n", - "\n", "df2 = pd.DataFrame(\n", " [[\"chr1\", 4, 8], [\"chr1\", 10, 11]], columns=[\"chrom\", \"start\", \"end\"]\n", ")" - ] + ], + "outputs": [], + "execution_count": 2 }, { "cell_type": "markdown", "id": "a884cd2960796fdb", "metadata": {}, - "source": [ - "### Overlap" - ] + "source": "### Overlap" }, { "cell_type": "code", - "execution_count": null, "id": "304f3aa6fcdc9650", "metadata": { "ExecuteTime": { @@ -100,14 +74,22 @@ "start_time": "2025-02-24T16:59:37.538707Z" } }, - "outputs": [], "source": [ "overlapping_intervals = pb.overlap(df1, df2, output_type=\"pandas.DataFrame\")" - ] + ], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:polars_bio.operation:Running Overlap operation with algorithm Coitrees and 1 thread(s)...\n" + ] + } + ], + "execution_count": 3 }, { "cell_type": "code", - "execution_count": null, "id": "61c9254622598622", "metadata": { "ExecuteTime": { @@ -115,14 +97,76 @@ "start_time": "2025-02-24T16:59:37.552440Z" } }, - "outputs": [], "source": [ "display(overlapping_intervals)" - ] + ], + "outputs": [ + { + "data": { + "text/plain": [ + " chrom_1 start_1 end_1 chrom_2 start_2 end_2\n", + "0 chr1 1 5 chr1 4 8\n", + "1 chr1 3 8 chr1 4 8" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
chrom_1start_1end_1chrom_2start_2end_2
0chr115chr148
1chr138chr148
\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 4 }, { "cell_type": "code", - "execution_count": null, "id": "e640901ec6e6ce11", "metadata": { "ExecuteTime": { @@ -130,22 +174,41 @@ "start_time": "2025-02-24T16:59:37.581481Z" } }, - "outputs": [], "source": [ "visualize_intervals(overlapping_intervals)" - ] + ], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAZEUlEQVR4nO3dB5QdVf0H8BtIQgshBCQQJPTeiyBFooAUI1KkChIIRwXpKiIqhB6K1MChKAKKNKWDlCABQQgdpCg1hibtHyAsSBLI+5/f9bx1d7OBbNjNXPZ9Pue8ZN+8dmdm3879zi3To1ar1RIAAEABZqm6AAAAAHUCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKQEHuuOOO1KNHj/x/CY444ohcnu4i1iXWCYByCSgAMIPeeeedNMsss6Rbbrkl37/66qvTbLPNliZOnDjVc2PZIYcckgYOHJjmmGOOtM4666RRo0ZVUGqAsgkoAEzTL3/5y/Sf//wndRexLrFOneX+++/P/0fYCPfee29affXVc0hpa/fdd0+nnHJK2mWXXdLpp5+eZp111vSNb3wj3X333Z1WHoDuoGfVBQAgpQ8//DD17t07laZnz5751l3MPvvsn/qc999/P80111zTHVCWXXbZ1K9fv+aAUg8rbZ932WWXpZNOOin95Cc/yct22223tNJKK6Wf/vSn6Z577unwugB0V1pQgIb2yCOPpC222CL17ds39enTJ2288cZpzJgxzY8/+OCDedzCRRddNNVro1tPPHbDDTc0L3vllVfSsGHD0oABA/JZ9BVXXDH99re/bXecSVRY42z+wgsvnOacc840YcKEdst41113pe233z4NGjQov+ciiyySDjrooKlaNuIMfazDCy+8kDbbbLNcyY7uREcddVSq1WrNz/vXv/6VP/9Xv/pVOvXUU9Oiiy6auxwNHjw4PfHEE586BiXu77vvvumaa67JFez6et58881TlT3Wda211srBYMkll0znnnvudI9r+epXv5rf/6GHHkrrrbdeLuPiiy+ezjnnnFbPmzRpUjr88MPTmmuumeaZZ5683l/5ylfS6NGjP3UMSr0sTz31VPrOd76T5p133rTBBht8Yrnefffd9NZbb+VbBJJVV101//z666/nsi633HL5fjyv7k9/+lNuMfn+97/fvCy2yZ577pnf46WXXvrU7QHQKLrPaTGADnryySdzRTbCSZzF7tWrV65AR8X4zjvvzGfCo3K9xBJLpCuuuCINHTq01esvv/zyXKGNMBCigvrlL3+5uQL/hS98Id100025Ehrh48ADD2z1+qOPPjq3msQZ9RifMK0WlD/+8Y/pgw8+SHvvvXeab7758tn4kSNHppdffjk/1tLHH3+cNt9881yOE088MYeG4cOHp48++igHlZZ+97vfpffeey/ts88+uQUnuh1ttNFG6fHHH88B65NEt6Srrroq/fCHP0xzzz13OuOMM9K3v/3t9OKLL+Yy1sNflGWhhRZKRx55ZC5blCG2y/R6++23czeoHXbYIe288855P8R2iG0VQTDEtv3Nb36TH//e976X1+n888/P+yW21WqrrfapnxMBcOmll07HHXdcqzDXnq222ir/frT9XaiLbRK3CHz1yQ5iWyyzzDL5d62ltddeO///6KOP5uAJQErxhxigIW299da13r17155//vnmZa+++mpt7rnnrm244YbNyw499NBar169auPHj29eNnHixFq/fv1qw4YNa16255571hZaaKHaW2+91epzdtppp9o888xT++CDD/L90aNHRw24tsQSSzQvq6s/Fv/XtX1OGDFiRK1Hjx61cePGNS8bOnRofu1+++3XvGzKlCm1IUOG5PV8880387KxY8fm580xxxy1l19+ufm59913X15+0EEHNS8bPnx4XtZS3I/3e+6555qXPfbYY3n5yJEjm5dtueWWtTnnnLP2yiuvNC979tlnaz179pzqPdszePDg/LyTTz651XZfbbXVagsssEBt0qRJedlHH32Ul7f09ttv1wYMGNBq/9TLHuvUdv123nnn2vR68MEHa6NGjaqdddZZ+bUXX3xxvr/77rvXFllkkfxz3OJ5dSuuuGJto402muq9nnzyyfwe55xzznR/PkB3p4sX0JDibP6tt96att5669xCUhdn+6OrT7QQ1Ltc7bjjjmny5Mm5xaAuXhszOMVjIeq+V155Zdpyyy3zz/UuQHGLM/nR3efhhx9uVYZokYluS5+m5XNifES8Z3R5is+JM/NtRetNXb01J7pB3Xbbba2eF+se3ctans2PVqM///nPn1qmTTbZJHfZqltllVVy60B0L6tv3/i8+IzoZla31FJL5S510yvG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qmcfVM8+qJ590L22/wwNkgcAAOgKungBAADFEFAAAIBiCCgAAEAxBBQAAODzHVDOOuustNhii6XZZ589rbPOOun+++/v/JLRrhEjRqQvfelLae65504LLLBA2nrrrdPTTz9ddbEa1vHHH5969OiRDjzwwKqL0nBeeeWVtOuuu6b55psvzTHHHGnllVdODz74YNXFaggff/xxOuyww9Liiy+et/2SSy6Zjj766GTOla7117/+NW255ZZp4MCB+e/ONddc0+rx2P6HH354WmihhfJ+2WSTTdKzzz5bWXkbaftPnjw5HXLIIfnv0FxzzZWfs9tuu6VXX3210jI32negpb322is/57TTTpupZezu/jod++Af//hH+ta3vpWvLB/fh6i3vvjii10bUC6//PL0ox/9KE8l9vDDD6dVV101bbbZZumNN97o6FsxA+688860zz77pDFjxqRRo0blP4qbbrppev/996suWsN54IEH0rnnnptWWWWVqovScN5+++20/vrrp169eqWbbropPfXUU+nkk09O8847b9VFawgnnHBCOvvss9OZZ56ZD0Rx/8QTT0wjR46sumjdWvydj2NunCRsT+yDM844I51zzjnpvvvuyxWDOD5/+OGHM72sjbb9P/jgg1wniuAe/1911VX55GFU0ph534G6q6++OteTohLNzN0Hzz//fNpggw3Scsstl+64447097//PX8volGjQ2odtPbaa9f22Wef5vsff/xxbeDAgbURI0Z09K3oBG+88UacsqzdeeedVRelobz33nu1pZdeujZq1Kja4MGDawcccEDVRWoohxxySG2DDTaouhgNa8iQIbVhw4a1WrbtttvWdtlll8rK1Gji7/7VV1/dfH/KlCm1BRdcsHbSSSc1L3vnnXdqs802W+3SSy+tqJSNs/3bc//99+fnjRs3bqaVq5FMax+8/PLLtYUXXrj2xBNP1BZddNHaqaeeWkn5GnUf7LjjjrVdd931M793h1pQJk2alB566KHcbFw3yyyz5Pv33ntvx5IRneLdd9/N//fv37/qojSUaMUaMmRIq+8CM891112X1lprrbT99tvnro6rr756+vWvf111sRrGeuutl/7yl7+kZ555Jt9/7LHH0t1335222GKLqovWsMaOHZtee+21Vn+TontFdMN2fK7u+BxdYPr161d1URrGlClT0ne/+9108MEHpxVXXLHq4jTk9r/xxhvTMsssk1tv4/gcf4M+qSvetHQooLz11lu57/GAAQNaLY/78YeRmf+LEGMfoqvLSiutVHVxGsZll12Wm/BjPBDVeOGFF3IXo6WXXjrdcsstae+99077779/uuiii6ouWkP42c9+lnbaaafchB/d7CIgxt+iXXbZpeqiNaz6MdjxuQzRrS7GpOy8886pb9++VRenYUR30549e+bjATNfDPdoamrK43M333zzdOutt6ZtttkmbbvttnmIQkf07LJSMlPO4j/xxBP5zCUzx0svvZQOOOCAPP6nw/0p6dRwHi0oxx13XL4fFeT4LkTf+6FDh1ZdvG7viiuuSH/4wx/SJZdcks9SPvroozmgRH9v259GF2NDd9hhhzxpQZxIYeaIHj6nn356PoEYLVdUc2wOW221VTrooIPyz6uttlq655578vF58ODBXdOCMv/886dZZ501vf76662Wx/0FF1ywI2/FZ7TvvvumG264IY0ePTp98YtfrLo4DfUHMM4QrLHGGvksTdzirEAMTI2fo4WRrhezFK2wwgqtli2//PIdniWEGRPdJ+qtKDFrUXSpiIORVsXq1I/Bjs9lhJNx48blE1laT2aeu+66Kx+fBw0a1Hx8jv3w4x//OM88S9eLnBDbvTOOzx0KKL17905rrrlm7nvcMi3F/XXXXbdDH8yMiTMyEU5ihorbb789T/PJzLPxxhunxx9/PJ8xrt/iTH50bYmfI8DT9aJbY9vptWM8xKKLLlpZmRpJzFgU4w9bit/9+tkzZr44FkQQaXl8njBhQp7Ny/F55oaTmNr5tttuy1OgM/PEiZKYMarl8TladeOESnQFputFTogphTvj+NzhLl4xxXA04UelbO21187zS8eUY3vssUdH34oZ7NYV3SquvfbafC2Uet/iGAwZ897TtWKbtx3vE1N5xoHIOKCZJ87Wx0Dt6OIVFYK4FtN5552Xb3S9mAP/2GOPzWcqo4vXI488kk455ZQ0bNiwqovWrUXf7ueee67VwPiohMUkKbEvopvdMccck8dmRWCJqT2jghbXy6Jrt3+06m633Xa5e1H0bojW9PrxOR6Pihtd/x1oGwpjjFwE92WXXbaC0jbmPjj44IPTjjvumDbccMP0ta99Ld18883p+uuvz1MOd8iMTP01cuTI2qBBg2q9e/fO0w6PGTPmM08nxvSJXdbe7YILLqi6aA3LNMPVuP7662srrbRSnkZ1ueWWq5133nlVF6lhTJgwIf/Ox3Fg9tlnry2xxBK1X/ziF7WJEydWXbRubfTo0e3+/R86dGjzVMOHHXZYbcCAAfl7sfHGG9eefvrpqovdENt/7Nix0zw+x+uYOd+BtkwzXM0+OP/882tLLbVUPj6suuqqtWuuuabDn9Mj/un8fAUAANBxHb6SPAAAQFcRUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAAAgleL/ATwTEzjW7N/GAAAAAElFTkSuQmCC" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAY4klEQVR4nO3dCbgd8/0/8G/IhogIlaASu9h3ak01ammqltZWKsSjpbFWVTdiTSxVS3iQUvRRa+3UEhpKiZ1Sak1jq+0XRKgkkvk/n+//Ofe59+aGe5N7MyPn9Xqek3tmzpxzvjOTc2be811Op6IoigQAAFAB85VdAAAAgBoBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBaBC7r333tSpU6f8twqOO+64XJ55RaxLrBMA1SWgAMBs+vDDD9N8882X7rzzzjx9ww03pG7duqUpU6Y0WW7y5Mlp+PDhabvttku9e/fOQenSSy8tqdQA1SagADBLv/3tb9P//ve/NK+IdYl1ai+PPPJI/rvxxhvnvw899FBad911c0hp7P33308nnHBCev7559Paa6/dbu8PMC/qXHYBAEjps88+S127dk1V07lz53ybV3Tv3v1Ll/nkk0/SQgst1OqAssoqq6RevXo1BJRaWGlsySWXTP/9739T375902OPPZY23HDD2Sg9QH1QgwLUtSeffDJtv/32qWfPnqlHjx5p0KBBady4cQ2Px8lkNMe57LLLZnpuNOuJx2699daGeW+++WYaOnRo6tOnT76Kvvrqq6c//vGPLfYzueqqq/LV/KWXXjotuOCCadKkSS2W8f7770+77rpr6tevX37NZZZZJh1xxBEz1Wzsu+++eR1effXVtO222+aT7KWWWipfuS+KomG5//znP/n9f/e736Uzzzwz9e/fPy2wwAJp4MCB6dlnn/3SPigxffDBB6cbb7wxrbHGGg3reccdd8xU9ljXDTbYIAeDFVZYIV144YWt7tfyzW9+M7/+448/njbddNNcxuWWWy5dcMEFTZabOnVqOvbYY9P666+fFllkkbzeW2yxRRo7duyX9kGpleW5555LP/zhD9Oiiy6aNt988y8s10cffZRrROIWgSRqROL+O++8k8s6YMCAPB3L1cQ2inACwJebdy6LAbTRv/71r3wiG+HkF7/4RerSpUs+gY4T4/vuuy9fCY+T6+WXXz5dc801aciQIU2ef/XVV+cT2ggDIU5Qv/GNbzScwH/ta19Lt99+e9p///1z+Dj88MObPP/EE0/MtSY///nPc5+FWdWgXHvttenTTz9NBx10UFpsscXyVftRo0alN954Iz/W2PTp03M/hyjHaaedlkND9H34/PPPc1Bp7E9/+lP6+OOP07Bhw3INztlnn52+9a1vpWeeeSYHrC/ywAMPpOuvvz799Kc/TQsvvHA655xz0ve///302muv5TLWwl+UJWoPjj/++Fy2KENsl9b64IMP0ne+85202267pT333DPvh9gOsa0iCIbYthdddFF+/IADDsjrdPHFF+f9EttqnXXW+dL3iQC40korpREjRjQJcy3Zcccd8/+P5v8XamKbxC0CX1UGOwD4SikA6tROO+1UdO3atXjllVca5r311lvFwgsvXGy55ZYN8371q18VXbp0KSZOnNgwb8qUKUWvXr2KoUOHNszbf//9iyWXXLJ4//33m7zPHnvsUSyyyCLFp59+mqfHjh0bZ8DF8ssv3zCvpvZY/K1pvkwYOXJk0alTp2LChAkN84YMGZKfe8ghhzTMmzFjRjF48OC8nu+9916eN378+LzcAgssULzxxhsNyz788MN5/hFHHNEwb/jw4XleYzEdr/fyyy83zHv66afz/FGjRjXM22GHHYoFF1ywePPNNxvmvfTSS0Xnzp1nes2WDBw4MC93xhlnNNnu66yzTrHEEksUU6dOzfM+//zzPL+xDz74oOjTp0+T/VMre6xT8/Xbc889i9Z67LHHijFjxhTnnXdefu7ll1+ep/fdd99imWWWyffjFsu15NFHH83Pu+SSS1r9ngD1RBMvoC7F1fy77ror7bTTTrmGpCau9kdTn6ghqDW52n333dO0adNyjUFNPDdGcIrHQpz7XnfddWmHHXbI92tNgOIWV/Kjuc8TTzzRpAxRIxPNlr5M42Wif0S8ZjR5iveJWormovamplabE82g7r777ibLxbpH87KajTbaKNca/fWvf/3SMm299da5yVbNWmutlWuionlZbfvG+8V7RDOzmhVXXDE3qWut6P/yk5/8pGE6ak5i+t13383NqcL888/fUPs0Y8aMNHHixFxjFLVfzbf5rBx44IGtLlM0JYv1j/eIddtrr73y9HvvvZebCMb9uMVy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VIaAAgAAfLUDynnnnZeWXXbZ1L1797TxxhunRx55pP1LRotGjhyZNtxww7TwwgunJZZYIu20007phRdeKLtYdeuUU05JnTp1SocffnjZRak7b775Ztp7773TYostlhZYYIG05pprpscee6zsYtWF6dOnp2OOOSYtt9xyeduvsMIK6cQTT0zGXOlYf//739MOO+yQllpqqfy9c+ONNzZ5PLb/sccem5Zccsm8X7beeuv00ksvlVbeetr+06ZNS0cffXT+HlpooYXyMvvss0966623Si1zvX0GGjvwwAPzMmedddZcLeO87u+t2AfPP/98+t73vpd/WT4+D3He+tprr3VsQLn66qvTz372szyU2BNPPJHWXnvttO2226Z33323rS/FbLjvvvvSsGHD0rhx49KYMWPyl+I222yTPvnkk7KLVnceffTRdOGFF6a11lqr7KLUnQ8++CBtttlmqUuXLun2229Pzz33XDrjjDPSoosuWnbR6sKpp56azj///HTuuefmA1FMn3baaWnUqFFlF22eFt/zccyNi4QtiX1wzjnnpAsuuCA9/PDD+cQgjs+fffbZXC9rvW3/Tz/9NJ8TRXCPv9dff32+eBgnacy9z0DNDTfckM+T4iSaubsPXnnllbT55punAQMGpHvvvTf985//zJ+LqNRok6KNNtpoo2LYsGEN09OnTy+WWmqpYuTIkW19KdrBu+++G5csi/vuu6/sotSVjz/+uFhppZWKMWPGFAMHDiwOO+ywsotUV44++uhi8803L7sYdWvw4MHF0KFDm8zbZZddir322qu0MtWb+N6/4YYbGqZnzJhR9O3btzj99NMb5n344YdFt27diiuvvLKkUtbP9m/JI488kpebMGHCXCtXPZnVPnjjjTeKpZdeunj22WeL/v37F2eeeWYp5avXfbD77rsXe++99xy/dptqUKZOnZoef/zxXG1cM9988+Xphx56qG3JiHbx0Ucf5b+9e/cuuyh1JWqxBg8e3OSzwNxz8803pw022CDtuuuuuanjuuuum/7whz+UXay6semmm6Z77rknvfjii3n66aefTg888EDafvvtyy5a3Ro/fnx6++23m3wnRfOKaIbt+Fze8TmawPTq1avsotSNGTNmpB/96EfpqKOOSquvvnrZxanL7X/bbbellVdeOdfexvE5voO+qCnerLQpoLz//vu57XGfPn2azI/p+GJk7v9HiL4P0dRljTXWKLs4deOqq67KVfjRH4hyvPrqq7mJ0UorrZTuvPPOdNBBB6VDDz00XXbZZWUXrS788pe/THvssUeuwo9mdhEQ47tor732Krtodat2DHZ8roZoVhd9Uvbcc8/Us2fPsotTN6K5aefOnfPxgLkvuntMnjw598/dbrvt0l133ZV23nnntMsuu+QuCm3RucNKyVy5iv/ss8/mK5fMHa+//no67LDDcv+fNrenpF3DedSgjBgxIk/HCXJ8FqLt/ZAhQ8ou3jzvmmuuSX/+85/TFVdcka9SPvXUUzmgRHtv2596F31Dd9tttzxoQVxIYe6IFj5nn312voAYNVeUc2wOO+64YzriiCPy/XXWWSc9+OCD+fg8cODAjqlBWXzxxdP888+f3nnnnSbzY7pv375teSnm0MEHH5xuvfXWNHbs2PT1r3+97OLU1RdgXCFYb7318lWauMVVgeiYGvejhpGOF6MUrbbaak3mrbrqqm0eJYTZE80narUoMWpRNKmIg5FaxfLUjsGOz9UIJxMmTMgXstSezD33339/Pj7369ev4fgc++HII4/MI8/S8SInxHZvj+NzmwJK165d0/rrr5/bHjdOSzG9ySabtOmNmT1xRSbCSYxQ8be//S0P88ncM2jQoPTMM8/kK8a1W1zJj6YtcT8CPB0vmjU2H147+kP079+/tDLVkxixKPofNhb/92tXz5j74lgQQaTx8XnSpEl5NC/H57kbTmJo57vvvjsPgc7cExdKYsSoxsfnqNWNCyrRFJiOFzkhhhRuj+Nzm5t4xRDDUYUfJ2UbbbRRHl86hhzbb7/92vpSzGazrmhWcdNNN+XfQqm1LY7OkDHuPR0rtnnz/j4xlGcciPQDmnvian101I4mXnFCEL/FNHr06Hyj48UY+CeffHK+UhlNvJ588sn0+9//Pg0dOrTsos3Tom33yy+/3KRjfJyExSApsS+imd1JJ52U+2ZFYImhPeMELX4vi47d/lGr+4Mf/CA3L4rWDVGbXjs+x+Nx4kbHfwaah8LoIxfBfZVVVimhtPW5D4466qi0++67py233DJttdVW6Y477ki33HJLHnK4TWZn6K9Ro0YV/fr1K7p27ZqHHR43btwcDydG68Qua+l2ySWXlF20umWY4XLccsstxRprrJGHUR0wYEAxevTosotUNyZNmpT/z8dxoHv37sXyyy9f/OY3vymmTJlSdtHmaWPHjm3x+3/IkCENQw0fc8wxRZ8+ffLnYtCgQcULL7xQdrHrYvuPHz9+lsfneB5z5zPQnGGGy9kHF198cbHiiivm48Paa69d3HjjjW1+n07xT/vnKwAAgLZr8y/JAwAAdBQBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAAqAwBBQAASFXx/wAOW0rnl+0oyQAAAABJRU5ErkJggg==" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 5 }, { "cell_type": "markdown", "id": "8e2509b9cb5237d8", "metadata": {}, - "source": [ - "### Nearest" - ] + "source": "### Nearest" }, { "cell_type": "code", - "execution_count": null, "id": "bc0f8689c31221b3", "metadata": { "ExecuteTime": { @@ -153,14 +216,22 @@ "start_time": "2025-02-24T16:59:37.652480Z" } }, - "outputs": [], "source": [ "nearest_intervals = pb.nearest(df1, df2, output_type=\"pandas.DataFrame\")" - ] + ], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:polars_bio.operation:Running Nearest operation with algorithm Coitrees and 1 thread(s)...\n" + ] + } + ], + "execution_count": 6 }, { "cell_type": "code", - "execution_count": null, "id": "aad83ab53e1294fc", "metadata": { "ExecuteTime": { @@ -168,14 +239,101 @@ "start_time": "2025-02-24T16:59:37.665033Z" } }, - "outputs": [], "source": [ "display(nearest_intervals)" - ] + ], + "outputs": [ + { + "data": { + "text/plain": [ + " chrom_1 start_1 end_1 chrom_2 start_2 end_2 distance\n", + "0 chr1 1 5 chr1 4 8 0\n", + "1 chr1 3 8 chr1 4 8 0\n", + "2 chr1 8 10 chr1 4 8 0\n", + "3 chr1 12 14 chr1 10 11 1" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
chrom_1start_1end_1chrom_2start_2end_2distance
0chr115chr1480
1chr138chr1480
2chr1810chr1480
3chr11214chr110111
\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 7 }, { "cell_type": "code", - "execution_count": null, "id": "5f69f700b50f58e2", "metadata": { "ExecuteTime": { @@ -183,29 +341,71 @@ "start_time": "2025-02-24T16:59:37.673937Z" } }, - "outputs": [], "source": [ "visualize_intervals(nearest_intervals, \"nearest pair\")" - ] + ], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAXGUlEQVR4nO3dCbRVZf0/4BdlUhEVTBANNHM2UVEyNcmFaWaZmmOaJLVSc0rNpQ2KMymZYznVQlc5VYpTOWDiUEpgakEaDiE4pKioeJ0gPf/1fX//c9e9CMLFy92vnOdZ63DPPnffs9+zN+fs97Pf4XSq1Wq1BAAAUIClqi4AAABAnYACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAJA8b71rW+lNdZYo+piANABBBQAPtRbb72VTjrppHT33XenJcluu+2W9t1333y/VqullVZaKV1++eXzXPemm25Km222WerevXvq379/GjFiRPrf//7XwSUGaAwCCgALDCgnn3xypQHlsssuS1OmTGnX55wwYULacsst8/3HHnssvfbaa83LLd16661p1113TSuuuGK64IIL8v3TTjstHX744e1aHgD+T+f//xOAJcSbb76ZlltuubQk6dKlywLXiRaN999/P3Xt2nWB6z777LPp+eefbw4kDzzwQFphhRXSuuuu+4F1f/CDH6SNN9443XHHHalz5/87bfbs2TOdccYZ6cgjj0zrrbfeIr0mAOZNCwrARxTdnzp16pSefPLJPFYirrRHZffAAw/MrQ9z++1vf5sGDRqUlllmmdSrV6+0zz77pGeeeabVOvfdd1/ac889c3eibt26pU9+8pPpqKOOSm+//Xar9WJ7PXr0SE899VT68pe/nJZffvm033775d9FZf3cc89NG264Ye6a1KdPn3TQQQelV199tdVzPPjgg2nHHXdMK6+8ci7TmmuumYYPH55/9/TTT6dPfOIT+X60osTrjFu85vmJblKxzr333pu317t371yhP+CAAz6w7RtvvDHtvPPOqV+/fvl1rrXWWunUU09N77333oeOQYlyxTZ+9rOf5dcYfxd//+ijj863XO+++256+eWX823cuHE59MR+jeUoa4SQV155JS/HvgvxfHH77ne/2xxOwve+973cLewPf/jDfLcHwKLRggLQTvbaa69cuR85cmR66KGH0q9+9au0yiqrpDPPPLN5ndNPPz2dcMIJed3vfOc76aWXXsrdhrbddtv08MMP53ATfv/73+dwc8ghh+QKfnRHivXiyn/8bu6WgwgY22yzTa6wL7vssvnxCAcRFiIoHXHEEWnq1KnpwgsvzNv561//mivoM2bMSDvssEMOIccff3zeflT+r7/++vwc8fhFF12UyxFjNnbffff8eFTmF+Swww7LzxdhJrpnxfNMmzYtdxWLcBGifBGwjj766PzzrrvuSieeeGKaNWtWGjVq1AK3MXr06PTOO+/kABEBJQLf/Fx99dV5X7S02mqrtVquh7HYVxGIYl+FzTffvNV6EahWX3315t8D0I5qAHwkI0aMqMXH6fDhw1s9vttuu9V69+7dvPz000/Xll566drpp5/ear1JkybVOnfu3Orxt9566wPbGTlyZK1Tp061adOmNT82bNiwvO3jjz++1br33XdffvzKK69s9fhtt93W6vExY8bk5YkTJ8739b300kt5nXidC2P06NF5/UGDBtVmz57d/PhZZ52VH7/xxhs/9HUedNBBtWWXXbb2zjvvtHqdAwYMaF6eOnVqfq6ePXvWZsyYsVDlev7552tjx47Nt3iuAw44IN+/+uqr83Odf/75zb9/++2389+MGjUq/2769OkfeL4tttiituWWWy7UtgFYeLp4AbSTgw8+uNXy5z//+dxlKFoDQrRKRNehaD2pdzWKW9++fdPaa6+dux3VRVerlmNKYr2tttoqdyua11X7aOFoKVpZopvZF7/4xVbbiq5l0VJR31a9xeaWW25Jc+bMadf9Ea0aLceORBmjm9Sf/vSneb7ON954I5cx9lu0Hv373/9e4Da+/vWvN7d6LMiqq66att9++9waEl3qoitcLEeZogtclDeW4xbLod6lLlpn5hbrzN3lDoCPThcvgHYS40VaimlrQ4y7iDEYTzzxRA4YEUbmpWVlfvr06bmrU0xvO/e4jddff73VclSwo7tRS7GtWC+6mM1LdO0KQ4YMyZX8GF9yzjnnpC984Qt5lqpvfOMb86yUt8XcrzOCUYSE6EJW969//Sv95Cc/yV276kFufq9zXqJL3cKI8FV/vttvvz0ttdRSeXB7BKJY3nTTTXNAilsEu/qxqAeoGL8yt+ha1jJgAdA+BBSAdrL00kvP8/EIJSFaT2Ls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3gN1Y8aMyfWkqETTscfgqaeeSttss01ab7310t13353++c9/5vdFNGq0Sa2NBg8eXDv00EObl997771av379aiNHjmzrU9EOZsyYEZcsa/fcc0/VRWkob7zxRm3ttdeujR07tjZkyJDakUceWXWRGspxxx1X22abbaouRsPaeeeda8OHD2/12O67717bb7/9KitTo4nP/TFjxjQvv//++7W+ffvWRo0a1fzYa6+9VuvWrVvt6quvrqiUjbP/52XChAl5vWnTpnVYuRrJ/I7Bs88+W1tttdVqkydPrg0YMKB2zjnnVFK+Rj0Ge++9d23//ff/yM/dphaU2bNnp7///e+52bhuqaWWyssPPPBA25IR7eL111/PP3v16lV1URpKtGLtvPPOrd4LdJybbropbb755mnPPffMXR033XTTdNlll1VdrIax1VZbpT//+c/p8ccfz8v/+Mc/0l/+8pe00047VV20hjV16tT0wgsvtPpMiu4V0Q3b+bm683N0gVlxxRWrLkrDeP/999M3v/nNdOyxx6YNN9yw6uI05P7/4x//mNZZZ53cehvn5/gM+rCuePPTpoDy8ssv577Hffr0afV4LMcHIx3/HyHGPkRXl4022qjq4jSMa665Jjfhx3ggqvGf//wndzFae+210+23354OOeSQdMQRR6Qrrrii6qI1hOOPPz7ts88+uQk/utlFQIzPov3226/qojWs+jnY+bkM0a0uxqTsu+++qWfPnlUXp2FEd9POnTvn8wEdL4Z7NDU15fG5X/rSl9Idd9yRdtttt7T77rvnIQpt0XmxlZIOuYo/efLkfOWSjvHMM8+kI488Mo//aXN/Sto1nEcLyhlnnJGXo4Ic74Xoez9s2LCqi7fE+93vfpeuvPLKdNVVV+WrlI888kgOKNHf2/6n0cXY0L322itPWhAXUugY0cPnvPPOyxcQo+WKas7N4Wtf+1o66qij8v1NNtkk3X///fn8PGTIkMXTgrLyyiunpZdeOr344outHo/lvn37tuWp+IgOO+ywdMstt6Rx48al1VdfveriNNQHYFwh2GyzzfJVmrjFVYEYmBr3o4WRxS9mKdpggw1aPbb++uu3eZYQFk10n6i3osSsRdGlIk5GWhWrUz8HOz+XEU6mTZuWL2RpPek49913Xz4/9+/fv/n8HMfhmGOOyTPPsvhFToj93h7n5zYFlK5du6ZBgwblvsct01Isf+5zn2vThlk0cUUmwknMUHHXXXflaT7pOEOHDk2TJk3KV4zrt7iSH11b4n4EeBa/6NY49/TaMR5iwIABlZWpkcSMRTH+sKX4v1+/ekbHi3NBBJGW5+dZs2bl2bycnzs2nMTUznfeeWeeAp2OExdKYsaolufnaNWNCyrRFZjFL3JCTCncHufnNnfxiimGowk/KmWDBw/O80vHlGMHHnhgW5+KRezWFd0qbrzxxvxdKPW+xTEYMua9Z/GKfT73eJ+YyjNORMYBdZy4Wh8DtaOLV1QI4ruYLr300nxj8Ys58E8//fR8pTK6eD388MPp5z//eRo+fHjVRVuiRd/uJ598stXA+KiExSQpcSyim91pp52Wx2ZFYImpPaOCFt+XxeLd/9Gqu8cee+TuRdG7IVrT6+fn+H1U3Fj874G5Q2GMkYvgvu6661ZQ2sY8Bscee2zae++907bbbpu22267dNttt6Wbb745TzncJosy9dcFF1xQ69+/f61r16552uHx48d/5OnEWDhxyOZ1Gz16dNVFa1imGa7GzTffXNtoo43yNKrrrbde7dJLL626SA1j1qxZ+f98nAe6d+9e+9SnPlX78Y9/XHv33XerLtoSbdy4cfP8/B82bFjzVMMnnHBCrU+fPvl9MXTo0NqUKVOqLnZD7P+pU6fO9/wcf0fHvAfmZprhao7Br3/969qnP/3pfH4YOHBg7YYbbmjzdjrFP+2frwAAANquzd8kDwAAsLgIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAACQSvH/AFFsXXBd2e9cAAAAAElFTkSuQmCC" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAWgUlEQVR4nO3dC7AWZf0H8Ae5iIqoYIpooBlqYqJpVspfcjTNmEzIG0GS1KSOpqk52gXxRqRmXstbDTqFaKWIWGqYeCklMbU0zVuItxQVBY+okL7/+T0z75lzEJQD55x95Hw+My+c3bPsPu8u77v73eeynWq1Wi0BAAAUYLWqCwAAAFAnoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAFC8b3zjG2nTTTetuhgAtAMBBYD3tXDhwnTyySen2267La1Khg0blkaMGJF/rtVqab311kuXX375e5a7+uqr06hRo9KAAQNSp06d0uc///kKSgvQcQgoAHxgQDnllFMqDSiXXXZZevTRR1t1nffcc0/67Gc/m39+5JFH0muvvdY43dRFF12Upk6dmj760Y/mEANA2+rSxusHoJ298cYbaa211kqrkq5du37gMv/73//Su+++m7p16/aByz777LPp+eefbwwkd999d1pnnXXSlltu+Z5lf/3rX6eNN944rbbaammbbbZZwXcAwPJSgwKwkqL5UzT9eeKJJ3JfiXXXXTdf7B5yyCG59mFJv/nNb9IOO+yQ1lhjjdSrV6900EEHpWeeeabZMnfeeWfaf//9U79+/dLqq6+e794fc8wx6c0332y2XGyvR48e6cknn0xf+tKX0tprr51GjhyZfxcX6+eee24aOHBg6t69e9pwww3ToYceml599dVm67j33nvTXnvtldZff/1cps022yyNGTMm/+6pp55KH/nIR/LPUYsS7zNe8Z6XJZpJxTJ33HFH3l7v3r1Tz54908EHH/yebUfNxNChQ1Pfvn3z+9x8883Taaedlt5555337YMS5Ypt/PSnP83vMf5d/PuHH354meV6++2308svv5xfM2bMyKEn9mtMR1m33Xbb9Morr+Tp2Hd1sUyEEwDahxoUgFZywAEH5Iv7CRMmpPvuuy/98pe/TBtssEE644wzGpcZP358Gjt2bF72W9/6VnrppZfSBRdckHbdddd0//3353ATfve73+Vwc/jhh+cL/GiOFMvFnf/43ZI1BxEwBg8enC/Y11xzzTw/wkGEhQhKRx11VJo9e3a68MIL83b++te/5gv0uXPnpj333DOHkBNPPDFvPy7+r7322ryOmB9NnKIc0Wdj+PDheX5czH+QI488Mq8vwkw0z4r1zJkzJzcVi3ARonwRsI499tj896233ppOOumktGDBgnTWWWd94DYmTpyY3nrrrfTtb387B5QIfMsyefLkvC+aipqRpuphLPaVTvkAFakBsFLGjRtXi6/TMWPGNJs/bNiwWu/evRunn3rqqVrnzp1r48ePb7bcgw8+WOvSpUuz+QsXLnzPdiZMmFDr1KlTbc6cOY3zRo8enbd94oknNlv2zjvvzPMnTZrUbP5NN93UbP6UKVPy9KxZs5b5/l566aW8TLzP5TFx4sS8/A477FBbtGhR4/wzzzwzz586der7vs9DDz20tuaaa9beeuutZu+zf//+jdOzZ8/O6+rZs2dt7ty5y1Wu559/vjZ9+vT8inUdfPDB+efJkyfndZ1//vmNv3/zzTeXuo6BAwfWhgwZslzbA2DFqLMGaCWHHXZYs+n/+7//y02GojYgRK1ENB2K2pN6U6N49enTJ48QFc2O6qKpVdM+JbHczjvvnEebihqQJUUNR1NRyxLNzL7whS8021Y0LYuaivq26jU2N9xwQ1q8eHGr7o+o1WjadyTK2KVLl/THP/5xqe/z9ddfz2WM/Ra1R//+978/cBtf/epXG2s9PshGG22U9thjj7TjjjvmJnXRFC6mo0zRBC7KG9PximkAqqGJF0Arif4iTdVHfIp+F9EH4/HHH88BI8LI0jS9mH/66adzU6frr7/+Pf025s+f32w6LrA32WSTZvNiW7FcNDFbmmjaFYYMGZIv8qN/yTnnnJOH0N13333T1772tdxkamUs+T4jGEVIiCZkdf/617/Sj370o9y0qx7klvU+lyaa1C2PCF/19d188825T8lWW22VA1FMb7/99jkgxSuC3fJ0ygegbQgoAK2kc+fOS50foSRE7Un0vbjxxhuXumxcwIfoIB41H/PmzUsnnHBCvpCOUbmee+653Fm8aQfuEEFiyU7csUyEk0mTJi21TPVahyjP73//+zRz5sw0bdq0fLEeHeTPPvvsPK9eprYQw/pGQIrwduqpp+aO7lFz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UAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAPDhDihvv/12Ovnkk/PfVMMxqJ5jUD3HoHqOQfUcg+o5BtVzDFat/d+pVqvVWvqPFixYkNZZZ500f/781LNnz1YpCC3jGFTPMaieY1A9x6B6jkH1HIPqOQar1v7XxAsAACiGgAIAABRDQAEAAD7cAWX11VdP48aNy39TDcegeo5B9RyD6jkG1XMMqucYVM8xWLX2/wp1kgcAAGgLmngBAADFEFAAAIBiCCgAAEAxBBQAAODDHVB+/vOfp0033TR17949feYzn0n33HNP65eMpZowYUL69Kc/ndZee+20wQYbpH333Tc9+uijVRerw/rJT36SOnXqlL773e9WXZQO57nnnkujRo1KvXv3TmussUb65Cc/me69996qi9UhvPPOO2ns2LFps802y/t+8803T6eddloy5krbuuOOO9KXv/zl1Ldv3/y9c9111zX7fez/k046KW200Ub5uOyxxx7p8ccfr6y8HWn/L168OJ1wwgn5e2ittdbKyxx88MHp+eefr7TMHe0z0NRhhx2Wlzn33HPbtYyrujuW4xg88sgjaZ999slPlo/PQ1y3Pv30020bUK6++up07LHH5qHE7rvvvjRo0KC01157pblz57Z0VayA22+/PR1xxBFp5syZafr06flLcc8990xvvPFG1UXrcGbNmpUuueSStO2221ZdlA7n1VdfTbvsskvq2rVruvHGG9PDDz+czj777LTeeutVXbQO4YwzzkgXXXRRuvDCC/OJKKbPPPPMdMEFF1RdtFVafM/HOTduEi5NHIPzzz8/XXzxxelvf/tbvjCI8/Nbb73V7mXtaPt/4cKF+Zoognv8fe211+abh3GRRvt9BuqmTJmSr5PiIpr2PQZPPvlkGjx4cNpqq63Sbbfdlv75z3/mz0VUarRIrYV22mmn2hFHHNE4/c4779T69u1bmzBhQktXRSuYO3du3LKs3X777VUXpUN5/fXXawMGDKhNnz69NmTIkNrRRx9ddZE6lBNOOKE2ePDgqovRYQ0dOrQ2ZsyYZvOGDx9eGzlyZGVl6mjie3/KlCmN0++++26tT58+tbPOOqtx3muvvVZbffXVa5MnT66olB1n/y/NPffck5ebM2dOu5WrI1nWMXj22WdrG2+8ce2hhx6q9e/fv3bOOedUUr6OegwOPPDA2qhRo1Z63S2qQVm0aFH6+9//nquN61ZbbbU8fffdd7csGdEq5s+fn//u1atX1UXpUKIWa+jQoc0+C7Sf66+/Pu24445p//33z00dt99++3TZZZdVXawOY+edd05//vOf02OPPZan//GPf6S//OUvae+99666aB3W7Nmz0wsvvNDsOymaV0QzbOfn6s7P0QRm3XXXrbooHca7776bvv71r6fjjz8+DRw4sOridMj9/4c//CFtscUWufY2zs/xHfR+TfGWpUUB5eWXX85tjzfccMNm82M6vhhp//8I0fchmrpss802VRenw7jqqqtyFX70B6Ia//nPf3ITowEDBqSbb745HX744emoo45KV1xxRdVF6xBOPPHEdNBBB+Uq/GhmFwExvotGjhxZddE6rPo52Pm5DNGsLvqkjBgxIvXs2bPq4nQY0dy0S5cu+XxA+4vuHg0NDbl/7he/+MX0pz/9KQ0bNiwNHz48d1FoiS5tVkra5S7+Qw89lO9c0j6eeeaZdPTRR+f+Py1uT0mrhvOoQfnxj3+cp+MCOT4L0fZ+9OjRVRdvlffb3/42TZo0KV155ZX5LuUDDzyQA0q097b/6eiib+gBBxyQBy2IGym0j2jhc9555+UbiFFzRTXn5vCVr3wlHXPMMfnn7bbbLt111135/DxkyJC2qUFZf/31U+fOndOLL77YbH5M9+nTpyWrYiUdeeSR6YYbbkgzZsxIm2yySdXF6VBfgHGH4FOf+lS+SxOvuCsQHVPj56hhpO3FKEVbb711s3mf+MQnWjxKCCsmmk/Ua1Fi1KJoUhEnI7WK1amfg52fywgnc+bMyTey1J60nzvvvDOfn/v169d4fo7jcNxxx+WRZ2l7kRNiv7fG+blFAaVbt25phx12yG2Pm6almP7c5z7Xog2zYuKOTISTGKHi1ltvzcN80n5233339OCDD+Y7xvVX3MmPpi3xcwR42l40a1xyeO3oD9G/f//KytSRxIhF0f+wqfi/X797RvuLc0EEkabn5wULFuTRvJyf2zecxNDOt9xySx4CnfYTN0pixKim5+eo1Y0bKtEUmLYXOSGGFG6N83OLm3jFEMNRhR8XZTvttFMeXzqGHDvkkENauipWsFlXNKuYOnVqfhZKvW1xdIaMce9pW7HPl+zvE0N5xolIP6D2E3fro6N2NPGKC4J4FtOll16aX7S9GAN//Pjx+U5lNPG6//77089+9rM0ZsyYqou2Sou23U888USzjvFxERaDpMSxiGZ2p59+eu6bFYElhvaMC7R4XhZtu/+jVne//fbLzYuidUPUptfPz/H7uHCj7T8DS4bC6CMXwX3LLbesoLQd8xgcf/zx6cADD0y77rpr2m233dJNN92Upk2bloccbpEVGfrrggsuqPXr16/WrVu3POzwzJkzV3o4MZZPHLKlvSZOnFh10ToswwxXY9q0abVtttkmD6O61VZb1S699NKqi9RhLFiwIP+fj/NA9+7dax/72MdqP/zhD2tvv/121UVbpc2YMWOp3/+jR49uHGp47NixtQ033DB/Lnbffffao48+WnWxO8T+nz179jLPz/HvaJ/PwJIMM1zNMfjVr35V+/jHP57PD4MGDapdd911Ld5Op/ij9fMVAABAy7X4SfIAAABtRUABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgFSK/wf6+B9vMqhECAAAAABJRU5ErkJggg==" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAXCUlEQVR4nO3dCbRd4/0/4DdkQgSJEqGJoSFFDY1qa0otStWqilkNqbSrKDVWpVViSmOomZraFdoS2hJTi0bF0JKiaKPUGDGVICSuKWmc//q+v//Jyo2E3OTeu1/3PM9ax7373J2z37O3c/b72e+wO9VqtVoCAAAowGJVFwAAAKBOQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAaB43/72t9Oqq65adTEAaAcCCgAf6Z133knHH398uuOOO1JHMmTIkLTnnnvm32u1WlpuueXSZZdd1myd119/PZ1++ulpiy22SJ/61KfSsssum770pS+lq6++uqJSA3R8AgoAHxtQTjjhhEoDyqWXXpoef/zxVn3N++67L4eN8Nhjj6U333xz9nLdvffem4455pjUq1ev9NOf/jSNHDkyLbnkkmmPPfZII0aMaNXyAPB/Ov//nwB0EG+//XZaaqmlUkfSpUuXj13nf//7X/rggw9S165dP3bdF154Ib300kuzA0kEkWWWWSattdZazdZbZ5110pNPPpn69+8/+7nvf//7aeutt06nnnpq+tGPftTh9jVA1bSgACyi6P7UqVOn9NRTT+WxEtENKCq7++23X259mNtvf/vbNGjQoLTEEkvkK/NxNf75559vts7dd9+ddt1119SvX7/UrVu39OlPfzodfvjh6d133222XmyvR48e6emnn05f//rX09JLL5322muv/LeorJ999tm5kt29e/e04oorpv333z+98cYbzV7jgQceSNtuu21afvnlc5lWW221NGzYsPy3Z599NndtCtGKEu8zHvGe5ye6ScU6d911V95e7969U8+ePdO+++77oW1ff/31afvtt099+/bN73ONNdZIJ510Upo1a9ZHjkGJcsU2fv7zn+f3GP8u/v2jjz4633K9//776bXXXsuP8ePH59AT+zWWo6zrrbde7tIVy7HvQuyLOcNJiO3uuOOO+fWeeeaZ+W4PgIWjBQWgley22265Qjtq1Kj04IMPpl/+8pdphRVWyFfa66KL0LHHHpvX/e53v5teffXVdN555+UxDg899FAON+H3v/99DjcHHnhgruBHd6RYL678x9/mbjmIgLHZZpvlCnt0QQoRDiIsRFA65JBD0qRJk9L555+ft/O3v/0tV9CnTJmSttlmmxxChg8fnrcflf9rr702v0Y8f+GFF+ZyxJiNnXbaKT8flfmPc/DBB+fXizAT3bPidSZPnpy7ikUlP0T5ImAdccQR+eftt9+ejjvuuDR9+vQ89uPjjB49Or333nvpe9/7Xg4oEfjmZ8yYMXlfzGnllVdutlwPY7GvPmpQ/ssvv5x/RqgDoJXVAFgkI0aMqMXX6bBhw5o9P2TIkFrv3r1nLz/77LO1xRdfvDZy5Mhm602cOLHWuXPnZs+/8847H9rOqFGjap06dapNnjx59nNDhw7N2x4+fHizde++++78/BVXXNHs+VtuuaXZ82PHjs3L999//3zf36uvvprXife5IEaPHp3XHzRoUG3GjBmznz/ttNPy89dff/1Hvs/999+/tuSSS9bee++9Zu+zf//+s5cnTZqUX6tnz561KVOmLFC5Xnrppdq4cePyI15r3333zb+PGTMmv9a55547++/vvvvufF/n9ddfr62wwgq1zTfffIG2C0DL6OIF0EoOOOCAZsubb7557jIUrQEhWiWi61C0ntS7GsWjT58+acCAAbnbUV10tZpzTEmst8kmm+TZpqIFZG7RwjGnaGWJbmZf/epXm20rupZFS0V9W/UWm5tuuinNnDmzVfdHtGrMOXYkyti5c+f0pz/9aZ7v86233spljP0WrUf/+c9/PnYbO++88+xWj4+z0kor5bEjG220Ue5SF13hYjnKFF3goryxHI9Ynpc4fvHvYkB9tGgB0Pp08QJoJTFeZE4xbW2IcRcxBiMGW0fAiDAyL3NW5p977rnc1emGG2740LiNadOmNVuOCvYqq6zS7LnYVqwXXczmJbp2hcGDB+dKfowvOeuss9JXvvKVPL7iW9/6Vu4ytSjmfp8RjCIkRBeyun//+995dqzo2lUPcvN7n/MSXeoWRISv+uvdeuutabHFFksDBw7MgSiWN9xwwxyQ4hHBbn6D8n/wgx+kW265Jf36179O66+//gJtG4CWEVAAWsniiy8+z+cjlNSvvsfYi5tvvnme60YFPsQA8Wj5mDp1ajr66KNzRTpminrxxRfzYPH6AO66CBJR4Z5TrBPh5IorrphnmeqtDlGeP/zhD2nChAnpxhtvzJX1GCB/xhln5OfqZWoL0QoRASnC24knnpgHukfLRYzfifc99/uclzlbYD5KjLnZcsstmz039+D3+j6J1qUIanOLEPeLX/winXLKKWmfffZZoO0C0HICCkA7iQp4hJW46r/mmmvOd72JEyemJ554Il1++eV55qu6cePGtWhbt912W9p0000XqBIf0+3GIwbxX3nllbkb01VXXZUH8tcHtLdUtOLMGQqamprSf//73zzbWIjB8tEFLrq+xSQBdTFAvbVFa0d9/0VXs3ivQ4cOza0qu+yySzrnnHPS2muvPXvduV1wwQV5sP9hhx2WwxMAbccYFIB2EjNgRctJXImvt6rUxXJU1kO9dWXOdeL3qEQvqBjnEi0xMWXv3GLWr2i9CNF9bO6ybLDBBvlnTKMb6rOC1f/NgrrkkkuajWuJWbxi29ttt9183+eMGTNyK0Vri+52MbYkZjqL7nPRrS2Wo2UqyvGd73xn9viTete8urhrfMyCFqHtzDPPbPWyAdCcFhSAdhKtGieffHL68Y9/nMdhxFiPuG9JtBiMHTs2D9L+4Q9/mLt0xbrxe3Trii5Q11xzzYfGonyU6DoV0wzHlMcPP/xwnko4xlVEq0YMoI+wEy0H0UoTgSCmEI5txhiMuGt7bLPe0hEtMNG6EBX1aPmJqXzXXXfd/PgoETa22mqrHJZimuHYTgSEHXbYIf89Bv1HGIiWjAgA0VLzm9/85kOBqTXFPV+iXLHtcM899+Qpk+d3s8WY3jlasWKq53gvc3eZi9dZffXV26y8AI1IQAFoR3Gvkajkx4D0aEkJcbPACBD1insEiRgPEpX2CBgxLiMCRNxXpCUDsy+66KI8a9fFF1+cfvKTn+TB9HFvj7333jt3/aoHmaiER3euV155JQ8Q33jjjXNFfM4B6HFPlxggHjeLjAr+iBEjPjagxD1X4nVisH+0pOy5557p3HPPnd1lLCr9MXvYkUcemQfKR1iJskUQiPu6tIUYixJBrD55QNxBvh5W5iVu/BjvN+5XU7955dz3YRFQAFpXp5hruJVfE4AGVr855P3335+n9AWAljAGBQAAKIaAAgAAFENAAQAAimEMCgAAUAwtKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAoRueqCwDAJ9vUqVNTU1NT1cVoaD169Ei9evWquhgArUJAAWCRwskJJ5yYZs6cUXVRGlqXLl3TiBHHCSlAhyCgALDQouUkwknvLXdOXZb9VNXFaUgz33w1vT7+mnwsBBSgIxBQAFhkEU66Lt+36mIA0AEYJA8AABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABSjc9UFAOCTb+abr1ZdhIZl3wMdjYACwELr0aNH6tKla3p9/DVVF6WhxTGIYwHQEXSq1Wq1qgsBwCfX1KlTU1NTU9XFaGgRTnr16lV1MQBahYACAAAUwyB5AACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGJ0rroA8Ek2derU1NTUVHUxoFI9evRIvXr1qroYAHQQAgosQjg58YQT0oyZM6suClSqa5cu6bgRI4QUAFqFgAILKVpOIpx8e8MvpT49elZdHKjEy03T02UPTcifBwEFgNYgoMAiinDSb1kVMwCA1mCQPAAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUIzOVRcAPulebppedRGgMv7/B6C1CSiwkHr06JG6dumSLntoQtVFgUrF5yA+DwDQGjrVarVaq7wSNKCpU6empqamqosBlYpw0qtXr6qLAUAHIaAAAADFMEgeAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAOCTHVDef//9dPzxx+efVMMxqJ5jUD3HoHqOQfUcg+o5BtVzDDrW/u9Uq9VqLf1H06dPT8sss0yaNm1a6tmzZ6sUhJZxDKrnGFTPMaieY1A9x6B6jkH1HIOOtf918QIAAIohoAAAAMUQUAAAgE92QOnWrVsaMWJE/kk1HIPqOQbVcwyq5xhUzzGonmNQPcegY+3/hRokDwAA0BZ08QIAAIohoAAAAMUQUAAAgGIIKAAAwCc7oFxwwQVp1VVXTd27d09f/OIX03333df6JWOeRo0alb7whS+kpZdeOq2wwgppxx13TI8//njVxWpYp5xySurUqVM67LDDqi5Kw3nxxRfT3nvvnXr37p2WWGKJ9LnPfS498MADVRerIcyaNSsde+yxabXVVsv7fo011kgnnXRSMudK27rrrrvSN77xjdS3b9/8vXPdddc1+3vs/+OOOy6ttNJK+bhsvfXW6cknn6ysvI20/2fOnJmOPvro/D201FJL5XX23Xff9NJLL1Va5kb7DMzpgAMOyOucffbZ7VrGju6uBTgGjz32WNphhx3yneXj8xD11ueee65tA8rVV1+djjjiiDyV2IMPPpjWX3/9tO2226YpU6a09KVYCHfeeWc66KCD0oQJE9K4cePyl+I222yT3n777aqL1nDuv//+dPHFF6f11luv6qI0nDfeeCNtuummqUuXLunmm29Ojz76aDrjjDPScsstV3XRGsKpp56aLrzwwnT++efnE1Esn3baaem8886rumgdWnzPxzk3LhLOSxyDc889N1100UXp73//e64YxPn5vffea/eyNtr+f+edd3KdKIJ7/Lz22mvzxcOopNF+n4G6sWPH5npSVKJp32Pw9NNPp8022ywNHDgw3XHHHelf//pX/lxEo0aL1Fpo4403rh100EGzl2fNmlXr27dvbdSoUS19KVrBlClT4pJl7c4776y6KA3lrbfeqg0YMKA2bty42uDBg2uHHnpo1UVqKEcffXRts802q7oYDWv77bevDRs2rNlzO+20U22vvfaqrEyNJr73x44dO3v5gw8+qPXp06d2+umnz37uzTffrHXr1q02ZsyYikrZOPt/Xu6777683uTJk9utXI1kfsfghRdeqK288sq1Rx55pNa/f//aWWedVUn5GvUY7L777rW99957kV+7RS0oM2bMSP/4xz9ys3HdYostlpfvvffeliUjWsW0adPyz169elVdlIYSrVjbb799s88C7eeGG25IG220Udp1111zV8cNN9wwXXrppVUXq2Fssskm6S9/+Ut64okn8vI///nP9Ne//jVtt912VRetYU2aNCm9/PLLzb6TontFdMN2fq7u/BxdYJZddtmqi9IwPvjgg7TPPvuko446Kq2zzjpVF6ch9/8f//jHtOaaa+bW2zg/x3fQR3XFm58WBZTXXnst9z1eccUVmz0fy/HFSPv/jxBjH6Kry7rrrlt1cRrGVVddlZvwYzwQ1XjmmWdyF6MBAwakW2+9NR144IHpkEMOSZdffnnVRWsIw4cPT3vssUduwo9udhEQ47tor732qrpoDat+DnZ+LkN0q4sxKXvuuWfq2bNn1cVpGNHdtHPnzvl8QPuL4R5NTU15fO7Xvva19Oc//zkNGTIk7bTTTnmIQkt0brNS0i5X8R955JF85ZL28fzzz6dDDz00j/9pcX9KWjWcRwvKz372s7wcFeT4LETf+6FDh1ZdvA7vd7/7XbriiivSlVdema9SPvzwwzmgRH9v+59GF2NDd9tttzxpQVxIoX1ED59zzjknX0CMliuqOTeHb37zm+nwww/Pv2+wwQbpnnvuyefnwYMHt00LyvLLL58WX3zx9MorrzR7Ppb79OnTkpdiER188MHppptuSuPHj0+rrLJK1cVpqC/AuELw+c9/Pl+liUdcFYiBqfF7tDDS9mKWorXXXrvZc5/97GdbPEsICye6T9RbUWLWouhSEScjrYrVqZ+DnZ/LCCeTJ0/OF7K0nrSfu+++O5+f+/XrN/v8HMfhyCOPzDPP0vYiJ8R+b43zc4sCSteuXdOgQYNy3+M501Isf/nLX27Rhlk4cUUmwknMUHH77bfnaT5pP1tttVWaOHFivmJcf8SV/OjaEr9HgKftRbfGuafXjvEQ/fv3r6xMjSRmLIrxh3OK//frV89of3EuiCAy5/l5+vTpeTYv5+f2DScxtfNtt92Wp0Cn/cSFkpgxas7zc7TqxgWV6ApM24ucEFMKt8b5ucVdvGKK4WjCj0rZxhtvnOeXjinH9ttvv5a+FAvZrSu6VVx//fX5Xij1vsUxGDLmvadtxT6fe7xPTOUZJyLjgNpPXK2PgdrRxSsqBHEvpksuuSQ/aHsxB/7IkSPzlcro4vXQQw+lM888Mw0bNqzqonVo0bf7qaeeajYwPiphMUlKHIvoZnfyySfnsVkRWGJqz6igxf2yaNv9H626u+yyS+5eFL0bojW9fn6Ov0fFjbb/DMwdCmOMXAT3tdZaq4LSNuYxOOqoo9Luu++etthii7TlllumW265Jd144415yuEWWZipv84777xav379al27ds3TDk+YMGGRpxNjwcQhm9dj9OjRVRetYZlmuBo33nhjbd11183TqA4cOLB2ySWXVF2khjF9+vT8/3ycB7p3715bffXVa8ccc0zt/fffr7poHdr48ePn+f0/dOjQ2VMNH3vssbUVV1wxfy622mqr2uOPP151sRti/0+aNGm+5+f4d7TPZ2Buphmu5hj86le/qn3mM5/J54f111+/dt1117V4O53iP62frwAAAFquxXeSBwAAaCsCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAACkUvw/PStWp8dTGfAAAAAASUVORK5CYII=" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAygAAADTCAYAAABqSTe2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8ekN5oAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAXCElEQVR4nO3dCbRVVf0H8I0CTogKJogGmqmoOJuV8pdcmGaunHIiEJJaqUvT1EwbECfCIXMsp1rqKqdKwaHUMFExJTG1NM0pxClFRcXnBOn9r99e67J4DMKT997Zj/v5rHV579x33j37nsO7Z3/PHk6nWq1WSwAAAAVYpuoCAAAA1AkoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAFO+b3/xmWmeddaouBgDtQEAB4GO9++676cQTT0x33nlnWprstddeaciQIfn7Wq2WVltttXT55ZfPt95RRx2Vttpqq9SjR4+04oorpo022ijvj6ampgpKDbD061x1AQAoP6CcdNJJ+fsvfelLlZTh0ksvTR999FGrvub999+ffvCDH+TvH3/88fTmm2+mL3zhC/OtN2XKlPR///d/6aCDDkrLL798euihh9Jpp52Wbr/99nT33XenZZZxrQ+gNQkoAEuZd955J6200kppadKlS5dFrvO///0vh5iuXbsuct0XXnghvfTSS3MCyX333ZdWWWWVtOGGG8637j333DPfc+utt176/ve/n0POgkINAJ+cyz4ASyi6+3Tq1Ck9/fTTeazEqquumiu7ccU9Wh/m9dvf/jZtvfXWaYUVVsjdhg444ID0/PPPN1tn0qRJad999019+/ZNyy23XPr0pz+duxq99957zdaL7XXr1i0988wz6atf/WpaeeWV09ChQ/PPorJ+zjnnpE022SRf+e/Vq1c6+OCD0xtvvNHsNR544IG0yy67pNVXXz2Xad11100jR47MP3v22WfTpz71qfx9tKLE+4xHvOeFiW5SsU60LsT2evbsmbp3756GDx8+37ZvuOGGtNtuu6U+ffrk9xkV/1NOOSV9+OGHHzsGJcoV2/jZz36W32P8Xvz+Y489ttByffDBB+m1117Lj4kTJ+bQE/s1lqOsm222WXr99dfz8qJaa+pliVYXAFqXFhSAVrLffvvlyv3YsWPTgw8+mH71q1+lNdZYI51++ulz1hkzZkwaNWpUXvfb3/52evXVV9P555+fdthhh9x1KMJN+P3vf5/DzaGHHpor+HGlPtaLK//xs3lbDiJgDBw4MFfYY5xEiHAQYSGC0hFHHJGmTp2aLrjggrydv/71r7mCPn369LTzzjvnEHL88cfn7Ufl//rrr8+vEc9feOGFuRwxZmPvvffOz0dlflEOP/zw/HoRZp544on8OtOmTctjWSJchChfBKyjjz46f73jjjvSCSeckGbOnJnOPPPMRW7jsssuS++//376zne+kwNKBL6Fufrqq/O+mNtaa63VbLkexmJfzR2IYh9HGJk1a1Z69NFH009+8pMcBrfddttFlhGAFqoBsERGjx5di4/TkSNHNnt+r732qvXs2XPO8rPPPltbdtlla2PGjGm23iOPPFLr3Llzs+fffffd+bYzduzYWqdOnWrTpk2b89yIESPyto8//vhm606aNCk/f+WVVzZ7/tZbb232/Lhx4/LylClTFvr+Xn311bxOvM/Fcdlll+X1t95669qsWbPmPH/GGWfk52+44YaPfZ8HH3xwbcUVV6y9//77zd5nv3795ixPnTo1v1b37t1r06dPX6xyvfTSS7UJEybkR7zW8OHD8/dXX311fq3zzjtvzs/fe++9Zr9733335XXqjw033LA2ceLExdouAC2jixdAKznkkEOaLcfA6ugyFK0BIVoloutQtJ7UuxrFo3fv3mn99dfP3Y7qoqvV3GNKYr3tttsuzzYVLSDzihaOuUUrS3Qz+/KXv9xsW9G1LFoq6tuqt9jcfPPNafbs2a26P6JVY+6xI1HGzp07pz/96U8LfJ9vv/12LmPst2g9+ve//73IbXz961+f0+qxKGuuuWbaaaed0jbbbJO71EVXuFiOMkUXuChvLMcjlue28cYbpwkTJqTx48fngfUxxscsXgBtQxcvgFYS40XmFtPWhhh3EWMwnnrqqRwwIowsyNyV+eeeey53dbrxxhvnG7fx1ltvNVuOCvbaa6/d7LnYVqwXXcwWJLp2hUGDBuVKfowvOfvss/MsXXvuuWf6xje+kbtMLYl532cEowgJ0YWs7l//+lfuLhVdu+pBbmHvc0GiS93iiPBVf73bbrstz7zVv3//HIhiecstt8wBKR4R7OYdlB/HL4JL2GOPPdJVV12Vv0ZXvs0333yxygDA4hFQAFrJ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YggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAAUAwBBQAAKIaAAgAAFENAAQAAiiGgAAAAxRBQAACAYggoAABAMQQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAACiGgAIAABRDQAEAAIohoAAAAMUQUAAAgGIIKAAAQDEEFAAAoBgCCgAA0LEDygcffJBOPPHE/JVqOAbVcwyq5xhUzzGonmNQPcegeo7B0rX/O9VqtVpLf2nmzJlplVVWSW+99Vbq3r17qxSElnEMqucYVM8xqJ5jUD3HoHqOQfUcg6Vr/+viBQAAFENAAQAAiiGgAAAAHTugLLfccmn06NH5K9VwDKrnGFTPMaieY1A9x6B6jkH1HIOla/9/okHyAAAAbUEXLwAAoBgCCgAAUAwBBQAAKIaAAgAAdOyA8otf/CKts846afnll0+f//zn0/3339/6JWOBxo4dmz73uc+llVdeOa2xxhppzz33TE888UTVxWpYp512WurUqVP63ve+V3VRGs6LL76Yhg0blnr27JlWWGGFtOmmm6YHHnig6mI1hA8//DCNGjUqrbvuunnfr7feeumUU05J5lxpW3fffXf62te+lvr06ZM/d8aPH9/s57H/TzjhhLTmmmvm47LTTjulp556qrLyNtL+nz17djruuOPy59BKK62U1xk+fHh66aWXKi1zo/0NzO2QQw7J65xzzjntWsal3d2LcQwef/zxtPvuu+c7y8ffQ9Rbn3vuubYNKNdee206+uij81RiDz74YNp8883TLrvskqZPn97Sl+ITuOuuu9Jhhx2WJk+enCZMmJA/FHfeeef0zjvvVF20hjNlypR08cUXp80226zqojScN954I22//fapS5cu6ZZbbkmPPfZYOuuss9Jqq61WddEawumnn54uvPDCdMEFF+QTUSyfccYZ6fzzz6+6aEu1+JyPc25cJFyQOAbnnXdeuuiii9Lf/va3XDGI8/P777/f7mVttP3/7rvv5jpRBPf4ev311+eLh1FJo/3+BurGjRuX60lRiaZ9j8EzzzyTBg4cmPr375/uvPPO9M9//jP/XUSjRovUWmjbbbetHXbYYXOWP/zww1qfPn1qY8eObelL0QqmT58elyxrd911V9VFaShvv/12bf31169NmDChNmjQoNqRRx5ZdZEaynHHHVcbOHBg1cVoWLvttltt5MiRzZ7be++9a0OHDq2sTI0mPvfHjRs3Z/mjjz6q9e7du3bmmWfOee7NN9+sLbfccrWrr766olI2zv5fkPvvvz+vN23atHYrVyNZ2DF44YUXamuttVbt0UcfrfXr16929tlnV1K+Rj0G+++/f23YsGFL/NotakGZNWtW+vvf/56bjeuWWWaZvHzfffe1LBnRKt566638tUePHlUXpaFEK9Zuu+3W7G+B9nPjjTembbbZJu277765q+OWW26ZLr300qqL1TC222679Je//CU9+eSTefkf//hHuueee9Kuu+5addEa1tSpU9PLL7/c7DMpuldEN2zn5+rOz9EFZtVVV626KA3jo48+SgceeGA69thj0yabbFJ1cRpy///xj39MG2ywQW69jfNzfAZ9XFe8hWlRQHnttddy3+NevXo1ez6W44OR9v+PEGMfoqvLgAEDqi5Ow7jmmmtyE36MB6Ia//nPf3IXo/XXXz/ddttt6dBDD01HHHFEuuKKK6ouWkM4/vjj0wEHHJCb8KObXQTE+CwaOnRo1UVrWPVzsPNzGaJbXYxJGTJkSOrevXvVxWkY0d20c+fO+XxA+4vhHk1NTXl87le+8pX05z//Oe21115p7733zkMUWqJzm5WSdrmK/+ijj+Yrl7SP559/Ph155JF5/E+L+1PSquE8WlB++tOf5uWoIMffQvS9HzFiRNXFW+r97ne/S1deeWW66qqr8lXKhx9+OAeU6O9t/9PoYmzofvvtlyctiAsptI/o4XPuuefmC4jRckU15+awxx57pKOOOip/v8UWW6R77703n58HDRrUNi0oq6++elp22WXTK6+80uz5WO7du3dLXooldPjhh6ebb745TZw4Ma299tpVF6ehPgDjCsFWW22Vr9LEI64KxMDU+D5aGGl7MUvRxhtv3Oy5jTbaqMWzhPDJRPeJeitKzFoUXSriZKRVsTr1c7DzcxnhZNq0aflCltaT9jNp0qR8fu7bt++c83Mch2OOOSbPPEvbi5wQ+701zs8tCihdu3ZNW2+9de57PHdaiuUvfvGLLdown0xckYlwEjNU3HHHHXmaT9rP4MGD0yOPPJKvGNcfcSU/urbE9xHgaXvRrXHe6bVjPES/fv0qK1MjiRmLYvzh3OL/fv3qGe0vzgURROY+P8+cOTPP5uX83L7hJKZ2vv322/MU6LSfuFASM0bNfX6OVt24oBJdgWl7kRNiSuHWOD+3uItXTDEcTfhRKdt2223z/NIx5dhBBx3U0pfiE3brim4VN9xwQ74XSr1vcQyGjHnvaVuxz+cd7xNTecaJyDig9hNX62OgdnTxigpB3IvpkksuyQ/aXsyBP2bMmHylMrp4PfTQQ+nnP/95GjlyZNVFW6pF3+6nn3662cD4qITFJClxLKKb3amnnprHZkVgiak9o4IW98uibfd/tOrus88+uXtR9G6I1vT6+Tl+HhU32v5vYN5QGGPkIrhvuOGGFZS2MY/Bsccem/bff/+0ww47pB133DHdeuut6aabbspTDrfIJ5n66/zzz6/17du31rVr1zzt8OTJk5d4OjEWTxyyBT0uu+yyqovWsEwzXI2bbrqpNmDAgDyNav/+/WuXXHJJ1UVqGDNnzsz/5+M8sPzyy9c+85nP1H784x/XPvjgg6qLtlSbOHHiAj//R4wYMWeq4VGjRtV69eqV/y4GDx5ce+KJJ6oudkPs/6lTpy70/By/R/v8DczLNMPVHINf//rXtc9+9rP5/LD55pvXxo8f3+LtdIp/Wj9fAQAAtFyL7yQPAADQVgQUAACgGAIKAABQDAEFAAAohoACAAAUQ0ABAACKIaAAAADFEFAAAIBiCCgAAEAxBBQAAKAYAgoAAFAMAQUAAEil+H91/GLN46PRBQAAAABJRU5ErkJggg==" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 8 } ], "metadata": { "kernelspec": { - "display_name": "3.12.9", + "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.9" + "pygments_lexer": "ipython2", + "version": "2.7.6" } }, "nbformat": 4, diff --git a/polars_bio/quality_stats.py b/polars_bio/quality_stats.py index c18ec841..d19daec9 100644 --- a/polars_bio/quality_stats.py +++ b/polars_bio/quality_stats.py @@ -1,5 +1,6 @@ from pathlib import Path from typing import Union +import datafusion import polars as pl import pandas as pd import pyarrow as pa @@ -10,19 +11,42 @@ ) -def base_sequence_quality(df: Union[str, pl.DataFrame, pl.LazyFrame, pd.DataFrame]): +def base_sequence_quality( + df: Union[str, pl.DataFrame, pl.LazyFrame, pd.DataFrame], + quality_scores_column: str = "quality_scores", + output_type: str = "polars.DataFrame", +) -> Union[pl.DataFrame, pd.DataFrame]: + """ + Compute base sequence quality statistics from various dataframe/file types. + + Args: + df: Input data as a file path or dataframe. + quality_scores_column: Name of the column with quality scores. + output_type: Output type, either "polars.DataFrame" or "pandas.DataFrame". + + Returns: + DataFrame with base sequence quality statistics. + """ if isinstance(df, str): - supported_exts = set([".parquet", ".csv", ".bed", ".vcf", ".fastq"]) + supported_exts = {".parquet", ".csv", ".bed", ".vcf", ".fastq"} ext = set(Path(df).suffixes) - assert ( - len(supported_exts.intersection(ext)) > 0 or len(ext) == 0 - ), "Dataframe1 must be a Parquet, CSV, BED, VCF, or FASTQ file." - return base_sequance_quality_scan(ctx, df) + if not (supported_exts & ext or not ext): + raise ValueError("Input file must be a Parquet, CSV, BED, VCF, or FASTQ file.") + result: datafusion.DataFrame = base_sequance_quality_scan(ctx, df, quality_scores_column) else: - if isinstance(df, pl.DataFrame): - df = df.to_arrow().to_reader() + if isinstance(df, pl.LazyFrame): + arrow_table = df.collect().to_arrow() + elif isinstance(df, pl.DataFrame): + arrow_table = df.to_arrow() elif isinstance(df, pd.DataFrame): - df = pa.Table.from_pandas(df) - elif isinstance(df, pl.LazyFrame): - df = df.collect().to_arrow().to_reader() - return base_sequance_quality_frame(ctx, df) + arrow_table = pa.Table.from_pandas(df) + else: + raise TypeError("Unsupported dataframe type.") + result: datafusion.DataFrame = base_sequance_quality_frame(ctx, arrow_table, quality_scores_column) + + if output_type == "polars.DataFrame": + return result.to_polars() + elif output_type == "pandas.DataFrame": + return result.to_pandas() + else: + raise ValueError("output_type must be 'polars.DataFrame' or 'pandas.DataFrame'") diff --git a/src/base_sequence_quality.rs b/src/base_sequence_quality.rs new file mode 100644 index 00000000..1ca4d1e4 --- /dev/null +++ b/src/base_sequence_quality.rs @@ -0,0 +1,247 @@ +use std::fmt::{Debug, Formatter}; +use std::sync::Arc; + +use arrow_array::{Array, StringArray}; +use async_trait::async_trait; +use datafusion::arrow::datatypes::{DataType, Field, Schema, SchemaRef}; +use datafusion::arrow::record_batch::RecordBatch; +use datafusion::catalog::{Session, TableProvider}; +use datafusion::error::{DataFusionError, Result}; +use datafusion::execution::context::TaskContext; +use datafusion::physical_expr::EquivalenceProperties; +use datafusion::physical_plan::repartition::RepartitionExec; +use datafusion::physical_plan::stream::RecordBatchStreamAdapter; +use datafusion::physical_plan::{ + DisplayAs, DisplayFormatType, ExecutionMode, ExecutionPlan, Partitioning, PlanProperties, + SendableRecordBatchStream, +}; +use datafusion::prelude::SessionContext; +use futures::stream::BoxStream; +use futures::{StreamExt, TryStreamExt}; + +pub struct BaseSequenceQualityProvider { + session: Arc, + table_name: String, + column_name: String, + schema: SchemaRef, +} + +impl BaseSequenceQualityProvider { + pub fn new(session: Arc, table_name: String, column_name: String) -> Self { + let schema = Arc::new(Schema::new(vec![ + Field::new("pos", DataType::Int64, false), + Field::new("score", DataType::Int8, false), + ])); + Self { + session, + table_name, + column_name, + schema, + } + } +} + +impl Debug for BaseSequenceQualityProvider { + fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result { + Ok(()) + } +} + +#[async_trait] +impl TableProvider for BaseSequenceQualityProvider { + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn schema(&self) -> SchemaRef { + self.schema.clone() + } + + fn table_type(&self) -> datafusion::datasource::TableType { + datafusion::datasource::TableType::Base + } + + async fn scan( + &self, + _state: &dyn Session, + _projection: Option<&Vec>, + _filters: &[datafusion::prelude::Expr], + _limit: Option, + ) -> Result> { + let target_partitions = self.session.state().config().target_partitions(); + + Ok(Arc::new(BaseSequenceQualityExec { + schema: self.schema.clone(), + session: Arc::clone(&self.session), + table_name: self.table_name.clone(), + column_name: self.column_name.clone(), + cache: PlanProperties::new( + EquivalenceProperties::new(self.schema.clone()), + Partitioning::UnknownPartitioning(target_partitions), + ExecutionMode::Bounded, + ), + })) + } +} + +pub struct BaseSequenceQualityExec { + schema: SchemaRef, + session: Arc, + table_name: String, + column_name: String, + cache: PlanProperties, +} + +impl Debug for BaseSequenceQualityExec { + fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result { + Ok(()) + } +} + +impl DisplayAs for BaseSequenceQualityExec { + fn fmt_as(&self, _t: DisplayFormatType, _f: &mut Formatter) -> std::fmt::Result { + Ok(()) + } +} + +impl ExecutionPlan for BaseSequenceQualityExec { + fn name(&self) -> &str { + "BaseSequenceQualityExec" + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn schema(&self) -> SchemaRef { + self.schema.clone() + } + + fn properties(&self) -> &PlanProperties { + &self.cache + } + + fn children(&self) -> Vec<&Arc> { + vec![] + } + + fn with_new_children( + self: Arc, + _children: Vec>, + ) -> Result> { + Ok(self) + } + + fn execute( + &self, + partition: usize, + context: Arc, + ) -> Result { + let fut = get_stream( + Arc::clone(&self.session), + self.table_name.clone(), + self.column_name.clone(), + self.cache.partitioning.partition_count(), + partition, + context, + self.schema.clone(), + ); + let stream = futures::stream::once(fut).try_flatten(); + let schema = self.schema.clone(); + Ok(Box::pin(RecordBatchStreamAdapter::new(schema, stream))) + } +} + +fn decode_score(c: char) -> Option { + let ascii = c as u8; + if ascii >= 33 { + Some(ascii - 33) + } else { + None + } +} + +fn calc_stats(values: &mut Vec) -> (f64, f64, f64, f64, f64, f64) { + values.sort_unstable(); + let n = values.len(); + let average = values.iter().map(|&v| v as f64).sum::() / n as f64; + let median = if n % 2 == 0 { + (values[n / 2 - 1] as f64 + values[n / 2] as f64) / 2.0 + } else { + values[n / 2] as f64 + }; + let q1 = values[n / 4] as f64; + let q3 = values[(3 * n) / 4] as f64; + let iqr = q3 - q1; + let lower = q1 - 1.5 * iqr; + let upper = q3 + 1.5 * iqr; + (average, median, q1, q3, lower, upper) +} + +async fn get_stream( + session: Arc, + table_name: String, + column_name: String, + target_partitions: usize, + partition: usize, + context: Arc, + new_schema: SchemaRef, +) -> Result { + let table_stream = session.table(table_name).await?; + let plan = table_stream.create_physical_plan().await?; + let repartition_stream = + RepartitionExec::try_new(plan, Partitioning::RoundRobinBatch(target_partitions))?; + let partition_stream = repartition_stream.execute(partition, context)?; + let new_schema_out = new_schema.clone(); + let iter = partition_stream.map(move |batch| match batch { + Ok(batch) => { + let index = match batch.schema().index_of(&column_name) { + Ok(idx) => idx, + Err(_) => { + return Err(DataFusionError::Internal(format!( + "Column '{}' not found in schema", + column_name + ))) + }, + }; + let col = batch.column(index); + + // Try to cast to StringArray if possible + let col = arrow::compute::cast(col, &DataType::Utf8) + .map_err(|e| DataFusionError::Internal(format!("Cast error: {e}")))?; + + let col = col + .as_any() + .downcast_ref::() + .ok_or_else(|| DataFusionError::Internal("Expected StringArray".into()))?; + + let mut positions = Vec::new(); + let mut scores = Vec::new(); + + for row in 0..col.len() { + if col.is_null(row) { + continue; + } + let s = col.value(row); + for (pos, byte) in s.bytes().enumerate() { + if let Some(score) = decode_score(byte as char) { + positions.push(pos as i64); + scores.push(score as i8); + } + } + } + + let pos_array = Arc::new(arrow_array::Int64Array::from(positions)); + let score_array = Arc::new(arrow_array::Int8Array::from(scores)); + let new_batch = + RecordBatch::try_new(new_schema.clone(), vec![pos_array, score_array]).unwrap(); + + Ok(new_batch) + }, + Err(e) => Err(e), + }); + + let adapted_stream = + RecordBatchStreamAdapter::new(new_schema_out, Box::pin(iter) as BoxStream<_>); + Ok(Box::pin(adapted_stream)) +} diff --git a/src/context.rs b/src/context.rs index afc02d4e..1525ef05 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,9 +1,6 @@ use std::collections::HashMap; -use std::sync::Arc; -use datafusion::arrow::datatypes::DataType; use datafusion::config::ConfigOptions; -use datafusion::logical_expr::{create_udaf, AggregateUDF, Volatility}; use datafusion::prelude::SessionConfig; use exon::config::ExonConfigExtension; use exon::ExonSession; @@ -11,8 +8,6 @@ use log::debug; use pyo3::{pyclass, pymethods, PyResult}; use sequila_core::session_context::SequilaConfig; -use crate::udaf::{base_quality_result_type, QualityScoresStats}; - #[pyclass(name = "BioSessionContext")] // #[derive(Clone)] pub struct PyBioSessionContext { @@ -30,7 +25,6 @@ impl PyBioSessionContext { pub fn new(seed: String, catalog_dir: String) -> PyResult { let ctx = create_context().unwrap(); let session_config: HashMap = HashMap::new(); - ctx.session.register_udaf(make_base_sequence_quality_udaf()); Ok(PyBioSessionContext { ctx, session_config, @@ -92,14 +86,3 @@ fn create_context() -> exon::Result { ExonSession::with_config_exon(config) } - -pub fn make_base_sequence_quality_udaf() -> AggregateUDF { - create_udaf( - "base_sequence_quality", // nazwa funkcji w SQL - vec![DataType::Utf8], // typ wejściowy - Arc::new(base_quality_result_type()), - Volatility::Immutable, - Arc::new(|_| Ok(Box::new(QualityScoresStats::new()))), - Arc::new(vec![]), - ) -} diff --git a/src/lib.rs b/src/lib.rs index d92eb0c4..ac78e9b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,17 +1,16 @@ +mod base_sequence_quality; mod context; mod operation; mod option; mod query; mod scan; mod streaming; -mod udaf; mod udtf; mod utils; use std::string::ToString; use std::sync::{Arc, Mutex}; -use arrow::array::*; use datafusion::arrow::ffi_stream::ArrowArrayStreamReader; use datafusion::arrow::pyarrow::PyArrowType; use datafusion::datasource::MemTable; @@ -23,8 +22,6 @@ use polars_lazy::prelude::{LazyFrame, ScanArgsAnonymous}; use polars_python::error::PyPolarsErr; use polars_python::lazyframe::PyLazyFrame; use pyo3::prelude::*; -use pyo3::types::{PyDict, PyList}; -use scan::deregister_table; use tokio::runtime::Runtime; use crate::context::PyBioSessionContext; @@ -409,128 +406,65 @@ fn py_from_polars( }) } -fn struct_array_to_pydict(py: Python<'_>, struct_array: &StructArray) -> PyResult { - let warn_array = struct_array - .column_by_name("base_quality_warn") - .and_then(|a| a.as_any().downcast_ref::()) - .unwrap(); - - let base_per_pos_array = struct_array - .column_by_name("base_per_pos_data") - .and_then(|a| a.as_any().downcast_ref::()) - .unwrap(); - - let struct_array = base_per_pos_array - .values() - .as_any() - .downcast_ref::() - .unwrap(); - - let mut base_per_pos_data = Vec::new(); - for i in 0..base_per_pos_array.value_length(0) { - let mut row = std::collections::HashMap::new(); - - let pos = struct_array - .column_by_name("pos") - .and_then(|a| a.as_any().downcast_ref::()) - .unwrap() - .value(i as usize); - let average = struct_array - .column_by_name("average") - .and_then(|a| a.as_any().downcast_ref::()) - .unwrap() - .value(i as usize); - let median = struct_array - .column_by_name("median") - .and_then(|a| a.as_any().downcast_ref::()) - .unwrap() - .value(i as usize); - let q1 = struct_array - .column_by_name("q1") - .and_then(|a| a.as_any().downcast_ref::()) - .unwrap() - .value(i as usize); - let q3 = struct_array - .column_by_name("q3") - .and_then(|a| a.as_any().downcast_ref::()) - .unwrap() - .value(i as usize); - let lower = struct_array - .column_by_name("lower") - .and_then(|a| a.as_any().downcast_ref::()) - .unwrap() - .value(i as usize); - let upper = struct_array - .column_by_name("upper") - .and_then(|a| a.as_any().downcast_ref::()) - .unwrap() - .value(i as usize); - - row.insert("pos", pos.into_py(py)); - row.insert("average", average.into_py(py)); - row.insert("median", median.into_py(py)); - row.insert("q1", q1.into_py(py)); - row.insert("q3", q3.into_py(py)); - row.insert("lower", lower.into_py(py)); - row.insert("upper", upper.into_py(py)); - - base_per_pos_data.push(row.into_py(py).to_object(py)); - } - - let result_dict = PyDict::new_bound(py); - result_dict.set_item("base_quality_warn", warn_array.value(0))?; - result_dict.set_item( - "base_per_pos_data", - PyList::new_bound(py, base_per_pos_data), - )?; - - Ok(result_dict.to_object(py)) -} - fn handle_base_sequence_quality<'a, F>( - py: Python<'a>, + _py: Python<'a>, py_ctx: &PyBioSessionContext, table_name: &str, + column: &str, register_fn: F, -) -> PyResult +) -> PyResult where F: FnOnce(&PyBioSessionContext, &str, &Runtime), { let ctx = &py_ctx.ctx; let rt = Runtime::new().unwrap(); register_fn(py_ctx, table_name, &rt); - let result_opt = rt.block_on(do_base_sequence_quality(ctx, &table_name.to_string())); - deregister_table(ctx, table_name); - if let Some(struct_array) = result_opt { - struct_array_to_pydict(py, &struct_array) - } else { - Ok(py.None()) - } + let data_frame = rt.block_on(do_base_sequence_quality( + ctx, + table_name.to_string(), + column.to_string(), + )); + // deregister_table(ctx, table_name); + Ok(PyDataFrame::new(data_frame)) } #[pyfunction] -#[pyo3(signature = (py_ctx, path))] +#[pyo3(signature = (py_ctx, path, column))] fn base_sequance_quality_scan( py: Python<'_>, py_ctx: &PyBioSessionContext, path: String, -) -> PyResult { - handle_base_sequence_quality(py, py_ctx, DEFAULT_TABLE_NAME, |py_ctx, table_name, rt| { - let ctx = &py_ctx.ctx; - maybe_register_table(path, &table_name.to_string(), None, ctx, rt); - }) + column: String, +) -> PyResult { + handle_base_sequence_quality( + py, + py_ctx, + DEFAULT_TABLE_NAME, + &column, + |py_ctx, table_name, rt| { + let ctx = &py_ctx.ctx; + maybe_register_table(path, &table_name.to_string(), None, ctx, rt); + }, + ) } #[pyfunction] -#[pyo3(signature = (py_ctx, df))] +#[pyo3(signature = (py_ctx, df, column))] fn base_sequance_quality_frame( py: Python<'_>, py_ctx: &PyBioSessionContext, df: PyArrowType, -) -> PyResult { - handle_base_sequence_quality(py, py_ctx, DEFAULT_TABLE_NAME, |py_ctx, table_name, _rt| { - register_frame(py_ctx, df, table_name.to_string()); - }) + column: String, +) -> PyResult { + handle_base_sequence_quality( + py, + py_ctx, + DEFAULT_TABLE_NAME, + &column, + |py_ctx, table_name, _rt| { + register_frame(py_ctx, df, table_name.to_string()); + }, + ) } #[pymodule] diff --git a/src/operation.rs b/src/operation.rs index 808c55a9..d4481184 100644 --- a/src/operation.rs +++ b/src/operation.rs @@ -1,12 +1,12 @@ use std::sync::Arc; -use arrow_array::{Array, StructArray}; use datafusion::catalog_common::TableReference; use exon::ExonSession; use log::{debug, info}; use sequila_core::session_context::{Algorithm, SequilaConfig}; use tokio::runtime::Runtime; +use crate::base_sequence_quality::BaseSequenceQualityProvider; use crate::context::set_option_internal; use crate::option::{FilterOp, RangeOp, RangeOptions}; use crate::query::{count_overlaps_query, nearest_query, overlap_query}; @@ -194,33 +194,20 @@ async fn do_count_overlaps_coverage_naive( pub(crate) async fn do_base_sequence_quality( ctx: &ExonSession, - table: &String, -) -> Option { - let query = format!( - "SELECT base_sequence_quality(quality_scores) as result FROM {}", - table - ); + table: String, + column: String, +) -> datafusion::dataframe::DataFrame { + let session = &ctx.session; + let provider = + BaseSequenceQualityProvider::new(Arc::new(session.clone()), table.clone(), column.clone()); + let table_name = format!("{}_base_sequence_quality", table); + ctx.session.deregister_table(table_name.clone()).ok(); + ctx.session + .register_table(table_name.clone(), Arc::new(provider)) + .unwrap(); + let query = format!("SELECT * FROM {}", table_name); debug!("Query: {}", query); - let batches = ctx.sql(&query).await.unwrap().collect().await.unwrap(); - - if let Some(batch) = batches.get(0) { - let col_idx = batch - .schema() - .fields() - .iter() - .position(|f| f.name() == "result") - .expect("Column 'result' not found"); - let array = batch.column(col_idx); - - if array.len() > 0 && !array.is_null(0) { - if let Some(struct_array) = array.as_any().downcast_ref::() { - return Some(struct_array.clone()); - } else { - panic!("Unsupported result type: {:?}", array.data_type()); - } - } - } - None + ctx.sql(&query).await.unwrap() } async fn get_non_join_columns( diff --git a/src/scan.rs b/src/scan.rs index e7795a99..34412780 100644 --- a/src/scan.rs +++ b/src/scan.rs @@ -156,7 +156,3 @@ pub(crate) fn maybe_register_table( } .to_string() } - -pub(crate) fn deregister_table(ctx: &ExonSession, table_name: &str) { - let _ = ctx.session.deregister_table(table_name); -} diff --git a/src/udaf.rs b/src/udaf.rs deleted file mode 100644 index a26ac237..00000000 --- a/src/udaf.rs +++ /dev/null @@ -1,210 +0,0 @@ -use std::collections::HashMap; -use std::sync::Arc; - -use arrow::buffer::OffsetBuffer; -use arrow_array::{Array, ArrayRef, Float64Array, Int64Array, ListArray, StringArray, StructArray}; -use arrow_schema::{DataType, Field, Fields}; -use datafusion::error::{DataFusionError, Result}; -use datafusion::physical_plan::Accumulator; -use datafusion::scalar::ScalarValue; - -#[derive(Debug)] -pub(crate) struct QualityScoresStats { - values_per_pos: HashMap>, // key: position, value: decoded quality scores -} - -impl QualityScoresStats { - pub fn new() -> Self { - Self { - values_per_pos: HashMap::new(), - } - } - - fn decode_score(c: char) -> Option { - let ascii = c as u8; - if ascii >= 33 { - Some(ascii - 33) - } else { - None - } - } - - fn calc_stats(values: &mut Vec) -> (f64, f64, f64, f64, f64, f64) { - values.sort_unstable(); - let n = values.len(); - let average = values.iter().map(|&v| v as f64).sum::() / n as f64; - let median = if n % 2 == 0 { - (values[n / 2 - 1] as f64 + values[n / 2] as f64) / 2.0 - } else { - values[n / 2] as f64 - }; - let q1 = values[n / 4] as f64; - let q3 = values[(3 * n) / 4] as f64; - let iqr = q3 - q1; - let lower = q1 - 1.5 * iqr; - let upper = q3 + 1.5 * iqr; - (average, median, q1, q3, lower, upper) - } -} - -impl Accumulator for QualityScoresStats { - fn state(&mut self) -> Result> { - Ok(vec![]) - } - - fn evaluate(&mut self) -> Result { - #[derive(Default)] - struct StatColumns { - pos: Vec, - avg: Vec, - median: Vec, - q1: Vec, - q3: Vec, - lower: Vec, - upper: Vec, - } - - let mut cols = StatColumns::default(); - let mut base_quality_warn = "pass"; - - for (&pos, values) in &mut self.values_per_pos { - if values.is_empty() { - continue; - } - - let (avg, median, q1, q3, lower, upper) = Self::calc_stats(values); - - cols.pos.push(pos as i64); - cols.avg.push(avg); - cols.median.push(median); - cols.q1.push(q1); - cols.q3.push(q3); - cols.lower.push(lower); - cols.upper.push(upper); - - base_quality_warn = match (q1 <= 20.0, q1 <= 25.0, base_quality_warn) { - (true, _, _) => "fail", - (false, true, "pass") => "warn", - _ => base_quality_warn, - }; - } - - let result_type = base_quality_result_type(); - - let fields = match result_type { - DataType::Struct(ref fields) => fields.clone(), - _ => { - return Err(DataFusionError::Execution( - "Unexpected result type".to_string(), - )) - }, - }; - - let base_quality_warn_field = fields[0].clone(); - let base_per_pos_data_field = fields[1].clone(); - - let base_per_pos_data_element_field = match base_per_pos_data_field.data_type() { - DataType::List(inner_field) => inner_field.as_ref().clone(), - _ => return Err(DataFusionError::Execution("Expected List type".to_string())), - }; - - let struct_fields = match base_per_pos_data_element_field.data_type() { - DataType::Struct(inner_fields) => inner_fields.clone(), - _ => { - return Err(DataFusionError::Execution( - "Expected Struct type inside list".to_string(), - )) - }, - }; - - let to_array = |vec: Vec| Arc::new(Float64Array::from(vec)) as ArrayRef; - - let struct_array = Arc::new(StructArray::new( - struct_fields.clone(), - vec![ - Arc::new(Int64Array::from(cols.pos)) as ArrayRef, - to_array(cols.avg), - to_array(cols.median), - to_array(cols.q1), - to_array(cols.q3), - to_array(cols.lower), - to_array(cols.upper), - ], - None, - )) as ArrayRef; - - let list_array = Arc::new(ListArray::new( - Arc::new(base_per_pos_data_element_field), - OffsetBuffer::new(vec![0, struct_array.len() as i32].into()), - struct_array, - None, - )); - - Ok(ScalarValue::Struct(Arc::new(StructArray::from(vec![ - ( - base_quality_warn_field, - Arc::new(StringArray::from(vec![base_quality_warn])) as ArrayRef, - ), - (base_per_pos_data_field, list_array), - ])))) - } - - fn update_batch(&mut self, values: &[ArrayRef]) -> Result<()> { - let arr = values[0] - .as_any() - .downcast_ref::() - .ok_or_else(|| { - datafusion::error::DataFusionError::Internal("Expected StringArray".to_string()) - })?; - - for i in 0..arr.len() { - if arr.is_null(i) { - continue; - } - let val = arr.value(i); - - for (j, c) in val.chars().enumerate() { - if let Some(decoded) = Self::decode_score(c) { - self.values_per_pos.entry(j).or_default().push(decoded); - } - } - } - - Ok(()) - } - - fn merge_batch(&mut self, _states: &[ArrayRef]) -> Result<()> { - Ok(()) - } - - fn size(&self) -> usize { - std::mem::size_of_val(self) - } -} - -pub fn base_quality_result_type() -> DataType { - let per_pos_fields = Fields::from(vec![ - Field::new("pos", DataType::Int64, false), - Field::new("average", DataType::Float64, false), - Field::new("median", DataType::Float64, false), - Field::new("q1", DataType::Float64, false), - Field::new("q3", DataType::Float64, false), - Field::new("lower", DataType::Float64, false), - Field::new("upper", DataType::Float64, false), - ]); - - let base_per_pos_element_field = Field::new( - "base_per_pos_data_element", - DataType::Struct(per_pos_fields), - false, - ); - - DataType::Struct(Fields::from(vec![ - Field::new("base_quality_warn", DataType::Utf8, false), - Field::new( - "base_per_pos_data", - DataType::List(Arc::new(base_per_pos_element_field)), - false, - ), - ])) -} From 1bff752c6caa4ea7e01d5a7a54501079c4b8131a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20=C5=9Acise=C5=82?= Date: Thu, 5 Jun 2025 17:58:00 +0200 Subject: [PATCH 6/6] Implement sequence quality histogram and quantile statistics - Added `SequenceQualityHistogramProvider` and `SequenceQualityHistogramExec` to compute quality histograms from sequence data. - Introduced `QuantileStatsTableProvider` and `QuantileStatsExec` for calculating quantile statistics based on histogram data. --- docs/notebooks/base_sequence_quality.ipynb | 267 ++++++++---------- polars_bio/quality_stats.py | 17 +- src/lib.rs | 66 ++--- src/operation.rs | 42 ++- src/quantile_stats.rs | 266 +++++++++++++++++ ...ality.rs => sequence_quality_histogram.rs} | 172 ++++++----- 6 files changed, 544 insertions(+), 286 deletions(-) create mode 100644 src/quantile_stats.rs rename src/{base_sequence_quality.rs => sequence_quality_histogram.rs} (53%) diff --git a/docs/notebooks/base_sequence_quality.ipynb b/docs/notebooks/base_sequence_quality.ipynb index cac9a2ce..ac49dd6f 100644 --- a/docs/notebooks/base_sequence_quality.ipynb +++ b/docs/notebooks/base_sequence_quality.ipynb @@ -37,27 +37,6 @@ "### Usage examples" ] }, - { - "cell_type": "markdown", - "id": "f9aedeb9", - "metadata": {}, - "source": [ - "#### Usage example - calling UDAF directly in SQL" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5f6fccf3", - "metadata": {}, - "outputs": [], - "source": [ - "a_lazyframe = pb.read_fastq(\"./example.fastq\")\n", - "# not implemented yet\n", - "result = pb.sql(\"???\").collect()\n", - "print(result)" - ] - }, { "cell_type": "markdown", "id": "b238193d", @@ -68,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "0420c240", "metadata": {}, "outputs": [ @@ -76,25 +55,25 @@ "name": "stdout", "output_type": "stream", "text": [ - " pos score\n", - "0 0 2\n", - "1 1 19\n", - "2 2 33\n", - "3 3 35\n", - "4 4 37\n", - "... ... ...\n", - "20195 96 35\n", - "20196 97 32\n", - "20197 98 35\n", - "20198 99 35\n", - "20199 100 33\n", + " pos avg q1 median q3 lower upper\n", + "0 47 37.665 37.535714 39.921053 41.060185 32.249008 46.346892\n", + "1 38 37.640 37.964286 40.067308 41.024038 33.374657 45.613668\n", + "2 65 35.995 35.190000 37.433333 39.810000 28.260000 46.740000\n", + "3 3 35.690 35.483333 37.208661 37.600394 32.307743 40.775984\n", + "4 41 37.870 37.678571 40.116071 41.004902 32.689076 45.994398\n", + ".. ... ... ... ... ... ... ...\n", + "96 42 37.780 37.583333 40.139344 40.954918 32.525956 46.012295\n", + "97 43 37.775 38.114583 40.126866 40.869403 33.982354 45.001632\n", + "98 15 38.725 38.226190 40.352459 41.168033 33.813427 45.580796\n", + "99 46 37.790 37.479167 39.975000 41.042453 32.134237 46.387382\n", + "100 24 38.265 38.397059 40.095745 41.125000 34.305147 45.216912\n", "\n", - "[20200 rows x 2 columns]\n" + "[101 rows x 7 columns]\n" ] } ], "source": [ - "result = pb.base_sequence_quality(\"example.fastq\", output_type=\"pandas.DataFrame\")\n", + "result = pb.base_sequence_quality(\"example.fastq\", output_type=\"pandas.DataFrame\", target_partitions=2)\n", "print(result)" ] }, @@ -108,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "66c3af24", "metadata": {}, "outputs": [ @@ -122,30 +101,30 @@ " white-space: pre-wrap;\n", "}\n", "\n", - "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + "shape: (101, 7)
posavgq1medianq3lowerupper
u64f64f64f64f64f64f64
4737.66537.53571439.92105341.06018532.24900846.346892
9032.27533.18333334.98684235.6396129.49891839.324026
2637.85538.02884640.07894740.95175433.64448445.336117
735.435.46590936.9062537.48737432.43371240.519571
335.6935.48333337.20866137.60039432.30774340.775984
1938.42538.237540.23846241.00490234.08639745.156005
9430.77532.05769234.65151535.5126.87923140.688462
1738.50538.12540.12745141.0937533.67187545.546875
7932.4631.9687535.20535736.437525.26562543.140625
4137.8737.67857140.11607141.00490232.68907645.994398
" ], "text/plain": [ - "shape: (20_200, 2)\n", - "┌─────┬───────┐\n", - "│ pos ┆ score │\n", - "│ --- ┆ --- │\n", - "│ i64 ┆ i8 │\n", - "╞═════╪═══════╡\n", - "│ 0 ┆ 2 │\n", - "│ 1 ┆ 19 │\n", - "│ 2 ┆ 33 │\n", - "│ 3 ┆ 35 │\n", - "│ 4 ┆ 37 │\n", - "│ … ┆ … │\n", - "│ 96 ┆ 35 │\n", - "│ 97 ┆ 32 │\n", - "│ 98 ┆ 35 │\n", - "│ 99 ┆ 35 │\n", - "│ 100 ┆ 33 │\n", - "└─────┴───────┘" + "shape: (101, 7)\n", + "┌─────┬────────┬───────────┬───────────┬───────────┬───────────┬───────────┐\n", + "│ pos ┆ avg ┆ q1 ┆ median ┆ q3 ┆ lower ┆ upper │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ u64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═════╪════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╡\n", + "│ 47 ┆ 37.665 ┆ 37.535714 ┆ 39.921053 ┆ 41.060185 ┆ 32.249008 ┆ 46.346892 │\n", + "│ 90 ┆ 32.275 ┆ 33.183333 ┆ 34.986842 ┆ 35.63961 ┆ 29.498918 ┆ 39.324026 │\n", + "│ 26 ┆ 37.855 ┆ 38.028846 ┆ 40.078947 ┆ 40.951754 ┆ 33.644484 ┆ 45.336117 │\n", + "│ 7 ┆ 35.4 ┆ 35.465909 ┆ 36.90625 ┆ 37.487374 ┆ 32.433712 ┆ 40.519571 │\n", + "│ 3 ┆ 35.69 ┆ 35.483333 ┆ 37.208661 ┆ 37.600394 ┆ 32.307743 ┆ 40.775984 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 19 ┆ 38.425 ┆ 38.2375 ┆ 40.238462 ┆ 41.004902 ┆ 34.086397 ┆ 45.156005 │\n", + "│ 94 ┆ 30.775 ┆ 32.057692 ┆ 34.651515 ┆ 35.51 ┆ 26.879231 ┆ 40.688462 │\n", + "│ 17 ┆ 38.505 ┆ 38.125 ┆ 40.127451 ┆ 41.09375 ┆ 33.671875 ┆ 45.546875 │\n", + "│ 79 ┆ 32.46 ┆ 31.96875 ┆ 35.205357 ┆ 36.4375 ┆ 25.265625 ┆ 43.140625 │\n", + "│ 41 ┆ 37.87 ┆ 37.678571 ┆ 40.116071 ┆ 41.004902 ┆ 32.689076 ┆ 45.994398 │\n", + "└─────┴────────┴───────────┴───────────┴───────────┴───────────┴───────────┘" ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -164,7 +143,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "a2cb9c97", "metadata": {}, "outputs": [ @@ -178,30 +157,30 @@ " white-space: pre-wrap;\n", "}\n", "\n", - "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + "shape: (101, 7)
posavgq1medianq3lowerupper
u64f64f64f64f64f64f64
4437.56537.7187540.13392941.02403832.76081745.981971
2738.4438.23437540.2741.20703133.77539145.666016
7233.26533.86111135.687537.92391327.76690844.018116
8631.81533.36538535.13291135.76265829.76947439.358569
9032.27533.18333334.98684235.6396129.49891839.324026
3438.20537.97916740.15957441.16803333.19586745.951332
8432.41533.2535.18243235.8547329.34290539.761824
4937.2136.67857139.64583340.76388930.55059546.891865
6336.2535.21590938.02631640.27527.62727347.863636
8032.6132.62535.28947436.42045526.93181842.113636
" ], "text/plain": [ - "shape: (20_200, 2)\n", - "┌─────┬───────┐\n", - "│ pos ┆ score │\n", - "│ --- ┆ --- │\n", - "│ i64 ┆ i8 │\n", - "╞═════╪═══════╡\n", - "│ 0 ┆ 2 │\n", - "│ 1 ┆ 19 │\n", - "│ 2 ┆ 33 │\n", - "│ 3 ┆ 35 │\n", - "│ 4 ┆ 37 │\n", - "│ … ┆ … │\n", - "│ 96 ┆ 35 │\n", - "│ 97 ┆ 32 │\n", - "│ 98 ┆ 35 │\n", - "│ 99 ┆ 35 │\n", - "│ 100 ┆ 33 │\n", - "└─────┴───────┘" + "shape: (101, 7)\n", + "┌─────┬────────┬───────────┬───────────┬───────────┬───────────┬───────────┐\n", + "│ pos ┆ avg ┆ q1 ┆ median ┆ q3 ┆ lower ┆ upper │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ u64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═════╪════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╡\n", + "│ 44 ┆ 37.565 ┆ 37.71875 ┆ 40.133929 ┆ 41.024038 ┆ 32.760817 ┆ 45.981971 │\n", + "│ 27 ┆ 38.44 ┆ 38.234375 ┆ 40.27 ┆ 41.207031 ┆ 33.775391 ┆ 45.666016 │\n", + "│ 72 ┆ 33.265 ┆ 33.861111 ┆ 35.6875 ┆ 37.923913 ┆ 27.766908 ┆ 44.018116 │\n", + "│ 86 ┆ 31.815 ┆ 33.365385 ┆ 35.132911 ┆ 35.762658 ┆ 29.769474 ┆ 39.358569 │\n", + "│ 90 ┆ 32.275 ┆ 33.183333 ┆ 34.986842 ┆ 35.63961 ┆ 29.498918 ┆ 39.324026 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 34 ┆ 38.205 ┆ 37.979167 ┆ 40.159574 ┆ 41.168033 ┆ 33.195867 ┆ 45.951332 │\n", + "│ 84 ┆ 32.415 ┆ 33.25 ┆ 35.182432 ┆ 35.85473 ┆ 29.342905 ┆ 39.761824 │\n", + "│ 49 ┆ 37.21 ┆ 36.678571 ┆ 39.645833 ┆ 40.763889 ┆ 30.550595 ┆ 46.891865 │\n", + "│ 63 ┆ 36.25 ┆ 35.215909 ┆ 38.026316 ┆ 40.275 ┆ 27.627273 ┆ 47.863636 │\n", + "│ 80 ┆ 32.61 ┆ 32.625 ┆ 35.289474 ┆ 36.420455 ┆ 26.931818 ┆ 42.113636 │\n", + "└─────┴────────┴───────────┴───────────┴───────────┴───────────┴───────────┘" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -220,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "1899ca01", "metadata": {}, "outputs": [ @@ -242,7 +221,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "200rows [00:00, 85580.58rows/s]\n" + "200rows [00:00, 62156.25rows/s]\n" ] }, { @@ -255,30 +234,30 @@ " white-space: pre-wrap;\n", "}\n", "\n", - "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + "shape: (101, 7)
posavgq1medianq3lowerupper
u64f64f64f64f64f64f64
6436.09535.06481537.740.14583327.44328747.767361
435.6835.55288537.20866137.60039432.48162140.671657
6835.9134.94047636.93181839.53947428.0419846.43797
7233.26533.86111135.687537.92391327.76690844.018116
5836.7735.33823538.9062540.71710527.2699348.78541
2637.85538.02884640.07894740.95175433.64448445.336117
937.3637.3437539.01470639.50245134.10569942.740502
7133.00533.79166735.85135138.58333326.60416745.770833
1137.7137.78448339.09459539.54279335.14701842.180258
2438.26538.39705940.09574541.12534.30514745.216912
" ], "text/plain": [ - "shape: (20_200, 2)\n", - "┌─────┬───────┐\n", - "│ pos ┆ score │\n", - "│ --- ┆ --- │\n", - "│ i64 ┆ i8 │\n", - "╞═════╪═══════╡\n", - "│ 0 ┆ 2 │\n", - "│ 1 ┆ 19 │\n", - "│ 2 ┆ 33 │\n", - "│ 3 ┆ 35 │\n", - "│ 4 ┆ 37 │\n", - "│ … ┆ … │\n", - "│ 96 ┆ 35 │\n", - "│ 97 ┆ 32 │\n", - "│ 98 ┆ 35 │\n", - "│ 99 ┆ 35 │\n", - "│ 100 ┆ 33 │\n", - "└─────┴───────┘" + "shape: (101, 7)\n", + "┌─────┬────────┬───────────┬───────────┬───────────┬───────────┬───────────┐\n", + "│ pos ┆ avg ┆ q1 ┆ median ┆ q3 ┆ lower ┆ upper │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ u64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═════╪════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╡\n", + "│ 64 ┆ 36.095 ┆ 35.064815 ┆ 37.7 ┆ 40.145833 ┆ 27.443287 ┆ 47.767361 │\n", + "│ 4 ┆ 35.68 ┆ 35.552885 ┆ 37.208661 ┆ 37.600394 ┆ 32.481621 ┆ 40.671657 │\n", + "│ 68 ┆ 35.91 ┆ 34.940476 ┆ 36.931818 ┆ 39.539474 ┆ 28.04198 ┆ 46.43797 │\n", + "│ 72 ┆ 33.265 ┆ 33.861111 ┆ 35.6875 ┆ 37.923913 ┆ 27.766908 ┆ 44.018116 │\n", + "│ 58 ┆ 36.77 ┆ 35.338235 ┆ 38.90625 ┆ 40.717105 ┆ 27.26993 ┆ 48.78541 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 26 ┆ 37.855 ┆ 38.028846 ┆ 40.078947 ┆ 40.951754 ┆ 33.644484 ┆ 45.336117 │\n", + "│ 9 ┆ 37.36 ┆ 37.34375 ┆ 39.014706 ┆ 39.502451 ┆ 34.105699 ┆ 42.740502 │\n", + "│ 71 ┆ 33.005 ┆ 33.791667 ┆ 35.851351 ┆ 38.583333 ┆ 26.604167 ┆ 45.770833 │\n", + "│ 11 ┆ 37.71 ┆ 37.784483 ┆ 39.094595 ┆ 39.542793 ┆ 35.147018 ┆ 42.180258 │\n", + "│ 24 ┆ 38.265 ┆ 38.397059 ┆ 40.095745 ┆ 41.125 ┆ 34.305147 ┆ 45.216912 │\n", + "└─────┴────────┴───────────┴───────────┴───────────┴───────────┴───────────┘" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -299,7 +278,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "7830b8aa", "metadata": {}, "outputs": [ @@ -308,7 +287,7 @@ "output_type": "stream", "text": [ "INFO:polars_bio:Table: example registered for path: ./example.fastq\n", - "200rows [00:00, 99332.24rows/s]" + "200rows [00:00, 66234.57rows/s]" ] }, { @@ -335,30 +314,30 @@ " white-space: pre-wrap;\n", "}\n", "\n", - "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + "shape: (101, 7)
posavgq1medianq3lowerupper
u64f64f64f64f64f64f64
335.6935.48333337.20866137.60039432.30774340.775984
2938.59538.3540.25833341.0937534.23437545.209375
4437.56537.7187540.13392941.02403832.76081745.981971
7630.26530.91666735.41489437.07352921.68137346.308824
6735.9634.72368436.97222239.8127.09421147.439474
1538.72538.2261940.35245941.16803333.81342745.580796
2637.85538.02884640.07894740.95175433.64448445.336117
3937.89538.02777840.12540.85661833.78451845.099877
9730.6731.57534.89062535.55722925.60165741.530572
5137.5336.7187539.44736841.02403830.26081747.481971
" ], "text/plain": [ - "shape: (20_200, 2)\n", - "┌─────┬───────┐\n", - "│ pos ┆ score │\n", - "│ --- ┆ --- │\n", - "│ i64 ┆ i8 │\n", - "╞═════╪═══════╡\n", - "│ 0 ┆ 2 │\n", - "│ 1 ┆ 19 │\n", - "│ 2 ┆ 33 │\n", - "│ 3 ┆ 35 │\n", - "│ 4 ┆ 37 │\n", - "│ … ┆ … │\n", - "│ 96 ┆ 35 │\n", - "│ 97 ┆ 32 │\n", - "│ 98 ┆ 35 │\n", - "│ 99 ┆ 35 │\n", - "│ 100 ┆ 33 │\n", - "└─────┴───────┘" + "shape: (101, 7)\n", + "┌─────┬────────┬───────────┬───────────┬───────────┬───────────┬───────────┐\n", + "│ pos ┆ avg ┆ q1 ┆ median ┆ q3 ┆ lower ┆ upper │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ u64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═════╪════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╡\n", + "│ 3 ┆ 35.69 ┆ 35.483333 ┆ 37.208661 ┆ 37.600394 ┆ 32.307743 ┆ 40.775984 │\n", + "│ 29 ┆ 38.595 ┆ 38.35 ┆ 40.258333 ┆ 41.09375 ┆ 34.234375 ┆ 45.209375 │\n", + "│ 44 ┆ 37.565 ┆ 37.71875 ┆ 40.133929 ┆ 41.024038 ┆ 32.760817 ┆ 45.981971 │\n", + "│ 76 ┆ 30.265 ┆ 30.916667 ┆ 35.414894 ┆ 37.073529 ┆ 21.681373 ┆ 46.308824 │\n", + "│ 67 ┆ 35.96 ┆ 34.723684 ┆ 36.972222 ┆ 39.81 ┆ 27.094211 ┆ 47.439474 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 15 ┆ 38.725 ┆ 38.22619 ┆ 40.352459 ┆ 41.168033 ┆ 33.813427 ┆ 45.580796 │\n", + "│ 26 ┆ 37.855 ┆ 38.028846 ┆ 40.078947 ┆ 40.951754 ┆ 33.644484 ┆ 45.336117 │\n", + "│ 39 ┆ 37.895 ┆ 38.027778 ┆ 40.125 ┆ 40.856618 ┆ 33.784518 ┆ 45.099877 │\n", + "│ 97 ┆ 30.67 ┆ 31.575 ┆ 34.890625 ┆ 35.557229 ┆ 25.601657 ┆ 41.530572 │\n", + "│ 51 ┆ 37.53 ┆ 36.71875 ┆ 39.447368 ┆ 41.024038 ┆ 30.260817 ┆ 47.481971 │\n", + "└─────┴────────┴───────────┴───────────┴───────────┴───────────┴───────────┘" ] }, - "execution_count": 7, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -380,7 +359,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "56817174", "metadata": {}, "outputs": [ @@ -389,7 +368,7 @@ "output_type": "stream", "text": [ "INFO:polars_bio:Table: example registered for path: ./example.fastq\n", - "200rows [00:00, 91638.72rows/s]" + "200rows [00:00, 91799.17rows/s]" ] }, { @@ -416,30 +395,30 @@ " white-space: pre-wrap;\n", "}\n", "\n", - "shape: (20_200, 2)
posscore
i64i8
02
119
233
335
437
9635
9732
9835
9935
10033
" + "shape: (101, 7)
posavgq1medianq3lowerupper
u64f64f64f64f64f64f64
7133.00533.79166735.85135138.58333326.60416745.770833
7430.8332.7535.53260937.48529425.64705944.588235
4537.4536.5937540.07142941.07727329.86846647.802557
4937.2136.67857139.64583340.76388930.55059546.891865
7531.0630.95833335.41836737.28333321.47083346.770833
5037.42535.97539.77083341.06018528.34722248.687963
335.6935.48333337.20866137.60039432.30774340.775984
030.13531.21363633.72222234.48214326.31087739.384903
3738.038.21527840.08035740.9687534.08506945.098958
6535.99535.1937.43333339.8128.2646.74
" ], "text/plain": [ - "shape: (20_200, 2)\n", - "┌─────┬───────┐\n", - "│ pos ┆ score │\n", - "│ --- ┆ --- │\n", - "│ i64 ┆ i8 │\n", - "╞═════╪═══════╡\n", - "│ 0 ┆ 2 │\n", - "│ 1 ┆ 19 │\n", - "│ 2 ┆ 33 │\n", - "│ 3 ┆ 35 │\n", - "│ 4 ┆ 37 │\n", - "│ … ┆ … │\n", - "│ 96 ┆ 35 │\n", - "│ 97 ┆ 32 │\n", - "│ 98 ┆ 35 │\n", - "│ 99 ┆ 35 │\n", - "│ 100 ┆ 33 │\n", - "└─────┴───────┘" + "shape: (101, 7)\n", + "┌─────┬────────┬───────────┬───────────┬───────────┬───────────┬───────────┐\n", + "│ pos ┆ avg ┆ q1 ┆ median ┆ q3 ┆ lower ┆ upper │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ u64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═════╪════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╡\n", + "│ 71 ┆ 33.005 ┆ 33.791667 ┆ 35.851351 ┆ 38.583333 ┆ 26.604167 ┆ 45.770833 │\n", + "│ 74 ┆ 30.83 ┆ 32.75 ┆ 35.532609 ┆ 37.485294 ┆ 25.647059 ┆ 44.588235 │\n", + "│ 45 ┆ 37.45 ┆ 36.59375 ┆ 40.071429 ┆ 41.077273 ┆ 29.868466 ┆ 47.802557 │\n", + "│ 49 ┆ 37.21 ┆ 36.678571 ┆ 39.645833 ┆ 40.763889 ┆ 30.550595 ┆ 46.891865 │\n", + "│ 75 ┆ 31.06 ┆ 30.958333 ┆ 35.418367 ┆ 37.283333 ┆ 21.470833 ┆ 46.770833 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 50 ┆ 37.425 ┆ 35.975 ┆ 39.770833 ┆ 41.060185 ┆ 28.347222 ┆ 48.687963 │\n", + "│ 3 ┆ 35.69 ┆ 35.483333 ┆ 37.208661 ┆ 37.600394 ┆ 32.307743 ┆ 40.775984 │\n", + "│ 0 ┆ 30.135 ┆ 31.213636 ┆ 33.722222 ┆ 34.482143 ┆ 26.310877 ┆ 39.384903 │\n", + "│ 37 ┆ 38.0 ┆ 38.215278 ┆ 40.080357 ┆ 40.96875 ┆ 34.085069 ┆ 45.098958 │\n", + "│ 65 ┆ 35.995 ┆ 35.19 ┆ 37.433333 ┆ 39.81 ┆ 28.26 ┆ 46.74 │\n", + "└─────┴────────┴───────────┴───────────┴───────────┴───────────┴───────────┘" ] }, - "execution_count": 8, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } diff --git a/polars_bio/quality_stats.py b/polars_bio/quality_stats.py index d19daec9..501bd44a 100644 --- a/polars_bio/quality_stats.py +++ b/polars_bio/quality_stats.py @@ -15,6 +15,7 @@ def base_sequence_quality( df: Union[str, pl.DataFrame, pl.LazyFrame, pd.DataFrame], quality_scores_column: str = "quality_scores", output_type: str = "polars.DataFrame", + target_partitions: int = 8, ) -> Union[pl.DataFrame, pd.DataFrame]: """ Compute base sequence quality statistics from various dataframe/file types. @@ -27,12 +28,20 @@ def base_sequence_quality( Returns: DataFrame with base sequence quality statistics. """ + ctx.set_option( + "datafusion.execution.target_partitions", str(target_partitions), False + ) + if isinstance(df, str): supported_exts = {".parquet", ".csv", ".bed", ".vcf", ".fastq"} ext = set(Path(df).suffixes) if not (supported_exts & ext or not ext): - raise ValueError("Input file must be a Parquet, CSV, BED, VCF, or FASTQ file.") - result: datafusion.DataFrame = base_sequance_quality_scan(ctx, df, quality_scores_column) + raise ValueError( + "Input file must be a Parquet, CSV, BED, VCF, or FASTQ file." + ) + result: datafusion.DataFrame = base_sequance_quality_scan( + ctx, df, quality_scores_column + ) else: if isinstance(df, pl.LazyFrame): arrow_table = df.collect().to_arrow() @@ -42,7 +51,9 @@ def base_sequence_quality( arrow_table = pa.Table.from_pandas(df) else: raise TypeError("Unsupported dataframe type.") - result: datafusion.DataFrame = base_sequance_quality_frame(ctx, arrow_table, quality_scores_column) + result: datafusion.DataFrame = base_sequance_quality_frame( + ctx, arrow_table, quality_scores_column + ) if output_type == "polars.DataFrame": return result.to_polars() diff --git a/src/lib.rs b/src/lib.rs index ac78e9b3..152b0736 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,8 @@ -mod base_sequence_quality; +mod sequence_quality_histogram; mod context; mod operation; mod option; +mod quantile_stats; mod query; mod scan; mod streaming; @@ -406,28 +407,6 @@ fn py_from_polars( }) } -fn handle_base_sequence_quality<'a, F>( - _py: Python<'a>, - py_ctx: &PyBioSessionContext, - table_name: &str, - column: &str, - register_fn: F, -) -> PyResult -where - F: FnOnce(&PyBioSessionContext, &str, &Runtime), -{ - let ctx = &py_ctx.ctx; - let rt = Runtime::new().unwrap(); - register_fn(py_ctx, table_name, &rt); - let data_frame = rt.block_on(do_base_sequence_quality( - ctx, - table_name.to_string(), - column.to_string(), - )); - // deregister_table(ctx, table_name); - Ok(PyDataFrame::new(data_frame)) -} - #[pyfunction] #[pyo3(signature = (py_ctx, path, column))] fn base_sequance_quality_scan( @@ -436,16 +415,17 @@ fn base_sequance_quality_scan( path: String, column: String, ) -> PyResult { - handle_base_sequence_quality( - py, - py_ctx, - DEFAULT_TABLE_NAME, - &column, - |py_ctx, table_name, rt| { - let ctx = &py_ctx.ctx; - maybe_register_table(path, &table_name.to_string(), None, ctx, rt); - }, - ) + py.allow_threads(|| { + let ctx = &py_ctx.ctx; + let rt = Runtime::new().unwrap(); + maybe_register_table(path, &DEFAULT_TABLE_NAME.to_string(), None, ctx, &rt); + let data_frame = rt.block_on(do_base_sequence_quality( + ctx, + DEFAULT_TABLE_NAME.to_string(), + column.to_string(), + )); + Ok(PyDataFrame::new(data_frame)) + }) } #[pyfunction] @@ -456,15 +436,17 @@ fn base_sequance_quality_frame( df: PyArrowType, column: String, ) -> PyResult { - handle_base_sequence_quality( - py, - py_ctx, - DEFAULT_TABLE_NAME, - &column, - |py_ctx, table_name, _rt| { - register_frame(py_ctx, df, table_name.to_string()); - }, - ) + py.allow_threads(|| { + let ctx = &py_ctx.ctx; + let rt = Runtime::new().unwrap(); + register_frame(py_ctx, df, DEFAULT_TABLE_NAME.to_string()); + let data_frame = rt.block_on(do_base_sequence_quality( + ctx, + DEFAULT_TABLE_NAME.to_string(), + column.to_string(), + )); + Ok(PyDataFrame::new(data_frame)) + }) } #[pymodule] diff --git a/src/operation.rs b/src/operation.rs index d4481184..bd50e182 100644 --- a/src/operation.rs +++ b/src/operation.rs @@ -6,9 +6,10 @@ use log::{debug, info}; use sequila_core::session_context::{Algorithm, SequilaConfig}; use tokio::runtime::Runtime; -use crate::base_sequence_quality::BaseSequenceQualityProvider; +use crate::sequence_quality_histogram::SequenceQualityHistogramProvider; use crate::context::set_option_internal; use crate::option::{FilterOp, RangeOp, RangeOptions}; +use crate::quantile_stats::QuantileStatsTableProvider; use crate::query::{count_overlaps_query, nearest_query, overlap_query}; use crate::udtf::CountOverlapsProvider; use crate::utils::default_cols_to_string; @@ -197,16 +198,37 @@ pub(crate) async fn do_base_sequence_quality( table: String, column: String, ) -> datafusion::dataframe::DataFrame { - let session = &ctx.session; - let provider = - BaseSequenceQualityProvider::new(Arc::new(session.clone()), table.clone(), column.clone()); - let table_name = format!("{}_base_sequence_quality", table); - ctx.session.deregister_table(table_name.clone()).ok(); - ctx.session - .register_table(table_name.clone(), Arc::new(provider)) + let session = Arc::new(ctx.session.clone()); + let base_provider = Arc::new(SequenceQualityHistogramProvider::new( + session.clone(), + table.clone(), + column, + )); + + let base_table_name = format!("{}_decoded", table); + session.deregister_table(base_table_name.clone()).unwrap(); + session + .register_table(&base_table_name, base_provider) .unwrap(); - let query = format!("SELECT * FROM {}", table_name); - debug!("Query: {}", query); + + let query = format!( + "SELECT pos, score, SUM(count) as count FROM {} GROUP BY pos, score", + base_table_name + ); + let base_df = ctx.sql(&query).await.unwrap(); + let base_plan = base_df.create_physical_plan().await.unwrap(); + + let quantile_provider = Arc::new(QuantileStatsTableProvider::new(base_plan)); + + let quantile_table_name = format!("{}_quantiles", table); + session + .deregister_table(quantile_table_name.clone()) + .unwrap(); + session + .register_table(&quantile_table_name, quantile_provider) + .unwrap(); + + let query = format!("SELECT * FROM {}", quantile_table_name); ctx.sql(&query).await.unwrap() } diff --git a/src/quantile_stats.rs b/src/quantile_stats.rs new file mode 100644 index 00000000..36bf01b2 --- /dev/null +++ b/src/quantile_stats.rs @@ -0,0 +1,266 @@ +use std::any::Any; +use std::collections::HashMap; +use std::fmt::{Debug, Formatter}; +use std::sync::Arc; + +use arrow::array::{Array, Float64Builder, UInt64Array, UInt64Builder, UInt8Array}; +use arrow::compute::concat_batches; +use arrow::datatypes::{DataType, Field, Schema, SchemaRef}; +use arrow::record_batch::RecordBatch; +use async_trait::async_trait; +use datafusion::catalog::{Session, TableProvider}; +use datafusion::datasource::TableType; +use datafusion::error::Result; +use datafusion::execution::context::TaskContext; +use datafusion::physical_expr::EquivalenceProperties; +use datafusion::physical_plan::memory::MemoryStream; +use datafusion::physical_plan::{ + collect, DisplayAs, DisplayFormatType, ExecutionMode, ExecutionPlan, Partitioning, + PlanProperties, SendableRecordBatchStream, +}; + +pub struct QuantileStatsTableProvider { + input: Arc, + schema: SchemaRef, +} + +impl QuantileStatsTableProvider { + pub fn new(input: Arc) -> Self { + let schema = Arc::new(Schema::new(vec![ + Field::new("pos", DataType::UInt64, false), + Field::new("avg", DataType::Float64, true), + Field::new("q1", DataType::Float64, true), + Field::new("median", DataType::Float64, true), + Field::new("q3", DataType::Float64, true), + Field::new("lower", DataType::Float64, true), + Field::new("upper", DataType::Float64, true), + ])); + Self { + input, + schema, + } + } +} + +impl Debug for QuantileStatsTableProvider { + fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result { + Ok(()) + } +} + +#[async_trait] +impl TableProvider for QuantileStatsTableProvider { + fn as_any(&self) -> &dyn std::any::Any { + self + } + + fn schema(&self) -> SchemaRef { + self.schema.clone() + } + + fn table_type(&self) -> TableType { + TableType::Base + } + + async fn scan( + &self, + _state: &dyn Session, + _projection: Option<&Vec>, + _filters: &[datafusion::logical_expr::Expr], + _limit: Option, + ) -> datafusion::error::Result> { + Ok(Arc::new(QuantileStatsExec::new(self.input.clone()))) + } +} + +#[derive(Debug)] +pub struct QuantileStatsExec { + input: Arc, + schema: SchemaRef, + properties: PlanProperties, +} + +impl QuantileStatsExec { + pub fn new(input: Arc) -> Self { + let schema = Arc::new(Schema::new(vec![ + Field::new("pos", DataType::UInt64, false), + Field::new("avg", DataType::Float64, true), + Field::new("q1", DataType::Float64, true), + Field::new("median", DataType::Float64, true), + Field::new("q3", DataType::Float64, true), + Field::new("lower", DataType::Float64, true), + Field::new("upper", DataType::Float64, true), + ])); + + let schema_clone = schema.clone(); + + Self { + input, + schema, + properties: PlanProperties::new( + EquivalenceProperties::new(schema_clone), + Partitioning::UnknownPartitioning(1), + ExecutionMode::Bounded, + ), + } + } +} + +impl ExecutionPlan for QuantileStatsExec { + fn name(&self) -> &str { + "QuantileAggregateExec" + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn schema(&self) -> SchemaRef { + Arc::clone(&self.schema) + } + + fn properties(&self) -> &PlanProperties { + &self.properties + } + + fn children(&self) -> Vec<&Arc> { + vec![&self.input] + } + + fn with_new_children( + self: Arc, + _children: Vec>, + ) -> Result> { + Ok(self) + } + + fn execute( + &self, + _partition: usize, + context: Arc, + ) -> Result { + let input = self.input.clone(); + let schema = self.schema.clone(); + + let batches = futures::executor::block_on(collect(input, context.clone()))?; + let combined = concat_batches(&self.input.schema(), &batches)?; + let pos_array = combined + .column_by_name("pos") + .expect("Column 'pos' not found") + .as_any() + .downcast_ref::() + .expect("Expected UInt64 for pos"); + + let score_array = combined + .column_by_name("score") + .expect("Column 'score' not found") + .as_any() + .downcast_ref::() + .expect("Expected UInt8 for score"); + + let count_array = combined + .column_by_name("count") + .expect("Column 'count' not found") + .as_any() + .downcast_ref::() + .expect("Expected UInt64 for count"); + + let mut groups: HashMap> = HashMap::new(); + for i in 0..combined.num_rows() { + if pos_array.is_valid(i) && score_array.is_valid(i) && count_array.is_valid(i) { + let pos = pos_array.value(i); + let score = score_array.value(i); + let count = count_array.value(i); + let entry = groups.entry(pos).or_insert_with(|| vec![0; 256]); + entry[score as usize] += count; + } + } + + let mut pos_builder = UInt64Builder::with_capacity(groups.len()); + let mut avg_builder = Float64Builder::with_capacity(groups.len()); + let mut q1_builder = Float64Builder::with_capacity(groups.len()); + let mut median_builder = Float64Builder::with_capacity(groups.len()); + let mut q3_builder = Float64Builder::with_capacity(groups.len()); + let mut lower_builder = Float64Builder::with_capacity(groups.len()); + let mut upper_builder = Float64Builder::with_capacity(groups.len()); + + for (pos, hist) in groups { + if let Some((average, q1, median, q3, lower, upper)) = calculate_histogram_stats(&hist) + { + pos_builder.append_value(pos); + avg_builder.append_value(average); + q1_builder.append_value(q1); + median_builder.append_value(median); + q3_builder.append_value(q3); + lower_builder.append_value(lower); + upper_builder.append_value(upper); + } + } + + let result_batch = RecordBatch::try_new( + schema.clone(), + vec![ + Arc::new(pos_builder.finish()), + Arc::new(avg_builder.finish()), + Arc::new(q1_builder.finish()), + Arc::new(median_builder.finish()), + Arc::new(q3_builder.finish()), + Arc::new(lower_builder.finish()), + Arc::new(upper_builder.finish()), + ], + )?; + let mem_stream = MemoryStream::try_new(vec![result_batch], schema, None)?; + Ok(Box::pin(mem_stream)) + } +} + +impl DisplayAs for QuantileStatsExec { + fn fmt_as(&self, _t: DisplayFormatType, _f: &mut Formatter) -> std::fmt::Result { + Ok(()) + } +} + +fn calculate_histogram_stats(hist: &[u64]) -> Option<(f64, f64, f64, f64, f64, f64)> { + let total_count: u64 = hist.iter().sum(); + if total_count == 0 { + return None; + } + + let weighted_sum: u64 = hist + .iter() + .enumerate() + .map(|(score, &count)| score as u64 * count) + .sum(); + let average = weighted_sum as f64 / total_count as f64; + + fn quantile(hist: &[u64], quantile: f64, total: u64) -> f64 { + let target = quantile * (total - 1) as f64; + let mut acc = 0u64; + let mut prev_idx = 0usize; + for (idx, &count) in hist.iter().enumerate() { + if count == 0 { + continue; + } + if (acc as f64) <= target && (acc + count) as f64 > target { + let delta = target - acc as f64; + if count > 1 && delta > 0.0 { + return idx as f64 + delta / count as f64; + } else { + return idx as f64; + } + } + acc += count; + prev_idx = idx; + } + prev_idx as f64 + } + + let q1 = quantile(hist, 0.25, total_count); + let median = quantile(hist, 0.5, total_count); + let q3 = quantile(hist, 0.75, total_count); + let iqr = q3 - q1; + let lower = q1 - 1.5 * iqr; + let upper = q3 + 1.5 * iqr; + + Some((average, q1, median, q3, lower, upper)) +} diff --git a/src/base_sequence_quality.rs b/src/sequence_quality_histogram.rs similarity index 53% rename from src/base_sequence_quality.rs rename to src/sequence_quality_histogram.rs index 1ca4d1e4..38c922aa 100644 --- a/src/base_sequence_quality.rs +++ b/src/sequence_quality_histogram.rs @@ -1,3 +1,5 @@ +use std::any::Any; +use std::collections::HashMap; use std::fmt::{Debug, Formatter}; use std::sync::Arc; @@ -6,6 +8,7 @@ use async_trait::async_trait; use datafusion::arrow::datatypes::{DataType, Field, Schema, SchemaRef}; use datafusion::arrow::record_batch::RecordBatch; use datafusion::catalog::{Session, TableProvider}; +use datafusion::datasource::TableType; use datafusion::error::{DataFusionError, Result}; use datafusion::execution::context::TaskContext; use datafusion::physical_expr::EquivalenceProperties; @@ -15,22 +18,22 @@ use datafusion::physical_plan::{ DisplayAs, DisplayFormatType, ExecutionMode, ExecutionPlan, Partitioning, PlanProperties, SendableRecordBatchStream, }; -use datafusion::prelude::SessionContext; +use datafusion::prelude::{col, SessionContext}; use futures::stream::BoxStream; use futures::{StreamExt, TryStreamExt}; - -pub struct BaseSequenceQualityProvider { +pub struct SequenceQualityHistogramProvider { session: Arc, table_name: String, column_name: String, schema: SchemaRef, } -impl BaseSequenceQualityProvider { +impl SequenceQualityHistogramProvider { pub fn new(session: Arc, table_name: String, column_name: String) -> Self { let schema = Arc::new(Schema::new(vec![ - Field::new("pos", DataType::Int64, false), - Field::new("score", DataType::Int8, false), + Field::new("pos", DataType::UInt64, false), + Field::new("score", DataType::UInt8, false), + Field::new("count", DataType::UInt64, false), ])); Self { session, @@ -41,14 +44,14 @@ impl BaseSequenceQualityProvider { } } -impl Debug for BaseSequenceQualityProvider { +impl Debug for SequenceQualityHistogramProvider { fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result { Ok(()) } } #[async_trait] -impl TableProvider for BaseSequenceQualityProvider { +impl TableProvider for SequenceQualityHistogramProvider { fn as_any(&self) -> &dyn std::any::Any { self } @@ -57,8 +60,8 @@ impl TableProvider for BaseSequenceQualityProvider { self.schema.clone() } - fn table_type(&self) -> datafusion::datasource::TableType { - datafusion::datasource::TableType::Base + fn table_type(&self) -> TableType { + todo!() } async fn scan( @@ -69,13 +72,12 @@ impl TableProvider for BaseSequenceQualityProvider { _limit: Option, ) -> Result> { let target_partitions = self.session.state().config().target_partitions(); - - Ok(Arc::new(BaseSequenceQualityExec { + Ok(Arc::new(SequenceQualityHistogramExec { schema: self.schema.clone(), - session: Arc::clone(&self.session), + session: self.session.clone(), table_name: self.table_name.clone(), column_name: self.column_name.clone(), - cache: PlanProperties::new( + properties: PlanProperties::new( EquivalenceProperties::new(self.schema.clone()), Partitioning::UnknownPartitioning(target_partitions), ExecutionMode::Bounded, @@ -84,32 +86,32 @@ impl TableProvider for BaseSequenceQualityProvider { } } -pub struct BaseSequenceQualityExec { +pub struct SequenceQualityHistogramExec { schema: SchemaRef, session: Arc, table_name: String, column_name: String, - cache: PlanProperties, + properties: PlanProperties, } -impl Debug for BaseSequenceQualityExec { +impl Debug for SequenceQualityHistogramExec { fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result { Ok(()) } } -impl DisplayAs for BaseSequenceQualityExec { +impl DisplayAs for SequenceQualityHistogramExec { fn fmt_as(&self, _t: DisplayFormatType, _f: &mut Formatter) -> std::fmt::Result { Ok(()) } } -impl ExecutionPlan for BaseSequenceQualityExec { +impl ExecutionPlan for SequenceQualityHistogramExec { fn name(&self) -> &str { "BaseSequenceQualityExec" } - fn as_any(&self) -> &dyn std::any::Any { + fn as_any(&self) -> &dyn Any { self } @@ -118,7 +120,7 @@ impl ExecutionPlan for BaseSequenceQualityExec { } fn properties(&self) -> &PlanProperties { - &self.cache + &self.properties } fn children(&self) -> Vec<&Arc> { @@ -138,10 +140,10 @@ impl ExecutionPlan for BaseSequenceQualityExec { context: Arc, ) -> Result { let fut = get_stream( - Arc::clone(&self.session), + self.session.clone(), self.table_name.clone(), self.column_name.clone(), - self.cache.partitioning.partition_count(), + self.properties.partitioning.partition_count(), partition, context, self.schema.clone(), @@ -161,23 +163,6 @@ fn decode_score(c: char) -> Option { } } -fn calc_stats(values: &mut Vec) -> (f64, f64, f64, f64, f64, f64) { - values.sort_unstable(); - let n = values.len(); - let average = values.iter().map(|&v| v as f64).sum::() / n as f64; - let median = if n % 2 == 0 { - (values[n / 2 - 1] as f64 + values[n / 2] as f64) / 2.0 - } else { - values[n / 2] as f64 - }; - let q1 = values[n / 4] as f64; - let q3 = values[(3 * n) / 4] as f64; - let iqr = q3 - q1; - let lower = q1 - 1.5 * iqr; - let upper = q3 + 1.5 * iqr; - (average, median, q1, q3, lower, upper) -} - async fn get_stream( session: Arc, table_name: String, @@ -187,61 +172,74 @@ async fn get_stream( context: Arc, new_schema: SchemaRef, ) -> Result { - let table_stream = session.table(table_name).await?; - let plan = table_stream.create_physical_plan().await?; + let df = session + .table(table_name.clone()) + .await? + .select(vec![col(&column_name)])?; + + let plan = df.create_physical_plan().await?; + let repartition_stream = RepartitionExec::try_new(plan, Partitioning::RoundRobinBatch(target_partitions))?; - let partition_stream = repartition_stream.execute(partition, context)?; - let new_schema_out = new_schema.clone(); - let iter = partition_stream.map(move |batch| match batch { - Ok(batch) => { - let index = match batch.schema().index_of(&column_name) { - Ok(idx) => idx, - Err(_) => { - return Err(DataFusionError::Internal(format!( - "Column '{}' not found in schema", - column_name - ))) - }, - }; - let col = batch.column(index); - - // Try to cast to StringArray if possible - let col = arrow::compute::cast(col, &DataType::Utf8) - .map_err(|e| DataFusionError::Internal(format!("Cast error: {e}")))?; - - let col = col - .as_any() - .downcast_ref::() - .ok_or_else(|| DataFusionError::Internal("Expected StringArray".into()))?; - - let mut positions = Vec::new(); - let mut scores = Vec::new(); - - for row in 0..col.len() { - if col.is_null(row) { - continue; - } - let s = col.value(row); - for (pos, byte) in s.bytes().enumerate() { - if let Some(score) = decode_score(byte as char) { - positions.push(pos as i64); - scores.push(score as i8); + + let mut partition_stream = repartition_stream.execute(partition, context)?; + + let mut pos_map: HashMap> = HashMap::new(); + + while let Some(batch_result) = partition_stream.next().await { + let batch = batch_result?; + let col = batch.column(0); // tylko jedna kolumna + + let col = arrow::compute::cast(col, &DataType::Utf8) + .map_err(|e| DataFusionError::Internal(format!("Cast error: {e}")))?; + + let col = col + .as_any() + .downcast_ref::() + .ok_or_else(|| DataFusionError::Internal("Expected StringArray".into()))?; + + for row in 0..col.len() { + if col.is_null(row) { + continue; + } + let s = col.value(row); + for (pos, byte) in s.bytes().enumerate() { + if let Some(score) = decode_score(byte as char) { + let entry = pos_map.entry(pos).or_insert_with(|| vec![0u64; 94]); + if (score as usize) < entry.len() { + entry[score as usize] += 1; } } } + } + } - let pos_array = Arc::new(arrow_array::Int64Array::from(positions)); - let score_array = Arc::new(arrow_array::Int8Array::from(scores)); - let new_batch = - RecordBatch::try_new(new_schema.clone(), vec![pos_array, score_array]).unwrap(); + let mut positions = Vec::new(); + let mut scores = Vec::new(); + let mut counts = Vec::new(); - Ok(new_batch) - }, - Err(e) => Err(e), - }); + for (pos, counts_vec) in pos_map { + for (score, &count) in counts_vec.iter().enumerate() { + if count > 0 { + positions.push(pos as u64); + scores.push(score as u8); + counts.push(count as u64); + } + } + } + let pos_array = Arc::new(arrow_array::UInt64Array::from(positions)); + let score_array = Arc::new(arrow_array::UInt8Array::from(scores)); + let count_array = Arc::new(arrow_array::UInt64Array::from(counts)); + let new_batch = RecordBatch::try_new( + new_schema.clone(), + vec![pos_array, score_array, count_array], + ) + .unwrap(); + + let iter = futures::stream::once(async move { Ok(new_batch) }); let adapted_stream = - RecordBatchStreamAdapter::new(new_schema_out, Box::pin(iter) as BoxStream<_>); + RecordBatchStreamAdapter::new(new_schema.clone(), Box::pin(iter) as BoxStream<_>); + Ok(Box::pin(adapted_stream)) }