seqloc 0.2.1 → 0.3
raw patch · 9 files changed
+118/−95 lines, 9 filesdep +biocore
Dependencies added: biocore
Files
- seqloc.cabal +3/−3
- src/Bio/SeqLoc/LocRepr.hs +21/−0
- src/Bio/SeqLoc/Location.hs +18/−16
- src/Bio/SeqLoc/OnSeq.hs +15/−7
- src/Bio/SeqLoc/Position.hs +13/−12
- src/Bio/SeqLoc/SpliceLocation.hs +6/−6
- src/Bio/SeqLoc/Strand.hs +5/−17
- src/Bio/SeqLoc/Transcript.hs +9/−9
- test/TestMain.hs +28/−25
seqloc.cabal view
@@ -1,5 +1,5 @@ Name: seqloc-Version: 0.2.1+Version: 0.3 Cabal-Version: >= 1.2 Synopsis: Handle sequence locations for bioinformatics Description: Handle sequence locations for bioinformatics@@ -24,7 +24,7 @@ Bio.SeqLoc.OnSeq, Bio.SeqLoc.LocRepr, Bio.SeqLoc.Transcript- Build-depends: base >= 4.2 && < 5, bytestring, haskell98, attoparsec >= 0.8.5+ Build-depends: base >= 4.2 && < 5, bytestring, haskell98, attoparsec >= 0.8.5, biocore Hs-Source-Dirs: src Ghc-options: -Wall @@ -38,6 +38,6 @@ Bio.SeqLoc.OnSeq, Bio.SeqLoc.LocRepr Build-depends: base >= 4.2 && < 5, bytestring, haskell98, attoparsec >= 0.8.5,- QuickCheck, random+ QuickCheck, random, biocore Hs-Source-Dirs: src, test Ghc-options: -Wall
src/Bio/SeqLoc/LocRepr.hs view
@@ -1,13 +1,21 @@+{-# LANGUAGE OverloadedStrings #-}+ module Bio.SeqLoc.LocRepr ( LocRepr(..), reprStr , unreprMaybe, unreprEither, unreprErr ) where +import Control.Applicative+import qualified Data.ByteString as BSW import qualified Data.ByteString.Char8 as BS +import qualified Data.Attoparsec.Char8 as AP (isDigit_w8) import qualified Data.Attoparsec.Zepto as ZP +import Bio.Core.Sequence+import Bio.Core.Strand+ class LocRepr l where repr :: l -> BS.ByteString unrepr :: ZP.Parser l@@ -23,3 +31,16 @@ unreprErr :: (LocRepr l) => BS.ByteString -> l unreprErr = either error id . ZP.parse unrepr++instance LocRepr Strand where+ repr Plus = BS.pack "(+)"+ repr Minus = BS.pack "(-)"+ unrepr = (ZP.string "(+)" *> return Plus) <|>+ (ZP.string "(-)" *> return Minus)++instance LocRepr Offset where+ repr = BS.pack . show . unOff+ unrepr = (negate <$> (ZP.string "-" *> decimal)) <|> (ZP.string "+" *> decimal) <|> decimal+ where decimal = Offset . BSW.foldl' step 0 <$> ZP.takeWhile AP.isDigit_w8+ step a w = a * 10 + fromIntegral (w - 48)+
src/Bio/SeqLoc/Location.hs view
@@ -26,6 +26,8 @@ import qualified Data.Attoparsec.Zepto as ZP +import Bio.Core.Strand+ import Bio.SeqLoc.LocRepr import qualified Bio.SeqLoc.Position as Pos import Bio.SeqLoc.Strand@@ -43,7 +45,7 @@ -- | Sequence position of the start of the location. This is the 5' -- end on the location strand, which will have a higher offset than- -- 'endPos' if the location is on the 'RevCompl' strand.+ -- 'endPos' if the location is on the 'Minus' strand. startPos :: l -> Pos.Pos -- | Sequence position of the end of the location, as described in@@ -96,7 +98,7 @@ -- location on each end, based on a pair of (/5\' extension/, /3\' -- extension/). The 5\' extension is applied to the 5\' end of the -- location on the location strand; if the location is on the- -- 'RevCompl' strand, the 5\' end will have a higher offset than the+ -- 'Minus' strand, the 5\' end will have a higher offset than the -- 3\' end and this offset will increase by the amount of the 5\' -- extension. Similarly, the 3\' extension is applied to the 3\' -- end of the location.@@ -149,12 +151,12 @@ bounds (ContigLoc seq5 len _) = (seq5, seq5 + len - 1) startPos (ContigLoc seq5 len str) = case str of- Fwd -> Pos.Pos seq5 str- RevCompl -> Pos.Pos (seq5 + len - 1) str+ Plus -> Pos.Pos seq5 str+ Minus -> Pos.Pos (seq5 + len - 1) str endPos (ContigLoc seq5 len str) = case str of- Fwd -> Pos.Pos (seq5 + len - 1) str- RevCompl -> Pos.Pos seq5 str+ Plus -> Pos.Pos (seq5 + len - 1) str+ Minus -> Pos.Pos seq5 str clocInto = clocClocInto clocOutof = clocClocOutof extend = clocExtend@@ -177,8 +179,8 @@ -- reverse complement strand. fromStartEnd :: Pos.Offset -> Pos.Offset -> ContigLoc fromStartEnd start end- | start < end = ContigLoc start (1 + end - start) Fwd- | otherwise = ContigLoc end (1 + start - end) RevCompl+ | start < end = ContigLoc start (1 + end - start) Plus+ | otherwise = ContigLoc end (1 + start - end) Minus -- | Create a sequence location from the sequence position of the -- start of the location and the length of the position. The strand@@ -186,8 +188,8 @@ -- position, are determined by the strand of the starting position. fromPosLen :: Pos.Pos -> Pos.Offset -> ContigLoc fromPosLen _ len | len < 0 = error "Bio.SeqLoc.Location.fromPosLen: len < 0"-fromPosLen (Pos.Pos off5 Fwd) len = ContigLoc off5 len Fwd-fromPosLen (Pos.Pos off3 RevCompl) len = ContigLoc (off3 - (len - 1)) len RevCompl+fromPosLen (Pos.Pos off5 Plus) len = ContigLoc off5 len Plus+fromPosLen (Pos.Pos off3 Minus) len = ContigLoc (off3 - (len - 1)) len Minus -- | Returns a location resulting from sliding the original location -- along the sequence by a specified offset. A positive offset will@@ -202,21 +204,21 @@ clocPosInto (Pos.Pos pos pStrand) (ContigLoc seq5 len cStrand) | pos < seq5 || pos >= seq5 + len = Nothing | otherwise = Just $ case cStrand of- Fwd -> Pos.Pos (pos - seq5) pStrand- RevCompl -> Pos.Pos (seq5 + len - (pos + 1)) (revCompl pStrand)+ Plus -> Pos.Pos (pos - seq5) pStrand+ Minus -> Pos.Pos (seq5 + len - (pos + 1)) (revCompl pStrand) clocPosOutof :: Pos.Pos -> ContigLoc -> Maybe Pos.Pos clocPosOutof (Pos.Pos pos pStrand) (ContigLoc seq5 len cStrand) | pos < 0 || pos >= len = Nothing | otherwise = Just $ case cStrand of- Fwd -> Pos.Pos (pos + seq5) pStrand- RevCompl -> Pos.Pos (seq5 + len - (pos + 1)) (revCompl pStrand)+ Plus -> Pos.Pos (pos + seq5) pStrand+ Minus -> Pos.Pos (seq5 + len - (pos + 1)) (revCompl pStrand) clocExtend :: (Pos.Offset, Pos.Offset) -> ContigLoc -> ContigLoc clocExtend (ext5, ext3) (ContigLoc seq5 len str) = case str of- Fwd -> ContigLoc (seq5 - ext5) (len + ext5 + ext3) str- RevCompl -> ContigLoc (seq5 - ext3) (len + ext5 + ext3) str+ Plus -> ContigLoc (seq5 - ext5) (len + ext5 + ext3) str+ Minus -> ContigLoc (seq5 - ext3) (len + ext5 + ext3) str clocClocInto :: ContigLoc -> ContigLoc -> Maybe ContigLoc clocClocInto subcloc tocloc
src/Bio/SeqLoc/OnSeq.hs view
@@ -8,7 +8,7 @@ -} module Bio.SeqLoc.OnSeq ( - SeqName(..)+ SeqLabel(..), unSeqLabel , OnSeq(..) @@ -18,7 +18,7 @@ -- * Contiguous location spans on named sequences , ContigSeqLoc - -- * Arbitrary location spans on named sequences+ -- * Arbitrary location spans on named sequences , SpliceSeqLoc , andSameSeq@@ -28,20 +28,23 @@ import Control.Applicative import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as LBS import Data.ByteString.Internal (c2w)-import Data.String import qualified Data.Attoparsec.Zepto as ZP +import Bio.Core.Sequence+ import Bio.SeqLoc.LocRepr import qualified Bio.SeqLoc.Location as Loc import qualified Bio.SeqLoc.Position as Pos import qualified Bio.SeqLoc.SpliceLocation as SpLoc import Bio.SeqLoc.Strand -newtype SeqName = SeqName { unSeqName :: BS.ByteString } deriving (Show, Read, Eq, Ord, IsString)+unSeqLabel :: SeqLabel -> BS.ByteString+unSeqLabel = BS.concat . LBS.toChunks . unSL -data OnSeq s = OnSeq { onSeqName :: !SeqName, unOnSeq :: !s } deriving (Show, Read, Eq, Ord)+data OnSeq s = OnSeq { onSeqLabel :: !SeqLabel, unOnSeq :: !s } deriving (Eq, Ord) at :: BS.ByteString at = BS.singleton '@'@@ -50,8 +53,8 @@ revCompl (OnSeq name obj) = OnSeq name (revCompl obj) instance LocRepr s => LocRepr (OnSeq s) where- repr (OnSeq name obj) = BS.concat [ unSeqName name, at, repr obj ]- unrepr = OnSeq <$> (SeqName <$> ZP.takeWhile (/= c2w '@')) <* ZP.string at <*> unrepr+ repr (OnSeq name obj) = BS.concat [ unSeqLabel name, at, repr obj ]+ unrepr = OnSeq <$> (SeqLabel . LBS.fromChunks . (: []) <$> ZP.takeWhile (/= c2w '@')) <* ZP.string at <*> unrepr type SeqOffset = OnSeq Pos.Offset @@ -69,3 +72,8 @@ andSameSeq :: (a -> b -> Bool) -> OnSeq a -> OnSeq b -> Bool andSameSeq p (OnSeq n1 x) (OnSeq n2 y) | n1 == n2 = p x y | otherwise = False++instance BioSeq (OnSeq BS.ByteString) where+ seqlabel = onSeqLabel+ seqdata = SeqData . LBS.fromChunks . (: []) . unOnSeq+ seqlength = Offset . fromIntegral . BS.length . unOnSeq
src/Bio/SeqLoc/Position.hs view
@@ -21,32 +21,33 @@ where import Control.Applicative+import Control.Arrow import Control.Monad (liftM)-import qualified Data.ByteString as BSW import qualified Data.ByteString.Char8 as BS-import Data.Int (Int64) -import qualified Data.Attoparsec.Char8 as AP (isDigit_w8)-import qualified Data.Attoparsec.Zepto as ZP+import Bio.Core.Sequence+import Bio.Core.Strand import Bio.SeqLoc.LocRepr import Bio.SeqLoc.SeqLike import Bio.SeqLoc.Strand --- | Unstranded offset in a sequence-newtype Offset = Offset { unOffset :: Int64 } deriving (Eq, Ord, Show, Read, Num, Real, Enum, Integral)+instance Enum Offset where+ toEnum = Offset . toEnum+ fromEnum = fromEnum . unOff -instance LocRepr Offset where- repr = BS.pack . show . unOffset- unrepr = (negate <$> (ZP.string "-" *> decimal)) <|> (ZP.string "+" *> decimal) <|> decimal- where decimal = Offset . BSW.foldl' step 0 <$> ZP.takeWhile AP.isDigit_w8- step a w = a * 10 + fromIntegral (w - 48)+instance Real Offset where+ toRational = toRational . unOff +instance Integral Offset where+ (Offset n) `quotRem` (Offset d) = (Offset *** Offset) $ n `quotRem` d+ toInteger = toInteger . unOff+ -- | 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, Read)+ deriving (Eq, Ord, Show) instance Stranded Pos where revCompl (Pos off str) = Pos off (revCompl str)
src/Bio/SeqLoc/SpliceLocation.hs view
@@ -54,8 +54,8 @@ c5end = snd . bounds $ c5 c3start = fst . bounds $ c3 inOrder = case strand c5 of- Fwd -> c5end < c3start- RevCompl -> c5end > c3start+ Plus -> c5end < c3start+ Minus -> c5end > c3start fromContigs :: [ContigLoc] -> Maybe SpliceLoc fromContigs [] = Nothing@@ -67,11 +67,11 @@ tails slp@(SpliceLocPrev _ n) = slp : (tails n) instance Stranded SpliceLoc where- revCompl sll = fromMaybe badRevCompl . foldl' addprev newlast $ slrest+ revCompl sll = fromMaybe badMinus . foldl' addprev newlast $ slrest where (sl0:slrest) = tails sll newlast = Just $! singleton . revCompl . contig $ sl0 addprev slnew slold = slnew >>= consContig (revCompl . contig $ slold)- badRevCompl = error $ "Bad junction doing reverse complement on " ++ (BS.unpack . repr) sll+ badMinus = error $ "Bad junction doing reverse complement on " ++ (BS.unpack . repr) sll instance LocRepr SpliceLoc where repr = BS.intercalate (BS.singleton ';') . map repr . contigs@@ -170,12 +170,12 @@ | pos5 < 0 = Nothing | len < 0 = error $ "Bio.SeqLoc.SpliceLocation.regionOutof: input, " ++ show (pos5, len, cloc0) | pos5 >= len0 = regionOutof (pos5 - len0) len rest- | (pos5 + len <= len0) = let subcloc = fromPosLen (Pos.Pos pos5 Fwd) len+ | (pos5 + len <= len0) = let subcloc = fromPosLen (Pos.Pos pos5 Plus) len in case clocOutof subcloc cloc0 of Just out0 -> Just [out0] Nothing -> error $ "regionOutof: final bounds failure, " ++ (BS.unpack . repr) subcloc | otherwise = let outlen0 = len0 - pos5- subcloc = fromPosLen (Pos.Pos pos5 Fwd) outlen0+ subcloc = fromPosLen (Pos.Pos pos5 Plus) outlen0 in case clocOutof subcloc cloc0 of Just out0 -> liftM (out0 :) . regionOutof 0 (len - outlen0) $ rest Nothing -> error $ "regionOutof: internal bounds failure, " ++ (BS.unpack . repr) subcloc
src/Bio/SeqLoc/Strand.hs view
@@ -12,15 +12,12 @@ ) where -import Control.Applicative import Data.ByteString.Internal (c2w, w2c) import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Lazy.Char8 as LBS import Data.Word (Word8) -import qualified Data.Attoparsec.Zepto as ZP--import Bio.SeqLoc.LocRepr+import Bio.Core.Strand -- | Complement of a nucleotide character, swap A/T and G/C preserving -- case and leave all other characters unchanged.@@ -35,15 +32,6 @@ compl 'T' = 'A' compl ch = ch --- | Sequence strand-data Strand = Fwd | RevCompl deriving (Eq, Ord, Show, Read, Bounded, Enum)--instance LocRepr Strand where- repr Fwd = BS.pack "(+)"- repr RevCompl = BS.pack "(-)"- unrepr = (ZP.string "(+)" *> return Fwd) <|>- (ZP.string "(-)" *> return RevCompl)- -- | A nucleotide sequence or location on a nucleotide sequence that -- lies on a specific strand and has an orientation. class Stranded s where@@ -52,12 +40,12 @@ -- | Convert the orientation of a 'Stranded' thing based on a -- specified 'Strand' stranded :: (Stranded s) => Strand -> s -> s-stranded Fwd = id-stranded RevCompl = revCompl+stranded Plus = id+stranded Minus = revCompl instance Stranded Strand where- revCompl Fwd = RevCompl- revCompl RevCompl = Fwd+ revCompl Plus = Minus+ revCompl Minus = Plus instance Stranded Char where revCompl = compl
src/Bio/SeqLoc/Transcript.hs view
@@ -44,8 +44,8 @@ fromDonorAcceptor :: Pos.Pos -> Pos.Pos -> Junction fromDonorAcceptor d a = let len = 1 + abs (Pos.offset a - Pos.offset d) in case Pos.strand d of- Fwd -> Junction $! Loc.fromPosLen (Pos.slide d 1) len- RevCompl -> Junction $! Loc.fromPosLen (Pos.slide d (-1)) len+ Plus -> Junction $! Loc.fromPosLen (Pos.slide d 1) len+ Minus -> Junction $! Loc.fromPosLen (Pos.slide d (-1)) len -- | Donor position, i.e., the last position in the 5' exon around a -- junction.@@ -72,11 +72,11 @@ -- transcript identifier, along with the genomic location of the -- processed transcript and an optional coding sequence on that -- transcript.-data Transcript = Transcript { geneId :: !SeqName -- ^ Gene or locus name for a collection of transcripts- , trxId :: !SeqName -- ^ Specific transcript identifier+data Transcript = Transcript { geneId :: !SeqLabel -- ^ Gene or locus name for a collection of transcripts+ , trxId :: !SeqLabel -- ^ Specific transcript identifier , location :: !SpliceSeqLoc -- ^ Sequence location of processed transcript , cds :: !(Maybe Loc.ContigLoc) -- ^ Location of CDS on the transcript- } deriving (Show)+ } -- | 'Just' the location of the 5' UTR on the transcript, or 'Nothing' -- if there is no 'cds' on the transcript or if the 'cds' location@@ -85,7 +85,7 @@ utr5 :: Transcript -> Maybe Loc.ContigLoc utr5 trx = cds trx >>= utr5loc where utr5loc cdsloc = case Loc.startPos cdsloc of- (Pos.Pos startoff Fwd) | startoff > 0 -> Just $! Loc.fromBoundsStrand 0 (startoff - 1) Fwd+ (Pos.Pos startoff Plus) | startoff > 0 -> Just $! Loc.fromBoundsStrand 0 (startoff - 1) Plus _ -> Nothing -- | 'Just' the location of the 3' UTR on the transcript, or 'Nothing'@@ -95,7 +95,7 @@ utr3 :: Transcript -> Maybe Loc.ContigLoc utr3 trx = cds trx >>= utr3loc where utr3loc cdsloc = case Loc.endPos cdsloc of- (Pos.Pos endoff Fwd) | endoff < trxlast -> Just $! Loc.fromBoundsStrand (endoff + 1) trxlast Fwd+ (Pos.Pos endoff Plus) | endoff < trxlast -> Just $! Loc.fromBoundsStrand (endoff + 1) trxlast Plus _ -> Nothing trxlast = snd . Loc.bounds . unOnSeq . location $ trx @@ -112,5 +112,5 @@ sortContigs cs@(c0:_)= liftM sortStrand contigStrand where contigStrand | all ((== Loc.strand c0) . Loc.strand) cs = Just . Loc.strand $ c0 | otherwise = Nothing- sortStrand Fwd = sortBy (comparing Loc.offset5) cs- sortStrand RevCompl = sortBy (comparing (negate . Loc.offset5)) cs+ sortStrand Plus = sortBy (comparing Loc.offset5) cs+ sortStrand Minus = sortBy (comparing (negate . Loc.offset5)) cs
test/TestMain.hs view
@@ -38,7 +38,7 @@ , T "Pos atPos2" property_Pos_atPos2 , T "Pos repr" test_Pos_repr - , T "Contig revCompl" test_Contig_RevCompl+ , T "Contig revCompl" test_Contig_Minus , T "Contig pos into/outof inverse" property_ContigIntoOutof , T "Contig pos outof/into inverse" property_ContigOutofInto , T "Contig loc into/outof inverse" property_ContigLocIntoOutof@@ -48,13 +48,13 @@ , T "Contig seqData" property_Contig_seqData , T "Contig seqDataPadded" property_Contig_seqDataPadded , T "Contig seqData2" property_Contig_seqData2- , T "Contig extend/revCompl" property_Contig_extendRevCompl+ , T "Contig extend/revCompl" property_Contig_extendMinus , T "Contig fromStartEnd" property_Contig_fromStartEnd , T "Contig fromBoundsStrand" property_Contig_fromBoundsStrand , T "Contig overlaps" property_Contig_overlaps , T "Contig repr" test_Contig_repr - , T "Loc revCompl" test_Loc_RevCompl+ , T "Loc revCompl" test_Loc_Minus , T "Loc pos into/outof inverse" property_LocIntoOutof , T "Loc pos outof/into inverse" property_LocOutofInto , T "Loc outof based on bounds" test_Loc_OutofBounds@@ -67,7 +67,7 @@ , T "Loc seqDataPadded" property_Loc_seqDataPadded , T "SpLoc seqData2" property_SpLoc_seqData2 , T "SpLoc repr" test_SpLoc_repr- , T "SpLoc termini/revCompl" property_SpLoc_terminiRevCompl+ , T "SpLoc termini/revCompl" property_SpLoc_terminiMinus , T "SpLoc termini/extend" property_SpLoc_terminiExtend ] @@ -77,14 +77,17 @@ genNtByteString :: Int -> Gen BS.ByteString genNtByteString = liftM BS.pack . flip replicateM (elements "ACGT") -genName :: Gen SeqName-genName = liftM (SeqName . BS.pack) $ genNameLength >>= flip replicateM genNameChar+genName :: Gen SeqLabel+genName = liftM (SeqLabel . LBS.pack) $ genNameLength >>= flip replicateM genNameChar where genNameLength = choose (1, 20) genNameChar = elements $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ "-_" -instance Arbitrary SeqName where+instance Arbitrary SeqLabel where arbitrary = genName +instance Show SeqLabel where+ show = show . unSeqLabel+ test_revCompl :: (Eq s, Stranded s) => s -> Bool test_revCompl s = (revCompl . revCompl) s == s @@ -120,8 +123,8 @@ in if and [ Pos.offset pos >= 0, Pos.offset pos < seqlen ] then let fwdNt = BS.index sequ (fromIntegral . Pos.offset $ pos) in case Pos.strand pos of- Fwd -> actual == Just fwdNt- RevCompl -> actual == Just (compl $ fwdNt)+ Plus -> actual == Just fwdNt+ Minus -> actual == Just (compl $ fwdNt) else actual == Nothing property_Pos_atPos2 :: Pos.Pos -> Property@@ -138,7 +141,7 @@ -- Bio.BioSeq.Location instance Arbitrary Strand where- arbitrary = elements [Fwd, RevCompl]+ arbitrary = elements [Plus, Minus] instance Arbitrary Pos.Pos where arbitrary = liftM2 Pos.Pos genOffset arbitrary@@ -146,8 +149,8 @@ instance Arbitrary Loc.ContigLoc where arbitrary = liftM2 Loc.fromPosLen arbitrary genPositiveOffset -test_Contig_RevCompl :: Loc.ContigLoc -> Bool-test_Contig_RevCompl = test_revCompl+test_Contig_Minus :: Loc.ContigLoc -> Bool+test_Contig_Minus = test_revCompl property_ContigIntoOutof :: Loc.ContigLoc -> Pos.Pos -> Property property_ContigIntoOutof contig pos@@ -198,7 +201,7 @@ property_Contig_seqDataPadded contig = forAll (genNonNegOffset >>= genNtByteString . fromIntegral) $ \sequ -> (BS.pack $ map (fromMaybe 'N' . Pos.atPos sequ) contigPoses) == Loc.seqDataPad sequ contig- where contigPoses = mapMaybe (flip Loc.posOutof contig . flip Pos.Pos Fwd) [0..(Loc.length contig - 1)]+ where contigPoses = mapMaybe (flip Loc.posOutof contig . flip Pos.Pos Plus) [0..(Loc.length contig - 1)] property_Contig_seqData2 :: Loc.ContigLoc -> Property property_Contig_seqData2 contig@@ -211,8 +214,8 @@ , Loc.seqDataPad sequ contig == BS.pack (Loc.seqDataPad (BS.unpack sequ) contig) ] -property_Contig_extendRevCompl :: Loc.ContigLoc -> Property-property_Contig_extendRevCompl contig+property_Contig_extendMinus :: Loc.ContigLoc -> Property+property_Contig_extendMinus contig = forAll (liftM2 (,) genNonNegOffset genNonNegOffset) $ \(ext5, ext3) -> (revCompl $ Loc.extend (ext5, ext3) contig) == (Loc.extend (ext3, ext5) $ revCompl contig) @@ -250,16 +253,16 @@ if rc then return $ revCompl fwdloc else return fwdloc where genContigs = liftM (reverse . foldl' intervalsToContigs []) . genIntervals genIntervals nints = replicateM nints $ liftM2 (,) genPositiveOffset genPositiveOffset- intervalsToContigs [] (init5, len) = [Loc.fromPosLen (Pos.Pos init5 Fwd) len]+ intervalsToContigs [] (init5, len) = [Loc.fromPosLen (Pos.Pos init5 Plus) len] intervalsToContigs prevs@(prev:_) (nextoffset, nextlen) = let !prevend = Loc.offset5 prev + Loc.length prev- in (Loc.fromPosLen (Pos.Pos (prevend + nextoffset) Fwd) nextlen):prevs+ in (Loc.fromPosLen (Pos.Pos (prevend + nextoffset) Plus) nextlen):prevs instance Arbitrary SpLoc.SpliceLoc where arbitrary = genInvertibleLoc -test_Loc_RevCompl :: SpLoc.SpliceLoc -> Bool-test_Loc_RevCompl = test_revCompl+test_Loc_Minus :: SpLoc.SpliceLoc -> Bool+test_Loc_Minus = test_revCompl property_LocIntoOutof :: SpLoc.SpliceLoc -> Pos.Pos -> Property property_LocIntoOutof loc pos@@ -323,7 +326,7 @@ property_Loc_seqDataPadded loc = forAll (genNonNegOffset >>= genNtByteString . fromIntegral) $ \sequ -> (BS.pack $ map (fromMaybe 'N' . Pos.atPos sequ) locPoses) == Loc.seqDataPad sequ loc- where locPoses = mapMaybe (flip Loc.posOutof loc . flip Pos.Pos Fwd) [0..(Loc.length loc - 1)]+ where locPoses = mapMaybe (flip Loc.posOutof loc . flip Pos.Pos Plus) [0..(Loc.length loc - 1)] property_SpLoc_seqData2 :: SpLoc.SpliceLoc -> Property property_SpLoc_seqData2 sploc@@ -339,15 +342,15 @@ property_Loc_Within :: Pos.Pos -> Property property_Loc_Within pos = forAll genInvertibleLoc $ \loc ->- and [ (pos `Loc.posWithin` loc) == (maybe False ((/= RevCompl) . Pos.strand) $ Loc.posInto pos loc)+ and [ (pos `Loc.posWithin` loc) == (maybe False ((/= Minus) . Pos.strand) $ Loc.posInto pos loc) , ((Pos.offset pos) `Loc.offsetWithin` loc) == (isJust . Loc.posInto pos $ loc) ] test_SpLoc_repr :: SpLoc.SpliceLoc -> Bool test_SpLoc_repr = test_repr -property_SpLoc_terminiRevCompl :: SpLoc.SpliceLoc -> Bool-property_SpLoc_terminiRevCompl loc+property_SpLoc_terminiMinus :: SpLoc.SpliceLoc -> Bool+property_SpLoc_terminiMinus loc = and [ revCompl (Loc.startPos loc) == Loc.endPos (revCompl loc) , revCompl (Loc.endPos loc) == Loc.startPos (revCompl loc) ]@@ -358,8 +361,8 @@ forAll genNonNegOffset $ \ext3 -> let extloc = Loc.extend (ext5, ext3) loc strandSlide pos doff = case Pos.strand pos of- Fwd -> Pos.slide pos doff- RevCompl -> Pos.slide pos (negate doff)+ Plus -> Pos.slide pos doff+ Minus -> Pos.slide pos (negate doff) in and [ Loc.startPos extloc == strandSlide (Loc.startPos loc) (negate ext5) , Loc.endPos extloc == strandSlide (Loc.endPos loc) ext3 ]