BiobaseTypes-0.2.0.1: Biobase/Types/Location.hs
-- | Annotate the genomic @Location@ of features or elements. A @Location@ is
-- always contiguous, using strand, 0-based position, and length.
-- Transformation to different systems of annotation is made possible.
module Biobase.Types.Location where
import Control.Lens hiding (Index, index)
import GHC.Generics (Generic)
import GHC.TypeNats
import Prelude hiding (length)
import Biobase.Types.Index
import Biobase.Types.Strand
-- | Location information.
data Location = Location
{ _lStrand ∷ !Strand
-- ^ On which strand are we
, _lStart ∷ !(Index 0)
-- ^ Start, 0-based
, _lLength ∷ !Int
-- ^ number of characters in this location
, _lTotalLength ∷ !Int
-- ^ the total length of the "contig" (or whatever) this location is positioned in.
} deriving (Eq,Ord,Read,Show,Generic)
makeLenses ''Location
makePrisms ''Location
instance Reversing Location where
{-# Inline reversing #-}
reversing = undefined
-- | An isomorphism between locations, and triples of @Strand,Start,End@, where
-- end is inclusive. For @length==0@ locations, this will mean @start<end@ on
-- the plus strand.
--
-- This should hold for all @k@, in @Index k@.
startEndInclusive ∷ (KnownNat k) ⇒ Iso' Location (Strand, (Index k, Index k), Int)
{-# Inline startEndInclusive #-}
startEndInclusive = iso l2r r2l
where l2r z = let s = z^.lStrand; f = z^.lStart; l = z^.lLength
in (s, (reIndex f, reIndex $ f +. l -. 1), z^.lTotalLength)
r2l (s,(f,t),ttl) = Location s (reIndex f) (delta f t + 1) ttl
-- | During streaming construction, it is possible that we know a feature is on
-- the @-@ strand, but the length of the contig is not known yet.
--
-- @
-- 0 1 2
-- 012345678901234567890
-- >--- + 2 4 Location + 2 4
-- <--- Reversed 5 4 Location - 12 4
-- 098765432109876543210
-- 2 1 0
-- @
--
--
data PartialLocation
-- | Location, when it is not yet known how long the contig will be.
= PartialLocation
{ _plStrand ∷ !Strand
, _plStart ∷ !(Index 0)
, _plLength ∷ !Int
}
-- | The reversed strand. However, we have an @plEnd@, not a @plStart@ now!
| ReversedPartialLocation
{ _plStrand ∷ !Strand
, _plEnd ∷ !(Index 0)
, _plLength ∷ !Int
}
deriving (Eq,Ord,Read,Show,Generic)
makeLenses ''PartialLocation
makePrisms ''PartialLocation
-- | Reversing a reversible location means moving the start to the end.
instance Reversing PartialLocation where
{-# Inline reversing #-}
reversing = \case
PartialLocation s t l → ReversedPartialLocation (s^.reversed) t l
-- An isomorphism between a 'Location' and the pair @('PartialLocation',Int)@
-- exists.
locationPartial ∷ Iso' Location (PartialLocation,Int)
{-# Inline locationPartial #-}
locationPartial = iso l2r r2l where
l2r l = (PartialLocation (view lStrand l) (view lStart l) (view lLength l), l^.lTotalLength)
r2l (p,z) = case p of PartialLocation s t l → Location s t l z
ReversedPartialLocation s e l
| s `elem` [PlusStrand,MinusStrand] → Location s (index $ z- getIndex e -l) l z
| otherwise → Location s e l z