module BioInf.ViennaRNA.Bindings.FFI.CoFold
( ffiCoFold
, ffiCoEnergyOfStructure
, ffiCoPartitionFunction
, ffiCoPartitionConstrained
, CofoldF (..)
) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Ptr as C2HSImp
import qualified Foreign.Storable as C2HSImp
import Control.Applicative
import Control.Monad
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 Unsafe.Coerce
import BioInf.ViennaRNA.Bindings.FFI.Utils
type CofoldFPtr = C2HSImp.Ptr (CofoldF)
data CofoldF = CofoldF
{ f0ab :: !Double
, fab :: !Double
, fcab :: !Double
, fa :: !Double
, fb :: !Double
}
deriving (Show)
instance Storable CofoldF where
sizeOf _ = 40
alignment _ = sizeOf (undefined :: CDouble)
peek p = CofoldF <$> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 0 :: IO C2HSImp.CDouble}) p)
<*> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 8 :: IO C2HSImp.CDouble}) p)
<*> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 16 :: IO C2HSImp.CDouble}) p)
<*> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 24 :: IO C2HSImp.CDouble}) p)
<*> liftM realToFrac ((\ptr -> do {C2HSImp.peekByteOff ptr 32 :: IO C2HSImp.CDouble}) p)
ffiCoFold :: Int -> String -> IO (Double,String)
ffiCoFold cp inp = withCAString inp $ \cinp ->
withCAString inp $ \struc -> do
setCutPoint cp
e <- cofold cinp struc
s <- peekCAString struc
return (cf2d e, s)
ffiCoEnergyOfStructure :: Int -> String -> String -> Int -> IO Double
ffiCoEnergyOfStructure cp inp struc verb =
withCAString inp $ \i ->
withCAString struc $ \s ->
setCutPoint cp
>> energy_of_structure i s (fromIntegral verb :: CInt)
>>= (return . cf2d)
ffiCoPartitionFunction :: Int -> String -> IO (CofoldF,String,A.Array (Int,Int) Double)
ffiCoPartitionFunction cutpoint i =
withCAString i $ \ci ->
withCAString i $ \cs ->
alloca $ \ptr -> do
setCutPoint cutpoint
let n = length i
let z = n * (n+1) `div` 2 +1
eF <- co_pf_fold_p ptr ci cs >> peek ptr
s <- peekCAString cs
bp <- 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,n1..1], jj <- [n,n1..ii]] (drop 1 $ map unsafeCoerce xs)
return (eF, s, ar)
ffiCoPartitionConstrained :: Int -> String -> String -> IO (CofoldF,String,A.Array (Int,Int) Double)
ffiCoPartitionConstrained cutpoint sq st =
withCAString sq $ \csq ->
withCAString st $ \cst ->
alloca $ \ptr -> do
setCutPoint cutpoint
let n = length sq
let z = n * (n+1) `div` 2 +1
eF <- co_pf_fold_constrained_p ptr csq cst 1 >> peek ptr
s <- peekCAString cst
bp <- 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,n1..1], jj <- [n,n1..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 ()
foreign import ccall safe "BioInf/ViennaRNA/Bindings/FFI/CoFold.chs.h cofold"
cofold :: ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (IO C2HSImp.CFloat)))
foreign import ccall safe "BioInf/ViennaRNA/Bindings/FFI/CoFold.chs.h energy_of_structure"
energy_of_structure :: ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (C2HSImp.CInt -> (IO C2HSImp.CFloat))))
foreign import ccall safe "BioInf/ViennaRNA/Bindings/FFI/CoFold.chs.h export_co_bppm"
export_co_bppm :: (IO (C2HSImp.Ptr C2HSImp.CDouble))