seqloc-0.5: src/Bio/SeqLoc/Position.hs
{-# LANGUAGE FlexibleContexts, GeneralizedNewtypeDeriving, OverloadedStrings #-}
{-| Data type for a sequence position.
Zero-based 'Offset'indices are used throughout, to facilitate direct
use of indexing functions on 'SeqData'.
-}
module Bio.SeqLoc.Position (
-- * Sequence positions
Offset(..)
, Pos(..)
-- * Manipulating positions
, slide
-- * Extracting sequences
, atPos
)
where
import Control.Applicative
import Control.Arrow
import Control.Monad (liftM)
import qualified Data.ByteString.Char8 as BS
import Bio.Core.Sequence
import Bio.Core.Strand
import Bio.SeqLoc.LocRepr
import Bio.SeqLoc.SeqLike
import Bio.SeqLoc.Strand
-- | Stranded position in a sequence
data Pos = Pos { offset :: !Offset -- ^ 0-based index of the position
, strand :: !Strand -- ^ Strand of the position
}
deriving (Eq, Ord, Show)
instance Stranded Pos where
revCompl (Pos off str) = Pos off (revCompl str)
instance LocRepr Pos where
repr (Pos off str) = BS.concat [ repr off, repr str ]
unrepr = Pos <$> unrepr <*> unrepr
-- | Returns a position resulting from sliding the original position
-- along the sequence by a specified offset. A positive offset will
-- move the position away from the 5\' end of the forward stand of the
-- sequence regardless of the strand of the position itself. Thus,
--
-- > slide (revCompl pos) off == revCompl (slide pos off)
slide :: Pos -> Offset -> Pos
slide (Pos off str) doff = Pos (off + doff) str
-- | Extract 'Just' the item at a specific sequence position, or
-- 'Nothing' if the position lies outside the bounds of the sequence.
atPos :: (SeqLike s) => s -> Pos -> Maybe Char
atPos sequ (Pos off str) = liftM (stranded str) . ntAt sequ $ off
{-# SPECIALIZE atPos :: String -> Pos -> Maybe Char #-}
{-# SPECIALIZE atPos :: BS.ByteString -> Pos -> Maybe Char #-}