packages feed

MC-Fold-DP-0.1.0.0: MCFoldDP.hs

{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE DeriveDataTypeable #-}

module Main where

import System.Console.CmdArgs
import Control.Monad (liftM)
import Text.Printf
import Data.List (sortBy)
import Data.Ord (comparing)

import Biobase.DataSource.MCFold
import Biobase.DataSource.MCFold.Import
import Biobase.RNA
import Biobase.Structure
import Biobase.Structure.DotBracket

import BioInf.MCFoldDP



data Options = Options
  { database :: FilePath
  , strictInput :: Bool
  , noSparseDataCorrection :: Bool
  , orderSuboptimals :: Bool
  , band :: Double
  , oneResult :: Bool
  } deriving (Data,Typeable,Show)

options = Options
  { database = "./MCFOLD-DB" &= typDir &= help "path to MCFOLD-DB (default: ./MCFOLD-DB)"
  , strictInput = False &= help "filter out other characters than ACGU (default: convert other characters to E and handle gracefully)"
  , noSparseDataCorrection = False &= help "disable sparse data correction (default: enabled)"
  , orderSuboptimals = False &= help "sort suboptimal results by score (better scores first) (default: false)"
  , band = 0.1 &= help "score band above the ground state for which suboptimal results are allowed (default: 0.1)"
  , oneResult = False &= help "Return only one of several co-optimal structures in the backtracking phase (default: false)"
  } &= summary "MCFold-DP, (c) Christian Hoener zu Siederdissen et al, 2010-2011"
    &= details  [ "This program performs calculations similar to those done by MC-Fold."
                , "Important differences are: polynomial runtime, no pseudoknot handling,"
                , "sparse data correction, and the possibility to gracefully handle all"
                , "input sequences."
                ]

main = do
  o@Options{..} <- cmdArgs options
  db <- parseDir database
  -- TODO enable sparsity correction!
  cnts <- liftM ((strictFilter strictInput) . lines) $ getContents
  mapM_ (doFold o db) cnts

strictFilter :: Bool -> [String] -> [String]
strictFilter False xs = xs
strictFilter True  xs = filter (all (`elem` "ACGUacgu")) xs

-- | Executes folding a single sequence. Allows

doFold :: Options -> MotifDB -> String -> IO ()
doFold Options{..} db inp = do
  putStrLn inp
  let pri = mkPrimary inp
  let ts = fold db pri
  let res = (if oneResult then take 1 else id) $ backtrack db band pri ts
  mapM_ (\(e,s) -> printf "%s   (%7.2f)\n" (dotbracket s) e) . (if orderSuboptimals then sortBy (comparing fst) else id) $ res
  if null res then error $ "XXX  " ++ inp else return ()



runtest = do
  db <- parseDir "/home/choener/tmp/mcfold/MCFOLD-DB"
  {-
  doFold db True 8.0 "cccaaaggg"
  doFold db True 10.0 "ccccccaaagggcccaaagggggg"
  -}
  doFold (Options undefined False False True 2.0 False) db "UGAGUUUAUCAGCUGAUUUU"