module Bio.SamTools.Iteratee
(
enumInHandle
, enumTam, enumTamWithIndex, enumBam
, enumQuery, enumIndexRegion, enumBamRegion
)
where
import Control.Exception
import Control.Monad.IO.Class
import qualified Data.ByteString.Char8 as BS
import Data.Int (Int64)
import qualified Bio.SamTools.Bam as Bam
import qualified Bio.SamTools.BamIndex as BamIndex
import qualified Data.Iteratee as Iter
enumInHandle :: Bam.InHandle -> Iter.Enumerator [Bam.Bam1] IO a
enumInHandle inh i0 = step i0
where step iter = do mbam <- Bam.get1 inh
case mbam of
Nothing -> return iter
Just b -> Iter.runIter iter Iter.idoneM onCont
where onCont k Nothing = step . k $ Iter.Chunk [b]
onCont k e = return $ Iter.icont k e
enumTam :: FilePath -> Iter.Enumerator [Bam.Bam1] IO a
enumTam inname i0 = bracket (Bam.openTamInFile inname) Bam.closeInHandle $ \h ->
enumInHandle h i0
enumTamWithIndex :: FilePath -> FilePath -> Iter.Enumerator [Bam.Bam1] IO a
enumTamWithIndex inname idxname i0
= bracket (Bam.openTamInFileWithIndex inname idxname) Bam.closeInHandle $ \h ->
enumInHandle h i0
enumBam :: FilePath -> Iter.Enumerator [Bam.Bam1] IO a
enumBam inname i0 = bracket (Bam.openBamInFile inname) Bam.closeInHandle $ \h ->
enumInHandle h i0
enumQuery :: BamIndex.Query -> Iter.Enumerator [Bam.Bam1] IO a
enumQuery q i0 = step i0
where step iter = do mbam <- BamIndex.next q
case mbam of
Nothing -> return iter
Just b -> Iter.runIter iter Iter.idoneM onCont
where onCont k Nothing = step . k $ Iter.Chunk [b]
onCont k e = return $ Iter.icont k e
enumIndexRegion :: BamIndex.IdxHandle -> Int -> (Int64, Int64) -> Iter.Enumerator [Bam.Bam1] IO a
enumIndexRegion h tid bnds i0 = do
q <- liftIO $ BamIndex.query h tid bnds
enumQuery q i0
enumBamRegion :: FilePath -> BS.ByteString -> (Int64, Int64) -> Iter.Enumerator [Bam.Bam1] IO a
enumBamRegion inname seqname bnds i0 = bracket (BamIndex.open inname) BamIndex.close $ \h -> do
tid <- lookupTid . BamIndex.idxHeader $ h
enumIndexRegion h tid bnds i0
where lookupTid h = maybe noTid return $! Bam.lookupTarget h seqname
noTid = ioError . userError $ "Target " ++ show seqname ++ " not found in " ++ show inname