module Bio.PDB.EventParser.ParseDBREF(parseDBREF, parseDBREF12)
where
import qualified Data.ByteString.Char8 as BS
import Data.Char(ord,chr)
import Bio.PDB.EventParser.PDBEvents
import Bio.PDB.EventParser.PDBParsingAbstractions
dbrefFields = [( 6, mKeyword "record id" "DBREF "),
( 7, mSpc 1),
(11, mStr "id code"),
(12, mSpc 1),
(13, mChr "chain id"),
(14, mSpc 1),
(18, mInt "initial sequence number of PDB sequence segment"),
(19, mChr "initial insertion code of the PDB sequence segment"),
(20, mSpc 1),
(24, mInt "ending sequence number of the PDB sequence segment"),
(25, mChr "ending insertion code of the PDB sequence segment"),
(26, mSpc 1),
(32, mStr "sequence database name"),
(33, mSpc 1),
(41, mStr "sequence database accession code"),
(42, mSpc 1),
(54, mStr "sequence database identification code"),
(55, mSpc 1),
(60, mInt "initial sequence number of the database segment"),
(61, dChr "insertion code of initial residue of the sequence, if PDB is the reference" ' '),
(62, mSpc 1),
(67, mInt "ending sequence number of the database segment"),
(68, dChr "insertion code of the ending residue of the segment, if PDB is the reference" ' ')]
parseDBREF :: (Monad m) => BS.ByteString -> Int -> m [PDBEvent]
parseDBREF line line_no = return $ if null errs
then [result]
else errs
where
(fields, errs) = parseFields dbrefFields line line_no
[fRec, _, fIdCode, _, fChain, _, fIniSeqNumPDB, fIniInsCodePDB, _,
fEndSeqNumPDB, fEndInsCodePDB, _,
fSeqDbName, _, fSeqDbAccCode, _, fSeqDbIdCode, _, fIniSeqNumInDb,
fIniInsCodeInPDBRef, _, fEndSeqNumInDb, fEndInsCodeInPDBRef] = fields
IFStr idCode = fIdCode
IFChar chain = fChain
IFInt iniSeqNumPDB = fIniSeqNumPDB
IFChar iniInsCodePDB = fIniInsCodePDB
IFInt endSeqNumPDB = fEndSeqNumPDB
IFChar endInsCodePDB = fEndInsCodePDB
IFStr seqDbName = fSeqDbName
IFStr seqDbAccCode = fSeqDbAccCode
IFStr seqDbIdCode = fSeqDbIdCode
IFInt iniSeqNumInDb = fIniSeqNumInDb
IFChar iniInsCodeInPDBRef = fIniInsCodeInPDBRef
IFInt endSeqNumInDb = fEndSeqNumInDb
IFChar endInsCodeInPDBRef = fEndInsCodeInPDBRef
result = DBREF idCode chain iniSeqNumPDB iniInsCodePDB endSeqNumPDB endInsCodePDB seqDbName seqDbAccCode seqDbIdCode iniSeqNumInDb iniInsCodeInPDBRef endSeqNumInDb endInsCodeInPDBRef
dbref1Fields = [( 6, mKeyword "record id" "DBREF1"),
( 7, mSpc 1),
(11, mStr "id code"),
(12, mSpc 1),
(13, mChr "chain id"),
(14, mSpc 1),
(18, mInt "initial sequence number of PDB sequence segment"),
(19, mChr "initial insertion code of the PDB sequence segment"),
(20, mSpc 1),
(24, mInt "ending sequence number of the PDB sequence segment"),
(25, mChr "ending insertion code of the PDB sequence segment"),
(26, mSpc 1),
(32, mStr "sequence database name"),
(47, mSpc 15),
(67, mStr "sequence database identification code")]
dbref2Fields = [( 6, mKeyword "record id" "DBREF2"),
( 7, mSpc 1),
(11, mStr "id code"),
(12, mSpc 1),
(13, mChr "chain id"),
(18, mSpc 5),
(40, mStr "sequence database accession code"),
(45, mSpc 5),
(55, mInt "initial sequence number of the database segment"),
(58, mSpc 3),
(67, mInt "ending sequence number of the database segment")]
checkEqs line_no [] = []
checkEqs line_no ((a, b, col_no):eqs) = if trim a /= trim b
then
PDBParseError line_no col_no
(BS.intercalate ""
["Fields of consecutive ",
"DBREF1/DBREF2 records don't agree: '",
a, "' /= '", b, "'."]): rest
else
rest
where rest = checkEqs line_no eqs
parseDBREF12 :: (Monad m) => (BS.ByteString, BS.ByteString) -> Int -> m [PDBEvent]
parseDBREF12 (!line1, !line2) !line_no = return $ if null errs
then [result]
else errs
where
(fields1, errs1) = parseFields dbref1Fields line1 line_no
(fields2, errs2) = parseFields dbref2Fields line2 (line_no + 1)
errs = errs1 ++ errs2 ++ mergeErrs
[fRec1, _, fIdCode1, _, fChain1, _, fIniSeqNumPDB, fIniInsCodePDB, _,
fEndSeqNumPDB, fEndInsCodePDB, _,
fSeqDbName, _, fSeqDbIdCode] = fields1
[fRec2, _, fIdCode2, _, fChain2, _, fSeqDbAccCode, _, fIniSeqNumInDb,
_, fEndSeqNumInDb] = fields2
IFStr idCode1 = fIdCode1
IFStr idCode2 = fIdCode1
IFChar chain1 = fChain1
IFChar chain2 = fChain2
IFInt iniSeqNumPDB = fIniSeqNumPDB
IFChar iniInsCodePDB = fIniInsCodePDB
IFInt endSeqNumPDB = fEndSeqNumPDB
IFChar endInsCodePDB = fEndInsCodePDB
IFStr seqDbName = fSeqDbName
IFStr seqDbAccCode = fSeqDbAccCode
IFStr seqDbIdCode = fSeqDbIdCode
IFInt iniSeqNumInDb = fIniSeqNumInDb
IFInt endSeqNumInDb = fEndSeqNumInDb
mergeErrs = checkEqs (line_no + 1) [(idCode1, idCode2, 11),
(BS.singleton chain1, BS.singleton chain2, 13)]
result = DBREF idCode1 chain1 iniSeqNumPDB iniInsCodePDB endSeqNumPDB endInsCodePDB
seqDbName seqDbAccCode seqDbIdCode iniSeqNumInDb ' ' endSeqNumInDb ' '