hyraxAbif 0.2.3.7 → 0.2.3.8
raw patch · 6 files changed
+13/−98 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- hyraxAbif.cabal +1/−1
- src/Hyrax/Abif.hs +0/−6
- src/Hyrax/Abif/Fasta.hs +0/−2
- src/Hyrax/Abif/Generate.hs +7/−40
- src/Hyrax/Abif/Read.hs +5/−33
- src/Hyrax/Abif/Write.hs +0/−16
hyraxAbif.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: hyraxAbif-version: 0.2.3.7+version: 0.2.3.8 synopsis: Modules for parsing, generating and manipulating AB1 files. homepage: https://github.com/hyraxbio/hyraxAbif/#readme license: BSD3
src/Hyrax/Abif.hs view
@@ -18,7 +18,6 @@ * <http://www6.appliedbiosystems.com/support/software_community/ABIF_File_Format.pdf The ABIF spec> -}-{-! SECTION< abif_module !-} module Hyrax.Abif ( Abif (..) , Header (..)@@ -30,10 +29,8 @@ import Protolude import qualified Data.ByteString.Lazy as BSL-{-! SECTION> abif_module !-} -{-! SECTION< abif_type !-} -- | A single ABIF data Abif = Abif { aHeader :: !Header , aRootDir :: !Directory@@ -62,10 +59,8 @@ , dData :: !BSL.ByteString -- ^ The entry's data , dDataDebug :: ![Text] -- ^ Optinal debug data, populated by 'Hyrax.Abif.Read.getDebug' when a ABIF is parsed } deriving (Show, Eq)-{-! SECTION> abif_type !-} -{-! SECTION< abif_elemType !-} -- | Type of the elements in a directory entry. See the spec for details on each type if required. data ElemType = ElemUnknown | ElemCustom@@ -127,4 +122,3 @@ describeElemType 384 = (ElemCompressedDataUnsupported, "Compressed Data (*unsupported*)") describeElemType 1023 = (ElemRoot, "root") describeElemType v = if v >= 1024 then (ElemCustom, "custom") else (ElemUnknown, "unknown")-{-! SECTION> abif_elemType !-}
src/Hyrax/Abif/Fasta.hs view
@@ -19,7 +19,6 @@ import Protolude import qualified Data.Text as Txt -{-! SECTION< fasta !-} -- | FASTA data data Fasta = Fasta { fastaName :: !Text -- ^ Name , fastaRead :: !Text -- ^ Data@@ -49,4 +48,3 @@ Left "Expecting read" go [] (Just name) read acc = Right $ Fasta (Txt.strip name) read : acc-{-! SECTION> fasta !-}
src/Hyrax/Abif/Generate.hs view
@@ -127,7 +127,6 @@ traverse_ (\(name, ab1) -> BS.writeFile (dest </> Txt.unpack name <> ".ab1") $ BSL.toStrict ab1) ab1s -{-! SECTION< gen_generateAb1_fn !-} -- | Create the 'ByteString' data for an AB1 given the data from a weighted FASTA (see 'readWeightedFasta') generateAb1 :: (Text, [(Double, Text)]) -> BSL.ByteString generateAb1 (fName, sourceFasta) = @@ -136,17 +135,14 @@ valsPerBase = trValsPerBase tr generatedFastaLen = (Txt.length $ trFasta tr) -{-! SECTION< gen_generateAb1_peak !-} -- The point that is the peak of the trace, i.e. mid point of trace for a single base midPeek = valsPerBase `div` 2 -- Get the peak locations for all bases peakLocations = take generatedFastaLen [midPeek, valsPerBase + midPeek..]-{-! SECTION> gen_generateAb1_peak !-} -- Sample name (from the FASTA name) sampleName = fst . Txt.breakOn "_" $ fName -{-! SECTION< gen_generateAb1_abif !-} -- Create the ABIF directories dirs = [ mkData 9 $ trData09G tr -- G , mkData 10 $ trData10A tr -- A@@ -168,48 +164,33 @@ , aRootDir = mkRoot , aDirs = dirs }-{-! SECTION> gen_generateAb1_abif !-} in -- Generate the data B.runPut (putAbif abif)-{-! SECTION> gen_generateAb1_fn !-} -{-! SECTION< gen_generateTraceData !-}-{-! SECTION< gen_generateTraceData_type !-} -- | Generate the traces for the AB1 from the parsed weighted FASTA generateTraceData :: [(Double, Text)] -> TraceData generateTraceData weighted =-{-! SECTION> gen_generateTraceData_type !-} let-{-! SECTION< gen_generateTraceData_weighted !-} weightedNucs' = (\(w, ns) -> (w,) . unIupac <$> Txt.unpack ns) <$> weighted weightedNucs = Lst.transpose weightedNucs'-{-! SECTION> gen_generateTraceData_weighted !-} -{-! SECTION< gen_generateTraceData_curve !-}- -- Values for a base that was present. This defines the shape of the chromatogram curve,- -- and defines the number of values per base+ -- Values for a base that was present. This defines the shape of the chromatogram curve, and defines the number of values per base curve = [0, 0, 128, 512, 1024, 1024, 512, 128, 0, 0] valsPerBase = length curve-{-! SECTION> gen_generateTraceData_curve !-} -{-! SECTION< gen_generateTraceData_traces !-} -- Create the G, A, T and C traces data09G = concat $ getWeightedTrace curve 'G' <$> weightedNucs data10A = concat $ getWeightedTrace curve 'A' <$> weightedNucs data11T = concat $ getWeightedTrace curve 'T' <$> weightedNucs data12C = concat $ getWeightedTrace curve 'C' <$> weightedNucs-{-! SECTION> gen_generateTraceData_traces !-} -{-! SECTION< gen_generateTraceData_fasta !-} -- Create fasta sequence for the trace fastaSeq = concat <$> (snd <<$>> weightedNucs) fasta = Txt.pack $ iupac fastaSeq-{-! SECTION> gen_generateTraceData_fasta !-} in -{-! SECTION< gen_generateTraceData_ret !-} TraceData { trData09G = data09G , trData10A = data10A , trData11T = data11T@@ -217,10 +198,8 @@ , trFasta = fasta , trValsPerBase = valsPerBase }-{-! SECTION> gen_generateTraceData_ret !-} where-{-! SECTION< gen_generateTraceData_getWeightedTrace !-} getWeightedTrace :: [Int] -> Char -> [(Double, [Char])] -> [Int16] getWeightedTrace curve nuc ws = let@@ -230,8 +209,6 @@ wave = floor . (score *) . fromIntegral <$> curve in wave-{-! SECTION> gen_generateTraceData_getWeightedTrace !-}-{-! SECTION> gen_generateTraceData !-} -- | Read a weighted FASTA file. See the module documentation for details on the format of the weighted FASTA @@ -261,7 +238,6 @@ -- +---- weight -- @ ---{-! SECTION< gen_readWeightedFasta !-} readWeightedFasta :: ByteString -> Either Text [(Double, Text)] readWeightedFasta fastaData = case parseFasta $ TxtE.decodeUtf8 fastaData of@@ -288,22 +264,20 @@ case (readMaybe . Txt.unpack $ hdr :: Maybe Double) of Just weight -> Right (min 1 . max 0 $ weight, processNucs $ Txt.strip dta) Nothing -> Left $ "Invalid header reading, expecting numeric weight, got: " <> hdr-{-! SECTION> gen_readWeightedFasta !-} -{-! SECTION< gen_readWeightedFastas !-} -- | Read all FASTA files in a directory -- -- The result data has the type -- -- @--- [ ('Text', [('Double', 'Text')]) ]--- ^ ^ ^--- | | |--- file name -------------+ | +---- read --- | --- +---- weight+-- [ ('Text', [('Double', 'Text')]) ]+-- ^ ^ ^+-- | | |+-- file name -------------+ | +---- read +-- | +-- +---- weight -- @ -- readWeightedFastas :: FilePath -> IO (Either Text [(Text, [(Double, Text)])])@@ -315,7 +289,6 @@ case sequenceA $ readWeightedFasta <$> contents of Left e -> pure . Left $ e Right rs -> pure . Right $ zip names rs-{-! SECTION> gen_readWeightedFastas !-} -- | Find all files in a directory@@ -325,11 +298,8 @@ filterM Dir.doesFileExist entries -{-! SECTION< gen_unIupac_fn !-} -- | Convert a IUPAC ambiguity code to the set of nucleotides it represents-{-! SECTION< gen_unIupac_type !-} unIupac :: Char -> [Char]-{-! SECTION> gen_unIupac_type !-} unIupac c = case c of 'T' -> "T"@@ -352,7 +322,6 @@ 'X' -> "GATC" _ -> ""-{-! SECTION> gen_unIupac_fn !-} -- | Given a set of nucleotides get the IUPAC ambiguity code@@ -387,7 +356,6 @@ _ -> '_' -{-! SECTION< gen_complement !-} -- | Return the complement of a nucelotide string complementNucleotides :: Text -> Text complementNucleotides ns =@@ -404,4 +372,3 @@ complementNuc 'T' = 'A' complementNuc 'C' = 'G' complementNuc x = x-{-! SECTION> gen_complement !-}
src/Hyrax/Abif/Read.hs view
@@ -47,14 +47,11 @@ import Hyrax.Abif -{-! SECTION< read_readAbif !-} -- | Read and parse an AB1 file readAbif :: FilePath -> IO (Either Text Abif) readAbif path = getAbif <$> BSL.readFile path-{-! SECTION> read_readAbif !-} -{-! SECTION< read_getAbif !-} -- | Parse an AB1 from a 'ByteString' getAbif :: BSL.ByteString -> Either Text Abif getAbif bs = do@@ -66,31 +63,23 @@ ds <- case B.runGetOrFail (getDirectories bs [] $ dElemNum rootDir) dirBytes of Right (_, _, x) -> pure x- Left (_, _, e) -> Left ("Error reading "- <> show (dElemNum rootDir)- <> " directories (at " <> show (dDataOffset rootDir) <> "): "- <> Txt.pack e- )+ Left (_, _, e) -> Left ("Error reading " <> show (dElemNum rootDir) <> " directories (at " <> show (dDataOffset rootDir) <> "): " <> Txt.pack e) pure $ Abif header rootDir ds-{-! SECTION> read_getAbif !-} -{-! SECTION< read_clear !-} -- | Removes all data from the ABIF's directories clearAbif :: Abif -> Abif clearAbif a = a { aRootDir = clear $ aRootDir a- , aDirs = clear <$> aDirs a- }+ , aDirs = clear <$> aDirs a+ } -- | Removes all data from a directory entry. This will probably only be useful when trying to show an ABIF value clear :: Directory -> Directory clear d = d { dData = "" }-{-! SECTION> read_clear !-} -{-! SECTION< read_getDebug !-} -- | Populate the directory entry with debug data (into 'dDataDebug'). -- This is done for selected types only, e.g. for strings so that printing the structure will display -- readable/meaningfull info@@ -110,7 +99,6 @@ if dDataSize d <= 4 then d { dDataDebug = [TxtE.decodeUtf8 . BSL.toStrict . BSL.take (fromIntegral $ dDataSize d - 1) $ dData d] } else d { dDataDebug = [B.runGet (lbl . getCString $ dDataSize d) bsAtOffset] }-{-! SECTION> read_getDebug !-} y -> -- For non-array entries@@ -187,7 +175,6 @@ pure (c:cs) -{-! SECTION< read_getStrings !-} -- | Parse a 'ElemPString' getPString :: B.Get Text getPString = do@@ -199,29 +186,23 @@ getCString :: Int -> B.Get Text getCString sz = TxtE.decodeUtf8 <$> B.getByteString (sz - 1)-{-! SECTION> read_getStrings !-} -{-! SECTION< read_getHeader !-} -- | Parse the ABIF 'Header' getHeader :: B.Get Header getHeader = Header <$> (TxtE.decodeUtf8 <$> B.getByteString 4) <*> (fromIntegral <$> B.getInt16be)-{-! SECTION> read_getHeader !-} -{-! SECTION< read_getRoot !-} -- | Parse the root ('Header' and 'Directory') getRoot :: BSL.ByteString -> B.Get (Header, Directory) getRoot bs = do h <- getHeader rd <- getDirectory bs pure (h, rd)-{-! SECTION> read_getRoot !-} -{-! SECTION< read_getDirectory !-} -- | Parse a single 'Directory' entry and read its data getDirectory :: BSL.ByteString -> B.Get Directory getDirectory bs = do@@ -240,14 +221,7 @@ then pure $ BSL.take (fromIntegral dataSize) offsetDataBytes else case B.runGetOrFail (B.getLazyByteString $ fromIntegral dataSize) $ BSL.drop (fromIntegral dataOffset) bs of Right (_, _, x) -> pure x- Left (_, _, e) -> fail $ "error reading data ("- <> show dataSize- <> " bytes starting at "- <> show dataOffset- <> ") for directory entry '"- <> Txt.unpack tagName- <> "': "- <> e+ Left (_, _, e) -> fail $ "error reading data (" <> show dataSize <> " bytes starting at " <> show dataOffset <> ") for directory entry '" <> Txt.unpack tagName <> "': " <> e let (elemType, elemCode) = describeElemType typeCode pure Directory { dTagName = tagName @@ -262,10 +236,8 @@ , dData = dataBytes , dDataDebug = [] } -{-! SECTION> read_getDirectory !-} -{-! SECTION< read_getDirectories !-} -- | Parse all the directoy entries getDirectories :: BSL.ByteString -> [Directory] -> Int -> B.Get [Directory] getDirectories _ acc 0 = pure acc@@ -274,4 +246,4 @@ B.skip 4 -- Skip the reserved field getDirectories bs (acc <> [d]) (more - 1) -{-! SECTION> read_getDirectories !-}+
src/Hyrax/Abif/Write.hs view
@@ -44,13 +44,10 @@ import Hyrax.Abif -{-! SECTION< write_base !-} -- | Used to specify the base order for the FWO directry entry, see 'mkBaseOrder' data Base = BaseA | BaseC | BaseG | BaseT-{-! SECTION> write_base !-} -{-! SECTION< write_create !-} -- | Write an 'Abif' to a 'ByteString' createAbifBytes :: Abif -> BSL.ByteString createAbifBytes ab1 =@@ -62,10 +59,8 @@ writeAbif destPath ab1 = do let b = createAbifBytes ab1 BS.writeFile destPath $ BSL.toStrict b-{-! SECTION> write_create !-} -{-! SECTION< write_putAbif !-} -- | Create the 'Abif' using "Data.Binary" putAbif :: Abif -> B.Put putAbif (Abif header root dirs) = do@@ -96,10 +91,8 @@ pure $ if dDataSize dir > 4 then offset + dDataSize dir else offset-{-! SECTION> write_putAbif !-} -{-! SECTION< write_strings !-} -- | Write 'Text' putTextStr :: Text -> B.Put putTextStr t = B.putByteString $ TxtE.encodeUtf8 t@@ -110,19 +103,15 @@ putPStr t = do B.putInt8 . fromIntegral $ Txt.length t B.putByteString $ TxtE.encodeUtf8 t-{-! SECTION> write_strings !-} -{-! SECTION< write_putHeader !-} -- | Write a 'Header' putHeader :: Header -> B.Put putHeader h = do putTextStr $ hName h B.putInt16be . fromIntegral $ hVersion h-{-! SECTION> write_putHeader !-} -{-! SECTION< write_putDirectory !-} -- | Write a 'Directory' putDirectory :: Int -> Directory -> B.Put putDirectory dirOffset d = do@@ -140,7 +129,6 @@ else B.putLazyByteString . BSL.take 4 $ dData d <> "\0\0\0\0" B.putInt32be 0 -- reserved / datahandle-{-! SECTION> write_putDirectory !-} -- | Create a 'Header'@@ -204,7 +192,6 @@ , dDataSize = fromIntegral (BSL.length sampleName) } -{-! SECTION< write_mk !-} -- | Create a base order (FWO_) 'Directory' entry data mkBaseOrder :: Base -> Base -> Base -> Base -> Directory mkBaseOrder w x y z =@@ -242,7 +229,6 @@ , dData = B.runPut $ B.putInt16be lane , dDataDebug = [] }-{-! SECTION> write_mk !-} -- | Create a called bases (PBAS) 'Directory' entry and data@@ -342,9 +328,7 @@ , dElemNum = length ds } -{-! SECTION< write_addDirectory !-} -- | Add a directory to an 'Abif' addDirectory :: Abif -> Directory -> Abif addDirectory abif dir = abif { aDirs = aDirs abif <> [dir] }-{-! SECTION> write_addDirectory !-}