samtools 0.2.3 → 0.2.4
raw patch · 5 files changed
+72/−2 lines, 5 files
Files
- include/samtools.h +3/−0
- samtools.cabal +1/−1
- src/Bio/SamTools/Bam.hs +42/−1
- src/Bio/SamTools/LowLevel.chs +10/−0
- test/SamTest.hs +16/−0
include/samtools.h view
@@ -44,4 +44,7 @@ void bam_init_header_hash(bam_header_t *header); +/* Prototype for bam_aux.c function */+void bam_aux_append(bam1_t *b, const char tag[2], char type, int len, uint8_t *data);+ #endif /* _samtools_h */
samtools.cabal view
@@ -1,5 +1,5 @@ Name: samtools-Version: 0.2.3+Version: 0.2.4 Synopsis: Binding to the C samtools library Description: Binding to the C samtools library, which reads and writes SAM format alignments, both binary and tab-
src/Bio/SamTools/Bam.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-} -- | This module provides a fairly direct representation of the -- SAM/BAM alignment format, along with an interface to read and write@@ -30,6 +30,8 @@ , mateTargetID, mateTargetName, mateTargetLen, matePosition, insertSize , nMismatch, nHits, matchDesc, auxGeti, auxGetf, auxGetd, auxGetA, auxGetZ, auxGet++ , addAuxA, addAuxi, addAuxZ , refSpLoc, refSeqLoc @@ -292,6 +294,45 @@ instance AuxGet BS.ByteString where auxGet b str = auxGetZ b str++addAuxA :: Bam1 -> String -> Char -> IO Bam1+addAuxA b0 tag ch+ = alloca $ \(valptr :: (Ptr CChar)) -> do+ poke valptr (CChar . fromIntegral . fromEnum $ ch)+ addAux b0 tag typecchar vallen (castPtr valptr)+ where typecchar = (CChar . fromIntegral . fromEnum $ 'A') + vallen = fromIntegral $ sizeOf (undefined :: CChar)++addAuxi :: Bam1 -> String -> Int -> IO Bam1+addAuxi b0 tag i+ = alloca $ \(valptr :: (Ptr CInt)) -> do+ poke valptr (CInt . fromIntegral $ i)+ addAux b0 tag typecchar vallen (castPtr valptr)+ where typecchar = (CChar . fromIntegral . fromEnum $ 'i')+ vallen = fromIntegral $ sizeOf (undefined :: CInt)++addAuxZ :: Bam1 -> String -> String -> IO Bam1+addAuxZ b0 tag str+ = withCAString str $ \cstr -> do+ strlen <- lengthArray0 (0 :: CChar) cstr+ addAux b0 tag typecchar (CInt . fromIntegral $ strlen + 1) (castPtr cstr)+ where typecchar = (CChar . fromIntegral . fromEnum $ 'Z')++addAux :: Bam1 -> String -> CChar -> CInt -> Ptr CUChar -> IO Bam1+addAux b0 tag typecchar vallen valptr+ | Prelude.length tag == 2 = withForeignPtr (ptrBam1 b0) $ \pbi0 ->+ do pb' <- bamDup1 pbi0 >>= newForeignPtr bamDestroy1Ptr+ withForeignPtr pb' $ \pbi' ->+ withCAStringLen tag $ \(tagstr, _tagstrlen) ->+ bamAuxAppend pbi' tagstr typecchar vallen valptr+ return $ Bam1 { ptrBam1 = pb', header = header b0 } + | otherwise = ioError . userError $ "Bad BAM Aux tag " ++ show tag++-- bamAuxAppend :: Bam1Ptr -> Ptr CChar -> CChar -> CInt -> Ptr CUChar -> IO ()++-- else do bptr <- newForeignPtr bamDestroy1Ptr b+-- return . Just $ Bam1 { ptrBam1 = bptr, header = inHeader inh }+ -- | 'Just' the match descriptor alignment field, or 'Nothing' when it -- is absent
src/Bio/SamTools/LowLevel.chs view
@@ -29,6 +29,8 @@ , bamAuxGet, bamAux2Z, bamAux2i, bamAux2f, bamAux2d, bamAux2A , bamInit1, bamDestroy1, bamDestroy1Ptr, bamDup1, bamFormat1++ , bamAuxAppend , BamIndexInt, BamIndexPtr , bamIndexLoad, bamIndexDestroy@@ -293,6 +295,14 @@ {#fun unsafe bam_format1 as bamFormat1 { id `BamHeaderPtr', id `Bam1Ptr' } -> `CString' id#}++{#fun unsafe bam_aux_append as bamAuxAppend+ { id `Bam1Ptr'+ , id `Ptr CChar'+ , id `CChar'+ , id `CInt'+ , id `Ptr CUChar' }+ -> `()'#} -- BAM indexing
test/SamTest.hs view
@@ -5,6 +5,7 @@ import Control.Exception import Control.Monad import qualified Data.ByteString.Char8 as BS+import Data.List import Data.Maybe import System.Environment import System.Exit@@ -51,6 +52,21 @@ bracket (Bam.openBamInFile bamin) Bam.closeInHandle $ \hin -> Bam.get1 hin >>= maybe (return ()) (parseBam (Bam.inHeader hin))++ addAuxFields bamin >>= hPutStrLn stderr++addAuxFields :: FilePath -> IO FilePath+addAuxFields inname = let outname = dropExtension inname ++ "-auxa.bam"+ in bracket (Bam.openBamInFile inname) Bam.closeInHandle $ \hin ->+ bracket (Bam.openBamOutFile outname (Bam.inHeader hin)) Bam.closeOutHandle $ \hout -> do+ myloop hin hout 0+ return outname+ where myloop hin hout idx = Bam.get1 hin >>= maybe (return ()) (\b -> go b >> myloop hin hout (idx + 1))+ where go b = Bam.addAuxA b "XX" 'm' >>= (\b' -> Bam.addAuxi b' "YZ" idx) >>= + (\b'' -> Bam.addAuxZ b'' "aa" (digitName $ idx `mod` 10)) >>=+ Bam.put1 hout+ digitName i | i < 0 || i > 9 = show i+ | otherwise = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"] !! i bamToSam :: FilePath -> IO FilePath bamToSam inname = let outname = dropExtension inname ++ "-test.sam"