RNAlien-1.7.0: Biobase/RNAlienScan.hs
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE DeriveDataTypeable #-}
-- | Unsupervized construction of RNA family models
-- For more information on RNA family models consult <http://>
-- Usage example: RNAlien -i /path/input.fa -c 5 -o /outdir/
-- Usage example offline mode: RNAlien -i /path/input.fa -b /backup/blast/nt_v5 -o /outdir/ -c 5 -t 1396 -j
module Main where
import System.Console.CmdArgs
import System.Directory
import Biobase.RNAlien.Types
import Biobase.RNAlien.Library
import Data.Maybe
import Data.Either.Unwrap
import Data.Time
import qualified System.FilePath as FP
import Paths_RNAlien (version)
import Data.Version (showVersion)
--import Biobase.Fasta.Streaming
import Control.Monad
data Options = Options
{ inputFastaFilePath :: String,
inputGenomesFastaFilePath :: String,
outputPath :: String,
inputnSCICutoff :: Maybe Double,
inputEvalueCutoff :: Maybe Double,
lengthFilter :: Bool,
coverageFilter :: Bool,
singleHitperTax :: Bool,
blastSoftmasking :: Bool,
inputQuerySelectionMethod :: String,
inputQueryNumber :: Int,
threads :: Int,
sessionIdentificator :: Maybe String,
performEvaluation :: Bool,
checkSetup :: Bool
} deriving (Show,Data,Typeable)
options :: Options
options = Options
{ inputFastaFilePath = def &= name "i" &= help "Path to input fasta file",
inputGenomesFastaFilePath = def &= name "b" &= help "Path to input genome fasta files",
outputPath = def &= name "o" &= help "Path to output directory. Default: current working directory",
inputnSCICutoff = Just (1 :: Double) &= name "z" &= help "Only candidate sequences with a normalized structure conservation index (nSCI) higher than this value are accepted. Default: 1",
inputEvalueCutoff = Just (0.001 :: Double) &= name "e" &= help "Evalue cutoff for cmsearch filtering. Default: 0.001",
lengthFilter = True &= name "l" &= help "Filter blast hits per genomic length. Default: True",
coverageFilter = True &= name "a" &= help "Filter blast hits by coverage of at least 80%. Default: True",
singleHitperTax = False &= name "s" &= help "Only the best blast hit per taxonomic entry is considered. Default: False",
blastSoftmasking = False &= name "f" &= help "Toggles blast query softmasking, meaning masking of non-conserved regions on the query. Default: False",
inputQuerySelectionMethod = "filtering" &= name "m" &= help "Method for selection of queries (filtering,clustering). Default: filtering",
inputQueryNumber = (5 :: Int) &= name "n" &= help "Number of queries used for candidate search. Default: 5",
threads = 1 &= name "c" &= help "Number of available cpu slots/cores. Default: 1",
sessionIdentificator = Nothing &= name "d" &= help "Optional session id that is used instead of automatically generated one.",
performEvaluation = True &= name "x" &= help "Perform evaluation step. Default: True",
checkSetup = False &= name "g" &= help "Just prints installed tool versions and performs connection check. Default: False"
} &= summary ("RNAlienScan " ++ alienVersion) &= help "Florian Eggenhofer - 2019" &= verbosity
main :: IO ()
main = do
Options{..} <- cmdArgs options
verboseLevel <- getVerbosity
let tools = if inputQuerySelectionMethod == "clustering" then ["clustalo","mlocarna","RNAfold","RNAalifold","cmcalibrate","cmstat","cmbuild","RNAz","RNAcode"] else ["mlocarna","RNAfold","RNAalifold","cmcalibrate","cmstat","cmbuild","RNAz","RNAcode"]
-- Generate SessionID
sessionId <- createSessionID sessionIdentificator
timestamp <- getCurrentTime
currentWorkDirectory <- getCurrentDirectory
let selectedOutputPath = if null outputPath then currentWorkDirectory else outputPath
let temporaryDirectoryPath = FP.addTrailingPathSeparator selectedOutputPath ++ sessionId ++ "/"
createDirectoryIfMissing False temporaryDirectoryPath
networkCheck <- checkNCBIConnection
if checkSetup
then do
toolsCheck <- checkTools tools inputQuerySelectionMethod temporaryDirectoryPath
let setupCheckPath = temporaryDirectoryPath ++ "setupCheck"
let toolCheckResult = either id id toolsCheck
let networkCheckResult = either id id networkCheck
writeFile setupCheckPath (toolCheckResult ++ "\n" ++ networkCheckResult ++ "\n")
else
if isLeft networkCheck
then do
putStrLn ("Error - Could not contact NCBI server: " ++ fromLeft networkCheck ++ "\n")
logMessage ("Error - Could not contact NCBI server: " ++ fromLeft networkCheck ++ "\n") temporaryDirectoryPath
else do
createDirectoryIfMissing False (temporaryDirectoryPath ++ "log")
-- Create Log files
writeFile (temporaryDirectoryPath ++ "Log") ("RNAlienEgg " ++ alienVersion ++ "\n")
writeFile (temporaryDirectoryPath ++ "log/warnings") ("")
logMessage ("Timestamp: " ++ (show timestamp) ++ "\n") temporaryDirectoryPath
logMessage ("Temporary Directory: " ++ temporaryDirectoryPath ++ "\n") temporaryDirectoryPath
fastaInput <- readFastaFile inputFastaFilePath
inputGenomesFasta <- readFastaFile inputGenomesFastaFilePath
if null fastaInput
then do
putStrLn "Error: Input fasta file is empty."
logMessage "Error: Input fasta file is empty.\n" temporaryDirectoryPath
else do
let iterationNumber = 0
toolsCheck <- checkTools tools inputQuerySelectionMethod temporaryDirectoryPath
if isLeft toolsCheck
then do
putStrLn ("Error - Not all required tools could be found in $PATH: " ++ fromLeft toolsCheck ++ "\n")
logMessage ("Error - Not all required tools could be found in $PATH: " ++ fromLeft toolsCheck ++ "\n") temporaryDirectoryPath
else do
when (null inputGenomesFasta) (error "Please provide input genomes with the cmd line parameter -s")
logToolVersions inputQuerySelectionMethod temporaryDirectoryPath
let reformatedFastaInput = map reformatFasta fastaInput
let staticOptions = StaticOptions temporaryDirectoryPath sessionId (fromJust inputnSCICutoff) Nothing singleHitperTax inputQuerySelectionMethod inputQueryNumber lengthFilter coverageFilter blastSoftmasking threads Nothing Nothing (setVerbose verboseLevel) True
let initialization = ModelConstruction iterationNumber reformatedFastaInput [] Nothing Nothing (fromJust inputEvalueCutoff) False [] [] inputGenomesFasta
logMessage (show initialization) temporaryDirectoryPath
modelConstructionResults <- scanModelConstructer staticOptions initialization
let resultTaxonomyRecordsCSVTable = constructTaxonomyRecordsCSVTable modelConstructionResults
writeFile (temporaryDirectoryPath ++ "result.csv") resultTaxonomyRecordsCSVTable
if performEvaluation
then do
resultEvaluation <- evaluateConstructionResult staticOptions modelConstructionResults
appendFile (temporaryDirectoryPath ++ "Log") resultEvaluation
resultSummary modelConstructionResults staticOptions
writeFile (temporaryDirectoryPath ++ "done") ""
else do
resultSummary modelConstructionResults staticOptions
writeFile (temporaryDirectoryPath ++ "done") ""
alienVersion :: String
alienVersion = showVersion version