cobot-io 0.1.3.3 → 0.1.3.4
raw patch · 4 files changed
+54/−19 lines, 4 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ Bio.ABI.Clean: instance Bio.ABI.Clean.Cleanable Bio.Sequence.Basecalled.Type.BasecalledSequenceWithRawData
Files
- ChangeLog.md +4/−0
- cobot-io.cabal +2/−2
- src/Bio/ABI/Clean.hs +38/−17
- test/ABISpec.hs +10/−0
ChangeLog.md view
@@ -2,6 +2,10 @@ ## [Unreleased] +## [0.1.3.4] - 2020-05-14+### Added+- `instance Cleanable BasecalledSequenceWithRawData`.+ ## [0.1.3.3] - 2020-05-07 ### Added - Type and decoder for `ab1` with raw channel data and peak locations.
cobot-io.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 476c2b78718477cf61d3cc8b8f752cbb5b4533d9a349a7aa05dc96fa352f2d7e+-- hash: 05e68567b67639441d54b7151e50e0999a951e1a25a719e0ec4e701057148753 name: cobot-io-version: 0.1.3.3+version: 0.1.3.4 synopsis: Biological data file formats and IO description: Please see the README on GitHub at <https://github.com/biocad/cobot-io#readme> category: Bio
src/Bio/ABI/Clean.hs view
@@ -5,10 +5,12 @@ , defaultThresholds ) where +import Control.Monad (guard, join)+import qualified Data.Vector as V+ import Bio.Sequence (mean, meanInRange)-import qualified Bio.Sequence as S (drop, length, reverse, tail)-import Bio.Sequence.Basecalled (BasecalledSequence)-import Control.Monad (join)+import qualified Bio.Sequence as S (drop, length, reverse, tail, take)+import Bio.Sequence.Basecalled (BasecalledSequence, BasecalledSequenceWithRawData (..)) -- | Ability to clean initial data. -- Returns cleaned variant or 'Nothing' if it can not be cleaned.@@ -43,29 +45,43 @@ -- Logic of this algorithm and 'defaultThresholds' were obtained by taking experiments with read ABI files. -- data Thresholds- = Thresholds { frameSize :: Int- , edgeThreshold :: Double- , innerThreshold :: Double- }+ = Thresholds+ { frameSize :: Int+ , edgeThreshold :: Double+ , innerThreshold :: Double+ } deriving (Eq, Show) --- | This thresholds were selected by many experiments on ab1-files.+-- | These thresholds were selected by many experiments on ab1-files. -- defaultThresholds :: Thresholds defaultThresholds = Thresholds 10 20 30 instance Cleanable BasecalledSequence where- cleanWith thr input = if fmap (checkInner thr) fromBoth == Just True- then fromBoth- else Nothing+ cleanWith thr input = do+ cut <- fromBoth+ guard $ checkInner thr cut+ return cut where- fromLeft = cutEdge thr input+ fromLeft = doCutEdge thr input fromBoth = fmap S.reverse . join- $ cutEdge thr+ $ doCutEdge thr . S.reverse <$> fromLeft +instance Cleanable BasecalledSequenceWithRawData where+ cleanWith thr input@BasecalledSequenceWithRawData{..} = do+ toDropLeft <- cutEdge thr bsSequence+ let leftDroppedSequ = S.drop toDropLeft bsSequence+ let leftDroppedPloc = V.drop toDropLeft bsPeakLocations++ toDropRight <- cutEdge thr $ S.reverse leftDroppedSequ+ let rightDroppedSequ = S.take (S.length leftDroppedSequ - toDropRight) leftDroppedSequ+ let rightDroppedPloc = V.take (V.length leftDroppedPloc - toDropRight) leftDroppedPloc++ return input { bsSequence = rightDroppedSequ, bsPeakLocations = rightDroppedPloc }+ ------------------------------------------------------------------------------- -- INTERNAL -------------------------------------------------------------------------------@@ -73,10 +89,15 @@ checkInner :: Thresholds -> BasecalledSequence -> Bool checkInner Thresholds{..} = (> innerThreshold) . mean -cutEdge :: Thresholds -> BasecalledSequence -> Maybe BasecalledSequence-cutEdge t@Thresholds{..} sequ | S.length sequ < frameSize = Just sequ- | meanInR < edgeThreshold && S.length sequ > 1 = cutEdge t $ S.tail sequ- | S.length sequ > frameSize = Just $ S.drop frameSize sequ+doCutEdge :: Thresholds -> BasecalledSequence -> Maybe BasecalledSequence+doCutEdge t sequ = do+ toDrop <- cutEdge t sequ+ return $ S.drop toDrop sequ++cutEdge :: Thresholds -> BasecalledSequence -> Maybe Int+cutEdge t@Thresholds{..} sequ | S.length sequ < frameSize = Just 0+ | meanInR < edgeThreshold && S.length sequ > 1 = (1+) <$> cutEdge t (S.tail sequ)+ | S.length sequ > frameSize = Just frameSize | otherwise = Nothing where meanInR = meanInRange sequ (0, frameSize - 1)
test/ABISpec.hs view
@@ -46,6 +46,16 @@ it "totally clean bad ABI file" $ do Right dat <- readData "test/ABI/bad_quality.ab1" clean dat `shouldBe` Nothing++ it "clean good ABI file with raw data" $ do+ Right bsWithRaw <- decodeRawSequence <$> BSL.readFile "test/ABI/bad_at_the_end.ab1"+ Just cleaned <- return $ clean bsWithRaw++ length (bsPeakLocations cleaned) `shouldBe` S.length (bsSequence cleaned)++ it "clean with raw data is the same as without" $ do+ Right bsWithRaw <- decodeRawSequence <$> BSL.readFile "test/ABI/bad_at_the_end.ab1"+ bsSequence <$> clean bsWithRaw `shouldBe` clean (bsSequence bsWithRaw) where checkFile :: FilePath -> Int -> Int -> String -> IO () checkFile path lengthBefore lengthAfter start = do