BiobaseXNA-0.5.0.0: Biobase/Secondary.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
-- | Secondary structure: define basepairs as Int-tuples, the three edges, a
-- nucleotide can use for pairing and the cis/trans isomerism. Both edges and
-- cis/trans come with a tag for "unknown".
--
-- TODO set ext-annotations to be (isomerism,edge,edge) and have a asString
-- instance to read "cWW" "tSH" and other notation.
module Biobase.Secondary where
import Data.Primitive.Types
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Generic.Mutable as VGM
import qualified Data.Vector.Unboxed as VU
import Data.Ix (Ix(..))
import Data.Tuple (swap)
import Biobase.Primary
import Biobase.Primary.Bounds
-- | A basepair is simply a pair of Ints which are 0-indexing a sequence.
--
-- TODO storable vector, newtype, peek/poke?
type PairIdx = (Int,Int)
-- | A pair as a tuple containing 'Nuc's.
type Pair = (Nuc,Nuc)
-- | Annotation for a basepair.
type ExtPairAnnotation = (CTisomerism,Edge,Edge)
-- | An extended basepair is a basepair, annotated with edge and CTisomerism.
type ExtPairIdx = (PairIdx,ExtPairAnnotation)
-- | An extended basepair, with nucleotides an annotation.
type ExtPair = (Pair,ExtPairAnnotation)
-- | Each nucleotide in a pair may be paired using one of three edges:
-- watson-crik, sugar, or hoogsteen.
newtype Edge = Edge {unEdge :: Int}
deriving (Eq,Ord,Ix)
(wc : sugar : hoogsteen : unknownEdge : _) = map Edge [0..]
charEdgeList =
[ ('W',wc)
, ('S',sugar)
, ('H',hoogsteen)
, ('?',unknownEdge)
]
edgeCharList = map swap charEdgeList
-- | Human-readable Show instance.
instance Show Edge where
show k
| Just v <- k `lookup` edgeCharList = [v]
| otherwise = "?"
-- | Human-readable Read instance.
instance Read Edge where
readsPrec p [] = []
readsPrec p (x:xs)
| x ==' ' = readsPrec p xs
| Just n <- x `lookup` charEdgeList = [(n,xs)]
| otherwise = []
-- | Nucleotides in a pairing may be in the cis(==?) or trans(==?) state.
newtype CTisomerism = CT {unCT :: Int}
deriving (Eq,Ord,Ix)
(cis : trans : unknownCT : _) = map CT [0..]
antiCT = undefined
paraCT = undefined
charCTList =
[ ('C',cis)
, ('T',trans)
-- TODO antiCT, paraCT
]
ctCharList = map swap charCTList
-- | Human-readable Show instance.
instance Show CTisomerism where
show k
| Just v <- k `lookup` ctCharList = [v]
| otherwise = "?"
-- | Human-readable Read instance.
instance Read CTisomerism where
readsPrec p [] = []
readsPrec p (x:xs)
| x ==' ' = readsPrec p xs
| Just n <- x `lookup` charCTList = [(n,xs)]
| otherwise = []
-- * Instances
-- ** Instances for 'Edge'
deriving instance Prim Edge
deriving instance VGM.MVector VU.MVector Edge
deriving instance VG.Vector VU.Vector Edge
deriving instance VU.Unbox Edge
instance Bounded Edge where
minBound = wc
maxBound = unknownEdge
instance Bounds Edge where
minNormal = wc
maxNormal = wc
minExtended = wc
maxExtended = hoogsteen
instance Enum Edge where
toEnum = Edge
fromEnum = unEdge
-- ** Instances for 'CTisomerism'
deriving instance Prim CTisomerism
deriving instance VGM.MVector VU.MVector CTisomerism
deriving instance VG.Vector VU.Vector CTisomerism
deriving instance VU.Unbox CTisomerism
instance Bounded CTisomerism where
minBound = cis
maxBound = unknownCT
instance Bounds CTisomerism where
minNormal = cis
maxNormal = cis
minExtended = cis
maxExtended = trans
instance Enum CTisomerism where
toEnum = CT
fromEnum = unCT
-- ** special show instances
-- | This one requires ghc head
--
-- TODO maybe newtype this triple?
instance Show (CTisomerism,Edge,Edge) where
show (ct,eI,eJ) = concat [show ct, show eI, show eJ]