module ZEBEDDE.Core.ReadXYZ (readXYZ,writeXYZ,showMolecule) where
import ZEBEDDE.Core.Vector
import ZEBEDDE.Core.Molecule
type XYZ = (Int,[(String,Vec)])
readXYZ :: String -> IO Molecule
readXYZ filepath = do
dat <- readFile filepath
let n = read (firstLine dat) in do
return (newMolecule n (map getName (atoms dat)))
where
getName (a,b) | a == "C" = (a,6,b)
| a == "H" = (a,1,b)
| otherwise = (a,0,b)
firstLine = takeWhile (not . (=='\n'))
rest a = drop ((length (firstLine a))+2) a
atoms a = map getAtom $ filter ((4==).length ) $ map ((split ' ')) (split '\n' (rest a))
where
getAtom :: [String] -> (String,Vec)
getAtom xss = let [a,b,c,d] = take 4 xss in (a,vec (read b,read c,read d))
split flag string | string == [] = []
| string == [flag] = []
| (head string) == flag = split flag (tail string)
| flag `elem` string = let x = (takeWhile (not.(==flag)) string) in x:(split flag (drop ((length x)+1) string))
| otherwise = [string]
writeXYZ :: String -> Molecule -> IO ()
writeXYZ s xyz = writeFile s (showMolecule xyz)
showMolecule m = let atoms' = (atoms m) in
(show (length atoms')) +++ (foldl (+++) "" (map show'' atoms'))
where
(+++) a b = a ++ "\n"++ ( b)
show'' ((s,_, v)) = (s) ++ show v
instance Show Vec where
show v = (show' ((unVec v)::(Double,Double,Double)) )
where
show' ((a,b,c)) = concat $ map (show''.show''') [a,b,c]
show'' a = if (head a) == '-' then (" " ++ (pad a)) else (" " ++ (pad a))
show''' a = show a
pad a | length a == 11 = a
| otherwise = a ++ (take (11(length a)) (repeat ' '))
test = do
putStr "please run this in the same directory as \"benzene.xyz\"\n"
_ <- getLine
xyz <- readXYZ "benzene.xyz"
writeXYZ "out.xyz" xyz
putStrLn "thank you, that worked."