packages feed

varan-0.5: src/Count.hs

-- High performance counting data structure

module Count (Counts(..)
             , addA, addC, addG, addT, addN, addDel, addV
             , addA_, addC_, addG_, addT_, addN_, addDel_
             , getA, getC, getG, getT, getN, getDel
             , czero
             , covC, ptAdd, ptSum
             , toList, sumList 
             ) where

import Variants       
import Data.Int
import Data.List (foldl1')

data Counts = C { getA_, getC_, getG_, getT_, getN_, getDel_ :: {-# UNPACK #-} !Int32
                , getV :: ![Variant]
                }
czero :: Counts
czero = C 0 0 0 0 0 0 []

getA, getC, getG, getT, getN, getDel :: Integral i => Counts -> i
getA = fromIntegral . getA_
getC = fromIntegral . getC_
getG = fromIntegral . getG_
getT = fromIntegral . getT_
getN = fromIntegral . getN_
getDel = fromIntegral . getDel_
{-# INLINE getA #-}
{-# INLINE getC #-}
{-# INLINE getG #-}
{-# INLINE getT #-}
{-# INLINE getN #-}
{-# INLINE getDel #-}

addA, addC, addG, addT, addN, addDel :: Integral i => Counts -> i -> Counts
addA c i = c { getA_ = getA_ c + fromIntegral i }
addC c i = c { getC_ = getC_ c + fromIntegral i }
addG c i = c { getG_ = getG_ c + fromIntegral i }
addT c i = c { getT_ = getT_ c + fromIntegral i }
addN c i = c { getN_ = getN_ c + fromIntegral i }
addDel c i = c { getDel_ = getDel_ c + fromIntegral i }
{-# INLINE addA #-}
{-# INLINE addC #-}
{-# INLINE addG #-}
{-# INLINE addT #-}
{-# INLINE addN #-}
{-# INLINE addDel #-}

addA_, addC_, addG_, addT_, addN_, addDel_ :: Counts -> Int32 -> Counts
addA_ c i = c { getA_ = getA_ c + i }
addC_ c i = c { getC_ = getC_ c + i }
addG_ c i = c { getG_ = getG_ c + i }
addT_ c i = c { getT_ = getT_ c + i }
addN_ c i = c { getN_ = getN_ c + i }
addDel_ c i = c { getDel_ = getDel_ c + i }

addV :: Counts -> Variant -> Counts
addV c v = c { getV = v : getV c }
{-# INLINE addV #-}

covC :: Counts -> Int
covC c = fromIntegral (getA_ c + getC_ c + getG_ c + getT_ c) -- + getN_ c + getDel_ c)
 -- mostly, we want to compare the identified bases.

ptAdd :: Counts -> Counts -> Counts
ptAdd a b = a `addA` (getA_ b) `addC` (getC_ b) `addG` (getG_ b) `addT` (getT_ b) `addN` (getN_ b) `addDel` (getDel_ b) -- todo: concat variants?

ptSum :: [Counts] -> Counts
ptSum = foldl1' ptAdd

-- Convert 'Counts' to a list of allele counts
toList :: Num a => Counts -> [a]
toList x = map fromIntegral [getA_ x,getC_ x,getG_ x,getT_ x]

-- | Pointwise summation of the input lists
sumList :: Num a => [[a]] -> [a]
sumList = foldr (zipWith (+)) [0,0,0,0]
{-# DEPRECATED sumList "use ptSum" #-}