hPDB-1.1.1: Bio/PDB/IO.hs
{-# LANGUAGE OverloadedStrings #-}
-- | Simple input/output wrappers taking filenames, and handling compression.
module Bio.PDB.IO(parse, write, PDBWritable()) where
import qualified Control.Exception(catch)
import Control.Exception.Base(SomeException)
import System.IO hiding(writeFile, FilePath)
import Prelude hiding(String,writeFile)
import Bio.PDB.EventParser.PDBParsingAbstractions
import Bio.PDB.Structure.List as L
import qualified Bio.PDB.StructurePrinter as PDBSP
import Bio.PDB.StructurePrinter(PDBWritable())
import Control.Monad(when)
import Bio.PDB.EventParser.PDBEvents(PDBEvent(PDBParseError, PDBIgnoredLine))
--import qualified Bio.PDB.EventParser.PDBEventPrinter as PDBEventPrinter
import qualified Bio.PDB.StructureBuilder(parse)
import qualified Bio.PDB.Structure
import qualified Data.ByteString.Char8 as BS
import Bio.PDB.IO.OpenAnyFile
import Control.DeepSeq
-- | Type alias.
type String = BS.ByteString
-- Until I get a newer version of Control.DeepSeq:
-- | Alias to a function present in newer versions of 'deepseq' library.
force x = x `deepseq` x
-- | Parse a .pdb file and return `Bio.PDB.Structure.Structure`.
parse :: FilePath -> IO (Maybe Bio.PDB.Structure.Structure)
parse filename = do input <- Bio.PDB.IO.OpenAnyFile.readFile filename
do (structure, errs) <- return $ Bio.PDB.StructureBuilder.parse filename input
mapM_ (showError filename) (L.toList errs)
structure `deepseq` return $ Just structure
`Control.Exception.catch`
exceptionHandler filename
-- | Default exception handler that for `IO (Maybe a)` just prints nice error message to stderr, and returns Nothing
exceptionHandler :: FilePath -> SomeException -> IO (Maybe a)
exceptionHandler filename e = do printError [BS.pack filename, ":", BS.pack $ show e]
return Nothing
-- | Prints a catenated list of ByteStrings to stderr. (Convenience function.)
printError msg = BS.hPutStrLn System.IO.stderr $ BS.concat msg
-- | Show error message from `PDBParser`.
showError filename (PDBParseError line_no col_no msg) =
printError [BS.pack filename, ":", BS.pack $ show line_no, ":", BS.pack $ show col_no, "\t", msg]
showError filename (PDBIgnoredLine line) =
printError [BS.pack filename, ": IGNORED ", line]
-- | Write structure to a .pdb file.
write :: PDBWritable a => a -> FilePath -> IO ()
write structure fname = writeFile fname $ \h -> PDBSP.write h structure