sequenceTools 1.4.0.2 → 1.4.0.3
raw patch · 9 files changed
+96/−107 lines, 9 filesdep ~sequence-formats
Dependency ranges changed: sequence-formats
Files
- Changelog.md +2/−0
- README.md +4/−5
- sequenceTools.cabal +6/−6
- src-executables/genoStats.hs +3/−4
- src-executables/pileupCaller.hs +7/−8
- src-executables/vcf2eigenstrat.hs +8/−27
- src/SequenceTools/PileupCaller.hs +5/−35
- src/SequenceTools/Utils.hs +40/−2
- test/SequenceTools/PileupCallerSpec.hs +21/−20
Changelog.md view
@@ -11,3 +11,5 @@ V 1.4.0: Added single strand mode, and new triallelic treatment. V 1.4.0.1: Improved README, fixed output bug in genoStats.hs++V 1.4.0.3: Updated to new sequence-formats version, now including reading of genetic position from eigenstrat files.
README.md view
@@ -6,13 +6,12 @@ This repository contains some programs that I use for processing sequencing data. -# Installation+# Simple Installation of the main tools 1. Download stack (https://docs.haskellstack.org/en/stable/README/#how-to-install<Paste>).-2. Clone the repository using `git clone https://github.com/stschiff/sequenceTools.git; cd sequenceTools`.-3. Run `stack install` inside the sequenceTools directory. If everything goes as planned, you should end up having the executables defined in this package under `~/.local/bin`.-4. Add `~/.local/bin` to your PATH, for example by adding to your `~/.profile` or `~/.bash_profile` the line `PATH=$PATH:$HOME/.local/bin`. Run `source ~/.profile` or `source ~/.bash_profile`, respectively, to update your path.-5. Run `pileupCaller --version`. It should output `1.4.0`. You're all set.+2. Run `stack install sequenceTools --resolver nightly`. You should now have the executables from this package under `~/.local/bin`.+3. Add `~/.local/bin` to your PATH, for example by adding to your `~/.profile` or `~/.bash_profile` the line `PATH=$PATH:$HOME/.local/bin`. Run `source ~/.profile` or `source ~/.bash_profile`, respectively, to update your path.+4. Run `pileupCaller --version`. It should output `1.4.0`. You're all set. ## pileupCaller
sequenceTools.cabal view
@@ -1,6 +1,6 @@ cabal-version: >=1.10 name: sequenceTools-version: 1.4.0.2+version: 1.4.0.3 license: GPL-3 license-file: LICENSE maintainer: stephan.schiffels@mac.com@@ -26,7 +26,7 @@ base >=4.7 && <5, optparse-applicative >=0.14.3.0, random >=1.1,- sequence-formats >=1.4.0,+ sequence-formats >=1.4.1, bytestring >=0.10.8.2, vector >=0.12.0.3, pipes >=4.3.11@@ -39,7 +39,7 @@ build-depends: base >=4.12.0.0, sequenceTools -any,- sequence-formats >=1.4.0,+ sequence-formats >=1.4.1, optparse-applicative >=0.14.3.0, pipes >=4.3.11, rio >=0.1.11.0,@@ -59,7 +59,7 @@ base >=4.12.0.0, sequenceTools -any, pipes-ordered-zip >=1.1.0,- sequence-formats >=1.4.0,+ sequence-formats >=1.4.1, bytestring >=0.10.8.2, vector >=0.12.0.3, optparse-applicative >=0.14.3.0,@@ -72,7 +72,7 @@ default-language: Haskell2010 build-depends: base >=4.12.0.0,- sequence-formats >=1.4.0,+ sequence-formats >=1.4.1, sequenceTools -any, foldl >=1.4.5, bytestring >=0.10.8.2,@@ -95,7 +95,7 @@ base >=4.12.0.0, hspec >=2.7.1, sequenceTools -any,- sequence-formats >=1.4.0,+ sequence-formats >=1.4.1, vector >=0.12.0.3, bytestring >=0.10.8.2, pipes >=4.3.11
src-executables/genoStats.hs view
@@ -10,7 +10,6 @@ import Control.Foldl (purely, Fold(..)) import Control.Monad (forM_) import Control.Monad.IO.Class (MonadIO, liftIO)-import qualified Data.ByteString.Char8 as B import qualified Data.Vector as V import Lens.Family2 (view) import qualified Options.Applicative as OP@@ -80,7 +79,7 @@ (FreqSumHeader names nrHaps, fsProd) <- case fsFile of Nothing -> readFreqSumStdIn Just fn -> readFreqSumFile fn- let prod = for fsProd $ \(FreqSumEntry chrom _ _ _ _ counts) -> do+ let prod = for fsProd $ \(FreqSumEntry chrom _ _ _ _ _ counts) -> do let genotypes = V.fromList $ do (count', nrHap) <- zip counts nrHaps case count' of@@ -90,7 +89,7 @@ Nothing -> return Missing _ -> error "should not happen" yield $ InputEntry chrom genotypes- return (map B.unpack names, prod)+ return (names, prod) runWithEigenstrat :: (MonadSafe m) => FilePath -> FilePath -> FilePath -> m ([String], Producer InputEntry m ())@@ -138,7 +137,7 @@ forM_ (zip names reports) $ \(n, StatsReport mis ref alt het) -> do let total = mis + ref + alt + het misPerc = round $ (fromIntegral mis / fromIntegral total) * (100.0 :: Double) :: Int- liftIO . putStrLn $ printf "%s\t%s\t%d(%d%%)\t%d\t%d\t%d" (unChrom chrom) n mis misPerc ref alt het+ liftIO . putStrLn $ printf "%s\t%s\t%d(%d%%)\t%d\t%d\t%d" (show chrom) n mis misPerc ref alt het accumulateAllChromStats :: [String] -> Fold (Chrom, StatsReportAllSamples) (Chrom, StatsReportAllSamples)
src-executables/pileupCaller.hs view
@@ -4,11 +4,10 @@ EigenstratIndEntry(..), Sex(..), writeEigenstrat) import SequenceFormats.FreqSum(FreqSumEntry(..), printFreqSumStdOut, FreqSumHeader(..)) import SequenceFormats.Pileup (PileupRow(..), readPileupFromStdIn)-import SequenceTools.Utils (versionInfoOpt, versionInfoText)+import SequenceTools.Utils (versionInfoOpt, versionInfoText, freqSumToEigenstrat) import SequenceTools.PileupCaller (CallingMode(..), callGenotypeFromPileup, callToDosage,- freqSumToEigenstrat, filterTransitions, TransitionsMode(..), cleanSSdamageAllSamples)+ filterTransitions, TransitionsMode(..), cleanSSdamageAllSamples) -import qualified Data.ByteString.Char8 as B import Data.List.Split (splitOn) import qualified Data.Vector.Unboxed.Mutable as V import qualified Options.Applicative as OP@@ -223,12 +222,12 @@ let ret = Pipes.for jointProd $ \jointEntry -> case jointEntry of (Just esEntry, Nothing) -> do- let (EigenstratSnpEntry chr pos _ id_ ref alt) = esEntry+ let (EigenstratSnpEntry chr pos gpos id_ ref alt) = esEntry dosages = (replicate nrSamples Nothing) liftIO $ addOneSite readStats- yield $ FreqSumEntry chr pos (Just . B.unpack $ id_) ref alt dosages+ yield $ FreqSumEntry chr pos (Just id_) (Just gpos) ref alt dosages (Just esEntry, Just pRow) -> do- let (EigenstratSnpEntry chr pos _ id_ ref alt) = esEntry+ let (EigenstratSnpEntry chr pos gpos id_ ref alt) = esEntry (PileupRow _ _ _ rawPileupBasesPerSample rawStrandInfoPerSample) = pRow let cleanBasesPerSample = if singleStrandMode@@ -243,7 +242,7 @@ (map length cleanBasesPerSample) (map length congruentBasesPerSample) calls <- liftIO $ mapM (callGenotypeFromPileup mode minDepth) congruentBasesPerSample let genotypes = map (callToDosage ref alt) calls- yield (FreqSumEntry chr pos (Just . B.unpack $ id_) ref alt genotypes)+ yield (FreqSumEntry chr pos (Just id_) (Just gpos) ref alt genotypes) _ -> return () return (fst <$> ret) where@@ -274,7 +273,7 @@ MajorityCalling _ -> 1 :: Int RandomCalling -> 1 RandomDiploidCalling -> 2- let header' = FreqSumHeader (map B.pack sampleNames) [nrHaplotypes | _ <- sampleNames]+ let header' = FreqSumHeader sampleNames [nrHaplotypes | _ <- sampleNames] outProd = freqSumProducer >-> filterTransitions transitionsOnly lift . runEffect $ outProd >-> printFreqSumStdOut header'
src-executables/vcf2eigenstrat.hs view
@@ -3,12 +3,11 @@ import Pipes.OrderedZip (orderedZip) import SequenceFormats.VCF (readVCFfromStdIn, VCFheader(..), VCFentry(..), isBiallelicSnp, getDosages, vcfToFreqSumEntry)-import SequenceFormats.Eigenstrat (EigenstratSnpEntry(..), readEigenstratSnpFile, writeEigenstrat, - GenoLine, GenoEntry(..), Sex(..), EigenstratIndEntry(..))+import SequenceFormats.Eigenstrat (EigenstratSnpEntry(..), readEigenstratSnpFile, writeEigenstrat,+ Sex(..), EigenstratIndEntry(..)) import SequenceFormats.FreqSum (FreqSumEntry(..), freqSumEntryToText)-import SequenceFormats.Utils (Chrom(..)) -import SequenceTools.Utils (versionInfoText, versionInfoOpt)+import SequenceTools.Utils (versionInfoText, versionInfoOpt, freqSumToEigenstrat) import Control.Exception.Base (throwIO, AssertionFailed(..)) import Control.Monad (when)@@ -16,7 +15,6 @@ import qualified Data.ByteString.Char8 as B import Data.Monoid ((<>)) -- import Debug.Trace (trace)-import Data.Vector (fromList) import qualified Options.Applicative as OP import Pipes (Pipe, yield, (>->), runEffect, Producer, Pipe, for, cat) import qualified Pipes.Prelude as P@@ -65,7 +63,7 @@ Just snpPosFile -> return $ runJointly vcfBodyBiAllelic nrInds snpPosFile Nothing -> return $ runSimple vcfBodyBiAllelic- runEffect $ vcfProducer >-> eigenStratPipe >-> writeEigenstrat genoOut snpOut indOut indEntries+ runEffect $ vcfProducer >-> P.map (freqSumToEigenstrat False) >-> writeEigenstrat genoOut snpOut indOut indEntries runJointly :: (MonadIO m, MonadSafe m) => Producer VCFentry m r -> Int -> FilePath -> Producer FreqSumEntry m r runJointly vcfBody nrInds snpPosFile =@@ -78,10 +76,10 @@ processVcfWithSnpFile :: (MonadIO m) => Int -> Pipe (Maybe EigenstratSnpEntry, Maybe VCFentry) FreqSumEntry m r processVcfWithSnpFile nrInds = for cat $ \jointEntry -> do case jointEntry of- (Just (EigenstratSnpEntry snpChrom' snpPos' _ snpId' snpRef' snpAlt'), Nothing) -> do+ (Just (EigenstratSnpEntry snpChrom' snpPos' gpos snpId' snpRef' snpAlt'), Nothing) -> do let dosages = replicate nrInds Nothing- yield $ FreqSumEntry snpChrom' snpPos' (Just . B.unpack $ snpId') snpRef' snpAlt' dosages- (Just (EigenstratSnpEntry snpChrom' snpPos' _ snpId' snpRef' snpAlt'), Just vcfEntry) -> do+ yield $ FreqSumEntry snpChrom' snpPos' (Just snpId') (Just gpos) snpRef' snpAlt' dosages+ (Just (EigenstratSnpEntry snpChrom' snpPos' gpos snpId' snpRef' snpAlt'), Just vcfEntry) -> do dosages <- case getDosages vcfEntry of Right dos -> return dos Left err -> liftIO . throwIO $ AssertionFailed err@@ -95,7 +93,7 @@ then map flipDosages dosages else replicate nrInds Nothing _ -> replicate nrInds Nothing- yield $ FreqSumEntry snpChrom' snpPos' (Just . B.unpack $ snpId') snpRef' snpAlt' normalizedDosages+ yield $ FreqSumEntry snpChrom' snpPos' (Just snpId') (Just gpos) snpRef' snpAlt' normalizedDosages _ -> return () where flipDosages dos = case dos of@@ -111,20 +109,3 @@ liftIO . B.putStr . freqSumEntryToText $ e' yield e' Left err -> (liftIO . throwIO) (AssertionFailed err)--eigenStratPipe :: (MonadIO m) => Pipe FreqSumEntry (EigenstratSnpEntry, GenoLine) m r-eigenStratPipe = P.map vcfToEigenstrat- where- vcfToEigenstrat (FreqSumEntry chrom pos maybeSnpId ref alt dosages) =- let snpId' = case maybeSnpId of- Just i -> B.pack i- Nothing -> B.pack (unChrom chrom <> "_" <> show pos)- snpEntry = EigenstratSnpEntry chrom pos 0.0 snpId' ref alt- genoLine = fromList [dosageToCall d | d <- dosages]- in (snpEntry, genoLine)- dosageToCall d = case d of- Just 0 -> HomRef- Just 1 -> Het- Just 2 -> HomAlt- Nothing -> Missing- _ -> error ("unknown dosage " ++ show d)
src/SequenceTools/PileupCaller.hs view
@@ -1,17 +1,14 @@+{-# LANGUAGE OverloadedStrings #-} module SequenceTools.PileupCaller (callToDosage, Call(..), callGenotypeFromPileup, callMajorityAllele, findMajorityAlleles, callRandomAllele,- callRandomDiploid, dosageToEigenstratGeno, freqSumToEigenstrat, CallingMode(..),+ callRandomDiploid, CallingMode(..), TransitionsMode(..), filterTransitions, cleanSSdamageAllSamples) where -import SequenceFormats.Utils (Chrom(..)) import SequenceFormats.FreqSum (FreqSumEntry(..))-import SequenceFormats.Eigenstrat (EigenstratSnpEntry(..), GenoEntry(..), GenoLine) import SequenceFormats.Pileup (Strand(..)) import SequenceTools.Utils (sampleWithoutReplacement) -import qualified Data.ByteString.Char8 as B import Data.List (sortOn, group, sort)-import Data.Vector (fromList) import Pipes (Pipe, cat) import qualified Pipes.Prelude as P @@ -89,42 +86,15 @@ Just [a1, a2] -> return $ DiploidCall a1 a2 _ -> error "should not happen" --- |convert a freqSum entry to an eigenstrat SNP entry-freqSumToEigenstrat :: Bool -> FreqSumEntry -> (EigenstratSnpEntry, GenoLine)-freqSumToEigenstrat diploidizeCall (FreqSumEntry chrom@(Chrom c) pos maybeSnpId ref alt calls) =- let snpId_ = case maybeSnpId of - Just id_ -> B.pack id_- Nothing -> B.pack $ c <> "_" <> show pos- snpEntry = EigenstratSnpEntry chrom pos 0.0 snpId_ ref alt- geno = fromList . map (dosageToEigenstratGeno diploidizeCall) $ calls- in (snpEntry, geno)---- |convert a Dosage to an eigenstrat-encoded genotype-dosageToEigenstratGeno :: Bool -> Maybe Int -> GenoEntry-dosageToEigenstratGeno diploidizeCall c =- if diploidizeCall then- case c of- Just 0 -> HomRef- Just 1 -> HomAlt- Nothing -> Missing- _ -> error "illegal call for pseudo-haploid Calling method"- else- case c of- Just 0 -> HomRef- Just 1 -> Het- Just 2 -> HomAlt- Nothing -> Missing- _ -> error ("unknown genotype " ++ show c)- filterTransitions :: (Monad m) => TransitionsMode -> Pipe FreqSumEntry FreqSumEntry m () filterTransitions transversionsMode = case transversionsMode of SkipTransitions ->- P.filter (\(FreqSumEntry _ _ _ ref alt _) -> isTransversion ref alt)+ P.filter (\(FreqSumEntry _ _ _ _ ref alt _) -> isTransversion ref alt) TransitionsMissing ->- P.map (\(FreqSumEntry chrom pos id_ ref alt calls) ->+ P.map (\(FreqSumEntry chrom pos id_ gpos ref alt calls) -> let calls' = if isTransversion ref alt then calls else [Nothing | _ <- calls]- in FreqSumEntry chrom pos id_ ref alt calls')+ in FreqSumEntry chrom pos id_ gpos ref alt calls') _ -> cat where isTransversion ref alt = not $ isTransition ref alt
src/SequenceTools/Utils.hs view
@@ -1,8 +1,16 @@-module SequenceTools.Utils (versionInfoOpt, versionInfoText, sampleWithoutReplacement) where +{-# LANGUAGE OverloadedStrings #-}+module SequenceTools.Utils (versionInfoOpt, versionInfoText, sampleWithoutReplacement,+ freqSumToEigenstrat, dosageToEigenstratGeno) where -import Paths_sequenceTools (version)+import SequenceFormats.FreqSum (FreqSumEntry(..))+import SequenceFormats.Eigenstrat (EigenstratSnpEntry(..), GenoLine, GenoEntry(..))+import SequenceFormats.Utils (Chrom(..))++import qualified Data.ByteString.Char8 as B+import Data.Vector (fromList) import Data.Version (showVersion) import qualified Options.Applicative as OP+import Paths_sequenceTools (version) import System.Random (randomRIO) versionInfoOpt :: OP.Parser (a -> a)@@ -24,3 +32,33 @@ xs' = remove rn xs go (a:res) xs' (n - 1) remove i xs = let (ys, zs) = splitAt i xs in ys ++ tail zs++-- |convert a freqSum entry to an eigenstrat SNP entry+freqSumToEigenstrat :: Bool -> FreqSumEntry -> (EigenstratSnpEntry, GenoLine)+freqSumToEigenstrat diploidizeCall (FreqSumEntry chrom@(Chrom c) pos maybeSnpId maybeGeneticPos ref alt calls) =+ let snpId_ = case maybeSnpId of + Just id_ -> id_+ Nothing -> c <> "_" <> B.pack (show pos)+ geneticPos = case maybeGeneticPos of+ Just p -> p+ Nothing -> 0.0+ snpEntry = EigenstratSnpEntry chrom pos geneticPos snpId_ ref alt+ geno = fromList . map (dosageToEigenstratGeno diploidizeCall) $ calls+ in (snpEntry, geno)++-- |convert a Dosage to an eigenstrat-encoded genotype+dosageToEigenstratGeno :: Bool -> Maybe Int -> GenoEntry+dosageToEigenstratGeno diploidizeCall c =+ if diploidizeCall then+ case c of+ Just 0 -> HomRef+ Just 1 -> HomAlt+ Nothing -> Missing+ _ -> error "illegal call for pseudo-haploid Calling method"+ else+ case c of+ Just 0 -> HomRef+ Just 1 -> Het+ Just 2 -> HomAlt+ Nothing -> Missing+ _ -> error ("unknown genotype " ++ show c)
test/SequenceTools/PileupCallerSpec.hs view
@@ -1,13 +1,10 @@ {-# LANGUAGE OverloadedStrings #-} module SequenceTools.PileupCallerSpec (spec) where -import SequenceFormats.FreqSum (FreqSumEntry(..))-import SequenceFormats.Eigenstrat (GenoEntry(..), EigenstratSnpEntry(..))-import SequenceFormats.Utils (Chrom(..))-import SequenceFormats.Pileup (Strand(..))+import SequenceTools.Utils (dosageToEigenstratGeno, freqSumToEigenstrat) import SequenceTools.PileupCaller (callToDosage, Call(..), callGenotypeFromPileup, callMajorityAllele, findMajorityAlleles, callRandomAllele,- callRandomDiploid, dosageToEigenstratGeno, freqSumToEigenstrat, CallingMode(..),+ callRandomDiploid, CallingMode(..), TransitionsMode(..), filterTransitions, cleanSSdamageAllSamples) import Control.Monad (replicateM, forM_)@@ -16,6 +13,10 @@ import Data.Vector (fromList) import Pipes (each, (>->)) import qualified Pipes.Prelude as P+import SequenceFormats.FreqSum (FreqSumEntry(..))+import SequenceFormats.Eigenstrat (GenoEntry(..), EigenstratSnpEntry(..))+import SequenceFormats.Utils (Chrom(..))+import SequenceFormats.Pileup (Strand(..)) import Test.Hspec spec :: Spec@@ -129,7 +130,7 @@ testFreqSumToEigenstrat :: Spec testFreqSumToEigenstrat = describe "freqSumtoEigenstrat" $ do- let fs = FreqSumEntry (Chrom "1") 1000 Nothing 'A' 'C' [Just 0, Just 1, Just 1, Nothing, Just 0]+ let fs = FreqSumEntry (Chrom "1") 1000 Nothing Nothing 'A' 'C' [Just 0, Just 1, Just 1, Nothing, Just 0] let es = EigenstratSnpEntry (Chrom "1") 1000 0.0 (B.pack "1_1000") 'A' 'C' genoLine = fromList [HomRef, HomAlt, HomAlt, Missing, HomRef] it "should convert a freqSum example correctly to eigenstrat" $@@ -140,29 +141,29 @@ mockFreqSumData :: [FreqSumEntry] mockFreqSumData = [- FreqSumEntry (Chrom "1") 1000 (Just "rs1") 'A' 'C' [Just 1, Just 2, Nothing, Just 0, Just 0],- FreqSumEntry (Chrom "1") 2000 (Just "rs2") 'C' 'T' [Just 1, Just 2, Nothing, Just 0, Just 0],- FreqSumEntry (Chrom "1") 3000 (Just "rs3") 'A' 'G' [Just 1, Just 2, Nothing, Just 0, Just 0],- FreqSumEntry (Chrom "2") 1000 (Just "rs4") 'A' 'G' [Just 1, Just 2, Nothing, Just 0, Just 0],- FreqSumEntry (Chrom "2") 2000 (Just "rs5") 'T' 'A' [Just 1, Just 2, Nothing, Just 0, Just 0],- FreqSumEntry (Chrom "2") 3000 (Just "rs6") 'T' 'C' [Just 1, Just 2, Nothing, Just 0, Just 0]]+ FreqSumEntry (Chrom "1") 1000 (Just "rs1") Nothing 'A' 'C' [Just 1, Just 2, Nothing, Just 0, Just 0],+ FreqSumEntry (Chrom "1") 2000 (Just "rs2") Nothing 'C' 'T' [Just 1, Just 2, Nothing, Just 0, Just 0],+ FreqSumEntry (Chrom "1") 3000 (Just "rs3") Nothing 'A' 'G' [Just 1, Just 2, Nothing, Just 0, Just 0],+ FreqSumEntry (Chrom "2") 1000 (Just "rs4") Nothing 'A' 'G' [Just 1, Just 2, Nothing, Just 0, Just 0],+ FreqSumEntry (Chrom "2") 2000 (Just "rs5") Nothing 'T' 'A' [Just 1, Just 2, Nothing, Just 0, Just 0],+ FreqSumEntry (Chrom "2") 3000 (Just "rs6") Nothing 'T' 'C' [Just 1, Just 2, Nothing, Just 0, Just 0]] testFilterTransitions :: Spec testFilterTransitions = describe "filterTransitions" $ do it "should remove transitions with SkipTransitions" $ do let r = P.toList $ each mockFreqSumData >-> filterTransitions SkipTransitions r `shouldBe` [- FreqSumEntry (Chrom "1") 1000 (Just "rs1") 'A' 'C' [Just 1, Just 2, Nothing, Just 0, Just 0],- FreqSumEntry (Chrom "2") 2000 (Just "rs5") 'T' 'A' [Just 1, Just 2, Nothing, Just 0, Just 0]]+ FreqSumEntry (Chrom "1") 1000 (Just "rs1") Nothing 'A' 'C' [Just 1, Just 2, Nothing, Just 0, Just 0],+ FreqSumEntry (Chrom "2") 2000 (Just "rs5") Nothing 'T' 'A' [Just 1, Just 2, Nothing, Just 0, Just 0]] it "should mark transitions as missing with TransitionsMissing" $ do let r = P.toList $ each mockFreqSumData >-> filterTransitions TransitionsMissing r `shouldBe` [- FreqSumEntry (Chrom "1") 1000 (Just "rs1") 'A' 'C' [Just 1, Just 2, Nothing, Just 0, Just 0],- FreqSumEntry (Chrom "1") 2000 (Just "rs2") 'C' 'T' [Nothing, Nothing, Nothing, Nothing, Nothing],- FreqSumEntry (Chrom "1") 3000 (Just "rs3") 'A' 'G' [Nothing, Nothing, Nothing, Nothing, Nothing],- FreqSumEntry (Chrom "2") 1000 (Just "rs4") 'A' 'G' [Nothing, Nothing, Nothing, Nothing, Nothing],- FreqSumEntry (Chrom "2") 2000 (Just "rs5") 'T' 'A' [Just 1, Just 2, Nothing, Just 0, Just 0],- FreqSumEntry (Chrom "2") 3000 (Just "rs6") 'T' 'C' [Nothing, Nothing, Nothing, Nothing, Nothing]]+ FreqSumEntry (Chrom "1") 1000 (Just "rs1") Nothing 'A' 'C' [Just 1, Just 2, Nothing, Just 0, Just 0],+ FreqSumEntry (Chrom "1") 2000 (Just "rs2") Nothing 'C' 'T' [Nothing, Nothing, Nothing, Nothing, Nothing],+ FreqSumEntry (Chrom "1") 3000 (Just "rs3") Nothing 'A' 'G' [Nothing, Nothing, Nothing, Nothing, Nothing],+ FreqSumEntry (Chrom "2") 1000 (Just "rs4") Nothing 'A' 'G' [Nothing, Nothing, Nothing, Nothing, Nothing],+ FreqSumEntry (Chrom "2") 2000 (Just "rs5") Nothing 'T' 'A' [Just 1, Just 2, Nothing, Just 0, Just 0],+ FreqSumEntry (Chrom "2") 3000 (Just "rs6") Nothing 'T' 'C' [Nothing, Nothing, Nothing, Nothing, Nothing]] it "should output all sites with AllSites" $ do let r = P.toList $ each mockFreqSumData >-> filterTransitions AllSites r `shouldBe` mockFreqSumData