From 4da61a151440fe7ee576fed3a81f8c868936af81 Mon Sep 17 00:00:00 2001 From: Alexander Sadovnikov Date: Thu, 16 Jan 2020 17:44:59 +0300 Subject: [PATCH] Version 0.1.2.6. Fixes for instance of StructureModels for Mae. (#25) --- ChangeLog.md | 4 ++++ package.yaml | 2 +- src/Bio/MAE.hs | 28 ++++++++++++++-------------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index b52d900..31a0730 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -2,6 +2,10 @@ ## [Unreleased] +## [0.1.2.6] - 2019-12-12 +### Fixed +- Fixes for instance of `StructureModels` for `Mae` when working with structures without explicit chain names. + ## [0.1.2.5] - 2019-12-24 ### Fixed - Possibility to have spaces in Fasta sequences. diff --git a/package.yaml b/package.yaml index ce915c9..cbcb79a 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: cobot-io -version: 0.1.2.5 +version: 0.1.2.6 github: "less-wrong/cobot-io" license: BSD3 category: Bio diff --git a/src/Bio/MAE.hs b/src/Bio/MAE.hs index ab593f2..f0b9c3d 100644 --- a/src/Bio/MAE.hs +++ b/src/Bio/MAE.hs @@ -18,13 +18,14 @@ import Bio.Structure (Atom (..), Bond (..), Chain (..), Model (..), Residue (..), SecondaryStructure (..), StructureModels (..)) +import Control.Monad (join) import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Attoparsec.Text (parseOnly) import Data.Bifunctor (bimap, first) import Data.Function (on) import qualified Data.List as L (find, groupBy, sortOn) import Data.Map.Strict (Map) -import qualified Data.Map.Strict as M (fromList, lookup, member, (!)) +import qualified Data.Map.Strict as M (fromList, lookup, (!)) import Data.Maybe (catMaybes, fromJust) import Data.Text (Text) import qualified Data.Text as T (head, init, last, null, pack, @@ -51,7 +52,7 @@ instance StructureModels Mae where unsafeGetFromContentsMap m name i = unsafeFromMaeValue $ (m M.! name) !! i getFromContentsMap :: FromMaeValue a => Map Text [MaeValue] -> Text -> Int -> Maybe a - getFromContentsMap m name i = fromMaeValue $ (m M.! name) !! i + getFromContentsMap m name i = join $ fromMaeValue . (!! i) <$> name `M.lookup` m blockToModel :: Block -> Model blockToModel Block{..} = Model (atomsTableToChains atomsTable) bonds @@ -94,19 +95,19 @@ instance StructureModels Mae where atomsTableToChains :: Map Text [MaeValue] -> Vector Chain atomsTableToChains m = V.fromList $ fmap groupToChain groupedByChains where - groupedByChains = toGroupsOn (unsafeGetFromContents @Text "s_m_chain_name") [0 .. numberOfAtoms - 1] + groupedByChains = toGroupsOn (getFromContents defaultChainName "s_m_chain_name") [0 .. numberOfAtoms - 1] + + getFromContents :: FromMaeValue a => a -> Text -> Int -> a + getFromContents def name ind = maybe def id $ getFromContentsMap m name ind unsafeGetFromContents :: FromMaeValue a => Text -> Int -> a unsafeGetFromContents = unsafeGetFromContentsMap m - getFromContents :: FromMaeValue a => Text -> Int -> Maybe a - getFromContents = getFromContentsMap m - groupToChain :: [Int] -> Chain groupToChain [] = error "Group that is result of List.groupBy can't be empty." groupToChain group@(h : _) = Chain name residues where - name = stripQuotes $ unsafeGetFromContents "s_m_chain_name" h + name = stripQuotes $ getFromContents defaultChainName "s_m_chain_name" h groupedByResidues = toGroupsOn by group residues = V.fromList $ fmap groupToResidue groupedByResidues @@ -114,6 +115,9 @@ instance StructureModels Mae where by :: Int -> (Int, Text) by i = (unsafeGetFromContents "i_m_residue_number" i, unsafeGetFromContents "s_m_pdb_residue_name" i) + defaultChainName :: Text + defaultChainName = "A" + groupToResidue :: [Int] -> Residue groupToResidue [] = error "Group that is result of List.groupBy can't be empty." groupToResidue group@(h : _) = Residue name atoms (V.fromList localBonds) secondary chemCompType @@ -140,17 +144,13 @@ instance StructureModels Mae where (stripQuotes $ getFromContentsI "s_m_pdb_atom_name") (elIndToElement M.! getFromContentsI "i_m_atomic_number") coords - (getFromContentsIWithDef 0 "i_m_formal_charge") - (getFromContentsIWithDef 0 "r_m_pdb_tfactor") - (getFromContentsIWithDef 0 "r_m_pdb_occupancy") + (getFromContents 0 "i_m_formal_charge" i) + (getFromContents 0 "r_m_pdb_tfactor" i) + (getFromContents 0 "r_m_pdb_occupancy" i) where getFromContentsI :: FromMaeValue a => Text -> a getFromContentsI = flip unsafeGetFromContents i - getFromContentsIWithDef :: FromMaeValue a => a -> Text -> a - getFromContentsIWithDef def n | n `M.member` m = maybe def id $ getFromContents n i - | otherwise = def - coords :: V3 Float coords = V3 (getFromContentsI "r_m_x_coord") (getFromContentsI "r_m_y_coord")