mmtf 0.1.1.0 → 0.1.2.0
raw patch · 5 files changed
+120/−74 lines, 5 filesdep ~binarydep ~containersdep ~data-msgpackPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: binary, containers, data-msgpack, http-conduit, text
API changes (from Hackage documentation)
- Bio.MMTF: AtomData :: !Maybe [Int32] -> !Maybe [Char] -> !Maybe [Float] -> ![Float] -> ![Float] -> ![Float] -> !Maybe [Float] -> AtomData
+ Bio.MMTF: AtomData :: ![Int32] -> ![Char] -> ![Float] -> ![Float] -> ![Float] -> ![Float] -> ![Float] -> AtomData
- Bio.MMTF: ChainData :: ![Int32] -> ![Text] -> !Maybe [Text] -> ChainData
+ Bio.MMTF: ChainData :: ![Int32] -> ![Text] -> ![Text] -> ChainData
- Bio.MMTF: GroupData :: ![GroupType] -> ![Int32] -> ![Int32] -> !Maybe [SecondaryStructure] -> !Maybe [Char] -> !Maybe [Int32] -> GroupData
+ Bio.MMTF: GroupData :: ![GroupType] -> ![Int32] -> ![Int32] -> ![SecondaryStructure] -> ![Char] -> ![Int32] -> GroupData
- Bio.MMTF: StructureData :: !Maybe Text -> !Maybe Text -> !Maybe Text -> !Maybe Text -> !Int32 -> !Int32 -> !Int32 -> !Int32 -> !Int32 -> !Maybe Text -> !Maybe UnitCell -> !Maybe [[Float]] -> !Maybe [Assembly] -> !Maybe [Entity] -> !Maybe Float -> !Maybe Float -> !Maybe Float -> !Maybe [Text] -> !Maybe [Int32] -> !Maybe [Int8] -> StructureData
+ Bio.MMTF: StructureData :: !Text -> !Text -> !Text -> !Text -> !Int32 -> !Int32 -> !Int32 -> !Int32 -> !Int32 -> !Text -> !Maybe UnitCell -> ![[Float]] -> ![Assembly] -> ![Entity] -> !Maybe Float -> !Maybe Float -> !Maybe Float -> ![Text] -> ![Int32] -> ![Int8] -> StructureData
- Bio.MMTF: [altLocList] :: AtomData -> !Maybe [Char]
+ Bio.MMTF: [altLocList] :: AtomData -> ![Char]
- Bio.MMTF: [atomIdList] :: AtomData -> !Maybe [Int32]
+ Bio.MMTF: [atomIdList] :: AtomData -> ![Int32]
- Bio.MMTF: [bFactorList] :: AtomData -> !Maybe [Float]
+ Bio.MMTF: [bFactorList] :: AtomData -> ![Float]
- Bio.MMTF: [bioAssemblyList] :: StructureData -> !Maybe [Assembly]
+ Bio.MMTF: [bioAssemblyList] :: StructureData -> ![Assembly]
- Bio.MMTF: [bondAtomList] :: StructureData -> !Maybe [Int32]
+ Bio.MMTF: [bondAtomList] :: StructureData -> ![Int32]
- Bio.MMTF: [bondOrderList] :: StructureData -> !Maybe [Int8]
+ Bio.MMTF: [bondOrderList] :: StructureData -> ![Int8]
- Bio.MMTF: [chainNameList] :: ChainData -> !Maybe [Text]
+ Bio.MMTF: [chainNameList] :: ChainData -> ![Text]
- Bio.MMTF: [depositionDate] :: StructureData -> !Maybe Text
+ Bio.MMTF: [depositionDate] :: StructureData -> !Text
- Bio.MMTF: [entityList] :: StructureData -> !Maybe [Entity]
+ Bio.MMTF: [entityList] :: StructureData -> ![Entity]
- Bio.MMTF: [experimentalMethods] :: StructureData -> !Maybe [Text]
+ Bio.MMTF: [experimentalMethods] :: StructureData -> ![Text]
- Bio.MMTF: [insCodeList] :: GroupData -> !Maybe [Char]
+ Bio.MMTF: [insCodeList] :: GroupData -> ![Char]
- Bio.MMTF: [ncsOperatorList] :: StructureData -> !Maybe [[Float]]
+ Bio.MMTF: [ncsOperatorList] :: StructureData -> ![[Float]]
- Bio.MMTF: [occupancyList] :: AtomData -> !Maybe [Float]
+ Bio.MMTF: [occupancyList] :: AtomData -> ![Float]
- Bio.MMTF: [releaseDate] :: StructureData -> !Maybe Text
+ Bio.MMTF: [releaseDate] :: StructureData -> !Text
- Bio.MMTF: [secStructList] :: GroupData -> !Maybe [SecondaryStructure]
+ Bio.MMTF: [secStructList] :: GroupData -> ![SecondaryStructure]
- Bio.MMTF: [sequenceIndexList] :: GroupData -> !Maybe [Int32]
+ Bio.MMTF: [sequenceIndexList] :: GroupData -> ![Int32]
- Bio.MMTF: [spaceGroup] :: StructureData -> !Maybe Text
+ Bio.MMTF: [spaceGroup] :: StructureData -> !Text
- Bio.MMTF: [structureId] :: StructureData -> !Maybe Text
+ Bio.MMTF: [structureId] :: StructureData -> !Text
- Bio.MMTF: [title] :: StructureData -> !Maybe Text
+ Bio.MMTF: [title] :: StructureData -> !Text
Files
- mmtf.cabal +15/−3
- src/Bio/MMTF/Decode.hs +46/−45
- src/Bio/MMTF/Decode/MessagePack.hs +6/−0
- src/Bio/MMTF/Type.hs +19/−19
- test/Spec.hs +34/−7
mmtf.cabal view
@@ -1,5 +1,5 @@ name: mmtf-version: 0.1.1.0+version: 0.1.2.0 synopsis: Macromolecular Transmission Format implementation description: Haskell implementation of MMTF biological structure format. homepage: https://github.com/zmactep/mmtf#readme@@ -34,12 +34,24 @@ test-suite mmtf-test type: exitcode-stdio-1.0 hs-source-dirs: test+ , src main-is: Spec.hs+ other-modules: Bio.MMTF+ , Bio.MMTF.Type+ , Bio.MMTF.MessagePack+ , Bio.MMTF.Decode+ , Bio.MMTF.Decode.Codec+ , Bio.MMTF.Decode.MessagePack build-depends: base , mmtf- , QuickCheck >= 2.9.2 && < 2.10- , hspec >= 2.4.1 && < 2.5+ , QuickCheck >= 2.9.2 && < 2.13+ , hspec >= 2.4.1 && < 2.7+ , data-msgpack+ , text , bytestring+ , binary+ , containers+ , http-conduit ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010
src/Bio/MMTF/Decode.hs view
@@ -7,6 +7,7 @@ import Bio.MMTF.Type import Control.Monad ((>=>))+import Data.ByteString.Lazy (empty) import Data.Map.Strict (Map) import Data.MessagePack (Object) import Data.Text (Text)@@ -27,76 +28,76 @@ -- chainData :: Monad m => Map Text Object -> m ChainData chainData mp = do gpc <- atP mp "groupsPerChain" asIntList- cil <- codec5 . parseBinary <$> atP mp "chainIdList" asBinary- cnl <- (codec5 . parseBinary <$>) <$> atPM mp "chainNameList" asBinary+ cil <- codec5 . parseBinary <$> atP mp "chainIdList" asBinary+ cnl <- codec5 . parseBinary <$> atPMD mp "chainNameList" asBinary empty pure $ ChainData gpc cil cnl -- | Parses atom data from ObjectMap -- atomData :: Monad m => Map Text Object -> m AtomData-atomData mp = do ail' <- (codec8 . parseBinary <$>) <$> atPM mp "atomIdList" asBinary- all' <- (codec6 . parseBinary <$>) <$> atPM mp "altLocList" asBinary- bfl' <- (codec10 . parseBinary <$>) <$> atPM mp "bFactorList" asBinary- xcl' <- codec10 . parseBinary <$> atP mp "xCoordList" asBinary- ycl' <- codec10 . parseBinary <$> atP mp "yCoordList" asBinary- zcl' <- codec10 . parseBinary <$> atP mp "zCoordList" asBinary- ol' <- (codec9 . parseBinary <$>) <$> atPM mp "occupancyList" asBinary+atomData mp = do ail' <- codec8 . parseBinary <$> atPMD mp "atomIdList" asBinary empty+ all' <- codec6 . parseBinary <$> atPMD mp "altLocList" asBinary empty+ bfl' <- codec10 . parseBinary <$> atPMD mp "bFactorList" asBinary empty+ xcl' <- codec10 . parseBinary <$> atP mp "xCoordList" asBinary+ ycl' <- codec10 . parseBinary <$> atP mp "yCoordList" asBinary+ zcl' <- codec10 . parseBinary <$> atP mp "zCoordList" asBinary+ ol' <- codec9 . parseBinary <$> atPMD mp "occupancyList" asBinary empty pure $ AtomData ail' all' bfl' xcl' ycl' zcl' ol' -- | Parses group data from ObjectMap -- groupData :: Monad m => Map Text Object -> m GroupData groupData mp = do gl' <- atP mp "groupList" asObjectList >>= traverse (transformObjectMap >=> groupType)- gtl' <- codec4 . parseBinary <$> atP mp "groupTypeList" asBinary- gil' <- codec8 . parseBinary <$> atP mp "groupIdList" asBinary- ssl' <- (map ssDec . codec2 . parseBinary <$>) <$> atPM mp "secStructList" asBinary- icl' <- (codec6 . parseBinary <$>) <$> atPM mp "insCodeList" asBinary- sil' <- (codec8 . parseBinary <$>) <$> atPM mp "sequenceIndexList" asBinary+ gtl' <- codec4 . parseBinary <$> atP mp "groupTypeList" asBinary+ gil' <- codec8 . parseBinary <$> atP mp "groupIdList" asBinary+ ssl' <- fmap ssDec . codec2 . parseBinary <$> atPMD mp "secStructList" asBinary empty+ icl' <- codec6 . parseBinary <$> atPMD mp "insCodeList" asBinary empty+ sil' <- codec8 . parseBinary <$> atPMD mp "sequenceIndexList" asBinary empty pure $ GroupData gl' gtl' gil' ssl' icl' sil' -- | Parses group type from ObjectMap -- groupType :: Monad m => Map Text Object -> m GroupType groupType mp = do fcl' <- atP mp "formalChargeList" asIntList- anl' <- atP mp "atomNameList" asStrList- el' <- atP mp "elementList" asStrList- bal' <- atP mp "bondAtomList" asIntList- bol' <- atP mp "bondOrderList" asIntList- gn' <- atP mp "groupName" asStr+ anl' <- atP mp "atomNameList" asStrList+ el' <- atP mp "elementList" asStrList+ bal' <- atP mp "bondAtomList" asIntList+ bol' <- atP mp "bondOrderList" asIntList+ gn' <- atP mp "groupName" asStr slc' <- atP mp "singleLetterCode" asChar- cct' <- atP mp "chemCompType" asStr+ cct' <- atP mp "chemCompType" asStr pure $ GroupType fcl' anl' el' bal' bol' gn' slc' cct' -- | Parses structure data from ObjectMap -- structureData :: Monad m => Map Text Object -> m StructureData-structureData mp = do ttl' <- atPM mp "title" asStr- sid' <- atPM mp "structureId" asStr- dd' <- atPM mp "depositionDate" asStr- rd' <- atPM mp "releaseDate" asStr- nb' <- atP mp "numBonds" asInt- na' <- atP mp "numAtoms" asInt- ng' <- atP mp "numGroups" asInt- nc' <- atP mp "numChains" asInt- nm' <- atP mp "numModels" asInt- sg' <- atPM mp "spaceGroup" asStr- uc' <- (>>= ucDec) <$> atPM mp "unitCell" asFloatList- nol' <- ((>>= asFloatList) <$>) <$> atPM mp "ncsOperatorList" asObjectList- bal' <- (>>= traverse (transformObjectMap >=> bioAssembly)) <$> atPM mp "bioAssemblyList" asObjectList- el' <- (>>= traverse (transformObjectMap >=> entity)) <$> atPM mp "entityList" asObjectList- res' <- atPM mp "resolution" asFloat- rf' <- atPM mp "rFree" asFloat- rw' <- atPM mp "rWork" asFloat- em' <- atPM mp "experimentalMethods" asStrList- btl' <- (codec4 . parseBinary <$>) <$> atPM mp "bondAtomList" asBinary- bol' <- (codec2 . parseBinary <$>) <$> atPM mp "bondOrderList" asBinary+structureData mp = do ttl' <- atPMD mp "title" asStr ""+ sid' <- atPMD mp "structureId" asStr ""+ dd' <- atPMD mp "depositionDate" asStr ""+ rd' <- atPMD mp "releaseDate" asStr ""+ nb' <- atP mp "numBonds" asInt+ na' <- atP mp "numAtoms" asInt+ ng' <- atP mp "numGroups" asInt+ nc' <- atP mp "numChains" asInt+ nm' <- atP mp "numModels" asInt+ sg' <- atPMD mp "spaceGroup" asStr ""+ uc' <- (>>= ucDec) <$> atPM mp "unitCell" asFloatList+ nol' <- (>>= asFloatList) <$> atPMD mp "ncsOperatorList" asObjectList []+ bal' <- atPMD mp "bioAssemblyList" asObjectList [] >>= traverse (transformObjectMap >=> bioAssembly)+ el' <- atPMD mp "entityList" asObjectList [] >>= traverse (transformObjectMap >=> entity)+ res' <- atPM mp "resolution" asFloat+ rf' <- atPM mp "rFree" asFloat+ rw' <- atPM mp "rWork" asFloat+ em' <- atPMD mp "experimentalMethods" asStrList []+ btl' <- codec4 . parseBinary <$> atPMD mp "bondAtomList" asBinary empty+ bol' <- codec2 . parseBinary <$> atPMD mp "bondOrderList" asBinary empty pure $ StructureData ttl' sid' dd' rd' nb' na' ng' nc' nm' sg' uc' nol' bal' el' res' rf' rw' em' btl' bol' -- | Parses bio assembly data from ObjectMap -- bioAssembly :: Monad m => Map Text Object -> m Assembly-bioAssembly mp = do nme' <- atP mp "name" asStr+bioAssembly mp = do nme' <- atP mp "name" asStr tlt' <- atP mp "transformList" asObjectList >>= traverse (transformObjectMap >=> transform) pure $ Assembly tlt' nme' @@ -104,14 +105,14 @@ -- transform :: Monad m => Map Text Object -> m Transform transform mp = do cil' <- atP mp "chainIndexList" asIntList- mtx' <- atP mp "matrix" asFloatList+ mtx' <- atP mp "matrix" asFloatList pure $ Transform cil' mtx' -- | Parses entity data from ObjectMap -- entity :: Monad m => Map Text Object -> m Entity entity mp = do cil' <- atP mp "chainIndexList" asIntList- dsc' <- atP mp "description" asStr- tpe' <- atP mp "type" asStr- sqc' <- atP mp "sequence" asStr+ dsc' <- atP mp "description" asStr+ tpe' <- atP mp "type" asStr+ sqc' <- atP mp "sequence" asStr pure $ Entity cil' dsc' tpe' sqc'
src/Bio/MMTF/Decode/MessagePack.hs view
@@ -24,6 +24,12 @@ atPM :: Monad m => Map Text Object -> Text -> (Object -> m a) -> m (Maybe a) atPM m k conv = traverse conv $ M.lookup k m +atPMD :: Monad m => Map Text Object -> Text -> (Object -> m a) -> a -> m a+atPMD m k conv def = do x <- atPM m k conv+ case x of+ Just r -> pure r+ Nothing -> pure def+ asStr :: Monad m => Object -> m Text asStr (ObjectStr s) = pure s asStr _ = fail "Not a string data"
src/Bio/MMTF/Type.hs view
@@ -72,26 +72,26 @@ -- | Structure data ---data StructureData = StructureData { title :: !(Maybe Text) -- ^ A short description of the structural data included in the file- , structureId :: !(Maybe Text) -- ^ An ID for the structure, for example the PDB ID if applicable- , depositionDate :: !(Maybe Text) -- ^ A date that relates to the deposition of the structure in a database- , releaseDate :: !(Maybe Text) -- ^ A date that relates to the release of the structure in a database+data StructureData = StructureData { title :: !Text -- ^ A short description of the structural data included in the file+ , structureId :: !Text -- ^ An ID for the structure, for example the PDB ID if applicable+ , depositionDate :: !Text -- ^ A date that relates to the deposition of the structure in a database+ , releaseDate :: !Text -- ^ A date that relates to the release of the structure in a database , numBonds :: !Int32 -- ^ The overall number of bonds , numAtoms :: !Int32 -- ^ The overall number of atoms in the structure , numGroups :: !Int32 -- ^ The overall number of groups in the structure , numChains :: !Int32 -- ^ The overall number of chains in the structure , numModels :: !Int32 -- ^ The overall number of models in the structure- , spaceGroup :: !(Maybe Text) -- ^ The Hermann-Mauguin space-group symbol+ , spaceGroup :: !Text -- ^ The Hermann-Mauguin space-group symbol , unitCell :: !(Maybe UnitCell) -- ^ Array of six values defining the unit cell- , ncsOperatorList :: !(Maybe [[Float]]) -- ^ List of lists representing 4x4 transformation matrices that are stored linearly in row major order (transformation matrices describe noncrystallographic symmetry operations needed to create all molecules in the unit cell)- , bioAssemblyList :: !(Maybe [Assembly]) -- ^ List of instructions on how to transform coordinates for an array of chains to create (biological) assemblies- , entityList :: !(Maybe [Entity]) -- ^ List of unique molecular entities within the structure+ , ncsOperatorList :: ![[Float]] -- ^ List of lists representing 4x4 transformation matrices that are stored linearly in row major order (transformation matrices describe noncrystallographic symmetry operations needed to create all molecules in the unit cell)+ , bioAssemblyList :: ![Assembly] -- ^ List of instructions on how to transform coordinates for an array of chains to create (biological) assemblies+ , entityList :: ![Entity] -- ^ List of unique molecular entities within the structure , resolution :: !(Maybe Float) -- ^ The experimental resolution in Angstrom , rFree :: !(Maybe Float) -- ^ The R-free value , rWork :: !(Maybe Float) -- ^ The R-work value- , experimentalMethods :: !(Maybe [Text]) -- ^ List of experimental methods employed for structure determination- , bondAtomList :: !(Maybe [Int32]) -- ^ Pairs of values represent indices of covalently bonded atoms [binary (type 4)]- , bondOrderList :: !(Maybe [Int8]) -- ^ List of bond orders for bonds in 'bondAtomList' [binary (type 2)]+ , experimentalMethods :: ![Text] -- ^ List of experimental methods employed for structure determination+ , bondAtomList :: ![Int32] -- ^ Pairs of values represent indices of covalently bonded atoms [binary (type 4)]+ , bondOrderList :: ![Int8] -- ^ List of bond orders for bonds in 'bondAtomList' [binary (type 2)] } deriving (Show, Eq) @@ -105,7 +105,7 @@ -- data ChainData = ChainData { groupsPerChain :: ![Int32] -- ^ List of the number of groups (aka residues) in each chain , chainIdList :: ![Text] -- ^ List of chain IDs [binary (type 5)]- , chainNameList :: !(Maybe [Text]) -- ^ List of chain names [binary (type 5)]+ , chainNameList :: ![Text] -- ^ List of chain names [binary (type 5)] } deriving (Show, Eq) @@ -114,21 +114,21 @@ data GroupData = GroupData { groupList :: ![GroupType] -- ^ List of groupType objects , groupTypeList :: ![Int32] -- ^ List of pointers to 'groupType' entries in 'groupList' by their keys [binary (type 4)] , groupIdList :: ![Int32] -- ^ List of group (residue) numbers [binary (type 8)]- , secStructList :: !(Maybe [SecondaryStructure]) -- ^ List of secondary structure assignments [binary (type 2)]- , insCodeList :: !(Maybe [Char]) -- ^ List of insertion codes, one for each group (residue) [binary (type 6)]- , sequenceIndexList :: !(Maybe [Int32]) -- ^ List of indices that point into the sequence property of an entity object in the 'entityList' field that is associated with the chain the group belongs to [binary (type 8)]+ , secStructList :: ![SecondaryStructure] -- ^ List of secondary structure assignments [binary (type 2)]+ , insCodeList :: ![Char] -- ^ List of insertion codes, one for each group (residue) [binary (type 6)]+ , sequenceIndexList :: ![Int32] -- ^ List of indices that point into the sequence property of an entity object in the 'entityList' field that is associated with the chain the group belongs to [binary (type 8)] } deriving (Show, Eq) -- | Atoms data ---data AtomData = AtomData { atomIdList :: !(Maybe [Int32]) -- ^ List of atom serial numbers [binary (type 8)]- , altLocList :: !(Maybe [Char]) -- ^ List of alternate location labels, one for each atom [binary (type 6)]- , bFactorList :: !(Maybe [Float]) -- ^ List of atom B-factors in in A^2, one for each atom [binary (type 10)]+data AtomData = AtomData { atomIdList :: ![Int32] -- ^ List of atom serial numbers [binary (type 8)]+ , altLocList :: ![Char] -- ^ List of alternate location labels, one for each atom [binary (type 6)]+ , bFactorList :: ![Float] -- ^ List of atom B-factors in in A^2, one for each atom [binary (type 10)] , xCoordList :: ![Float] -- ^ List of x atom coordinates in A, one for each atom [binary (type 10)] , yCoordList :: ![Float] -- ^ List of y atom coordinates in A, one for each atom [binary (type 10)] , zCoordList :: ![Float] -- ^ List of z atom coordinates in A, one for each atom [binary (type 10)]- , occupancyList :: !(Maybe [Float]) -- ^ List of atom occupancies, one for each atom [binary (type 9)]+ , occupancyList :: ![Float] -- ^ List of atom occupancies, one for each atom [binary (type 9)] } deriving (Show, Eq)
test/Spec.hs view
@@ -2,13 +2,40 @@ import Bio.MMTF import qualified Data.ByteString.Lazy as B+import Data.Int (Int8) import Test.Hspec +import Bio.MMTF.Decode.Codec++codecSpec :: Spec+codecSpec =+ describe "MMTF decoding" $ do+ it "unpacks by Run-length encoding" $ do+ let sample = [ 1, 10, 2, 1, 1, 4 ] :: [Int8]+ runLengthDec sample `shouldBe` ([ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1 ] :: [Int8])+ it "unpacks by Delta encoding" $ do+ let sample = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1 ] :: [Int8]+ deltaDec sample `shouldBe` ([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16 ] :: [Int8])+ it "unpacks by Recursive indexing encoding" $ do+ let sample = [ 127, 41, 34, 1, 0, -50, -128, 0, 7, 127, 0, 127, 127, 14 ] :: [Int8]+ recIndexDec sample `shouldBe` [ 168, 34, 1, 0, -50, -128, 7, 127, 268 ]+ it "upacks by Integer encoding" $ do+ let sample = [ 100, 100, 100, 100, 50, 50 ] :: [Int8]+ integerDec 100 sample `shouldBe` [ 1.00, 1.00, 1.00, 1.00, 0.50, 0.50 ]++parserSpec :: Spec+parserSpec =+ describe "MMTF parser" $+ it "should parse 1FSD" $ do+ m <- fetch "1FSD"+ (structureId . structure) m `shouldBe` "1FSD"+ (numModels . structure) m `shouldBe` 41+ (length . bFactorList . atom) m `shouldBe` 20664+ (experimentalMethods . structure) m `shouldBe` ["SOLUTION NMR"]+ (head . xCoordList . atom) m `shouldBe` (-12.847)+ (last . xCoordList . atom) m `shouldBe` 5.672+ main :: IO ()-main = hspec $- describe "MMTF" $- it "should parse 1FSD" $ do- contents <- B.readFile "resource/1FSD.mmtf"- m <- decode contents- (structureId . structure) m `shouldBe` Just "1FSD"- (numModels . structure) m `shouldBe` 41+main = hspec $ do+ codecSpec+ parserSpec