module Biobase.GeneticCodes
( module Biobase.GeneticCodes
, module Biobase.GeneticCodes.Types
, fromByteString
, fromFile
, geneticCodes
, translate
) where
import Control.Lens
import Control.Monad.Except
import Data.List (find)
import Data.Text (pack)
import Data.Text (Text,isInfixOf,unpack)
import System.Directory (doesFileExist)
import Text.Printf
import System.Exit (exitSuccess)
import Biobase.GeneticCodes.Embedded
import Biobase.GeneticCodes.Import
import Biobase.GeneticCodes.Translation
import Biobase.GeneticCodes.Types
codeByTableID
:: (MonadError String m)
=> [TranslationTable c a]
-> Int
-> m (TranslationTable c a)
codeByTableID :: [TranslationTable c a] -> Int -> m (TranslationTable c a)
codeByTableID [TranslationTable c a]
ts Int
i
= m (TranslationTable c a)
-> (TranslationTable c a -> m (TranslationTable c a))
-> Maybe (TranslationTable c a)
-> m (TranslationTable c a)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> m (TranslationTable c a)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String -> m (TranslationTable c a))
-> String -> m (TranslationTable c a)
forall a b. (a -> b) -> a -> b
$ String -> Int -> String
forall r. PrintfType r => String -> r
printf String
"No TranslationTable with ID %d found!" Int
i) TranslationTable c a -> m (TranslationTable c a)
forall (m :: * -> *) a. Monad m => a -> m a
return
(Maybe (TranslationTable c a) -> m (TranslationTable c a))
-> Maybe (TranslationTable c a) -> m (TranslationTable c a)
forall a b. (a -> b) -> a -> b
$ (TranslationTable c a -> Bool)
-> [TranslationTable c a] -> Maybe (TranslationTable c a)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\TranslationTable c a
t -> TranslationTable c a
tTranslationTable c a
-> Getting Int (TranslationTable c a) Int -> Int
forall s a. s -> Getting a s a -> a
^.Getting Int (TranslationTable c a) Int
forall c a. Lens' (TranslationTable c a) Int
tableID Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
i) [TranslationTable c a]
ts
codeByTableNameInfix
:: (MonadError String m)
=> [TranslationTable c a]
-> Text
-> m (TranslationTable c a)
codeByTableNameInfix :: [TranslationTable c a] -> Text -> m (TranslationTable c a)
codeByTableNameInfix [TranslationTable c a]
ts Text
n
= m (TranslationTable c a)
-> (TranslationTable c a -> m (TranslationTable c a))
-> Maybe (TranslationTable c a)
-> m (TranslationTable c a)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> m (TranslationTable c a)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String -> m (TranslationTable c a))
-> String -> m (TranslationTable c a)
forall a b. (a -> b) -> a -> b
$ String -> String -> String
forall r. PrintfType r => String -> r
printf String
"No TranslationTable with Name infix %s found!" (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Text -> String
unpack Text
n) TranslationTable c a -> m (TranslationTable c a)
forall (m :: * -> *) a. Monad m => a -> m a
return
(Maybe (TranslationTable c a) -> m (TranslationTable c a))
-> Maybe (TranslationTable c a) -> m (TranslationTable c a)
forall a b. (a -> b) -> a -> b
$ (TranslationTable c a -> Bool)
-> [TranslationTable c a] -> Maybe (TranslationTable c a)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\TranslationTable c a
t -> Text
n Text -> Text -> Bool
`isInfixOf` (TranslationTable c a
tTranslationTable c a
-> Getting Text (TranslationTable c a) Text -> Text
forall s a. s -> Getting a s a -> a
^.Getting Text (TranslationTable c a) Text
forall c a. Lens' (TranslationTable c a) Text
tableName)) [TranslationTable c a]
ts
fromFileOrCached
:: (MonadIO m, MonadError String m)
=> FilePath
-> m (TranslationTable Char Char)
fromFileOrCached :: String -> m (TranslationTable Char Char)
fromFileOrCached String
fp = do
Bool
dfe ← IO Bool -> m Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> m Bool) -> IO Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ String -> IO Bool
doesFileExist String
fp
if | String
fp String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"list" -> do
((Int, Text) -> m ()) -> [(Int, Text)] -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> ((Int, Text) -> IO ()) -> (Int, Text) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Text -> IO ()) -> (Int, Text) -> IO ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (String -> Int -> Text -> IO ()
forall r. PrintfType r => String -> r
printf String
"%3d %s\n")) [ (TranslationTable Char Char
tTranslationTable Char Char
-> Getting Int (TranslationTable Char Char) Int -> Int
forall s a. s -> Getting a s a -> a
^.Getting Int (TranslationTable Char Char) Int
forall c a. Lens' (TranslationTable c a) Int
tableID,TranslationTable Char Char
tTranslationTable Char Char
-> Getting Text (TranslationTable Char Char) Text -> Text
forall s a. s -> Getting a s a -> a
^.Getting Text (TranslationTable Char Char) Text
forall c a. Lens' (TranslationTable c a) Text
tableName) | TranslationTable Char Char
t ← [TranslationTable Char Char]
geneticCodes ]
IO (TranslationTable Char Char) -> m (TranslationTable Char Char)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (TranslationTable Char Char)
forall a. IO a
exitSuccess
| Bool
dfe -> String -> m [TranslationTable Char Char]
forall (m :: * -> *).
(MonadIO m, MonadError String m) =>
String -> m [TranslationTable Char Char]
fromFile String
fp m [TranslationTable Char Char]
-> ([TranslationTable Char Char] -> m (TranslationTable Char Char))
-> m (TranslationTable Char Char)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
[TranslationTable Char Char
x] -> TranslationTable Char Char -> m (TranslationTable Char Char)
forall (m :: * -> *) a. Monad m => a -> m a
return TranslationTable Char Char
x
[TranslationTable Char Char]
xs -> String -> m (TranslationTable Char Char)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String -> m (TranslationTable Char Char))
-> String -> m (TranslationTable Char Char)
forall a b. (a -> b) -> a -> b
$ String
fp String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" should contain exactly one translation table!"
| [(Int
k,String
"")] <- ReadS Int
forall a. Read a => ReadS a
reads String
fp -> [TranslationTable Char Char]
-> Int -> m (TranslationTable Char Char)
forall (m :: * -> *) c a.
MonadError String m =>
[TranslationTable c a] -> Int -> m (TranslationTable c a)
codeByTableID [TranslationTable Char Char]
geneticCodes Int
k
| Bool
otherwise -> [TranslationTable Char Char]
-> Text -> m (TranslationTable Char Char)
forall (m :: * -> *) c a.
MonadError String m =>
[TranslationTable c a] -> Text -> m (TranslationTable c a)
codeByTableNameInfix [TranslationTable Char Char]
geneticCodes (Text -> m (TranslationTable Char Char))
-> Text -> m (TranslationTable Char Char)
forall a b. (a -> b) -> a -> b
$ String -> Text
pack String
fp