hPDB-0.99: Bio/PDB/EventParser/ParseSEQRES.hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
-- | Parsing a SEQRES record.
module Bio.PDB.EventParser.ParseSEQRES(parseSEQRES)
where
import qualified Data.ByteString.Char8 as BS
import Bio.PDB.EventParser.PDBEvents
import Bio.PDB.EventParser.PDBParsingAbstractions
--------------- {{{ SEQRES records
{--
COLUMNS DATA TYPE FIELD DEFINITION
----------------------------------------------------------------------------------
COLUMNS DATA TYPE FIELD DEFINITION
-------------------------------------------------------------------------------------
1 - 6 Record name "SEQRES"
8 - 10 Int serNum Serial number of the SEQRES record for the
current chain. Starts at 1 and increments
by one each line. Reset to 1 for each chain.
WARNING: As seen in 3JYV - serial number spans from 7th column!!!
12 Character chainID Chain identifier. This may be any single
legal character, including a blank which is
is used if there is only one chain.
14 - 17 Int numRes Number of residues in the chain.
This value is repeated on every record.
20 - 22 Residue name resName Residue name.
24 - 26 Residue name resName Residue name.
28 - 30 Residue name resName Residue name.
32 - 34 Residue name resName Residue name.
36 - 38 Residue name resName Residue name.
40 - 42 Residue name resName Residue name.
44 - 46 Residue name resName Residue name.
48 - 50 Residue name resName Residue name.
52 - 54 Residue name resName Residue name.
56 - 58 Residue name resName Residue name.
60 - 62 Residue name resName Residue name.
64 - 66 Residue name resName Residue name.
68 - 70 Residue name resName Residue name.
--}
seqresFields = [(6, mKeyword "record header" "SEQRES"),
(7, mSpc 1),
(10, mInt "serial number"),
(11, mSpc 1),
(12, mChr "chain id"),
(13, mSpc 1),
(17, mInt "number of residues"),
(70, pStr "residues")]
splitResidues resStr = if BS.null resStr
then []
else res:splitResidues rest2
where
(res, rest) = BS.splitAt 3 resStr
(" ", rest2) = BS.splitAt 1 rest
-- | Parses a SEQRES record:
--
-- Arguments:
--
-- (1) input line
--
-- (2) input line number
--
-- Result is a monad action returning a list of 'PDBEvent's.
parseSEQRES :: (Monad m) => BS.ByteString -> Int -> m [PDBEvent]
parseSEQRES line line_no = return $ if errs == []
then [result]
else errs
where
-- parse
(fields, errs) = parseFields seqresFields line line_no
[fRec, fSpc1, fSerial, fSpc2, fChain, fSpc3, fNum, fRes] = fields
-- unpack fields
IFInt serial = fSerial
IFChar chain = fChain
IFInt num = fNum
IFStr residues = fRes
resList = filter (not . BS.null) (BS.split ' ' residues)
-- assuming residue name won't contain spaces...
result = SEQRES serial chain num resList
-- NOTE: consecutive "SEQRES" records should be merged into a single multiline entry with SUCH method
--mergeTitle :: [PDBEvent] -> m [PDBEvent]
--------------- }}} SEQRES records