-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Residue index supported in PDB * Residue number and insertion code: the proper way * HETATMs now parsed from PDB * Insertion code support in mae * PDBSpec renamed to PDBParserSpec * Bond restoring first version. Doesn't work correctly for now * Global bond restoring work correctly * Fixed text * Type * Bond restoring works correctly. Input data must be slightly fixed * Added missing disulfide bridges to mae structures * Local bond for PDB, with no tests yet * Fuck, nothing works * Everything works! * pedantation * Fetching from REST API avoided in MMTF test * Changelog, version * Removed some strange comments in a test * Changes after the review * Added atomInputIndex. GlobalID is 0-based now * Changelog and formatting
- Loading branch information
Showing
71 changed files
with
45,491 additions
and
606 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
name: cobot-io | ||
version: 0.1.2.10 | ||
version: 0.1.3.0 | ||
github: "less-wrong/cobot-io" | ||
license: BSD3 | ||
category: Bio | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,82 @@ | ||
{-# OPTIONS_GHC -fno-warn-orphans #-} | ||
module Bio.PDB | ||
( | ||
( modelsFromPDBText | ||
, modelsFromPDBFile | ||
) where | ||
|
||
import qualified Bio.PDB.Type as PDB | ||
import qualified Bio.PDB.Type as PDB | ||
import Bio.PDB.Reader (fromTextPDB, PDBWarnings) | ||
import Bio.PDB.BondRestoring (restoreModelGlobalBonds, restoreChainLocalBonds, residueID) | ||
import Bio.PDB.Functions (groupChainByResidue) | ||
import Bio.Structure | ||
|
||
import Control.Arrow ((&&&)) | ||
import Data.Coerce (coerce) | ||
import Data.Foldable (Foldable (..)) | ||
import Data.Text as T (Text, singleton, unpack) | ||
import qualified Data.Vector as V | ||
import Linear.V3 (V3 (..)) | ||
import Control.Arrow ((&&&)) | ||
import Control.Monad.IO.Class (MonadIO, liftIO) | ||
|
||
import Data.Text as T (Text, singleton, unpack, strip) | ||
import Data.Text.IO as TIO (readFile) | ||
import Data.Map (Map) | ||
import qualified Data.Map as M ((!), fromList) | ||
import qualified Data.Vector as V | ||
import Data.List (sort) | ||
import Data.Maybe (fromMaybe) | ||
|
||
import Text.Read (readMaybe) | ||
|
||
import Linear.V3 (V3 (..)) | ||
|
||
instance StructureModels PDB.PDB where | ||
modelsOf PDB.PDB {..} = fmap mkModel models | ||
where | ||
mkModel :: PDB.Model -> Model | ||
mkModel = flip Model V.empty . fmap mkChain | ||
|
||
mkChain :: PDB.Chain -> Chain | ||
mkChain = uncurry Chain . (mkChainName &&& mkChainResidues) | ||
|
||
mkChainName :: PDB.Chain -> Text | ||
mkChainName = T.singleton . PDB.atomChainID . safeFirstAtom | ||
|
||
mkChainResidues :: PDB.Chain -> V.Vector Residue | ||
mkChainResidues = V.fromList . fmap mkResidue . flip groupByResidue [] . pure . toList | ||
|
||
-- can be rewritten with sortOn and groupBy | ||
groupByResidue :: [[PDB.Atom]] -> [PDB.Atom] -> [[PDB.Atom]] | ||
groupByResidue res [] = res | ||
groupByResidue [] (x : xs) = groupByResidue [[x]] xs | ||
groupByResidue res@(lastList : resultTail) (x : xs) | ||
| (PDB.atomResSeq x, PDB.atomICode x) == (PDB.atomResSeq (head lastList), PDB.atomICode (head lastList)) | ||
= groupByResidue ((x : lastList) : resultTail) xs | ||
| otherwise = groupByResidue ([x] : res) xs | ||
|
||
safeFirstAtom :: V.Vector PDB.Atom -> PDB.Atom | ||
safeFirstAtom arr | V.length arr > 0 = arr V.! 0 | ||
| otherwise = error "Could not pick first atom" | ||
|
||
|
||
mkResidue :: [PDB.Atom] -> Residue | ||
mkResidue [] = error "Cound not make residue from empty list" | ||
mkResidue atoms' = Residue (PDB.atomResName . head $ atoms') | ||
(V.fromList $ mkAtom <$> atoms') | ||
V.empty -- now we do not read bonds | ||
Undefined -- now we do not read secondary structure | ||
"" -- chemical component type?! | ||
|
||
|
||
mkAtom :: PDB.Atom -> Atom | ||
mkAtom PDB.Atom{..} = Atom (coerce atomSerial) | ||
atomName | ||
atomElement | ||
(V3 atomX atomY atomZ) | ||
(read $ T.unpack atomCharge) | ||
atomTempFactor | ||
atomOccupancy | ||
mkModel model = Model (fmap mkChain model) (restoreModelGlobalBonds atomSerialToNilBasedIndex model) | ||
where | ||
atomSerialToNilBasedIndex :: Map Int Int | ||
atomSerialToNilBasedIndex = M.fromList $ allModelAtomSerials `zip` [0..] | ||
|
||
allModelAtomSerials :: [Int] | ||
allModelAtomSerials = sort . V.toList . fmap PDB.atomSerial . V.concat $ V.toList model | ||
|
||
mkChain :: PDB.Chain -> Chain | ||
mkChain = uncurry Chain . (mkChainName &&& mkChainResidues) | ||
|
||
mkChainName :: PDB.Chain -> Text | ||
mkChainName = T.singleton . PDB.atomChainID . safeFirstAtom | ||
|
||
mkChainResidues :: PDB.Chain -> V.Vector Residue | ||
mkChainResidues chain = V.fromList . fmap (mkResidue (restoreChainLocalBonds chain)) $ groupChainByResidue chain | ||
|
||
safeFirstAtom :: V.Vector PDB.Atom -> PDB.Atom | ||
safeFirstAtom arr | V.length arr > 0 = arr V.! 0 | ||
| otherwise = error "Could not pick first atom" | ||
|
||
mkResidue :: Map Text (V.Vector (Bond LocalID)) -> [PDB.Atom] -> Residue | ||
mkResidue _ [] = error "Cound not make residue from empty list" | ||
mkResidue localBondsMap atoms' = Residue (T.strip $ PDB.atomResName firstResidueAtom) | ||
(PDB.atomResSeq firstResidueAtom) | ||
(PDB.atomICode firstResidueAtom) | ||
(V.fromList $ mkAtom <$> atoms') | ||
(localBondsMap M.! residueID firstResidueAtom) | ||
Undefined -- now we do not read secondary structure | ||
"" -- chemical component type?! | ||
where | ||
firstResidueAtom = head atoms' | ||
|
||
mkAtom :: PDB.Atom -> Atom | ||
mkAtom PDB.Atom{..} = Atom (GlobalID $ atomSerialToNilBasedIndex M.! atomSerial) | ||
atomSerial | ||
(T.strip atomName) | ||
atomElement | ||
(V3 atomX atomY atomZ) | ||
(fromMaybe 0 . readMaybe $ T.unpack atomCharge) | ||
atomTempFactor | ||
atomOccupancy | ||
|
||
modelsFromPDBFile :: (MonadIO m) => FilePath -> m (Either Text ([PDBWarnings], V.Vector Model)) | ||
modelsFromPDBFile = liftIO . fmap modelsFromPDBText . TIO.readFile | ||
|
||
modelsFromPDBText :: Text -> Either Text ([PDBWarnings], V.Vector Model) | ||
modelsFromPDBText pdbText = do | ||
(warnings, parsedPDB) <- fromTextPDB pdbText | ||
let models = modelsOf parsedPDB | ||
pure (warnings, models) |
Oops, something went wrong.