module SequenceFormats.Genomic where

import SequenceFormats.Bed (BedEntry(..), filterThroughBed)
import SequenceFormats.Eigenstrat (EigenstratSnpEntry(..))
import SequenceFormats.FreqSum (FreqSumEntry(..))
import SequenceFormats.Pileup (PileupRow(..))
import SequenceFormats.Utils (Chrom)
import SequenceFormats.VCF (VCFentry(..))

import Pipes (Producer)

class Genomic a where
    genomicPosition :: a -> (Chrom, Int)

    genomicChrom :: a -> Chrom
    genomicChrom = forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Genomic a => a -> (Chrom, Int)
genomicPosition

    genomicBase :: a -> Int 
    genomicBase = forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Genomic a => a -> (Chrom, Int)
genomicPosition

instance Genomic EigenstratSnpEntry where
    genomicPosition :: EigenstratSnpEntry -> (Chrom, Int)
genomicPosition (EigenstratSnpEntry Chrom
c Int
p Double
_ ByteString
_ Char
_ Char
_) = (Chrom
c, Int
p)

instance Genomic FreqSumEntry where
    genomicPosition :: FreqSumEntry -> (Chrom, Int)
genomicPosition (FreqSumEntry Chrom
c Int
p Maybe ByteString
_ Maybe Double
_ Char
_ Char
_ [Maybe Int]
_) = (Chrom
c, Int
p)

instance Genomic PileupRow where
    genomicPosition :: PileupRow -> (Chrom, Int)
genomicPosition (PileupRow Chrom
c Int
p Char
_ [String]
_ [[Strand]]
_) = (Chrom
c, Int
p)

instance Genomic VCFentry where
    genomicPosition :: VCFentry -> (Chrom, Int)
genomicPosition (VCFentry Chrom
c Int
p Maybe ByteString
_ ByteString
_ [ByteString]
_ Double
_ Maybe ByteString
_ [ByteString]
_ [ByteString]
_ [[ByteString]]
_) = (Chrom
c, Int
p)

chromFilter :: (Genomic e) => [Chrom] -> e -> Bool
chromFilter :: forall e. Genomic e => [Chrom] -> e -> Bool
chromFilter [Chrom]
exclusionList = (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Chrom]
exclusionList) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Genomic a => a -> Chrom
genomicChrom

genomicFilterThroughBed :: (Monad m, Genomic e) => Producer BedEntry m () -> Producer e m () -> Producer e m ()
genomicFilterThroughBed :: forall (m :: * -> *) e.
(Monad m, Genomic e) =>
Producer BedEntry m () -> Producer e m () -> Producer e m ()
genomicFilterThroughBed Producer BedEntry m ()
bedProd = forall (m :: * -> *) a.
Monad m =>
Producer BedEntry m ()
-> (a -> (Chrom, Int)) -> Producer a m () -> Producer a m ()
filterThroughBed Producer BedEntry m ()
bedProd forall a. Genomic a => a -> (Chrom, Int)
genomicPosition