bioinformatics-toolkit 0.6.0 → 0.7.0
raw patch · 11 files changed
+373/−139 lines, 11 files
Files
- bioinformatics-toolkit.cabal +4/−1
- src/Bio/Data/Bed.hs +38/−44
- src/Bio/Data/Bed/Utils.hs +23/−60
- src/Bio/Data/Fastq.hs +36/−5
- src/Bio/RealWorld/GENCODE.hs +36/−20
- src/Bio/Utils/BitVector.hs +1/−1
- tests/Tests/Bam.hs +1/−1
- tests/Tests/Bed.hs +7/−7
- tests/Tests/Fastq.hs +25/−0
- tests/data/test.fastq +200/−0
- tests/test.hs +2/−0
bioinformatics-toolkit.cabal view
@@ -1,5 +1,5 @@ name: bioinformatics-toolkit-version: 0.6.0+version: 0.7.0 synopsis: A collection of bioinformatics tools description: A collection of bioinformatics tools license: MIT@@ -21,6 +21,8 @@ tests/data/example_intersect_peaks.bed tests/data/motifs.fasta tests/data/motifs.meme+ tests/data/test.fastq+ library hs-source-dirs: src ghc-options: -Wall@@ -114,6 +116,7 @@ other-modules: Tests.Bed , Tests.Bam+ , Tests.Fastq , Tests.Motif , Tests.Seq , Tests.Tools
src/Bio/Data/Bed.hs view
@@ -36,14 +36,15 @@ , mergeSortedBed , mergeSortedBedWith , splitOverlapped- , hReadBed- , hReadBed'++ -- * IO+ , streamBed+ , streamBedGzip , readBed- , readBed'- , hWriteBed- , hWriteBed'+ , sinkFileBed+ , sinkFileBedGzip+ , sinkHandleBed , writeBed- , writeBed' , compareBed ) where@@ -59,6 +60,7 @@ import qualified Data.IntervalMap.Strict as IM import Data.List (groupBy, sortBy) import Data.Ord (comparing)+import Data.Conduit.Zlib (gzip, ungzip, multiple) import qualified Data.Vector as V import qualified Data.Vector.Algorithms.Intro as I import System.IO@@ -252,50 +254,42 @@ chr = head xs ^. chrom {-# INLINE splitOverlapped #-} --- | Read records from a bed file handler in a streaming fashion.-hReadBed :: (BEDConvert b, MonadIO m) => Handle -> ConduitT i b m ()-hReadBed h = do eof <- liftIO $ hIsEOF h- unless eof $ do- line <- liftIO $ B.hGetLine h- yield $ fromLine line- hReadBed h-{-# INLINE hReadBed #-} --- | Non-streaming version.-hReadBed' :: (BEDConvert b, MonadIO m) => Handle -> m [b]-hReadBed' h = runConduit $ hReadBed h .| sinkList-{-# INLINE hReadBed' #-}+streamBed :: (MonadResource m, BEDConvert b, MonadIO m)+ => FilePath -> ConduitT i b m () +streamBed input = sourceFile input .| bsToBed+{-# INLINE streamBed #-} --- | Read records from a bed file in a streaming fashion.-readBed :: (BEDConvert b, MonadIO m) => FilePath -> ConduitT i b m ()-readBed fl = do handle <- liftIO $ openFile fl ReadMode- hReadBed handle- liftIO $ hClose handle+streamBedGzip :: (BEDConvert b, MonadResource m, MonadThrow m, PrimMonad m)+ => FilePath -> ConduitT i b m () +streamBedGzip input = sourceFile input .| multiple ungzip .| bsToBed+{-# INLINE streamBedGzip #-}++readBed :: BEDConvert b => FilePath -> IO [b]+readBed fl = runResourceT $ runConduit $ streamBed fl .| sinkList {-# INLINE readBed #-} --- | Non-streaming version.-readBed' :: (BEDConvert b, MonadIO m) => FilePath -> m [b]-readBed' fl = runConduit $ readBed fl .| sinkList-{-# INLINE readBed' #-}+sinkFileBed :: (BEDConvert b, MonadResource m) => FilePath -> ConduitT b o m ()+sinkFileBed output = bedToBS .| sinkFile output+{-# INLINE sinkFileBed #-} -hWriteBed :: (BEDConvert b, MonadIO m) => Handle -> ConduitT b o m ()-hWriteBed handle = do- x <- await- case x of- Nothing -> return ()- Just bed -> (liftIO . B.hPutStrLn handle . toLine) bed >> hWriteBed handle-{-# INLINE hWriteBed #-}+sinkFileBedGzip :: (BEDConvert b, MonadResource m, MonadThrow m, PrimMonad m)+ => FilePath -> ConduitT b o m ()+sinkFileBedGzip output = bedToBS .| gzip .| sinkFile output+{-# INLINE sinkFileBedGzip #-} -hWriteBed' :: (BEDConvert b, MonadIO m) => Handle -> [b] -> m ()-hWriteBed' handle beds = runConduit $ yieldMany beds .| hWriteBed handle-{-# INLINE hWriteBed' #-}+sinkHandleBed :: (BEDConvert b, MonadIO m) => Handle -> ConduitT b o m ()+sinkHandleBed hdl = bedToBS .| sinkHandle hdl+{-# INLINE sinkHandleBed #-} -writeBed :: (BEDConvert b, MonadIO m) => FilePath -> ConduitT b o m ()-writeBed fl = do handle <- liftIO $ openFile fl WriteMode- hWriteBed handle- liftIO $ hClose handle+writeBed :: BEDConvert b => FilePath -> [b] -> IO ()+writeBed fl beds = runResourceT $ runConduit $ yieldMany beds .| sinkFileBed fl {-# INLINE writeBed #-} -writeBed' :: (BEDConvert b, MonadIO m) => FilePath -> [b] -> m ()-writeBed' fl beds = runConduit $ yieldMany beds .| writeBed fl-{-# INLINE writeBed' #-}+bedToBS :: (BEDConvert b, Monad m) => ConduitT b B.ByteString m ()+bedToBS = mapC toLine .| unlinesAsciiC+{-# INLINE bedToBS #-}++bsToBed :: (BEDConvert b, Monad m) => ConduitT B.ByteString b m ()+bsToBed = linesUnboundedAsciiC .| mapC fromLine+{-# INLINE bsToBed #-}
src/Bio/Data/Bed/Utils.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE BangPatterns #-} module Bio.Data.Bed.Utils@@ -34,6 +35,7 @@ import qualified Data.Vector.Generic as G import qualified Data.Vector.Generic.Mutable as GM import qualified Data.Vector.Unboxed as U+import System.IO import Bio.Data.Bed import Bio.Data.Bed.Types@@ -68,7 +70,9 @@ motifScan g motifs bg p = awaitForever $ \bed -> do r <- liftIO $ getSeq g (bed^.chrom, bed^.chromStart, bed^.chromEnd) case r of- Left _ -> return ()+ Left _ -> liftIO $ hPutStrLn stderr $+ "Warning: no sequence for region: " ++ show + (bed^.chrom, bed^.chromStart, bed^.chromEnd) Right dna -> mapM_ (getTFBS dna (bed^.chrom, bed^.chromStart)) motifs' where getTFBS dna (chr, s) (nm, (pwm, cutoff), (pwm', cutoff')) = toProducer@@ -223,36 +227,29 @@ -> [b] -- ^ regions -> ConduitT BED o m ([v a], Int) countTagsBinBed k beds = do- initRC <- lift $ forM beds $ \bed -> do+ vs <- lift $ fmap V.fromList $ forM beds $ \bed -> do let start = bed^.chromStart- end = bed^.chromEnd- num = (end - start) `div` k+ num = ((bed^.chromEnd) - start) `div` k index i = (i - start) `div` k v <- GM.replicate num 0 return (v, index)-- sink 0 $ V.fromList initRC+ nTags <- foldMC (f vs) 0+ rc <- lift $ mapM (G.unsafeFreeze . fst) $ G.toList vs+ return (rc, nTags) where- sink !nTags vs = do- tag <- await- case tag of- Just bed -> do- let p | bed^.strand == Just True = bed^.chromStart- | bed^.strand == Just False = bed^.chromEnd - 1- | otherwise = error "profiling: unkown strand"- overlaps = concat $ IM.elems $- IM.containing (M.lookupDefault IM.empty (bed^.chrom) intervalMap) p- lift $ forM_ overlaps $ \x -> do- let (v, idxFn) = vs `G.unsafeIndex` x- i = let i' = idxFn p- l = GM.length v- in if i' >= l then l - 1 else i'- GM.unsafeRead v i >>= GM.unsafeWrite v i . (+1)- sink (nTags+1) vs-- _ -> do rc <- lift $ mapM (G.unsafeFreeze . fst) $ G.toList vs- return (rc, nTags)-+ f vs n bed = do+ let pos | bed^.strand == Just True = bed^.chromStart+ | bed^.strand == Just False = bed^.chromEnd - 1+ | otherwise = error "unkown strand."+ overlaps = concat $ IM.elems $ IM.containing+ (M.lookupDefault IM.empty (bed^.chrom) intervalMap) pos+ forM_ overlaps $ \x -> do+ let (v, idxFn) = vs `G.unsafeIndex` x+ i = let i' = idxFn pos+ l = GM.length v+ in if i' >= l then l - 1 else i'+ GM.unsafeModify v (+1) i+ return $ n + 1 intervalMap = bedToTree (++) $ zip beds $ map return [0..] {-# INLINE countTagsBinBed #-} @@ -298,40 +295,6 @@ intervalMap = bedToTree (++) $ zip beds $ map return [0..] {-# INLINE countTagsBinBed' #-}---{---- | calculate RPKM using BAM file (*.bam) and its index file (*.bam.bai), using--- constant space-rpkmBam :: BEDLike b => FilePath -> Conduit b IO Double-rpkmBam fl = do- nTags <- lift $ readBam fl $$ foldMC (\acc bam -> return $- if isUnmap bam then acc else acc + 1) 0.0- handle <- lift $ BI.open fl- conduit nTags handle- where- conduit n h = do- x <- await- case x of- Nothing -> lift $ BI.close h- Just bed -> do let chr = chrom bed- s = chromStart bed- e = chromEnd bed- rc <- lift $ viewBam h (chr, s, e) $$ readCount s e- yield $ rc * 1e9 / n / fromIntegral (e-s)- conduit n h- readCount l u = foldMC f 0.0- where- f acc bam = do let p1 = fromIntegral . fromJust . position $ bam- rl = fromIntegral . fromJust . queryLength $ bam- p2 = p1 + rl - 1- return $ if isReverse bam- then if l <= p2 && p2 < u then acc + 1- else acc- else if l <= p1 && p1 < u then acc + 1- else acc-{-# INLINE rpkmBam #-}--} tagCountDistr :: PrimMonad m => G.Vector v Int => ConduitT BED o m (v Int) tagCountDistr = loop M.empty
src/Bio/Data/Fastq.hs view
@@ -2,6 +2,10 @@ {-# LANGUAGE OverloadedStrings #-} module Bio.Data.Fastq ( Fastq(..)+ , streamFastqGzip+ , streamFastq+ , sinkFastqGzip+ , sinkFastq , parseFastqC , fastqToByteString , qualitySummary@@ -9,12 +13,14 @@ ) where import Conduit+import Data.Conduit.Zlib (ungzip, multiple, gzip) import Control.Monad (when) import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString as BS import Data.Maybe (isJust)-import Data.Attoparsec.ByteString+import qualified Data.Attoparsec.ByteString as A+import Data.Attoparsec.ByteString.Char8 import Data.Conduit.Attoparsec -- | A FASTQ file normally uses four lines per sequence.@@ -35,17 +41,42 @@ , fastqSeqQual :: B.ByteString } deriving (Show, Eq) +-- | Read gzipped fastq file.+streamFastqGzip :: (PrimMonad m, MonadThrow m, MonadResource m) + => FilePath -> ConduitT i Fastq m ()+streamFastqGzip fl = sourceFileBS fl .| multiple ungzip .| parseFastqC++streamFastq :: (MonadResource m, MonadThrow m)+ => FilePath -> ConduitT i Fastq m ()+streamFastq fl = sourceFileBS fl .| parseFastqC++sinkFastq :: (MonadResource m, MonadThrow m)+ => FilePath -> ConduitT Fastq o m ()+sinkFastq fl = mapC fastqToByteString .| unlinesAsciiC .| sinkFileBS fl++sinkFastqGzip :: (PrimMonad m, MonadThrow m, MonadResource m)+ => FilePath -> ConduitT Fastq o m ()+sinkFastqGzip fl = mapC fastqToByteString .| unlinesAsciiC .| gzip .| sinkFileBS fl+ parseFastqC :: MonadThrow m => ConduitT B.ByteString Fastq m () parseFastqC = conduitParser fastqParser .| mapC snd {-# INLINE parseFastqC #-} fastqParser :: Parser Fastq fastqParser = do- ident <- word8 64 *> takeTill (==10)- sequence <- BS.filter (/=10) <$> takeTill (==43)- skip (/=10)- score <- BS.filter (/=10) <$> takeTill (==64)+ _ <- skipWhile (/='@') >> char8 '@'+ ident <- A.takeTill isEndOfLine+ endOfLine+ sequence <- BS.filter (not . isEndOfLine) <$> takeTill (=='+')+ char8 '+' >> A.skipWhile (not . isEndOfLine) >> endOfLine+ score <- BS.filter (not . isEndOfLine) <$>+ A.scan 0 (f (B.length sequence))+ skipWhile (/='@') return $ Fastq ident sequence score+ where+ f n i x | i >= n = Nothing+ | isEndOfLine x = Just i+ | otherwise = Just $ i + 1 {-# INLINE fastqParser #-} fastqToByteString :: Fastq -> B.ByteString
src/Bio/RealWorld/GENCODE.hs view
@@ -1,16 +1,20 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE FlexibleContexts #-} module Bio.RealWorld.GENCODE ( Gene(..) , readGenes+ , streamElements ) where import Conduit import qualified Data.ByteString.Char8 as B import Data.CaseInsensitive (CI, mk) import qualified Data.HashMap.Strict as M+import Data.List.Ordered (nubSort) import Data.Maybe (fromJust) +import Bio.Data.Bed.Types import Bio.Utils.Misc (readInt) -- | GTF's position is 1-based, but here we convert it to 0-based indexing.@@ -21,35 +25,47 @@ , geneLeft :: !Int , geneRight :: !Int , geneStrand :: !Bool- , geneTranscripts :: [(Int, Int)]+ , geneTranscripts :: ![(Int, Int)]+ , geneExon :: ![(Int, Int)] } deriving (Show) -- | Read gene information from Gencode GTF file readGenes :: FilePath -> IO [Gene] readGenes input = do- (genes, transcripts) <- runResourceT $ runConduit $ sourceFile input .|- linesUnboundedAsciiC .| foldlC f (M.empty, M.empty)- return $ M.elems $ M.foldlWithKey'- (\m k v -> M.adjust (\g -> g{geneTranscripts=v}) k m)- genes transcripts+ (genes, transcripts, exon) <- runResourceT $ runConduit $ sourceFile input .|+ linesUnboundedAsciiC .| foldlC f (M.empty, M.empty, M.empty)+ return $ M.elems $ flip+ (M.foldlWithKey' (\m k v -> M.adjust (\g -> g{geneExon=nubSort v}) k m)) exon $+ flip (M.foldlWithKey' (\m k v -> M.adjust (\g -> g{geneTranscripts=nubSort v}) k m))+ transcripts genes where- f (genes, transcripts) l- | B.head l == '#' = (genes, transcripts)+ f (genes, transcripts, exon) l+ | B.head l == '#' = (genes, transcripts, exon) | f3 == "gene" =- let g = Gene (mk $ getField "gene_name") i f1 (readInt f4 - 1)- (readInt f5 - 1) (f7=="+") []- i = getField "gene_id"- in (M.insert i g genes, transcripts)- | f3 == "transcript" =- let t = (readInt f4 - 1, readInt f5 - 1)- i = getField "gene_id"- updateFn Nothing = Just [t]- updateFn (Just x) = Just $ t : x- in (genes, M.alter updateFn i transcripts)- | otherwise = (genes, transcripts)+ let g = Gene (mk $ getField "gene_name") gid f1 leftPos rightPos+ (f7=="+") [] []+ in (M.insert gid g genes, transcripts, exon)+ | f3 == "transcript" = (genes, update transcripts, exon)+ | f3 == "exon" = (genes, transcripts, update exon)+ | otherwise = (genes, transcripts, exon) where+ gid = getField "gene_id"+ leftPos = readInt f4 - 1+ rightPos = readInt f5 - 1+ update m = let updateFn Nothing = Just [(leftPos, rightPos)]+ updateFn (Just x) = Just $ (leftPos, rightPos) : x+ in M.alter updateFn gid m [f1,_,f3,f4,f5,_,f7,_,f9] = B.split '\t' l- fields = map (B.break (==' ') . strip) $ B.split ';' f9+ fields = map (B.break isSpace . strip) $ B.split ';' f9 getField x = B.init $ B.drop 2 $ fromJust $ lookup x fields strip = fst . B.spanEnd isSpace . B.dropWhile isSpace isSpace = (== ' ')++streamElements :: Monad m => ConduitT B.ByteString BED m ()+streamElements = linesUnboundedAsciiC .| concatMapC f+ where+ f l | B.head l == '#' = Nothing+ | otherwise = Just $ BED chr (readInt start - 1) (readInt end - 1)+ (Just name) Nothing (Just $ strand == "+")+ where+ [chr,_,name,start,end,_,strand,_,_] = B.split '\t' l
src/Bio/Utils/BitVector.hs view
@@ -1,5 +1,5 @@ module Bio.Utils.BitVector- ( BitVector+ ( BitVector(..) , BitMVector , size , (!)
tests/Tests/Bam.hs view
@@ -32,7 +32,7 @@ bamToBedTest :: Assertion bamToBedTest = do- bed <- readBed' "tests/data/example.bed"+ bed <- readBed "tests/data/example.bed" bed' <- do let input = "tests/data/example.bam" header <- getBamHeader input
tests/Tests/Bed.hs view
@@ -27,9 +27,9 @@ ] sortBedTest :: Assertion-sortBedTest = do beds <- readBed' "tests/data/peaks.bed" :: IO [BED]+sortBedTest = do beds <- readBed "tests/data/peaks.bed" :: IO [BED] let (Sorted actual) = sortBed beds- expect <- fmap V.fromList $ readBed' "tests/data/peaks.sorted.bed"+ expect <- fmap V.fromList $ readBed "tests/data/peaks.sorted.bed" expect @=? actual splitBedTest :: Assertion@@ -73,18 +73,18 @@ intersectBedTest :: Assertion intersectBedTest = do- expect <- readBed' "tests/data/example_intersect_peaks.bed" :: IO [BED3]- peaks <- readBed' "tests/data/peaks.bed" :: IO [BED3]- result <- runConduit $ readBed "tests/data/example.bed" .| intersectBed peaks .| sinkList+ expect <- readBed "tests/data/example_intersect_peaks.bed" :: IO [BED3]+ peaks <- readBed "tests/data/peaks.bed" :: IO [BED3]+ result <- runResourceT $ runConduit $ streamBed "tests/data/example.bed" .| intersectBed peaks .| sinkList expect @=? result baseMapTest :: Assertion baseMapTest = do- BaseMap bv <- runConduit $ readBed "tests/data/example.bed" .|+ BaseMap bv <- runResourceT $ runConduit $ streamBed "tests/data/example.bed" .| baseMap [("chr1", 300000000)] let res = M.lookupDefault undefined "chr1" $ fmap (map fst . filter snd . zip [0..] . toList) bv- expect <- runConduit $ readBed "tests/data/example.bed" .|+ expect <- runResourceT $ runConduit $ streamBed "tests/data/example.bed" .| concatMapC f .| sinkList sort expect @=? sort res where
+ tests/Tests/Fastq.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE OverloadedStrings #-}++module Tests.Fastq (tests) where++import Bio.Data.Fastq+import Control.Lens+import Conduit+import Test.Tasty+import Test.Tasty.Golden+import Test.Tasty.HUnit+import qualified Data.HashMap.Strict as M+import Data.Ord+import Data.Maybe++tests :: TestTree+tests = testGroup "Test: Bio.Data.Fastq"+ [ fastqIO+ ]++fastqIO :: TestTree+fastqIO = goldenVsFile "FASTQ Read/Write Test" input output io+ where+ io = runResourceT $ runConduit $ streamFastq input .| sinkFastq output+ input = "tests/data/test.fastq" + output = "out.fastq"
+ tests/data/test.fastq view
@@ -0,0 +1,200 @@+@M00436:256:000000000-B3PGP:1:1101:12997:1870 2:N:0:TAAGACGA+TTTTTCCCTCCTTTTCTCTTCTCCTCTTTTTTTTTTTTTTTTTTTTTTTTT+++111>1111B1111313A33A1B11B01BDAB0AA/AAAAA>E>>>E>EE<<+@M00436:256:000000000-B3PGP:1:1101:20142:2157 2:N:0:TAAGGCGA+CATTAGAGCCTGTTATTAATGATTGTAATGTATTTTCTGTATAATTTTACT+++11>>>13B1>>BBGFGBGGGGF3BBAGHFHHHHGG3FBFGHFHFGDFGFHG+@M00436:256:000000000-B3PGP:1:1101:15166:2177 2:N:0:TAAGGCGA+TGCCACGTGATTGCTGAGGCTGTAAGAACCACCCTGGGTCCCCGTGGCATG+++A11>>1>>1>FFCGGFGGGGGGHHG3BDFGH0FGCCGGGGHGHGFCCGFHH+@M00436:256:000000000-B3PGP:1:1101:16584:2188 2:N:0:TAAGGCGA+CTAGTAAGGCATTGTAAAAGTTACTGGATTTGGTTTAAAAAAAAAAAAAA+++>A11>BF11>CBAA3BGGG11BEGAE1FD1GD1000EGGGHCGGGGG?E@+@M00436:256:000000000-B3PGP:1:1101:15256:2192 2:N:0:TAAGGCGA+CTTTGGAACAACTATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+++1AA?11CFBFFABG3FGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG+@M00436:256:000000000-B3PGP:1:1101:18301:2193 2:N:0:TAAGGCGA+CACCTACAGAAGGAGCGCTGTGCCCCCTGGAGCTGACAAGAAAGCTGAGGC+++111>AFCC1DFFA1FG?FGAEGHHHGGGGABGGHHDG11000BFGHG1BFG+@M00436:256:000000000-B3PGP:1:1101:13721:2196 2:N:0:TAAGGCGA+TAGCCTGAGCGTTTAATTTATTCAGTACCTGTGTTTGTGTGAATGCGGTGT+++111>AFFBBFDAECG3FGDGGGHGGHFHBGHHHBBFFGFGFHBGHGGGEAA+@M00436:256:000000000-B3PGP:1:1101:14584:2200 2:N:0:TAAGGCGA+GCAAAAGGACCATTTAAAGTAAAAAAAAAAAAAAAAAAAAAAAATCTCTCC+++1>>1>BCAFFAAGFGG3FGG3FG3GG?ECGGGGGC?EGCEGGE@FH2B2BC+@M00436:256:000000000-B3PGP:1:1101:11335:2200 2:N:0:TAAGGCGA+CTGAATGCCATTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+++1AAAA33@11113BGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG+@M00436:256:000000000-B3PGP:1:1101:13303:2201 2:N:0:TAAGGCGA+TGCTTATACAATGTGAGTGTACTGAGGTAAGGGGAATATGGGAGCAGAGAC+++A3>A?FFF5BCFFDGGGFGGGGHHGHGCF5GHA?EGGFGHGFFEEG3FHCG+@M00436:256:000000000-B3PGP:1:1101:13286:2203 2:N:0:TAAGGCGA+TTCCCGAGACCGGCAGGCCTCAGCCCAAAAGAACAAAGGGAGAAAGAACTG+++1>111A>111>10AE00AA101110AGHH/0/00B0B00///A011B0011+@M00436:256:000000000-B3PGP:1:1101:11054:2203 2:N:0:TAAGGCGA+TTCGTACTCTGAGTTGATACCACTGCTTCCGCGGACAGGCGTGTAGCACTC+++1111>>1?DBF1BB31FFE3BA1B1E3BF1A0AEECAF////A/BA22BGC+@M00436:256:000000000-B3PGP:1:1101:15278:2204 2:N:0:TAAGGCGA+ACATAGTTCAGTATGAAAATAAGAGAATAAAATCTGTTATAAGCAAGTGAT+++111>1@DFDBFFFGGGGF1BFGF1E11BDHFCGFDHGHHHH3GFH0GAEHH+@M00436:256:000000000-B3PGP:1:1101:14285:2204 2:N:0:TAAGGCGA+AATGTGCGTATTGAGCACATTAAGCACTCTAAGAGCCGAGATAGCTTCCTG+++11>1AFBAAA1@D3GGGGGGGGG1GFFH0E1F31E0F?0AECBADDGGHHE+@M00436:256:000000000-B3PGP:1:1101:15307:2205 2:N:0:TAAGGCGA+TCTATAAGAAGGAGAAAGCTCGAGTCATCACTGAGGAAGAGAAGAATTTC+++AA3AAFDDBDCFAGECGFFGGGGGHCFHHGHBGHHGHHHHHGHHHHHHBG+@M00436:256:000000000-B3PGP:1:1101:17837:2208 2:N:0:TAAGGCGA+GCAGAGGTGAATGGGATTCAGACGGTACTAAAAAAAAAAAAAAAAAAAAA+++111>1A?1>FFFDCFGCEGGGGGCGEHEHFFHFFAEEGCEEGGGGGGGGG+@M00436:256:000000000-B3PGP:1:1101:14152:2208 2:N:0:TAAGGCGA+TCTATGCTCCCTCTGTGTTAGAATTGGCTGAAGTGTTTTTGTGCAGCTGAC+++AA>A1BD311>1A113331BFGH3311010BFE313300000A1E1FE1F0+@M00436:256:000000000-B3PGP:1:1101:17005:2214 2:N:0:TAAGGCGA+GTCTTGAGAGCTTCCTTTTGCTTTCTTCTCTTGCCTCTGAGAACATCAGCC+++1AAA>FFCA1A1B1EA3311B313A333313311B11B1F1FGCG1FH110+@M00436:256:000000000-B3PGP:1:1101:15244:2216 2:N:0:TAAGGCGA+GCCAAGAATGTGTTGTCTAAAATGCCTGTTTAGTTTTCAAGGATGGAACTC+++1>>AAAFFD@333B11B3BGGGFAAEA11B3GEAD333FHB1F1EFHH11A+@M00436:256:000000000-B3PGP:1:1101:12952:2217 2:N:0:TAAGGCGA+GAACTGGAGCGTGTGGCCAAGTCTAACCGCTGATTTCCCAGCTGCTGCCT+++111>AD1CFBDAEA11FFFGAAGFDFGF0EECE1GFHHFGFHHHFHHGFG+@M00436:256:000000000-B3PGP:1:1101:16915:2218 2:N:0:TAAGGCGA+ATGCACATGTGGTGTAGGAACTTTTTTCTACCATAAGTGACACCAATAAAT+++3>3AAFFFFD@BAFFDFGGGGGHHHHGHGHCHGHHHBFBGGFGGGFHGHHH+@M00436:256:000000000-B3PGP:1:1101:11613:2220 2:N:0:TAAGGCGA+TGTGTACTCTGCGTTGATACCACTGCTTCCGCGGACAGGCGTGTAGATCTC+++33>AADFFFFFFCGGGGFGGFCHHH4GFHFGDGGGCFFDGGEE1BFFHFH5+@M00436:256:000000000-B3PGP:1:1101:18615:2225 2:N:0:TAAGGCGA+CCTATCAGGAGTTCACTGACCACCTCGTCAAGACCCACACCAGAGTCTCCG+++>AAAAFFFFFB4FFGGFFGGGGHG4GDHGHGBGHBGHGGGGHGFEDGHHHG+@M00436:256:000000000-B3PGP:1:1101:11230:2227 2:N:0:TAAGGCGA+GTACTGTCACTTAACCCCTATTAACATACGGTGTTCAAGCCTTCCAGTATC+++?A?AAFFFBDFBFDFFGCGGGGCFHFBDHFG4FE2DFFGHDGBGFGHBGBF+@M00436:256:000000000-B3PGP:1:1101:14569:2228 2:N:0:TAAGGCGA+GTGAATGGAAATGCCCCAACTAAATACTACCGTATGGCCCACCATAATTAC+++3>AAAFFFBFFFGFGGFEFFGBGHGFHHHHHGGGGFGHHHGGGDH3GGHGH+@M00436:256:000000000-B3PGP:1:1101:15926:2228 2:N:0:TAAGGCGA+AATCTAGGAAAATAAAACAAGAGAAGCTGAATTAAAAAAAAAAAAAAAAA+++>AAA1FF1BDFFGGGGGFGG111B101ABGHDGGHHHHGGGGGGGGGGGG+@M00436:256:000000000-B3PGP:1:1101:15169:2228 2:N:0:TAAGGCGA+GTATCAACGAAAAGTGAGACTCATTGCTGCCCGCCGAAATGAACGGCTGCG+++1>A1AFF1>1>AGB11313A11B3331311000A00/A//11B10//////+@M00436:256:000000000-B3PGP:1:1101:15774:2230 2:N:0:TAAGGCGA+CCCAAAGACAAGGAAAGGAAAAAATAAAAACAACAAATACCTAAAAGCTG+++111>AFF11>C11111111BE0F0011D110000BGC1F1111BGGD011+@M00436:256:000000000-B3PGP:1:1101:11431:2230 2:N:0:TAAGGCGA+GAGCTGAACCTGTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+++111>A1DD1>>1BGGDGGGCEEEEGGGCGGGGGGCEGCEEGCGCGCCCCG+@M00436:256:000000000-B3PGP:1:1101:19030:2230 2:N:0:TAAGGCGA+ATCCCATTACTCTCTTTGTGGAGAAGGAACGAGATAAGGAAGTCAGTGATG+++1AAAAFFFFBBD3FFAFF3BEGGHHH00FG?EGGGGFFFHHG1FGHDGGHB+@M00436:256:000000000-B3PGP:1:1101:16869:2231 2:N:0:TAAGGCGA+CCTTCCACCTGGTCCGGAGATCCCTGGACCTTAGGAGGCACTCATTTTTCC+++AAAA1>@D111111A1110A01101100A001BA110A/BC0AG12AA10A+@M00436:256:000000000-B3PGP:1:1101:12374:2231 2:N:0:TAAGGCGA+CTTTAGATGGTGGGGACATCATCAATGCCTTGTGCTTCAGCCCCAACCGCT+++?AAAAFFFFBBDEEGGEGGGFGHHHG5FGGGHFEDGHHHHGHGGGEGG?EA+@M00436:256:000000000-B3PGP:1:1101:14609:2232 2:N:0:TAAGGCGA+TCCTCCTAAGTAACTGGGACTACATATGTGCATCACCACGTCCAGTTAATT+++3>>AAFFFFFFFFGGGFAAG4GG4FD5A66DGHBHH4DC22BFE3GH5EFG+@M00436:256:000000000-B3PGP:1:1101:11898:2233 2:N:0:TAAGGCGA+GTACTGTAGTCACTCAGTATTTGTATATGTTGCTAGAATTTAGATTGTAA+++1A1AAFFFFFFFGBGGGBEF3BF3FFGFFGGGHFBGGFFDGGFFFFHFGF+@M00436:256:000000000-B3PGP:1:1101:15215:2233 2:N:0:TAAGGCGA+GTAAAAGAGTATATGTAAACTGAATGAGAACTAAAAAATAGAAATAAAAC+++AA1AAFF113@33333BFF1311B3311DF11FGGHH00B11DG1FAGH1+@M00436:256:000000000-B3PGP:1:1101:18320:2233 2:N:0:TAAGGCGA+GCATTTAATATTGATACACTTTCACCTCTAAAATGGATTTGAAGAAATGC+++111>>DF3BBDFGGGGGG1FBGFFCHHHHGF3ADF1GGHFH2A1AB0BFG+@M00436:256:000000000-B3PGP:1:1101:13822:2234 2:N:0:TAAGGCGA+TCCACAAGTACTCTGGCAAGGAAGGAGACAAGCACACCCTGAGCAAGAAGG+++BA3ABFA?DFFFFDGGCGGGCGHFE4AGFHBCGFHGFE2EFFFBHHEHBEF+@M00436:256:000000000-B3PGP:1:1101:12165:2235 2:N:0:TAAGGCGA+ACCATGCTGTGTCTGTTATGCGGCAAAGCCGAAGATACTAACAGTATTCTC+++AA?A@1B11313A3133B311110AEH0000AE0E1F11F21B11D2222A+@M00436:256:000000000-B3PGP:1:1101:19900:2236 2:N:0:TAAGGCGA+CCATTTTAGTTCAGGAGTGTTTCCTTATTTTCTCTTTTCTGATAGAGTTT+++>>3>AFFFFFFFGGGGCGGABGHHHCFHHGGHHHHHHHHHHHHHGHFHHH+@M00436:256:000000000-B3PGP:1:1101:11136:2236 2:N:0:TAAGGCGA+GGAGAGGAGCGAGGCTGAGAGAAGAGAAGAACAATGTACTCATAAAGAAAC+++>111111B111110000A0B1AE0F0F101B00B112D2211112111B00+@M00436:256:000000000-B3PGP:1:1101:15661:2236 2:N:0:TAAGGCGA+GTGTTGCCCAGGCTGGTCTCAAACTCCTGGGCTCAAGCGATCCTCCCACCT+++>A>AABFFFFAAGGGFAFFFFGDEGECGF4FDFHFHHHGGEEEHGGG2FEG+@M00436:256:000000000-B3PGP:1:1101:20014:2238 2:N:0:TAAGGCGA+TGTGCATCACAGAGGTGTGCATCACCTTTGACCAGGCTGACCTGACCATC+++1111>B3311DDGCC1A1ABGFFHHB1BAGHHHHFEC0FF001FGBHFHH+@M00436:256:000000000-B3PGP:1:1101:13789:2238 2:N:0:TAAGGCGA+ACCCTGGACTCTGGACTTCGCAGGTTCCTGCCTGTCACGCCACCCCCTTCC+++>A1A11AFFFBF31FGGCGGGGGGCFFHGBGHGHHHHHGHGGGHGGEEGFH+@M00436:256:000000000-B3PGP:1:1101:11741:2240 2:N:0:TAAGGCGA+CTCCATCCGGCACCCTGACGTTGAGGTGGATGGGTTCTCTGAGCTTCGGTG+++1>1A1FDF11DDEECGGFG?FCGHC0B0AFEGCCGCAGBFGGGGGGFGGFE+@M00436:256:000000000-B3PGP:1:1101:19980:2240 2:N:0:TAAGGCGA+GATGTGCGCATTGACACCAGGCTCAACAAAGCTGTCTGGGCCAAAGGAAT+++11>1>DBA@AAAGGFFGFGFGGCGHHHHG0FGFHGGHF00/GE/GFFFFH+@M00436:256:000000000-B3PGP:1:1101:20675:2240 2:N:0:TAAGGCGA+GGGTCCCTCTGTACTCTGCGTTGATACCACTGCTTCCGCGGACAGGCGTGT+++333AAAFFFFFFGGGGGGCFFGGFGHFHHHHHHHGHHGGGGEFGGGGGEGE+@M00436:256:000000000-B3PGP:1:1101:14624:2241 2:N:0:TAAGGCGA+TACTTATAAGTCTATCATTTAAAGACATGTACTGAAACAAATGTATTTGTT+++A1>AAFFFBDDBG3EFGGGGB3FBGHHHFHHHHHFFGFB0BFGEBGGHHGH+@M00436:256:000000000-B3PGP:1:1101:11465:2241 2:N:0:TAAGGCGA+GCCTCACCGGTGACCAGCCTGGACTCGCATGGCAGCACCCAGGGCATGCTG+++333AACAFAD>DGGGGGFGGGGHHGHGGEGCHFBEGCHHGGHGG1FGFHHG+@M00436:256:000000000-B3PGP:1:1101:20263:2242 2:N:0:TAAGGCGA+GTGTGAATGGGTTTATACTGATTTTGATATCATGTTCTTTTCATAGTCGT+++111>ADDFFC?CCFGGGGGFFGFHHHGHHHCHHHHFHCHHHGHHHHHGFG+@M00436:256:000000000-B3PGP:1:1101:16263:2243 2:N:0:TAAGGCGA+GAACTATACTGACGAAGCCATTGAAACAGATGATCTGACCATTAAGCTGGT+++11>AAFFFFFDFGGGG?GGGGGGGFHHHHHGHHBGHGFBFGGFHGFHFF00
tests/test.hs view
@@ -1,6 +1,7 @@ import qualified Tests.Bed as Bed import qualified Tests.Bam as Bam import qualified Tests.Motif as Motif+import qualified Tests.Fastq as Fastq import qualified Tests.Seq as Seq import qualified Tests.Tools as Tools import Test.Tasty@@ -12,4 +13,5 @@ , Seq.tests , Motif.tests , Tools.tests+ , Fastq.tests ]