module ELynx.Sequence.Translate
( translateSeq,
)
where
import qualified Data.Vector.Unboxed as V
import ELynx.Alphabet.Alphabet
import qualified ELynx.Alphabet.Character as C
import ELynx.Character.Codon
import ELynx.Sequence.Sequence
chopVec :: V.Unbox a => Int -> V.Vector a -> [V.Vector a]
chopVec :: forall a. Unbox a => Int -> Vector a -> [Vector a]
chopVec Int
n Vector a
xs
| forall a. Unbox a => Vector a -> Int
V.length Vector a
xs forall a. Ord a => a -> a -> Bool
< Int
n = []
| Bool
otherwise = forall a. Unbox a => Int -> Vector a -> Vector a
V.take Int
n Vector a
xs forall a. a -> [a] -> [a]
: forall a. Unbox a => Int -> Vector a -> [Vector a]
chopVec Int
n (forall a. Unbox a => Int -> Vector a -> Vector a
V.drop Int
n Vector a
xs)
translateSeq :: UniversalCode -> Int -> Sequence -> Sequence
translateSeq :: UniversalCode -> Int -> Sequence -> Sequence
translateSeq UniversalCode
uc Int
rf (Sequence Name
n Name
d Alphabet
a Characters
cs) = case Alphabet
a of
Alphabet
DNA -> Name -> Name -> Alphabet -> Characters -> Sequence
Sequence Name
n Name
d Alphabet
ProteinS (forall {a} {a}.
(Character a, Character a) =>
(Codon a -> a) -> Characters
cs' forall a b. (a -> b) -> a -> b
$ UniversalCode -> Codon Nucleotide -> AminoAcidS
translate UniversalCode
uc)
Alphabet
DNAX -> Name -> Name -> Alphabet -> Characters -> Sequence
Sequence Name
n Name
d Alphabet
ProteinS (forall {a} {a}.
(Character a, Character a) =>
(Codon a -> a) -> Characters
cs' forall a b. (a -> b) -> a -> b
$ UniversalCode -> Codon NucleotideX -> AminoAcidS
translateX UniversalCode
uc)
Alphabet
DNAI -> Name -> Name -> Alphabet -> Characters -> Sequence
Sequence Name
n Name
d Alphabet
ProteinI (forall {a} {a}.
(Character a, Character a) =>
(Codon a -> a) -> Characters
cs' forall a b. (a -> b) -> a -> b
$ UniversalCode -> Codon NucleotideI -> AminoAcidI
translateI UniversalCode
uc)
Alphabet
_ -> forall a. HasCallStack => [Char] -> a
error [Char]
"translate: can only translate DNA, DNAX, and DNAI."
where
cs' :: (Codon a -> a) -> Characters
cs' Codon a -> a
f = forall a. Character a => Vector a -> Characters
C.fromCVec forall a b. (a -> b) -> a -> b
$ forall a b.
(Unbox a, Ord a, Unbox b) =>
(Codon a -> b) -> Int -> Vector a -> Vector b
translateVecWith Codon a -> a
f Int
rf (forall a. Character a => Characters -> Vector a
C.toCVec Characters
cs)
translateVecWith ::
(V.Unbox a, Ord a, V.Unbox b) =>
(Codon a -> b) ->
Int ->
V.Vector a ->
V.Vector b
translateVecWith :: forall a b.
(Unbox a, Ord a, Unbox b) =>
(Codon a -> b) -> Int -> Vector a -> Vector b
translateVecWith Codon a -> b
f Int
rf Vector a
cs
| Int
rf forall a. Ord a => a -> a -> Bool
> Int
2 = forall a. HasCallStack => [Char] -> a
error [Char]
"translateVecWith: reading frame is larger than 2."
| Int
rf forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"translateVecWith: reading frame is negative."
| Bool
otherwise = Vector b
aas
where
codons :: [Codon a]
codons = forall a b. (a -> b) -> [a] -> [b]
map forall (v :: * -> *) a. Vector v a => v a -> Codon a
fromVecUnsafe forall a b. (a -> b) -> a -> b
$ forall a. Unbox a => Int -> Vector a -> [Vector a]
chopVec Int
3 forall a b. (a -> b) -> a -> b
$ forall a. Unbox a => Int -> Vector a -> Vector a
V.drop Int
rf Vector a
cs
aas :: Vector b
aas = forall a. Unbox a => [a] -> Vector a
V.fromList forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Codon a -> b
f [Codon a]
codons