packages feed

ViennaRNA-extras (empty) → 0.0.0.1

raw patch · 13 files changed

+685/−0 lines, 13 filesdep +BiobaseTypesdep +BiobaseXNAdep +QuickChecksetup-changed

Dependencies added: BiobaseTypes, BiobaseXNA, QuickCheck, ViennaRNA-bindings, ViennaRNA-extras, array, attoparsec, base, bytestring, deepseq, lens, streaming, streaming-bytestring, strict, strict-base-types, tasty, tasty-quickcheck, tasty-th, vector

Files

+ BioInf/ViennaRNA.hs view
@@ -0,0 +1,5 @@++-- | Ease-of-use module exporting the major functionality.++module BioInf.ViennaRNA where+
+ BioInf/ViennaRNA/Internal.hs view
@@ -0,0 +1,33 @@++-- | Internal mutex system to be used as long as the ViennaRNA package is not+-- thread-safe.++module BioInf.ViennaRNA.Internal+  ( viennaRNAmutex+  , withMutex+  , unsafePerformIO+  ) where++import Control.Concurrent.MVar (MVar, newMVar, withMVar, takeMVar, putMVar)+import System.IO.Unsafe (unsafePerformIO, unsafeInterleaveIO)+import Debug.Trace++-- | The mutex guarding single-threaded access to the @ViennaRNA@ bindings as+-- long as the @C@ library is not multi-threaded.++viennaRNAmutex ∷ MVar ()+viennaRNAmutex = unsafePerformIO $! newMVar ()+{-# NoInline viennaRNAmutex #-}++-- | Work with the ViennaRNA mutex.+--+-- This version seems strict enough to not block indefinitely.++withMutex ∷ IO a → IO a+withMutex f = do+  () ← takeMVar viennaRNAmutex+  !x ← f+  putMVar viennaRNAmutex ()+  return $! x+{-# NoInline withMutex #-}+
+ BioInf/ViennaRNA/Parsers/RNAfold.hs view
@@ -0,0 +1,78 @@++-- | An efficient pipes-based parser for @RNAfold@ output.++module BioInf.ViennaRNA.Parsers.RNAfold where++{-+-- | Lazily read @RNAfold@ structures.+--+-- TODO use @pipes/machines@! we need lazy reading of files and live in an exceptt transformer stack!+-- TODO generalize transformer stack++readRNAfoldFiles+  ∷ FilePath+  → IO [RNAfoldResult]+readRNAfoldFiles fp = do+  let go [] = return []+      go (f:fs) = do+        bs ← unsafeInterleaveIO (putStrLn ("#" ++ f) >> decompress <$> BSL.readFile f)+        let rs = either error id $ runExcept (bslToRNAfoldResult bs)+        rss ← go fs+        return $ rs ++ rss+      go ∷ [FilePath] → IO [RNAfoldResult]+  FP.find FP.always (FP.extension FP.==? ".gz")  (fp </> "structures") >>= go+{-# NoInline readRNAfoldFiles #-}++-- |++bslToRNAfoldResult ∷ (Monad m) ⇒ BSL.ByteString → ExceptT String m [RNAfoldResult]+bslToRNAfoldResult bs = do+  case A.eitherResult $ A.parse pRNAfold bs of+    Left e  → throwE e+    Right r → return r+{-# Inline bslToRNAfoldResult #-}++-- | Parser for @RNAfold@ output. @RNAfold@ can have between 2 and 5 output lines.+--+-- TODO Extend the parser to deal with all cases. Our best hint is probably if+-- there is whitespace in a line.+--+-- @+-- echo "CCCAAAGGG\nCCCAAAGGG" | ./RNAfold -p+-- CCCAAAGGG+-- (((...))) ( -1.20)+-- (((...))) [ -1.41]+-- (((...))) { -1.20 d=1.06}+--  frequency of mfe structure in ensemble 0.707288; ensemble diversity 1.67  +-- CCCAAAGGG+-- (((...))) ( -1.20)+-- (((...))) [ -1.41]+-- (((...))) { -1.20 d=1.06}+--  frequency of mfe structure in ensemble 0.707288; ensemble diversity 1.67  +-- @++pRNAfold ∷ A.Parser [RNAfoldResult]+pRNAfold = A.many1' go <* A.endOfInput where+  go = do+    -- 1. sequence+    rnaFoldSequence       ← BS.copy <$> AC.takeWhile AC.isAlpha_ascii <* AC.skipSpace A.<?> "RNAfold sequence"+    -- 2. mfe+    rnaFoldMFEStruc       ← BS.copy <$> AC.takeTill AC.isSpace <* AC.skipSpace A.<?> "RNAfold MFE structure"+    rnaFoldMFEEner        ← AC.char '(' *> AC.skipSpace *> AC.double <* AC.char ')' <* AC.skipSpace A.<?> "RNAfold MFE energy"+    -- 3. ensemble+    rnaFoldEnsembleStruc  ← BS.copy <$> AC.takeTill AC.isSpace <* AC.skipSpace+    rnaFoldEnsembleEner   ← AC.char '[' *> AC.skipSpace *> AC.double <* AC.char ']' <* AC.skipSpace+    -- 4. centroid+    rnaFoldCentroidStruc  ← BS.copy <$> AC.takeTill AC.isSpace <* AC.skipSpace+    rnaFoldCentroidEner   ← AC.char '{' *> AC.skipSpace *> AC.double <* AC.skipSpace+    dequal                ← AC.string "d=" *> AC.double <* AC.char '}' <* AC.skipSpace+    -- 5.mfe frequency and diversity+    AC.string "frequency of mfe structure in ensemble" *> AC.skipSpace A.<?> "frequency"+    rnaFoldMfeFrequency ← AC.double+    AC.string "; ensemble diversity" *> AC.skipSpace+    rnaFoldDiversity ← AC.double+    AC.skipSpace+    return RNAfoldResult{..}+{-# Inline pRNAfold #-}+-}+
+ BioInf/ViennaRNA/Parsers/Types.hs view
@@ -0,0 +1,18 @@++-- | Data types for the different @ViennaRNA@ outputs.+--+-- TODO I think these should be more generic types to be filled in by+-- high-level functions...++module BioInf.ViennaRNA.Parsers.Types where++import Data.ByteString (ByteString)+import GHC.Generics (Generic)+import Control.Lens++import Biobase.Types.Sequence+import Biobase.Types.Structure+import Biobase.Types.Energy+++
+ BioInf/ViennaRNA/RNAeval.hs view
@@ -0,0 +1,21 @@++module BioInf.ViennaRNA.RNAeval where++import Biobase.Types.Energy (DG(..))+import Biobase.Types.Sequence (RNAseq(..))+import Biobase.Types.Structure (RNAss(..))+import BioInf.ViennaRNA.Bindings (eosTemp)++import BioInf.ViennaRNA.Internal++++-- | High-level wrapper for energy-of-struct calculations similar to the+-- command line @RNAeval@.++rnaeval ∷ Double → RNAseq → RNAss → DG+rnaeval t (RNAseq s1) (RNAss s2)+  = unsafePerformIO . withMutex+  $! DG <$> eosTemp t s1 s2+{-# NoInline rnaeval #-}+
+ BioInf/ViennaRNA/RNAfold.hs view
@@ -0,0 +1,265 @@++-- | Everything needed to wrap @RNAfold@ results, parse lines with @RNAfold@+-- input, fold a sequence with @rnafold@, and more.++module BioInf.ViennaRNA.RNAfold+  ( module BioInf.ViennaRNA.RNAfold+  , module BioInf.ViennaRNA.Types+  ) where++import           Control.Arrow+import           Control.DeepSeq+import           Control.Lens+import           Control.Monad (guard)+import           Data.Attoparsec.ByteString as A+import           Data.Attoparsec.ByteString.Char8 as A8+import           Data.ByteString.Builder+import           Data.ByteString (ByteString)+import           Data.ByteString.Char8 as BS+import           Data.Char (toUpper)+import           Data.Maybe.Strict+import           Data.Monoid+import           Data.Tuple (swap)+import           Debug.Trace+import           GHC.Generics (Generic)+import           Prelude hiding(Maybe(..))+import           Test.QuickCheck as QC+import           Text.Printf++import           Biobase.Types.Energy+import           Biobase.Types.Sequence (mkRNAseq, RNAseq(..), rnaseq)+import           Biobase.Types.Structure+import qualified BioInf.ViennaRNA.Bindings as Bindings++import           BioInf.ViennaRNA.Internal+import           BioInf.ViennaRNA.Types++++-- | Space-efficient RNAfold structure. RNAfold allows a DNA input, but this is+-- not allowed in this data structure. If you want that, keep the original+-- input string around.+--+-- This structure provides only @Getter@'s. Only the @sequenceID@ can be+-- updated via @sequenceIDlens@. This is to prevent accidental updates of+-- fields that are actually interdependent.+--+-- Missing parts are sloppily encoded by bogus values and empty strings. All+-- @Folded@ structures and derived values are lazy. In case @rnafold@ was used+-- to construct the structure, calculations are deferred until needed.+--+-- TODO newtype the sequence id.+--+-- TODO temperature. How to encode? Kelvin? In BiobaseTypes! Could use (Nat)SciTypes!+--+-- TODO complete BP probability array+--+-- TODO lazy fields for computation on demand!+--+-- TODO Wrapped via @Maybe@?++data RNAfold = RNAfold+  { _sequenceID   ∷ !ByteString+  -- ^ Set to @not . null@ if the sequence was given a name. This is (likely) a+  -- fasta-style identifier.+  , _input        ∷ !RNAseq+  -- ^ The input sequence, converting into an RNA string.+  , _mfe          ∷ !Folded+  -- ^ Minimum-free energy and corresponding structure.+  , _mfeFrequency ∷ !Double+  -- ^ The mfe frequency can be calculated as follows: @exp ((ensemble energy -+  -- mfe energy) / kT)@.+  --+  -- ^ TODO newtype wrapper?+  , _ensemble     ∷ !Folded+  -- ^ Uses special syntax with unpaired, weakly paired, somewhat paired,+  -- somewhat paired up or down, strongly paired up or down for the ensemble.+  -- The energy is the *ensemble free energy*.+  , _centroid     ∷ !Folded+  -- ^ Centroid energy and structure.+  , _centroidDistance ∷ !Double+  -- ^ Centroid distance to ensemble.+  , _diversity        ∷ !Double+  -- ^ Average basepair distance between all structures in the Boltzmann+  -- ensemble+  --+  -- TODO Needs own newtype?+  , _temperature      ∷ !(Maybe Double)+  -- ^ Temperature in Celsius+  --+  -- TODO own newtype Celsius+  }+  deriving (Read,Show,Eq,Ord,Generic)+makeLensesWith (lensRules & generateUpdateableOptics .~ False) ''RNAfold+makeLensesFor [("_sequenceID", "sequenceIDlens")] ''RNAfold++instance NFData RNAfold++++-- | Fold a sequence.+--+-- This function is threadsafe via the viennaRNA-mutex.+--+-- TODO add temperature parameter+--+-- TODO consider creating a "super-lens" that updates whenever @_input@ or+-- @_temperature@ change.++rnafold ∷ RNAseq → RNAfold+rnafold _input = unsafePerformIO . withMutex $! do+  let _temperature = Just 37+  let _sequenceID = ""+  _mfe      ← uncurry Folded . swap <$> (DG *** RNAss) <$> Bindings.mfe (_input^.rnaseq)+  (_centroid, _centroidDistance) ← (\(e,s,d) → (Folded (RNAss s) (DG e), d)) <$> Bindings.centroidTemp 37 (_input^.rnaseq)+  -- fucked up from here+  let k0 = 273.15+  let gasconst = 1.98717 -- in kcal * (K^(-1)) * (mol^(-1))+  let kT = (k0 + 37) * gasconst * 1000+  let _ensemble = Folded (RNAss "DO NOT USE ME") (DG 999999)+  let _diversity = 999999+  -- the energy of the mfe structure calculated with @dangles=1@ model,+  -- otherwise we get different mfe frequency values compared to rnafold.+  let d1mfeenergy = 0+  let _mfeFrequency = exp $ (_centroid^.foldedEnergy.to dG - d1mfeenergy) / kT+  return $! RNAfold {..}+{-# NoInline rnafold #-}++++data RNArewrite+  = NoRewrite+  | ForceRNA+  deriving (Read,Show,Eq,Ord,Generic)++-- | Parsing for 'RNAfold'. This should parse all variants that @RNAfold@+-- produces.+--+-- The parser for a 'Folded' structure has to deal with different "energy"+-- types. The different energies are bracketed by different types of brackets.+--+-- @+-- mfe        (((...))) ( -1.20)+-- ensemble   (((...))) [ -1.41]+-- centroid   (((...))) { -1.20 d=1.06}+-- @+--+-- TODO Move into submodule.+--+-- TODO pipes-based streaming parser+--+-- TODO how to handle parsing the BP probability array, if known?+--+-- TODO I think it is possible to figure the line type based on the energy and+-- the brackets around the energy.++pRNAfold+  ∷ RNArewrite+  → Double+  → Parser RNAfold+pRNAfold r celsius = do+  let _temperature = Just celsius+  let endedLine = A.takeTill isEndOfLine <* endOfLine+  let s2line = A8.takeWhile1 (`BS.elem` "(.)") <* skipSpace+  let ensline = A8.takeWhile1 (`BS.elem` "(){}.,|") <* skipSpace+  let nope = Folded (RNAss "") (DG 0)+  let rewrite = case r of+        NoRewrite → id+        ForceRNA  → BS.map (go . toUpper) where+          go x+            | x `BS.elem` "ACGUacgu" = x+          go x   = 'N'+  _sequenceID ← option "" $ char '>' *> endedLine+  _input      ← RNAseq <$> rewrite <$> endedLine+  let l = _input^.rnaseq.to BS.length+  let lenGuard s2 = guard (BS.length s2 == l)+        <?> ("s2 line length /= _input length: " ++ show (s2,_input) ++ "")+  -- mfe is always present ?!+  _mfe ← do s2 ← s2line+            lenGuard s2+            skipSpace+            e  ← char '(' *> skipSpace *> signed double <* char ')'+            let _foldedStructure = RNAss s2+            let _foldedEnergy    = DG e+            return Folded{..}+            <?> "mfe"+  -- from here on, things are optional, including the newline after the mfe+  -- energy!+  _ensemble ← option nope $+    (do endOfLine+        s2 ← ensline+        lenGuard s2+        skipSpace+        e  ← char '[' *> skipSpace *> signed double <* char ']'+        let _foldedStructure = RNAss s2+        let _foldedEnergy    = DG e+        return Folded{..}+        <?> "ensemble")+  (_centroid, _centroidDistance) ← option (nope, 0) $+    (do endOfLine+        s2 ← s2line+        lenGuard s2+        e ← char '{' *> skipSpace *> signed double+        -- TODO handle @d@ values+        d ← skipSpace *> "d=" *> skipSpace *> double+        skipSpace *> char '}'+        let _foldedStructure  = RNAss s2+        let _foldedEnergy     = DG e+        return (Folded{..}, d)+        <?> "centroid")+  (_mfeFrequency, _diversity) ← option (0, 0) $+    (do endOfLine -- previous line ending+        skipSpace+        "frequency of mfe structure in ensemble"+        skipSpace+        f ← double+        "; ensemble diversity"+        skipSpace+        ed ← double+        skipSpace+        return (f, ed)+        <?> "mfe frequency / diversity")+  return RNAfold{..}++++builderRNAfold ∷ RNAfold → Builder+builderRNAfold RNAfold{..} = mconcat [hdr, sqnce, emfe, nsmbl, cntrd]+  where+    -- SLOW!+    dbl d = byteString . BS.pack $ printf "%.2f" (d∷Double)+    addFolded l r Folded{..} = if BS.null (_rnass _foldedStructure)+                               then mempty+                               else nl <> byteString (_rnass _foldedStructure) <> char7 ' '+                                    <> char7 l <> dbl (dG _foldedEnergy) <> char7 r+    nl = char7 '\n'+    hdr = if BS.null _sequenceID then mempty else char7 '>' <> byteString _sequenceID <> nl+    sqnce = byteString (_input^.rnaseq)+    emfe = addFolded '(' ')' _mfe+    nsmbl = addFolded '[' ']' _ensemble+    cntrd = let s = _centroid^.foldedStructure.rnass+            in if BS.null (_centroid^.foldedStructure.rnass)+                then mempty+                else nl <> byteString s <> " {"+                     <> dbl (_centroid^.foldedEnergy.to dG)+                     <> " d=" <> dbl _diversity <> "}"++++-- ** QuickCheck generator for 'RNAfold'. This is slightly unusual but allows+-- us to generate random sequence/structure pairs easily.+--+-- This should only be used for quickcheck testing, not anything involving+-- properties of random RNAs.+--+-- Generation is simple: A sequence with @[0,100]@ characters from @ACGU@ is+-- generated and the 'RNAfold' structure is filled by 'rnafold'. We test for+-- size @0@ explicitly, too!++instance Arbitrary RNAfold where+  -- Generate a sequence and calculate the structure for it.+  arbitrary =  choose (0,100)+            >>= \k → rnafold <$> mkRNAseq <$> BS.pack <$> vectorOf k (QC.elements "ACGU")+  -- Try with all sequences missing one character.+  shrink rna = [ rnafold $ mkRNAseq $ BS.pack s | s ← shrink $ rna^.input.rnaseq.to unpack ]+
+ BioInf/ViennaRNA/Types.hs view
@@ -0,0 +1,23 @@++module BioInf.ViennaRNA.Types where++import Control.Lens+import Control.DeepSeq+import GHC.Generics (Generic)++import Biobase.Types.Energy+import Biobase.Types.Structure++++-- | Holds a pair of energy and structure.++data Folded = Folded+  { _foldedStructure  ∷ !RNAss+  , _foldedEnergy     ∷ !DG+  }+  deriving (Read,Show,Eq,Ord,Generic)+makeLensesWith (lensRules & generateUpdateableOptics .~ False) ''Folded++instance NFData Folded+
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Christian Hoener zu Siederdissen 2010-2013++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Christian Hoener zu Siederdissen nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,16 @@+[![Build Status](https://travis-ci.org/choener/ViennaRNA-extras.svg?branch=master)](https://travis-ci.org/choener/ViennaRNA-extras)++# ViennaRNA extras++A number of high-level functions that extend the functionality provided by+ViennaRNA-bindings.++++#### Contact++Christian Hoener zu Siederdissen  +Leipzig University, Leipzig, Germany  +choener@bioinf.uni-leipzig.de  +http://www.bioinf.uni-leipzig.de/~choener/  +
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ ViennaRNA-extras.cabal view
@@ -0,0 +1,137 @@+name:           ViennaRNA-extras+version:        0.0.0.1+author:         Christian Hoener zu Siederdissen, 2017+copyright:      Christian Hoener zu Siederdissen, 2017+license:        BSD3+license-file:   LICENSE+category:       Bioinformatics+homepage:       https://github.com/choener/ViennaRNA-extras+bug-reports:    https://github.com/choener/ViennaRNA-extras/issues+maintainer:     choener@bioinf.uni-leipzig.de+build-type:     Simple+stability:      experimental+cabal-version:  >= 1.10.0+tested-with:    GHC == 8.0.2, GHC == 8.2.1+synopsis:       ViennaRNA v2 extensions+description:    +                Extra functionality on top of the ViennaRNA bindings. Please+                note the special license of the ViennaRNA bindings (while the+                -extras library is BSD3, it is not very useful without the+                bindings)!+                .+                .+                If you use this software, please cite:+                .+                @+                R. Lorenz, S.H. Bernhart, C. Hoener zu Siederdissen, H. Tafer, C. Flamm, P.F. Stadler and I.L. Hofacker (2011)+                ViennaRNA Package 2.0+                Algorithms for Molecular Biology: 6:26+                @+                .+                <http://www.almob.org/content/6/1/26>++++Extra-Source-Files:+  README.md+  changelog.md++++flag debug+  description:  Enable bounds checking and various other debug operations+  default:      False+  manual:       True++++library+  exposed-modules:+    BioInf.ViennaRNA+    BioInf.ViennaRNA.Internal+    BioInf.ViennaRNA.Parsers.RNAfold+    BioInf.ViennaRNA.Parsers.Types+    BioInf.ViennaRNA.RNAeval+    BioInf.ViennaRNA.RNAfold+    BioInf.ViennaRNA.Types+  build-depends: base                   >= 4.7    && < 5.0+               , array+               , attoparsec             >= 0.13+               , bytestring+               , deepseq                >= 1.4+               , lens                   >= 4.0+--               , pipes                  >= 4.0+               , QuickCheck             >= 2.0+               , streaming              >= 0.1+               , streaming-bytestring   >= 0.1+               , strict                 >= 0.3+               , strict-base-types      >= 0.5+               --+               , BiobaseTypes           == 0.1.3.*+               , BiobaseXNA             == 0.10.0.*+               , ViennaRNA-bindings     == 0.233.2.*+  default-language:+    Haskell2010+  default-extensions: BangPatterns+                    , DeriveDataTypeable+                    , DeriveGeneric+                    , GeneralizedNewtypeDeriving+                    , OverloadedStrings+                    , RecordWildCards+                    , TemplateHaskell+                    , UnicodeSyntax+  ghc-options:+    -O2 -funbox-strict-fields+  if flag(debug)+--    cpp-options: -DADPFUSION_CHECKS+    ghc-options: -fno-ignore-asserts -O0++++test-suite properties+  type:+    exitcode-stdio-1.0+  main-is:+    properties.hs+  ghc-options:+    -threaded -rtsopts -with-rtsopts=-N+  hs-source-dirs:+    tests+  default-language:+    Haskell2010+  default-extensions: BangPatterns+                    , CPP+                    , FlexibleContexts+                    , FlexibleInstances+                    , MultiParamTypeClasses+                    , OverloadedStrings+                    , ScopedTypeVariables+                    , TemplateHaskell+                    , TypeFamilies+                    , TypeOperators+                    , TypeSynonymInstances+                    , UnicodeSyntax+  build-depends: base+               , attoparsec+               , bytestring+               , QuickCheck+               , tasty                        >= 0.11+               , tasty-quickcheck             >= 0.8+               , tasty-th                     >= 0.1+               , vector+               --+               , ViennaRNA-extras++++-- its a library, get it from hackage++--source-repository this+--  type: git+--  location: git://github.com/choener/ViennaRNA-extras/tree/0.0.0.1+--  tag: 0.0.0.1++source-repository head+  type: git+  location: git://github.com/choener/ViennaRNA-extras+
+ changelog.md view
@@ -0,0 +1,5 @@+0.0.0.1+-------++- constraints to partial sums over base pair probability matrices+
+ tests/properties.hs view
@@ -0,0 +1,52 @@++-- |+--+-- TODO golden tests of known good RNAfold output as parser input+--+-- TODO re-enable the build/parse paired tests.++module Main where++import Data.Attoparsec.ByteString.Char8 as A8+import Data.ByteString.Builder+import Data.ByteString.Lazy.Char8 (toStrict)+import Data.List (intersperse)+import Debug.Trace+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.QuickCheck (testProperty)+import Test.Tasty.TH++import BioInf.ViennaRNA.RNAfold++-- prop_build ∷ RNAfold → Bool+-- prop_build r+--   | True = traceShow lbs False+--   where+--     bld = builderRNAfold r+--     lbs = toStrict $ toLazyByteString bld+-- +-- prop_build_parse ∷ RNAfold → Bool+-- prop_build_parse r+--   | Left err ← ap = traceShow (err,r) False+--   | Right pr ← ap = pr == r+--   where+--     -- the final builder of all @RNAfold@ structures+--     bld = builderRNAfold r+--     lbs = toStrict $ toLazyByteString bld+--     ap  = parseOnly ((pRNAfold NoRewrite 37) <* endOfInput) lbs+-- +-- +-- prop_builds_parses ∷ [RNAfold] → Bool+-- prop_builds_parses rs+--   | Left err  ← ap = traceShow err False+--   | Right prs ← ap = prs == rs+--   where+--     -- the final builder of all @RNAfold@ structures+--     bld = mconcat $ intersperse "\n" $ map builderRNAfold rs+--     lbs = toStrict $ toLazyByteString bld+--     ap  = parseOnly (many' (pRNAfold NoRewrite 37) <* endOfInput) lbs++main ∷ IO ()+main = $(defaultMainGenerator)+