{-# LANGUAGE OverloadedStrings #-}

{-| A module to help with parsing VCF files. The VCF format is defined here:
<https://en.wikipedia.org/wiki/Variant_Call_Format>
-}

module SequenceFormats.VCF (VCFheader(..),
                     VCFentry(..),
                     readVCFfromStdIn,
                     readVCFfromFile,
                     readVCFfromProd,
                     getGenotypes,
                     getDosages,
                     isTransversionSnp,
                     vcfToFreqSumEntry,
                     isBiallelicSnp) where

import SequenceFormats.Utils (consumeProducer, Chrom(..),
    readFileProd, SeqFormatException(..), word)
import SequenceFormats.FreqSum (FreqSumEntry(..))

import Control.Applicative ((<|>))
import Control.Error (headErr, assertErr)
import Control.Monad (void)
import Control.Monad.Catch (MonadThrow, throwM)
import Control.Monad.Trans.State.Strict (runStateT)
import Control.Monad.IO.Class (MonadIO)
import qualified Data.Attoparsec.ByteString.Char8 as A
import Data.Char (isSpace)
import qualified Data.ByteString.Char8 as B
import Pipes (Producer)
import Pipes.Attoparsec (parse)
import Pipes.Safe (MonadSafe)
import qualified Pipes.ByteString as PB

-- |A datatype to represent the VCF Header. Most comments are simply parsed as entire lines, but the very last comment line, containing the sample names, is separated out
data VCFheader = VCFheader {
    VCFheader -> [String]
vcfHeaderComments :: [String], -- ^A list of containing all comments starting with a single '#'
    VCFheader -> [String]
vcfSampleNames :: [String] -- ^The list of sample names parsed from the last comment line 
                             -- starting with '##'
} deriving (Int -> VCFheader -> ShowS
[VCFheader] -> ShowS
VCFheader -> String
(Int -> VCFheader -> ShowS)
-> (VCFheader -> String)
-> ([VCFheader] -> ShowS)
-> Show VCFheader
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VCFheader] -> ShowS
$cshowList :: [VCFheader] -> ShowS
show :: VCFheader -> String
$cshow :: VCFheader -> String
showsPrec :: Int -> VCFheader -> ShowS
$cshowsPrec :: Int -> VCFheader -> ShowS
Show)

-- |A Datatype representing a single VCF entry.
data VCFentry = VCFentry {
    VCFentry -> Chrom
vcfChrom :: Chrom, -- ^The chromosome
    VCFentry -> Int
vcfPos :: Int, -- ^The position
    VCFentry -> Maybe ByteString
vcfId :: Maybe B.ByteString, -- ^The SNP ID if non-missing
    VCFentry -> ByteString
vcfRef :: B.ByteString, -- ^ The reference allele (supports also multi-character alleles for Indels)
    VCFentry -> [ByteString]
vcfAlt :: [B.ByteString], -- ^The alternative alleles, each one possible of multiple characters 
    VCFentry -> Double
vcfQual :: Double, -- ^The quality value
    VCFentry -> Maybe ByteString
vcfFilter :: Maybe B.ByteString, -- ^The Filter value, if non-missing.
    VCFentry -> [ByteString]
vcfInfo :: [B.ByteString], -- ^A list of Info fields
    VCFentry -> [ByteString]
vcfFormatString :: [B.ByteString], -- ^A list of format tags
    VCFentry -> [[ByteString]]
vcfGenotypeInfo :: [[B.ByteString]] -- ^A list of format fields for each sample.
} deriving (Int -> VCFentry -> ShowS
[VCFentry] -> ShowS
VCFentry -> String
(Int -> VCFentry -> ShowS)
-> (VCFentry -> String) -> ([VCFentry] -> ShowS) -> Show VCFentry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VCFentry] -> ShowS
$cshowList :: [VCFentry] -> ShowS
show :: VCFentry -> String
$cshow :: VCFentry -> String
showsPrec :: Int -> VCFentry -> ShowS
$cshowsPrec :: Int -> VCFentry -> ShowS
Show, VCFentry -> VCFentry -> Bool
(VCFentry -> VCFentry -> Bool)
-> (VCFentry -> VCFentry -> Bool) -> Eq VCFentry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VCFentry -> VCFentry -> Bool
$c/= :: VCFentry -> VCFentry -> Bool
== :: VCFentry -> VCFentry -> Bool
$c== :: VCFentry -> VCFentry -> Bool
Eq)

-- |reads a VCFheader and VCFentries from a text producer.
readVCFfromProd :: (MonadThrow m) =>
    Producer B.ByteString m () -> m (VCFheader, Producer VCFentry m ())
readVCFfromProd :: Producer ByteString m () -> m (VCFheader, Producer VCFentry m ())
readVCFfromProd Producer ByteString m ()
prod = do
    (Maybe (Either ParsingError VCFheader)
res, Producer ByteString m ()
rest) <- StateT
  (Producer ByteString m ())
  m
  (Maybe (Either ParsingError VCFheader))
-> Producer ByteString m ()
-> m (Maybe (Either ParsingError VCFheader),
      Producer ByteString m ())
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (Parser ByteString VCFheader
-> Parser ByteString m (Maybe (Either ParsingError VCFheader))
forall (m :: * -> *) a b.
(Monad m, ParserInput a) =>
Parser a b -> Parser a m (Maybe (Either ParsingError b))
parse Parser ByteString VCFheader
vcfHeaderParser) Producer ByteString m ()
prod
    VCFheader
header <- case Maybe (Either ParsingError VCFheader)
res of
        Maybe (Either ParsingError VCFheader)
Nothing -> SeqFormatException -> m VCFheader
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SeqFormatException -> m VCFheader)
-> SeqFormatException -> m VCFheader
forall a b. (a -> b) -> a -> b
$ String -> SeqFormatException
SeqFormatException String
"freqSum file exhausted"
        Just (Left ParsingError
e) -> SeqFormatException -> m VCFheader
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (String -> SeqFormatException
SeqFormatException (ParsingError -> String
forall a. Show a => a -> String
show ParsingError
e))
        Just (Right VCFheader
h) -> VCFheader -> m VCFheader
forall (m :: * -> *) a. Monad m => a -> m a
return VCFheader
h
    (VCFheader, Producer VCFentry m ())
-> m (VCFheader, Producer VCFentry m ())
forall (m :: * -> *) a. Monad m => a -> m a
return (VCFheader
header, Parser VCFentry
-> Producer ByteString m () -> Producer VCFentry m ()
forall (m :: * -> *) a.
MonadThrow m =>
Parser a -> Producer ByteString m () -> Producer a m ()
consumeProducer Parser VCFentry
vcfEntryParser Producer ByteString m ()
rest)

-- |Reading a VCF from StdIn. Returns a VCFHeader and a Producer over VCFentries.
readVCFfromStdIn :: (MonadIO m, MonadThrow m) => m (VCFheader, Producer VCFentry m ())
readVCFfromStdIn :: m (VCFheader, Producer VCFentry m ())
readVCFfromStdIn = Producer ByteString m () -> m (VCFheader, Producer VCFentry m ())
forall (m :: * -> *).
MonadThrow m =>
Producer ByteString m () -> m (VCFheader, Producer VCFentry m ())
readVCFfromProd Producer ByteString m ()
forall (m :: * -> *). MonadIO m => Producer' ByteString m ()
PB.stdin

-- |Reading a VCF from a file. Returns a VCFHeader and a Producer over VCFentries.
readVCFfromFile :: (MonadSafe m) => FilePath -> m (VCFheader, Producer VCFentry m ())
readVCFfromFile :: String -> m (VCFheader, Producer VCFentry m ())
readVCFfromFile = Producer ByteString m () -> m (VCFheader, Producer VCFentry m ())
forall (m :: * -> *).
MonadThrow m =>
Producer ByteString m () -> m (VCFheader, Producer VCFentry m ())
readVCFfromProd (Producer ByteString m () -> m (VCFheader, Producer VCFentry m ()))
-> (String -> Producer ByteString m ())
-> String
-> m (VCFheader, Producer VCFentry m ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Producer ByteString m ()
forall (m :: * -> *).
MonadSafe m =>
String -> Producer ByteString m ()
readFileProd

vcfHeaderParser :: A.Parser VCFheader
vcfHeaderParser :: Parser ByteString VCFheader
vcfHeaderParser = [String] -> [String] -> VCFheader
VCFheader ([String] -> [String] -> VCFheader)
-> Parser ByteString [String]
-> Parser ByteString ([String] -> VCFheader)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString String -> Parser ByteString [String]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
A.many1' Parser ByteString String
doubleCommentLine Parser ByteString ([String] -> VCFheader)
-> Parser ByteString [String] -> Parser ByteString VCFheader
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString [String]
singleCommentLine
  where
    doubleCommentLine :: Parser ByteString String
doubleCommentLine = do
        ByteString
c1 <- ByteString -> Parser ByteString
A.string ByteString
"##"
        ByteString
s_ <- (Char -> Bool) -> Parser ByteString
A.takeWhile1 (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=Char
'\n')
        Parser ()
A.endOfLine
        String -> Parser ByteString String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Parser ByteString String)
-> (ByteString -> String) -> ByteString -> Parser ByteString String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
B.unpack (ByteString -> Parser ByteString String)
-> ByteString -> Parser ByteString String
forall a b. (a -> b) -> a -> b
$ ByteString
c1 ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
s_
    singleCommentLine :: Parser ByteString [String]
singleCommentLine = do
        Parser ByteString Char -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser ByteString Char -> Parser ())
-> Parser ByteString Char -> Parser ()
forall a b. (a -> b) -> a -> b
$ Char -> Parser ByteString Char
A.char Char
'#'
        ByteString
s_ <- (Char -> Bool) -> Parser ByteString
A.takeWhile1 (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=Char
'\n')
        Parser ()
A.endOfLine
        let fields :: [ByteString]
fields = (Char -> Bool) -> ByteString -> [ByteString]
B.splitWith (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'\t') ByteString
s_
        [String] -> Parser ByteString [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> Parser ByteString [String])
-> ([ByteString] -> [String])
-> [ByteString]
-> Parser ByteString [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
drop Int
9 ([String] -> [String])
-> ([ByteString] -> [String]) -> [ByteString] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> String) -> [ByteString] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> String
B.unpack ([ByteString] -> Parser ByteString [String])
-> [ByteString] -> Parser ByteString [String]
forall a b. (a -> b) -> a -> b
$ [ByteString]
fields

vcfEntryParser :: A.Parser VCFentry
vcfEntryParser :: Parser VCFentry
vcfEntryParser = Parser VCFentry
vcfEntryParserFull Parser VCFentry -> Parser VCFentry -> Parser VCFentry
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser VCFentry
vcfEntryParserTruncated
  where
    vcfEntryParserFull :: Parser VCFentry
vcfEntryParserFull = Chrom
-> Int
-> Maybe ByteString
-> ByteString
-> [ByteString]
-> Double
-> Maybe ByteString
-> [ByteString]
-> [ByteString]
-> [[ByteString]]
-> VCFentry
VCFentry (Chrom
 -> Int
 -> Maybe ByteString
 -> ByteString
 -> [ByteString]
 -> Double
 -> Maybe ByteString
 -> [ByteString]
 -> [ByteString]
 -> [[ByteString]]
 -> VCFentry)
-> Parser ByteString Chrom
-> Parser
     ByteString
     (Int
      -> Maybe ByteString
      -> ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ByteString -> Chrom
Chrom (ByteString -> Chrom)
-> Parser ByteString -> Parser ByteString Chrom
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString
word) Parser
  ByteString
  (Int
   -> Maybe ByteString
   -> ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (Int
      -> Maybe ByteString
      -> ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  (Int
   -> Maybe ByteString
   -> ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Int
-> Parser
     ByteString
     (Maybe ByteString
      -> ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString Int
forall a. Integral a => Parser a
A.decimal Parser
  ByteString
  (Maybe ByteString
   -> ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (Maybe ByteString
      -> ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  (Maybe ByteString
   -> ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString (Maybe ByteString)
-> Parser
     ByteString
     (ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString (Maybe ByteString)
parseId Parser
  ByteString
  (ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*
        Parser ByteString Char
sp Parser
  ByteString
  (ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString
-> Parser
     ByteString
     ([ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString
word Parser
  ByteString
  ([ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     ([ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  ([ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString [ByteString]
-> Parser
     ByteString
     (Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString [ByteString]
parseAlternativeAlleles Parser
  ByteString
  (Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  (Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Double
-> Parser
     ByteString
     (Maybe ByteString
      -> [ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString Double
A.double Parser
  ByteString
  (Maybe ByteString
   -> [ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (Maybe ByteString
      -> [ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  (Maybe ByteString
   -> [ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString (Maybe ByteString)
-> Parser
     ByteString
     ([ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString (Maybe ByteString)
parseFilter Parser
  ByteString
  ([ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     ([ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* 
        Parser ByteString Char
sp Parser
  ByteString
  ([ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString [ByteString]
-> Parser ByteString ([ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString [ByteString]
parseInfoFields Parser ByteString ([ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString Char
-> Parser ByteString ([ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser ByteString ([ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString [ByteString]
-> Parser ByteString ([[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString [ByteString]
parseFormatStrings Parser ByteString ([[ByteString]] -> VCFentry)
-> Parser ByteString Char
-> Parser ByteString ([[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser ByteString ([[ByteString]] -> VCFentry)
-> Parser ByteString [[ByteString]] -> Parser VCFentry
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString [[ByteString]]
parseGenotypeInfos Parser VCFentry -> Parser () -> Parser VCFentry
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* 
        Parser ()
A.endOfLine
    vcfEntryParserTruncated :: Parser VCFentry
vcfEntryParserTruncated = Chrom
-> Int
-> Maybe ByteString
-> ByteString
-> [ByteString]
-> Double
-> Maybe ByteString
-> [ByteString]
-> [ByteString]
-> [[ByteString]]
-> VCFentry
VCFentry (Chrom
 -> Int
 -> Maybe ByteString
 -> ByteString
 -> [ByteString]
 -> Double
 -> Maybe ByteString
 -> [ByteString]
 -> [ByteString]
 -> [[ByteString]]
 -> VCFentry)
-> Parser ByteString Chrom
-> Parser
     ByteString
     (Int
      -> Maybe ByteString
      -> ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ByteString -> Chrom
Chrom (ByteString -> Chrom)
-> Parser ByteString -> Parser ByteString Chrom
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString
word) Parser
  ByteString
  (Int
   -> Maybe ByteString
   -> ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (Int
      -> Maybe ByteString
      -> ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  (Int
   -> Maybe ByteString
   -> ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Int
-> Parser
     ByteString
     (Maybe ByteString
      -> ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString Int
forall a. Integral a => Parser a
A.decimal Parser
  ByteString
  (Maybe ByteString
   -> ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (Maybe ByteString
      -> ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  (Maybe ByteString
   -> ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString (Maybe ByteString)
-> Parser
     ByteString
     (ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString (Maybe ByteString)
parseId Parser
  ByteString
  (ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (ByteString
      -> [ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*
        Parser ByteString Char
sp Parser
  ByteString
  (ByteString
   -> [ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString
-> Parser
     ByteString
     ([ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString
word Parser
  ByteString
  ([ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     ([ByteString]
      -> Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  ([ByteString]
   -> Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString [ByteString]
-> Parser
     ByteString
     (Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString [ByteString]
parseAlternativeAlleles Parser
  ByteString
  (Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (Double
      -> Maybe ByteString
      -> [ByteString]
      -> [ByteString]
      -> [[ByteString]]
      -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  (Double
   -> Maybe ByteString
   -> [ByteString]
   -> [ByteString]
   -> [[ByteString]]
   -> VCFentry)
-> Parser ByteString Double
-> Parser
     ByteString
     (Maybe ByteString
      -> [ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString Double
A.double Parser
  ByteString
  (Maybe ByteString
   -> [ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     (Maybe ByteString
      -> [ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
sp Parser
  ByteString
  (Maybe ByteString
   -> [ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString (Maybe ByteString)
-> Parser
     ByteString
     ([ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString (Maybe ByteString)
parseFilter Parser
  ByteString
  ([ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString Char
-> Parser
     ByteString
     ([ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*
        Parser ByteString Char
sp Parser
  ByteString
  ([ByteString] -> [ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString [ByteString]
-> Parser ByteString ([ByteString] -> [[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString [ByteString]
parseInfoFields Parser ByteString ([ByteString] -> [[ByteString]] -> VCFentry)
-> Parser ByteString [ByteString]
-> Parser ByteString ([[ByteString]] -> VCFentry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [ByteString] -> Parser ByteString [ByteString]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [] Parser ByteString ([[ByteString]] -> VCFentry)
-> Parser ByteString [[ByteString]] -> Parser VCFentry
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [[ByteString]] -> Parser ByteString [[ByteString]]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [] Parser VCFentry -> Parser () -> Parser VCFentry
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
A.endOfLine
    sp :: Parser ByteString Char
sp = (Char -> Bool) -> Parser ByteString Char
A.satisfy (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\t')
    parseId :: Parser ByteString (Maybe ByteString)
parseId = (Parser ByteString Char
parseDot Parser ByteString Char
-> Parser ByteString (Maybe ByteString)
-> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Maybe ByteString -> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe ByteString
forall a. Maybe a
Nothing) Parser ByteString (Maybe ByteString)
-> Parser ByteString (Maybe ByteString)
-> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> Parser ByteString -> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString
word)
    parseDot :: Parser ByteString Char
parseDot = Char -> Parser ByteString Char
A.char Char
'.'
    parseAlternativeAlleles :: Parser ByteString [ByteString]
parseAlternativeAlleles = (Parser ByteString Char
parseDot Parser ByteString Char
-> Parser ByteString [ByteString] -> Parser ByteString [ByteString]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [ByteString] -> Parser ByteString [ByteString]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []) Parser ByteString [ByteString]
-> Parser ByteString [ByteString] -> Parser ByteString [ByteString]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser ByteString
parseAllele Parser ByteString
-> Parser ByteString Char -> Parser ByteString [ByteString]
forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`A.sepBy1` Char -> Parser ByteString Char
A.char Char
',')
    parseAllele :: Parser ByteString
parseAllele = (Char -> Bool) -> Parser ByteString
A.takeTill (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
',' Bool -> Bool -> Bool
|| Char -> Bool
isSpace Char
c)
    parseFilter :: Parser ByteString (Maybe ByteString)
parseFilter = (Parser ByteString Char
parseDot Parser ByteString Char
-> Parser ByteString (Maybe ByteString)
-> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Maybe ByteString -> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe ByteString
forall a. Maybe a
Nothing) Parser ByteString (Maybe ByteString)
-> Parser ByteString (Maybe ByteString)
-> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> Parser ByteString -> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString
word)
    parseInfoFields :: Parser ByteString [ByteString]
parseInfoFields = (Parser ByteString Char
parseDot Parser ByteString Char
-> Parser ByteString [ByteString] -> Parser ByteString [ByteString]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [ByteString] -> Parser ByteString [ByteString]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []) Parser ByteString [ByteString]
-> Parser ByteString [ByteString] -> Parser ByteString [ByteString]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser ByteString
parseInfoField Parser ByteString
-> Parser ByteString Char -> Parser ByteString [ByteString]
forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`A.sepBy1` Char -> Parser ByteString Char
A.char Char
';')
    parseInfoField :: Parser ByteString
parseInfoField = (Char -> Bool) -> Parser ByteString
A.takeTill (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
';' Bool -> Bool -> Bool
|| Char -> Bool
isSpace Char
c)
    parseFormatStrings :: Parser ByteString [ByteString]
parseFormatStrings = Parser ByteString
parseFormatString Parser ByteString
-> Parser ByteString Char -> Parser ByteString [ByteString]
forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`A.sepBy1` Char -> Parser ByteString Char
A.char Char
':'
    parseFormatString :: Parser ByteString
parseFormatString = (Char -> Bool) -> Parser ByteString
A.takeTill (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':' Bool -> Bool -> Bool
|| Char -> Bool
isSpace Char
c)
    parseGenotypeInfos :: Parser ByteString [[ByteString]]
parseGenotypeInfos = Parser ByteString [ByteString]
parseGenotype Parser ByteString [ByteString]
-> Parser ByteString Char -> Parser ByteString [[ByteString]]
forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`A.sepBy1` Parser ByteString Char
sp
    parseGenotype :: Parser ByteString [ByteString]
parseGenotype = Parser ByteString
parseGenoField Parser ByteString
-> Parser ByteString Char -> Parser ByteString [ByteString]
forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
`A.sepBy1` Char -> Parser ByteString Char
A.char Char
':'
    parseGenoField :: Parser ByteString
parseGenoField = (Char -> Bool) -> Parser ByteString
A.takeTill (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':' Bool -> Bool -> Bool
|| Char -> Bool
isSpace Char
c) 

-- |returns True if the SNP is biallelic.
isBiallelicSnp :: B.ByteString -> [B.ByteString] -> Bool
isBiallelicSnp :: ByteString -> [ByteString] -> Bool
isBiallelicSnp ByteString
ref [ByteString]
alt = Bool
validRef Bool -> Bool -> Bool
&& Bool
validAlt
  where
    validRef :: Bool
validRef = (ByteString
ref ByteString -> [ByteString] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ByteString
"A", ByteString
"C", ByteString
"G", ByteString
"T"])
    validAlt :: Bool
validAlt = case [ByteString]
alt of
        [ByteString
alt'] -> ByteString
alt' ByteString -> [ByteString] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ByteString
"A", ByteString
"C", ByteString
"G", ByteString
"T"]
        [ByteString]
_ -> Bool
False

-- |returns True if the SNp is a biallelic Transversion SNP (i.e. one of G/T, G/C, A/T, A/C)
isTransversionSnp :: B.ByteString -> [B.ByteString] -> Bool
isTransversionSnp :: ByteString -> [ByteString] -> Bool
isTransversionSnp ByteString
ref [ByteString]
alt =
    case [ByteString]
alt of
        [ByteString
alt'] -> ByteString -> [ByteString] -> Bool
isBiallelicSnp ByteString
ref [ByteString]
alt Bool -> Bool -> Bool
&& (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> Bool
forall a a. (Eq a, Eq a, IsString a, IsString a) => a -> a -> Bool
isTransition ByteString
ref ByteString
alt')
        [ByteString]
_ -> Bool
False
  where
    isTransition :: a -> a -> Bool
isTransition a
r a
a = ((a
r a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"A") Bool -> Bool -> Bool
&& (a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"G")) Bool -> Bool -> Bool
|| ((a
r a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"G") Bool -> Bool -> Bool
&& (a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"A")) Bool -> Bool -> Bool
||
                       ((a
r a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"C") Bool -> Bool -> Bool
&& (a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"T")) Bool -> Bool -> Bool
|| ((a
r a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"T") Bool -> Bool -> Bool
&& (a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"C"))

-- |Extracts the genotype fields (for each sapmle) from a VCF entry
getGenotypes :: VCFentry -> Either String [B.ByteString]
getGenotypes :: VCFentry -> Either String [ByteString]
getGenotypes VCFentry
vcfEntry = do
    Int
gtIndex <- ((Int, ByteString) -> Int)
-> Either String (Int, ByteString) -> Either String Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, ByteString) -> Int
forall a b. (a, b) -> a
fst (Either String (Int, ByteString) -> Either String Int)
-> (VCFentry -> Either String (Int, ByteString))
-> VCFentry
-> Either String Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [(Int, ByteString)] -> Either String (Int, ByteString)
forall e a. e -> [a] -> Either e a
headErr String
"GT format field not found" ([(Int, ByteString)] -> Either String (Int, ByteString))
-> (VCFentry -> [(Int, ByteString)])
-> VCFentry
-> Either String (Int, ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, ByteString) -> Bool)
-> [(Int, ByteString)] -> [(Int, ByteString)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
==ByteString
"GT") (ByteString -> Bool)
-> ((Int, ByteString) -> ByteString) -> (Int, ByteString) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, ByteString) -> ByteString
forall a b. (a, b) -> b
snd) ([(Int, ByteString)] -> [(Int, ByteString)])
-> (VCFentry -> [(Int, ByteString)])
-> VCFentry
-> [(Int, ByteString)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
               [Int] -> [ByteString] -> [(Int, ByteString)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] ([ByteString] -> [(Int, ByteString)])
-> (VCFentry -> [ByteString]) -> VCFentry -> [(Int, ByteString)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VCFentry -> [ByteString]
vcfFormatString (VCFentry -> Either String Int) -> VCFentry -> Either String Int
forall a b. (a -> b) -> a -> b
$ VCFentry
vcfEntry
    [ByteString] -> Either String [ByteString]
forall (m :: * -> *) a. Monad m => a -> m a
return ([ByteString] -> Either String [ByteString])
-> [ByteString] -> Either String [ByteString]
forall a b. (a -> b) -> a -> b
$ ([ByteString] -> ByteString) -> [[ByteString]] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map ([ByteString] -> Int -> ByteString
forall a. [a] -> Int -> a
!!Int
gtIndex) (VCFentry -> [[ByteString]]
vcfGenotypeInfo VCFentry
vcfEntry)

-- |Extracts the dosages (the sum of non-reference alleles) per sample (returns a Left Error if it fails.)
getDosages :: VCFentry -> Either String [Maybe Int]
getDosages :: VCFentry -> Either String [Maybe Int]
getDosages VCFentry
vcfEntry = do
    [ByteString]
genotypes <- VCFentry -> Either String [ByteString]
getGenotypes VCFentry
vcfEntry
    let dosages :: [Maybe Int]
dosages = do
            ByteString
gen <- [ByteString]
genotypes
            if Char
'.' Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (ByteString -> String
B.unpack ByteString
gen) then
                Maybe Int -> [Maybe Int]
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int
forall a. Maybe a
Nothing
            else
                Maybe Int -> [Maybe Int]
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> [Maybe Int])
-> (Int -> Maybe Int) -> Int -> [Maybe Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> [Maybe Int]) -> Int -> [Maybe Int]
forall a b. (a -> b) -> a -> b
$ Char -> ByteString -> Int
B.count Char
'1' ByteString
gen
    [Maybe Int] -> Either String [Maybe Int]
forall (m :: * -> *) a. Monad m => a -> m a
return [Maybe Int]
dosages

-- |Converts a VCFentry to the simpler FreqSum format (returns a Left Error if it fails.)
vcfToFreqSumEntry :: VCFentry -> Either String FreqSumEntry
vcfToFreqSumEntry :: VCFentry -> Either String FreqSumEntry
vcfToFreqSumEntry VCFentry
vcfEntry = do
    [Maybe Int]
dosages <- VCFentry -> Either String [Maybe Int]
getDosages VCFentry
vcfEntry
    String -> Bool -> Either String ()
forall e. e -> Bool -> Either e ()
assertErr String
"multi-site reference allele" (Bool -> Either String ()) -> Bool -> Either String ()
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
B.length (VCFentry -> ByteString
vcfRef VCFentry
vcfEntry) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
    String -> Bool -> Either String ()
forall e. e -> Bool -> Either e ()
assertErr String
"need exactly one alternative allele" (Bool -> Either String ()) -> Bool -> Either String ()
forall a b. (a -> b) -> a -> b
$ [ByteString] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (VCFentry -> [ByteString]
vcfAlt VCFentry
vcfEntry) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
    String -> Bool -> Either String ()
forall e. e -> Bool -> Either e ()
assertErr String
"multi-site alternative allele" (Bool -> Either String ()) -> Bool -> Either String ()
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
B.length ([ByteString] -> ByteString
forall a. [a] -> a
head ([ByteString] -> ByteString)
-> (VCFentry -> [ByteString]) -> VCFentry -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VCFentry -> [ByteString]
vcfAlt (VCFentry -> ByteString) -> VCFentry -> ByteString
forall a b. (a -> b) -> a -> b
$ VCFentry
vcfEntry) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
    let ref :: Char
ref = ByteString -> Char
B.head (VCFentry -> ByteString
vcfRef VCFentry
vcfEntry)
    let alt :: Char
alt = ByteString -> Char
B.head (ByteString -> Char)
-> (VCFentry -> ByteString) -> VCFentry -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
forall a. [a] -> a
head ([ByteString] -> ByteString)
-> (VCFentry -> [ByteString]) -> VCFentry -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VCFentry -> [ByteString]
vcfAlt (VCFentry -> Char) -> VCFentry -> Char
forall a b. (a -> b) -> a -> b
$ VCFentry
vcfEntry
    String -> Bool -> Either String ()
forall e. e -> Bool -> Either e ()
assertErr String
"Invalid Reference Allele" (Bool -> Either String ()) -> Bool -> Either String ()
forall a b. (a -> b) -> a -> b
$ Char
ref Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char
'A', Char
'C', Char
'T', Char
'G', Char
'N']
    String -> Bool -> Either String ()
forall e. e -> Bool -> Either e ()
assertErr String
"Invalid Alternative Allele" (Bool -> Either String ()) -> Bool -> Either String ()
forall a b. (a -> b) -> a -> b
$ Char
alt Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char
'A', Char
'C', Char
'T', Char
'G', Char
'.']
    FreqSumEntry -> Either String FreqSumEntry
forall (m :: * -> *) a. Monad m => a -> m a
return (FreqSumEntry -> Either String FreqSumEntry)
-> FreqSumEntry -> Either String FreqSumEntry
forall a b. (a -> b) -> a -> b
$ Chrom
-> Int
-> Maybe ByteString
-> Maybe Double
-> Char
-> Char
-> [Maybe Int]
-> FreqSumEntry
FreqSumEntry (VCFentry -> Chrom
vcfChrom VCFentry
vcfEntry) (VCFentry -> Int
vcfPos VCFentry
vcfEntry) (VCFentry -> Maybe ByteString
vcfId VCFentry
vcfEntry) Maybe Double
forall a. Maybe a
Nothing Char
ref Char
alt [Maybe Int]
dosages