{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
module Bio.PDB.BondRestoring
( restoreModelGlobalBonds
, restoreModelLocalBonds
, restoreChainLocalBonds
, residueID
) where
import qualified Bio.PDB.Type as PDB (Atom(..))
import Bio.PDB.Functions (groupChainByResidue)
import Bio.Structure (Bond (..), GlobalID (..), LocalID (..))
import Data.Vector (Vector)
import qualified Data.Vector as V (fromList, toList)
import Data.List (find, sort)
import Data.Text (Text)
import qualified Data.Text as T (strip, pack, unpack)
import Data.Map.Strict (Map, (!?), (!))
import qualified Data.Map.Strict as M (fromList)
import Data.Maybe (catMaybes)
import Linear.Metric (distance)
import Linear.V3 (V3(..))
import Control.Monad (guard)
residueID :: PDB.Atom -> Text
residueID :: Atom -> Text
residueID PDB.Atom{Char
Float
Int
Text
atomCharge :: Atom -> Text
atomElement :: Atom -> Text
atomTempFactor :: Atom -> Float
atomOccupancy :: Atom -> Float
atomZ :: Atom -> Float
atomY :: Atom -> Float
atomX :: Atom -> Float
atomICode :: Atom -> Char
atomResSeq :: Atom -> Int
atomChainID :: Atom -> Char
atomResName :: Atom -> Text
atomAltLoc :: Atom -> Char
atomName :: Atom -> Text
atomSerial :: Atom -> Int
atomCharge :: Text
atomElement :: Text
atomTempFactor :: Float
atomOccupancy :: Float
atomZ :: Float
atomY :: Float
atomX :: Float
atomICode :: Char
atomResSeq :: Int
atomChainID :: Char
atomResName :: Text
atomAltLoc :: Char
atomName :: Text
atomSerial :: Int
..} = String -> Text
T.pack (Char -> String
forall a. Show a => a -> String
show Char
atomChainID) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
atomResSeq) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Char -> String
forall a. Show a => a -> String
show Char
atomICode)
restoreModelLocalBonds :: Vector (Vector PDB.Atom) -> Map Text (Vector (Bond LocalID))
restoreModelLocalBonds :: Vector (Vector Atom) -> Map Text (Vector (Bond LocalID))
restoreModelLocalBonds = [(Text, Vector (Bond LocalID))] -> Map Text (Vector (Bond LocalID))
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Text, Vector (Bond LocalID))]
-> Map Text (Vector (Bond LocalID)))
-> (Vector (Vector Atom) -> [(Text, Vector (Bond LocalID))])
-> Vector (Vector Atom)
-> Map Text (Vector (Bond LocalID))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector Atom -> [(Text, Vector (Bond LocalID))])
-> Vector (Vector Atom) -> [(Text, Vector (Bond LocalID))]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Vector Atom -> [(Text, Vector (Bond LocalID))]
restoreChainLocalBonds'
restoreChainLocalBonds :: Vector PDB.Atom -> Map Text (Vector (Bond LocalID))
restoreChainLocalBonds :: Vector Atom -> Map Text (Vector (Bond LocalID))
restoreChainLocalBonds = [(Text, Vector (Bond LocalID))] -> Map Text (Vector (Bond LocalID))
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Text, Vector (Bond LocalID))]
-> Map Text (Vector (Bond LocalID)))
-> (Vector Atom -> [(Text, Vector (Bond LocalID))])
-> Vector Atom
-> Map Text (Vector (Bond LocalID))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Atom -> [(Text, Vector (Bond LocalID))]
restoreChainLocalBonds'
restoreChainLocalBonds' :: Vector PDB.Atom -> [(Text, Vector (Bond LocalID))]
restoreChainLocalBonds' :: Vector Atom -> [(Text, Vector (Bond LocalID))]
restoreChainLocalBonds' Vector Atom
chainAtoms = [(Text, Vector (Bond LocalID))]
residueIDToLocalBonds
where
residueIDToLocalBonds :: [(Text, Vector (Bond LocalID))]
residueIDToLocalBonds :: [(Text, Vector (Bond LocalID))]
residueIDToLocalBonds = do
([Atom]
residueAtoms, [Bond Atom]
residueBonds) <- [[Atom]] -> [[Bond Atom]] -> [([Atom], [Bond Atom])]
forall a b. [a] -> [b] -> [(a, b)]
zip [[Atom]]
chainAtomsGroupedByResidue [[Bond Atom]]
intraResidueGlobalBonds
let localBonds :: Vector (Bond LocalID)
localBonds = [Bond LocalID] -> Vector (Bond LocalID)
forall a. [a] -> Vector a
V.fromList ([Bond LocalID] -> Vector (Bond LocalID))
-> [Bond LocalID] -> Vector (Bond LocalID)
forall a b. (a -> b) -> a -> b
$ [Atom] -> [Bond Atom] -> [Bond LocalID]
convertGlobalsToLocals [Atom]
residueAtoms [Bond Atom]
residueBonds
let _residueID :: Text
_residueID = Atom -> Text
residueID (Atom -> Text) -> Atom -> Text
forall a b. (a -> b) -> a -> b
$ [Atom] -> Atom
forall a. [a] -> a
head [Atom]
residueAtoms
(Text, Vector (Bond LocalID)) -> [(Text, Vector (Bond LocalID))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
_residueID, Vector (Bond LocalID)
localBonds)
intraResidueGlobalBonds :: [[Bond PDB.Atom]]
intraResidueGlobalBonds :: [[Bond Atom]]
intraResidueGlobalBonds = ([Atom] -> [Bond Atom]) -> [[Atom]] -> [[Bond Atom]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Atom] -> [Bond Atom]
restoreIntraResidueBonds [[Atom]]
chainAtomsGroupedByResidue
chainAtomsGroupedByResidue :: [[PDB.Atom]]
chainAtomsGroupedByResidue :: [[Atom]]
chainAtomsGroupedByResidue = Vector Atom -> [[Atom]]
groupChainByResidue Vector Atom
chainAtoms
convertGlobalsToLocals :: [PDB.Atom] -> [Bond PDB.Atom] -> [Bond LocalID]
convertGlobalsToLocals :: [Atom] -> [Bond Atom] -> [Bond LocalID]
convertGlobalsToLocals [Atom]
residueAtoms = (Bond Atom -> Bond LocalID) -> [Bond Atom] -> [Bond LocalID]
forall a b. (a -> b) -> [a] -> [b]
map Bond Atom -> Bond LocalID
convertGlobalToLocal
where
convertGlobalToLocal :: Bond PDB.Atom -> Bond LocalID
convertGlobalToLocal :: Bond Atom -> Bond LocalID
convertGlobalToLocal (Bond Atom
from Atom
to Int
order) =
LocalID -> LocalID -> Int -> Bond LocalID
forall m. m -> m -> Int -> Bond m
Bond (Int -> LocalID
LocalID (Int -> LocalID) -> Int -> LocalID
forall a b. (a -> b) -> a -> b
$ Map Atom Int
atomToLocalIdMap Map Atom Int -> Atom -> Int
forall k a. Ord k => Map k a -> k -> a
! Atom
from) (Int -> LocalID
LocalID (Int -> LocalID) -> Int -> LocalID
forall a b. (a -> b) -> a -> b
$ Map Atom Int
atomToLocalIdMap Map Atom Int -> Atom -> Int
forall k a. Ord k => Map k a -> k -> a
! Atom
to) Int
order
atomToLocalIdMap :: Map PDB.Atom Int
atomToLocalIdMap :: Map Atom Int
atomToLocalIdMap = [(Atom, Int)] -> Map Atom Int
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Atom, Int)] -> Map Atom Int) -> [(Atom, Int)] -> Map Atom Int
forall a b. (a -> b) -> a -> b
$ [Atom] -> [Int] -> [(Atom, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Atom]
sortedAtoms [Int
0..]
sortedAtoms :: [PDB.Atom]
sortedAtoms :: [Atom]
sortedAtoms = [Atom] -> [Atom]
forall a. Ord a => [a] -> [a]
sort [Atom]
residueAtoms
restoreModelGlobalBonds :: Map PDB.Atom Int -> Vector (Vector PDB.Atom) -> Vector (Bond GlobalID)
restoreModelGlobalBonds :: Map Atom Int -> Vector (Vector Atom) -> Vector (Bond GlobalID)
restoreModelGlobalBonds Map Atom Int
atomToNilBasedIndex Vector (Vector Atom)
chains = Map Atom Int -> Vector (Bond Atom) -> Vector (Bond GlobalID)
convertToGlobalIDs Map Atom Int
atomToNilBasedIndex (Vector (Bond Atom) -> Vector (Bond GlobalID))
-> ([Bond Atom] -> Vector (Bond Atom))
-> [Bond Atom]
-> Vector (Bond GlobalID)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Bond Atom] -> Vector (Bond Atom)
forall a. [a] -> Vector a
V.fromList ([Bond Atom] -> Vector (Bond GlobalID))
-> [Bond Atom] -> Vector (Bond GlobalID)
forall a b. (a -> b) -> a -> b
$ [Bond Atom]
_intraResidueBonds [Bond Atom] -> [Bond Atom] -> [Bond Atom]
forall a. [a] -> [a] -> [a]
++ [Bond Atom]
peptideBonds [Bond Atom] -> [Bond Atom] -> [Bond Atom]
forall a. [a] -> [a] -> [a]
++ [Bond Atom]
disulfideBonds
where
convertToGlobalIDs :: Map PDB.Atom Int -> Vector (Bond PDB.Atom) -> Vector (Bond GlobalID)
convertToGlobalIDs :: Map Atom Int -> Vector (Bond Atom) -> Vector (Bond GlobalID)
convertToGlobalIDs Map Atom Int
mapping = (Atom -> GlobalID) -> Vector (Bond Atom) -> Vector (Bond GlobalID)
forall a b. (a -> b) -> Vector (Bond a) -> Vector (Bond b)
reindexBonds (\Atom
atom -> Int -> GlobalID
GlobalID (Int -> GlobalID) -> Int -> GlobalID
forall a b. (a -> b) -> a -> b
$ Map Atom Int
mapping Map Atom Int -> Atom -> Int
forall k a. Ord k => Map k a -> k -> a
! Atom
atom)
reindexBonds :: (a -> b) -> Vector (Bond a) -> Vector (Bond b)
reindexBonds :: (a -> b) -> Vector (Bond a) -> Vector (Bond b)
reindexBonds a -> b
convertID = (Bond a -> Bond b) -> Vector (Bond a) -> Vector (Bond b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Bond a
from a
to Int
order) -> b -> b -> Int -> Bond b
forall m. m -> m -> Int -> Bond m
Bond (a -> b
convertID a
from) (a -> b
convertID a
to) Int
order)
chainAtomsGroupedByResidue :: Vector [[PDB.Atom]]
chainAtomsGroupedByResidue :: Vector [[Atom]]
chainAtomsGroupedByResidue = (Vector Atom -> [[Atom]])
-> Vector (Vector Atom) -> Vector [[Atom]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector Atom -> [[Atom]]
groupChainByResidue Vector (Vector Atom)
chains
_intraResidueBonds :: [Bond PDB.Atom]
_intraResidueBonds :: [Bond Atom]
_intraResidueBonds = ([[Atom]] -> [Bond Atom]) -> Vector [[Atom]] -> [Bond Atom]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [[Atom]] -> [Bond Atom]
restoreChainIntraResidueBonds Vector [[Atom]]
chainAtomsGroupedByResidue
peptideBonds :: [Bond PDB.Atom]
peptideBonds :: [Bond Atom]
peptideBonds = ([[Atom]] -> [Bond Atom]) -> Vector [[Atom]] -> [Bond Atom]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [[Atom]] -> [Bond Atom]
restoreChainPeptideBonds Vector [[Atom]]
chainAtomsGroupedByResidue
disulfideBonds :: [Bond PDB.Atom]
disulfideBonds :: [Bond Atom]
disulfideBonds = [[Atom]] -> [Bond Atom]
restoreDisulfideBonds ([[Atom]] -> [Bond Atom])
-> ([[[Atom]]] -> [[Atom]]) -> [[[Atom]]] -> [Bond Atom]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[[Atom]]] -> [[Atom]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[[Atom]]] -> [Bond Atom]) -> [[[Atom]]] -> [Bond Atom]
forall a b. (a -> b) -> a -> b
$ Vector [[Atom]] -> [[[Atom]]]
forall a. Vector a -> [a]
V.toList Vector [[Atom]]
chainAtomsGroupedByResidue
restoreDisulfideBonds :: [[PDB.Atom]] -> [Bond PDB.Atom]
restoreDisulfideBonds :: [[Atom]] -> [Bond Atom]
restoreDisulfideBonds [[Atom]]
atomsGroupedByResidue = do
Atom
atom1 <- [Atom]
cystineSulfur
Atom
atom2 <- [Atom]
cystineSulfur
Bool -> [()]
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Atom -> Int
PDB.atomSerial Atom
atom1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Atom -> Int
PDB.atomSerial Atom
atom2)
Bool -> [()]
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> [()]) -> Bool -> [()]
forall a b. (a -> b) -> a -> b
$ V3 Float -> V3 Float -> Float
forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a -> a
distance (Atom -> V3 Float
coords Atom
atom1) (Atom -> V3 Float
coords Atom
atom2) Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
sulfidicBondMaxLength
Bond Atom -> [Bond Atom]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bond Atom -> [Bond Atom]) -> Bond Atom -> [Bond Atom]
forall a b. (a -> b) -> a -> b
$ Atom -> Atom -> Int -> Bond Atom
forall m. m -> m -> Int -> Bond m
Bond Atom
atom1 Atom
atom2 Int
1
where
cystineSulfur :: [PDB.Atom]
cystineSulfur :: [Atom]
cystineSulfur = (Atom -> Bool) -> [Atom] -> [Atom]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Text
"SG" Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
==) (Text -> Bool) -> (Atom -> Text) -> Atom -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Atom -> Text) -> Atom -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Atom -> Text
PDB.atomName) ([Atom] -> [Atom]) -> [Atom] -> [Atom]
forall a b. (a -> b) -> a -> b
$ [[Atom]] -> [Atom]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Atom]]
cystines
cystines :: [[PDB.Atom]]
cystines :: [[Atom]]
cystines = ([Atom] -> Bool) -> [[Atom]] -> [[Atom]]
forall a. (a -> Bool) -> [a] -> [a]
filter [Atom] -> Bool
cystinePredicate [[Atom]]
atomsGroupedByResidue
cystinePredicate :: [PDB.Atom] -> Bool
cystinePredicate :: [Atom] -> Bool
cystinePredicate [Atom]
residue = (Atom -> Bool) -> [Atom] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((Text
"SG" Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
==) (Text -> Bool) -> (Atom -> Text) -> Atom -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Atom -> Text) -> Atom -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Atom -> Text
PDB.atomName) [Atom]
residue Bool -> Bool -> Bool
&& (Atom -> Bool) -> [Atom] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((Text
"HG" Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/=) (Text -> Bool) -> (Atom -> Text) -> Atom -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Atom -> Text) -> Atom -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Atom -> Text
PDB.atomName) [Atom]
residue
coords :: PDB.Atom -> V3 Float
coords :: Atom -> V3 Float
coords PDB.Atom{Char
Float
Int
Text
atomCharge :: Text
atomElement :: Text
atomTempFactor :: Float
atomOccupancy :: Float
atomZ :: Float
atomY :: Float
atomX :: Float
atomICode :: Char
atomResSeq :: Int
atomChainID :: Char
atomResName :: Text
atomAltLoc :: Char
atomName :: Text
atomSerial :: Int
atomCharge :: Atom -> Text
atomElement :: Atom -> Text
atomTempFactor :: Atom -> Float
atomOccupancy :: Atom -> Float
atomZ :: Atom -> Float
atomY :: Atom -> Float
atomX :: Atom -> Float
atomICode :: Atom -> Char
atomResSeq :: Atom -> Int
atomChainID :: Atom -> Char
atomResName :: Atom -> Text
atomAltLoc :: Atom -> Char
atomName :: Atom -> Text
atomSerial :: Atom -> Int
..} = Float -> Float -> Float -> V3 Float
forall a. a -> a -> a -> V3 a
V3 Float
atomX Float
atomY Float
atomZ
sulfidicBondMaxLength :: Float
sulfidicBondMaxLength :: Float
sulfidicBondMaxLength = Float
2.56
peptideBondMaxLength :: Float
peptideBondMaxLength :: Float
peptideBondMaxLength = Float
1.5
restoreChainPeptideBonds :: [[PDB.Atom]] -> [Bond PDB.Atom]
restoreChainPeptideBonds :: [[Atom]] -> [Bond Atom]
restoreChainPeptideBonds [[Atom]]
atomsGroupedByResidue = [Maybe (Bond Atom)] -> [Bond Atom]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe (Bond Atom)] -> [Bond Atom])
-> [Maybe (Bond Atom)] -> [Bond Atom]
forall a b. (a -> b) -> a -> b
$ [[Atom]] -> [Maybe (Bond Atom)] -> [Maybe (Bond Atom)]
restoreChainPeptideBonds' [[Atom]]
atomsGroupedByResidue [Maybe (Bond Atom)]
forall a. Monoid a => a
mempty
where
restoreChainPeptideBonds' :: [[PDB.Atom]] -> [Maybe (Bond PDB.Atom)] -> [Maybe (Bond PDB.Atom)]
restoreChainPeptideBonds' :: [[Atom]] -> [Maybe (Bond Atom)] -> [Maybe (Bond Atom)]
restoreChainPeptideBonds' [] [Maybe (Bond Atom)]
acc = [Maybe (Bond Atom)]
acc
restoreChainPeptideBonds' [[Atom]
_] [Maybe (Bond Atom)]
acc = [Maybe (Bond Atom)]
acc
restoreChainPeptideBonds' ([Atom]
residue1:[Atom]
residue2:[[Atom]]
residues) [Maybe (Bond Atom)]
acc =
[[Atom]] -> [Maybe (Bond Atom)] -> [Maybe (Bond Atom)]
restoreChainPeptideBonds' ([Atom]
residue2[Atom] -> [[Atom]] -> [[Atom]]
forall a. a -> [a] -> [a]
:[[Atom]]
residues) ([Atom] -> [Atom] -> Maybe (Bond Atom)
constructBond [Atom]
residue1 [Atom]
residue2 Maybe (Bond Atom) -> [Maybe (Bond Atom)] -> [Maybe (Bond Atom)]
forall a. a -> [a] -> [a]
: [Maybe (Bond Atom)]
acc)
constructBond :: [PDB.Atom] -> [PDB.Atom] -> Maybe (Bond PDB.Atom)
constructBond :: [Atom] -> [Atom] -> Maybe (Bond Atom)
constructBond [Atom]
residue1 [Atom]
residue2 = do
Atom
carbonAtom1 <- [Atom] -> Text -> Maybe Atom
getAtomByName [Atom]
residue1 Text
"C"
Atom
nitrogenAtom2 <- [Atom] -> Text -> Maybe Atom
getAtomByName [Atom]
residue2 Text
"N"
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ V3 Float -> V3 Float -> Float
forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a -> a
distance (Atom -> V3 Float
coords Atom
carbonAtom1) (Atom -> V3 Float
coords Atom
nitrogenAtom2) Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
peptideBondMaxLength
Bond Atom -> Maybe (Bond Atom)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bond Atom -> Maybe (Bond Atom)) -> Bond Atom -> Maybe (Bond Atom)
forall a b. (a -> b) -> a -> b
$ Atom -> Atom -> Int -> Bond Atom
forall m. m -> m -> Int -> Bond m
Bond Atom
carbonAtom1 Atom
nitrogenAtom2 Int
1
getAtomByName :: [PDB.Atom] -> Text -> Maybe PDB.Atom
getAtomByName :: [Atom] -> Text -> Maybe Atom
getAtomByName [Atom]
atoms Text
atomNameToFind = (Atom -> Bool) -> [Atom] -> Maybe Atom
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((Text
atomNameToFind Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
==) (Text -> Bool) -> (Atom -> Text) -> Atom -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Atom -> Text) -> Atom -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Atom -> Text
PDB.atomName) [Atom]
atoms
restoreChainIntraResidueBonds :: [[PDB.Atom]] -> [Bond PDB.Atom]
restoreChainIntraResidueBonds :: [[Atom]] -> [Bond Atom]
restoreChainIntraResidueBonds = ([Atom] -> [Bond Atom]) -> [[Atom]] -> [Bond Atom]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [Atom] -> [Bond Atom]
restoreIntraResidueBonds
restoreIntraResidueBonds :: [PDB.Atom] -> [Bond PDB.Atom]
restoreIntraResidueBonds :: [Atom] -> [Bond Atom]
restoreIntraResidueBonds [Atom]
residueAtoms = [Maybe (Bond Atom)] -> [Bond Atom]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe (Bond Atom)] -> [Bond Atom])
-> [Maybe (Bond Atom)] -> [Bond Atom]
forall a b. (a -> b) -> a -> b
$ (Text, Text) -> Maybe (Bond Atom)
constructBond ((Text, Text) -> Maybe (Bond Atom))
-> [(Text, Text)] -> [Maybe (Bond Atom)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Text, Text)]
residueBonds
where
constructBond :: (Text, Text) -> Maybe (Bond PDB.Atom)
constructBond :: (Text, Text) -> Maybe (Bond Atom)
constructBond (Text
fromAtomName, Text
toAtomName) = Atom -> Atom -> Int -> Bond Atom
forall m. m -> m -> Int -> Bond m
Bond (Atom -> Atom -> Int -> Bond Atom)
-> Maybe Atom -> Maybe (Atom -> Int -> Bond Atom)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Maybe Atom
constructAtom Text
fromAtomName Maybe (Atom -> Int -> Bond Atom)
-> Maybe Atom -> Maybe (Int -> Bond Atom)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Maybe Atom
constructAtom Text
toAtomName Maybe (Int -> Bond Atom) -> Maybe Int -> Maybe (Bond Atom)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
constructAtom :: Text -> Maybe PDB.Atom
constructAtom :: Text -> Maybe Atom
constructAtom Text
atomName = Map Text Atom
atomNameToAtom Map Text Atom -> Text -> Maybe Atom
forall k a. Ord k => Map k a -> k -> Maybe a
!? Text
atomName
atomNameToAtom :: Map Text PDB.Atom
atomNameToAtom :: Map Text Atom
atomNameToAtom = [(Text, Atom)] -> Map Text Atom
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Text, Atom)] -> Map Text Atom)
-> [(Text, Atom)] -> Map Text Atom
forall a b. (a -> b) -> a -> b
$ (\atom :: Atom
atom@PDB.Atom{Char
Float
Int
Text
atomCharge :: Text
atomElement :: Text
atomTempFactor :: Float
atomOccupancy :: Float
atomZ :: Float
atomY :: Float
atomX :: Float
atomICode :: Char
atomResSeq :: Int
atomChainID :: Char
atomResName :: Text
atomAltLoc :: Char
atomName :: Text
atomSerial :: Int
atomCharge :: Atom -> Text
atomElement :: Atom -> Text
atomTempFactor :: Atom -> Float
atomOccupancy :: Atom -> Float
atomZ :: Atom -> Float
atomY :: Atom -> Float
atomX :: Atom -> Float
atomICode :: Atom -> Char
atomResSeq :: Atom -> Int
atomChainID :: Atom -> Char
atomResName :: Atom -> Text
atomAltLoc :: Atom -> Char
atomName :: Atom -> Text
atomSerial :: Atom -> Int
..} -> (Text -> Text
T.strip Text
atomName, Atom
atom)) (Atom -> (Text, Atom)) -> [Atom] -> [(Text, Atom)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Atom]
residueAtoms
residueBonds :: [(Text, Text)]
residueBonds :: [(Text, Text)]
residueBonds = Text -> [(Text, Text)]
intraResidueBonds (Text -> [(Text, Text)])
-> (Atom -> Text) -> Atom -> [(Text, Text)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Atom -> Text) -> Atom -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Atom -> Text
PDB.atomResName (Atom -> [(Text, Text)]) -> Atom -> [(Text, Text)]
forall a b. (a -> b) -> a -> b
$ [Atom] -> Atom
forall a. [a] -> a
head [Atom]
residueAtoms
intraResidueBonds :: Text -> [(Text, Text)]
intraResidueBonds :: Text -> [(Text, Text)]
intraResidueBonds Text
"NMA" = [(Text
"CA", Text
"N")]
intraResidueBonds Text
"ACE" = [(Text
"C", Text
"O"), (Text
"C", Text
"CH3")]
intraResidueBonds Text
residueName = [(Text, Text)]
backboneBonds [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ Text -> [(Text, Text)]
caCbBonds Text
residueName [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ Text -> [(Text, Text)]
sideChainBonds Text
residueName
backboneBonds :: [(Text, Text)]
backboneBonds :: [(Text, Text)]
backboneBonds = [(Text
"N", Text
"CA"), (Text
"CA", Text
"C"), (Text
"C", Text
"O"), (Text
"N", Text
"H")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text
"C",Text
"OXT"), (Text
"C",Text
"HXT")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"N", [Text
"H1", Text
"H2", Text
"H3"])]
caCbBonds :: Text -> [(Text, Text)]
caCbBonds :: Text -> [(Text, Text)]
caCbBonds Text
aminoacid = case Text
aminoacid of
Text
"GLY" -> [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CA", [Text
"HA1", Text
"HA2", Text
"HA3"])]
Text
_ -> [(Text
"CA", Text
"CB"), (Text
"CA", Text
"HA"), (Text
"CA", Text
"HA1"), (Text
"CA", Text
"HA2"), (Text
"CA", Text
"HA3")]
sideChainBonds :: Text -> [(Text, Text)]
sideChainBonds :: Text -> [(Text, Text)]
sideChainBonds Text
"ALA" = [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB1", Text
"HB2", Text
"HB3"])]
sideChainBonds Text
"ARG" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD"), (Text
"CD", Text
"NE"), (Text
"NE", Text
"CZ"), (Text
"CZ", Text
"NH2"), (Text
"CZ", Text
"NH1")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany[(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"CG", [Text
"HG3", Text
"HG2"]), (Text
"CD", [Text
"HD3", Text
"HD2"]), (Text
"NE", [Text
"HE"]), (Text
"NH1", [Text
"HH12", Text
"HH11"]), (Text
"NH2", [Text
"HH22", Text
"HH21"])]
sideChainBonds Text
"ASN" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"OD1"), (Text
"CG", Text
"ND2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"ND2", [Text
"HD22", Text
"HD21"])]
sideChainBonds Text
"ASP" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"OD1"), (Text
"CG", Text
"OD2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"OD2", [Text
"HD2"])]
sideChainBonds Text
"ASH" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"OD1"), (Text
"CG", Text
"OD2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"OD2", [Text
"HD2"])]
sideChainBonds Text
"CYS" = [(Text
"CB", Text
"SG")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"SG", [Text
"HG"])]
sideChainBonds Text
"CYX" = [(Text
"CB", Text
"SG")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"SG", [Text
"HG"])]
sideChainBonds Text
"GLN" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD"), (Text
"CD", Text
"OE1"), (Text
"CD", Text
"NE2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"CG", [Text
"HG3", Text
"HG2"]), (Text
"NE2", [Text
"HE22", Text
"HE21"])]
sideChainBonds Text
"GLU" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD"), (Text
"CD", Text
"OE1"), (Text
"CD", Text
"OE2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB1", Text
"HB2", Text
"HB3"]), (Text
"CG", [Text
"HG3", Text
"HG2"]), (Text
"OE2", [Text
"HE2"])]
sideChainBonds Text
"GLH" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD"), (Text
"CD", Text
"OE1"), (Text
"CD", Text
"OE2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB1", Text
"HB2", Text
"HB3"]), (Text
"CG", [Text
"HG3", Text
"HG2"]), (Text
"OE2", [Text
"HE2"])]
sideChainBonds Text
"GLY" = []
sideChainBonds Text
"HID" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"ND1"), (Text
"ND1", Text
"CE1"), (Text
"CE1", Text
"NE2"), (Text
"NE2", Text
"CD2"), (Text
"CD2", Text
"CG")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"ND1", [Text
"HD1"]), (Text
"CE1", [Text
"HE1"]), (Text
"CD2", [Text
"HD2"]), (Text
"CD2", [Text
"HD2"])]
sideChainBonds Text
"HIE" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"ND1"), (Text
"ND1", Text
"CE1"), (Text
"CE1", Text
"NE2"), (Text
"NE2", Text
"CD2"), (Text
"CD2", Text
"CG")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"CE1", [Text
"HE1"]), (Text
"NE2", [Text
"HE2"]), (Text
"CD2", [Text
"HD2"]), (Text
"CD2", [Text
"HD2"])]
sideChainBonds Text
"HIP" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"ND1"), (Text
"ND1", Text
"CE1"), (Text
"CE1", Text
"NE2"), (Text
"NE2", Text
"CD2"), (Text
"CD2", Text
"CG")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"ND1", [Text
"HD1"]), (Text
"CE1", [Text
"HE1"]), (Text
"NE2", [Text
"HE2"]), (Text
"CD2", [Text
"HD2"])]
sideChainBonds Text
"HIS" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"ND1"), (Text
"ND1", Text
"CE1"), (Text
"CE1", Text
"NE2"), (Text
"NE2", Text
"CD2"), (Text
"CD2", Text
"CG")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"ND1", [Text
"HD1"]), (Text
"CE1", [Text
"HE1"]), (Text
"NE2", [Text
"HE2"]), (Text
"CD2", [Text
"HD2"])]
sideChainBonds Text
"ILE" = [(Text
"CB", Text
"CG1"), (Text
"CB", Text
"CG2"), (Text
"CG1", Text
"CD1")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB", Text
"HB2", Text
"HB3"]), (Text
"CG1", [Text
"HG13", Text
"HG12"]), (Text
"CG2", [Text
"HG21", Text
"HG22", Text
"HG23"]), (Text
"CD1", [Text
"HD11", Text
"HD12", Text
"HD13"])]
sideChainBonds Text
"LEU" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD1"), (Text
"CG", Text
"CD2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"CG", [Text
"HG", Text
"HG2"]), (Text
"CD1", [Text
"HD11", Text
"HD12", Text
"HD13"]), (Text
"CD2", [Text
"HD21", Text
"HD22", Text
"HD23"])]
sideChainBonds Text
"LYS" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD"), (Text
"CD", Text
"CE"), (Text
"CE", Text
"NZ")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB1", Text
"HB2", Text
"HB3"]), (Text
"CG", [Text
"HG1", Text
"HG2", Text
"HG3"]), (Text
"CD", [Text
"HD3", Text
"HD2"]), (Text
"CE", [Text
"HE3", Text
"HE2"]), (Text
"NZ", [Text
"HZ1", Text
"HZ2", Text
"HZ3"])]
sideChainBonds Text
"MET" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"SD"), (Text
"SD", Text
"CE")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"CG", [Text
"HG3", Text
"HG2"]), (Text
"CE", [Text
"HE1", Text
"HE2", Text
"HE3"])]
sideChainBonds Text
"PHE" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD1"), (Text
"CD1", Text
"CE1"), (Text
"CE1", Text
"CZ"), (Text
"CZ", Text
"CE2"), (Text
"CE2", Text
"CD2"), (Text
"CD2", Text
"CG")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"CD1", [Text
"HD1"]), (Text
"CE1", [Text
"HE1"]), (Text
"CZ", [Text
"HZ"]), (Text
"CE2", [Text
"HE2"]), (Text
"CD2", [Text
"HD2"])]
sideChainBonds Text
"PRO" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD"), (Text
"CD", Text
"N")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB1", Text
"HB2", Text
"HB3"]), (Text
"CG", [Text
"HG3", Text
"HG2"]), (Text
"CD", [Text
"HD2", Text
"HD3"])]
sideChainBonds Text
"SER" = [(Text
"CB", Text
"OG")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2", Text
"HB1"]), (Text
"OG", [Text
"HG"])]
sideChainBonds Text
"THR" = [(Text
"CB", Text
"OG1"), (Text
"CB", Text
"CG2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB", Text
"HB3"]), (Text
"OG1", [Text
"HG1"]), (Text
"CG2", [Text
"HG21", Text
"HG22", Text
"HG23"])]
sideChainBonds Text
"TRP" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD1"), (Text
"CD1", Text
"NE1"), (Text
"NE1", Text
"CE2"), (Text
"CE2", Text
"CD2"), (Text
"CD2", Text
"CG"), (Text
"CD2", Text
"CE3"), (Text
"CE3", Text
"CZ3"), (Text
"CZ3", Text
"CH2"), (Text
"CH2", Text
"CZ2"), (Text
"CZ2", Text
"CE2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"CD1", [Text
"HD1"]), (Text
"NE1", [Text
"HE1"]), (Text
"CE3", [Text
"HE3"]), (Text
"CZ3", [Text
"HZ3"]), (Text
"CH2", [Text
"HH2"]), (Text
"CZ2", [Text
"HZ2"])]
sideChainBonds Text
"TYR" = [(Text
"CB", Text
"CG"), (Text
"CG", Text
"CD1"), (Text
"CD1", Text
"CE1"), (Text
"CE1", Text
"CZ"), (Text
"CZ", Text
"CE2"), (Text
"CE2", Text
"CD2"), (Text
"CD2", Text
"CG"), (Text
"CZ", Text
"OH")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB3", Text
"HB2"]), (Text
"CD1", [Text
"HD1"]), (Text
"CE1", [Text
"HE1"]), (Text
"CE2", [Text
"HE2"]), (Text
"CD2", [Text
"HD2"]), (Text
"OH", [Text
"HH"])]
sideChainBonds Text
"VAL" = [(Text
"CB", Text
"CG1"), (Text
"CB", Text
"CG2")] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ [(Text, [Text])] -> [(Text, Text)]
bwhMany [(Text
"CB", [Text
"HB", Text
"HB3"]), (Text
"CG1", [Text
"HG11", Text
"HG12", Text
"HG13"]), (Text
"CG2", [Text
"HG21", Text
"HG22", Text
"HG23"])]
sideChainBonds Text
unknownResidue = String -> [(Text, Text)]
forall a. HasCallStack => String -> a
error (String -> [(Text, Text)])
-> (Text -> String) -> Text -> [(Text, Text)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> [(Text, Text)]) -> Text -> [(Text, Text)]
forall a b. (a -> b) -> a -> b
$ Text
"cobot-io: we don't know what to do with residue " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
unknownResidue
bwhMany :: [(Text, [Text])] -> [(Text, Text)]
bwhMany :: [(Text, [Text])] -> [(Text, Text)]
bwhMany = ((Text, [Text]) -> [(Text, Text)])
-> [(Text, [Text])] -> [(Text, Text)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Text, [Text]) -> [(Text, Text)]
bwh
bwh :: (Text, [Text]) -> [(Text, Text)]
bwh :: (Text, [Text]) -> [(Text, Text)]
bwh = (Text, [Text]) -> [(Text, Text)]
heavyAtomBondsWithHydrogens
heavyAtomBondsWithHydrogens :: (Text, [Text]) -> [(Text, Text)]
heavyAtomBondsWithHydrogens :: (Text, [Text]) -> [(Text, Text)]
heavyAtomBondsWithHydrogens (Text
heavyAtomName, [Text]
hydrogenNames) = (Text
heavyAtomName,) (Text -> (Text, Text)) -> [Text] -> [(Text, Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text]
hydrogenNames