cobot-tools-0.1.0.1: src/Bio/Tools/Sequence/ViennaRNA/Internal/Cofold.hs
module Bio.Tools.Sequence.ViennaRNA.Internal.Cofold
( cofold
) where
import Bio.NucleicAcid.Nucleotide (symbol)
import Bio.Tools.Sequence.ViennaRNA.Internal.RNALike (RNALike (..))
import Foreign.C.String (CString,
newCString,
peekCString)
import Foreign.C.Types (CDouble (..),
CFloat (..))
import Foreign.Marshal.Alloc (free)
import System.IO.Unsafe (unsafePerformIO)
foreign import ccall "vrna_cofold_temperature" vrna_cofold_temperature :: CString -> CString -> CDouble -> CFloat
-- TODO make it for list of pairs to allocate CString of only one size
-- TODO (need to handle different sizes of oligs, try to take just max size (because CString ends with \0)
vRnaCofoldString :: Double -> (String, String) -> (Float, String)
vRnaCofoldString temperature (rnaSequence1, rnaSequence2) = unsafePerformIO $ do
let inputSeq = rnaSequence1 ++ "&" ++ rnaSequence2
cRnaSequence <- newCString' inputSeq
let energy = realToFrac $ vrna_cofold_temperature cRnaSequence cRnaSequence (realToFrac temperature)
structureRes <- evalResult energy cRnaSequence
free' cRnaSequence
return (energy, structureRes)
where
newCString' = newCString
free' = free
evalResult energy cRnaSequence = energy `seq` peekCString cRnaSequence
-- | Calculates cofolding energy and interaction dot-plot between two 'RNALike' strands.
--
cofold :: RNALike a => Double -> ([a], [a]) -> (Float, String)
cofold temperature = vRnaCofoldString temperature . toStringsPair
where
toStringsPair (nucs1, nucs2) = (symbol . toRNA <$> nucs1, symbol . toRNA <$> nucs2)