hPDB-0.99: Bio/PDB/EventParser/ParseLINK.hs
{-# LANGUAGE ScopedTypeVariables, OverloadedStrings #-}
-- | Parsing LINK records.
module Bio.PDB.EventParser.ParseLINK(parseLINK)
where
import Prelude hiding(String)
import qualified Data.ByteString.Char8 as BS
import Bio.PDB.EventParser.PDBEvents
import Bio.PDB.EventParser.PDBParsingAbstractions
--------------- {{{ LINK records
{--
COLUMNS DATA TYPE FIELD DEFINITION
------------------------------------------------------------------------------------
1 - 6 Record name "LINK "
13 - 16 Atom name1 Atom name.
17 Character altLoc1 Alternate location indicator.
18 - 20 Residue name resName1 Residue name.
22 Character chainID1 Chain identifier.
23 - 26 Integer resSeq1 Residue sequence number.
27 AChar iCode1 Insertion code.
43 - 46 Atom name2 Atom name.
47 Character altLoc2 Alternate location indicator.
48 - 50 Residue name resName2 Residue name.
52 Character chainID2 Chain identifier.
53 - 56 Integer resSeq2 Residue sequence number.
57 AChar iCode2 Insertion code.
60 - 65 SymOP sym1 Symmetry operator atom 1.
67 - 72 SymOP sym2 Symmetry operator atom 2.
74 – 78 Real(5.2) Length Link distance
--}
{-# INLINE linkFields #-}
linkFields = [(6, mKeyword "record header" "LINK " ),
(12, mSpc 6 ),
(16, mStr "atom name" ),
(17, mChr "alternate location indicator 1" ),
(20, mStr "residue name 1" ),
(21, mSpc 1 ),
(22, mChr "chain id 1" ),
(26, mInt "residue sequence number 1" ),
(27, mChr "insertion code 1" ),
(42, mSpc 15 ),
(46, mStr "atom name 1" ),
(47, mChr "alternate location indicator 2" ),
(50, mStr "residue name 2" ),
(51, mSpc 1 ),
(52, mChr "chain id 2" ),
(56, mInt "residue sequence number 2" ),
(57, mChr "insertion code 2" ),
(59, mSpc 2 ),
(65, mStr "symmetry operator for atom 1" ),
(66, mSpc 1 ),
(72, mStr "symmetry operator for atom 2" ),
(73, mSpc 1 ),
(78, pDouble "link distance" )]
-- | Parses a LINK record.
--
-- Arguments:
--
-- (1) input line
--
-- (2) input line number
--
-- Result is a monad action returning a list of 'PDBEvent's.
parseLINK :: (Monad m) => String -> Int -> m [PDBEvent]
parseLINK line line_no = return $ if errs == []
then [result]
else errs
where
-- parse
errs = if fErrs == [] then fgErrs else fErrs
(fields, fErrs) = parseFields linkFields line line_no
[fRec, _,
fAtName1, fAltLoc1, fResname1, _, fChain1, fResnum1, fInsCode1, _,
fAtName2, fAltLoc2, fResname2, _, fChain2, fResnum2, fInsCode2, _,
fSymOp1, _, fSymOp2, _, fLinkDist] = fields
IFChar altloc1 = fAltLoc1
IFChar altloc2 = fAltLoc2
IFStr symop1 = fSymOp1
IFStr symop2 = fSymOp2
linkdist = case fLinkDist of
IFDouble ld -> Just ld
IFNone -> Nothing
fgAt1 = fgAtom "atom 1" 16 fAtName1 fResname1 fChain1 fResnum1 fInsCode1
fgAt2 = fgAtom "atom 2" 26 fAtName2 fResname2 fChain2 fResnum2 fInsCode2
fgErrs = liftFgErrs line_no [fgAt1, fgAt2]
[at1, at2] = rights [fgAt1, fgAt2]
-- unpack fields
result = LINK at1 altloc1 at2 altloc2 symop1 symop2 linkdist
--------------- }}} LINK/LINKSYN records