{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
module Utility
( findWithError
, bamToFasta
, appendHeader
, fastaToMap
, getMatchMap
, nub'
, decodeSAMFlag
) where
import Data.Bool
import Data.Char
import Data.Maybe
import Data.Monoid
import Numeric
import qualified Data.ByteString.Char8 as B
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import qualified Control.Foldl as Fold
import qualified Data.Text as T
import Data.Fasta.Text
import Safe
import Turtle.Line
import Types
findWithError :: (Eq a, Ord a, Show a) => a -> Map.Map a b -> b
findWithError x = Map.findWithDefault (error (show x <> " not found.")) x
isIgnore :: T.Text -> Bool
isIgnore = (== "M") . T.filter isAlpha
bamToFasta :: Maybe AccessionMap
-> Maybe MatchMap
-> T.Text
-> Maybe Headers
-> BamRow
-> [T.Text]
bamToFasta aMap mMap fileHeader headers (BamRow row) =
[ ">" <> header
, maybe (row `at` 9) (lookupErr (row `at` 2) . unAccessionMap) aMap
]
where
header = T.intercalate "|"
. catMaybes
$ [ Just fileHeader
, Just $ if isJust aMap then (row `at` 2) else (row `at` 0)
, Just $ if isJust aMap then "" else (row `at` 3)
, Just . bool "1" "0"
. maybe
(isIgnore $ row `at` 5)
(lookupErr (row `at` 2) . unMatchMap)
$ mMap
, fmap unHeaders headers
]
appendHeader :: Maybe Headers -> Line -> Line
appendHeader Nothing row = row
appendHeader (Just (Headers h)) row@((T.take 1 . lineToText) -> ">") =
unsafeTextToLine $ lineToText row <> "|" <> h
appendHeader _ row = row
fastaToMap :: Char -> [FastaSequence] -> AccessionMap
fastaToMap sep =
AccessionMap . Map.fromList . fmap (\ !x -> (getField 1 sep x, fastaSeq x))
getMatchMap :: [BamRow] -> MatchMap
getMatchMap = MatchMap
. Map.fromListWith (&&)
. fmap (\ (BamRow !x) -> (x `at` 2, isIgnore $ x `at` 5))
lookupErr :: (Ord k, Show k) => k -> Map.Map k a -> a
lookupErr k = fromMaybe (error $ "Cannot find: " <> (show k)) . Map.lookup k
nub' :: (Eq a, Ord a) => [a] -> [a]
nub' = Set.toList . Set.fromList
decodeSAMFlag :: Int -> String
decodeSAMFlag x = showIntAtBase 2 intToDigit x ""