packages feed

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 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