ViennaRNA-bindings-0.233.2.0: BioInf/ViennaRNA/Bindings/FFI/CoFold.chs
module BioInf.ViennaRNA.Bindings.FFI.CoFold
( ffiCoFold
, ffiCoEnergyOfStructure
, ffiCoPartitionFunction
, ffiCoPartitionConstrained
, CofoldF (..)
) where
import Control.Applicative
import Control.Monad
import Data.ByteString.Char8 (ByteString, useAsCString, packCString)
import Foreign.C.String
import Foreign.C.Types
import Foreign.Marshal.Alloc
import Foreign.Marshal.Array
import Foreign.Ptr
import Foreign.Storable
import GHC.Float
import qualified Data.Array.IArray as A
import qualified Data.ByteString.Char8 as BS
import Unsafe.Coerce
import BioInf.ViennaRNA.Bindings.FFI.Utils
#include "ViennaRNA/cofold.h"
#include "ViennaRNA/data_structures.h"
#include "ViennaRNA/fold.h"
#include "ViennaRNA/part_func_co.h"
{#pointer *cofoldF as CofoldFPtr -> CofoldF #}
data CofoldF = CofoldF
{ f0ab :: {-# UNPACK #-} !Double
, fab :: {-# UNPACK #-} !Double
, fcab :: {-# UNPACK #-} !Double
, fa :: {-# UNPACK #-} !Double
, fb :: {-# UNPACK #-} !Double
}
deriving (Show)
instance Storable CofoldF where
sizeOf _ = {#sizeof cofoldF#}
alignment _ = sizeOf (undefined :: CDouble)
peek p = CofoldF <$> liftM realToFrac ({# get cofoldF->F0AB #} p)
<*> liftM realToFrac ({# get cofoldF->FAB #} p)
<*> liftM realToFrac ({# get cofoldF->FcAB #} p)
<*> liftM realToFrac ({# get cofoldF->FA #} p)
<*> liftM realToFrac ({# get cofoldF->FB #} p)
-- |
ffiCoFold :: Int -> ByteString -> IO (Double,ByteString)
ffiCoFold cp inp = useAsCString inp $ \cinp ->
useAsCString inp $ \struc -> do
setCutPoint cp
e <- {#call cofold #} cinp struc
s <- packCString struc
return (cf2d e, s)
-- |
ffiCoEnergyOfStructure :: Int -> ByteString -> ByteString -> Int -> IO Double
ffiCoEnergyOfStructure cp inp struc verb =
useAsCString inp $ \i ->
useAsCString struc $ \s ->
setCutPoint cp
>> {#call energy_of_structure #} i s (fromIntegral verb :: CInt)
>>= (return . cf2d)
-- |
ffiCoPartitionFunction :: Int -> ByteString -> IO (CofoldF,ByteString,A.Array (Int,Int) Double)
ffiCoPartitionFunction cutpoint i =
useAsCString i $ \ci ->
useAsCString i $ \cs ->
alloca $ \ptr -> do
setCutPoint cutpoint
let n = BS.length i
let z = n * (n+1) `div` 2 +1
eF <- co_pf_fold_p ptr ci cs >> peek ptr
s <- packCString cs
bp <- {#call export_co_bppm #}
xs <- peekArray z (bp :: Ptr CDouble)
let ar = A.accumArray (const id) 0 ((1,1),(n,n)) $ zip [ (ii,jj) | ii <- [n,n-1..1], jj <- [n,n-1..ii]] (drop 1 $ map unsafeCoerce xs)
return (eF, s, ar)
-- | Constrained partition function
ffiCoPartitionConstrained :: Int -> ByteString -> ByteString -> IO (CofoldF,ByteString,A.Array (Int,Int) Double)
ffiCoPartitionConstrained cutpoint sq st =
useAsCString sq $ \csq ->
useAsCString st $ \cst ->
alloca $ \ptr -> do
setCutPoint cutpoint
let n = BS.length sq
let z = n * (n+1) `div` 2 +1
eF <- co_pf_fold_constrained_p ptr csq cst 1 >> peek ptr
s <- packCString cst
bp <- {#call export_co_bppm #}
xs <- peekArray z (bp :: Ptr CDouble)
let ar = A.accumArray (const id) 0 ((1,1),(n,n)) $ zip [ (ii,jj) | ii <- [n,n-1..1], jj <- [n,n-1..ii]] (drop 1 $ map unsafeCoerce xs)
return (eF, s, ar)
foreign import ccall "ffiwrap_co_pf_fold" co_pf_fold_p :: CofoldFPtr -> CString -> CString -> IO ()
foreign import ccall "ffiwrap_co_pf_fold_constrained" co_pf_fold_constrained_p :: CofoldFPtr -> CString -> CString -> Int -> IO ()