hPDB-0.99: Bio/PDB/EventParser/ParseMatrixRecord.hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedStrings #-}
-- | Parsing of records on scale (SCALEn), origin (ORIGXn) and transformation (MTRIXn.)
module Bio.PDB.EventParser.ParseMatrixRecord(parseSCALEn, parseORIGXn, parseMTRIXn)
where
import Prelude hiding(String)
import qualified Data.ByteString.Char8 as BS
import Control.Exception(assert)
import Bio.PDB.EventParser.PDBEvents
import Bio.PDB.EventParser.PDBParsingAbstractions
--------------- {{{ Matrix records (SCALEn, ORIGXn, MTRIXn)
{--
COLUMNS DATA TYPE FIELD DEFINITION
----------------------------------------------------------------------------------
1 - 6 Record name "SCALE[123]", "ORIGX[123]" or "MTRIX[123]"
11 - 20 Real(10.6) o[n][1]
21 - 30 Real(10.6) o[n][2]
31 - 40 Real(10.6) o[n][3]
46 - 55 Real(10.5) t[n]
60 Integer 1 if coordinates for the related molecule are present;
otherwise, blank.
<MTRIXn> only
--}
titleFields = [(5, mKeywords "record header" ["SCALE", "ORIGX", "TVECT", "MTRIX"]),
(6, mInt "recno" ),
(7, mSpc 1 ),
(10, dInt "serial number" 0 ),
(20, mDouble "o[n][1]" ),
(30, mDouble "o[n][2]" ),
(40, mDouble "o[n][3]" ),
(45, mSpc 5 ),
(55, mDouble "t[n]" ),
(59, pSpc ),
(60, dInt "related molecule present?" 0 )]
-- | Parses a single line with matrix or vector information.
--
-- Arguments:
--
-- (1) record constructor: SCALEn, ORIGXn, MTRIXn
--
-- (2) input line
--
-- (3) input line number
--
-- Result is a monad action returning a list of 'PDBEvent's.
parseMatrixRecord :: (Monad m) =>(Int -> Bool -> Int -> [Vector3] -> [Double] -> PDBEvent)-> String-> Int-> m [PDBEvent]
parseMatrixRecord cons line line_no = return $ if errs == []
then [result]
else errs
where
-- parse
(fields, errs) = parseFields titleFields line line_no
[fRec, fRecNo, _, fSerial, fo1, fo2, fo3, fSpc2, ft, fSpc3, fRelMol] = fields
-- unpack fields
IFInt serial = fSerial
IFInt n = fRecNo
IFDouble o1 = fo1
IFDouble o2 = fo2
IFDouble o3 = fo3
IFDouble t = ft
IFInt relMol = fRelMol
result = cons serial (relMol==1) n [Vector3 o1 o2 o3] [t]
-- | Parses a SCALEn record.
--
-- Arguments:
--
-- (1) input line
--
-- (2) input line number
--
-- Result is a monad action returning a list of 'PDBEvent's.
parseSCALEn :: (Monad m) => String -> Int -> m [PDBEvent]
parseSCALEn = parseMatrixRecord (\s _ -> assert (s==0) SCALEn)
-- | Parses a ORIGXn record.
--
-- Arguments:
--
-- (1) input line
--
-- (2) input line number
--
-- Result is a monad action returning a list of 'PDBEvent's.
parseORIGXn :: (Monad m) => String -> Int -> m [PDBEvent]
parseORIGXn = parseMatrixRecord (\s _ -> assert (s==0) ORIGXn)
-- | Parses a MTRIXn record.
--
-- Arguments:
--
-- (1) input line
--
-- (2) input line number
--
-- Result is a monad action returning a list of 'PDBEvent's.
parseMTRIXn :: (Monad m) => String -> Int -> m [PDBEvent]
parseMTRIXn = parseMatrixRecord MTRIXn
-- NOTE: consecutive "TITLE" records should be merged into a single multiline entry with SUCH method
--mergeMatrixRecords :: [PDBEvent] -> m [PDBEvent]
--------------- }}} Matrix records