[contrib][haskell] add Edf support
[hkl.git] / contrib / haskell / src / Hkl / Edf.hs
blob78a2bdfc2ee80fadab728d3ee259cf58fb5566e9
1 {-# LANGUAGE OverloadedStrings #-}
3 module Hkl.Edf
4 ( Edf(..)
5 , edfP
6 , edfFromFile
7 ) where
9 import Control.Applicative
10 import Data.Attoparsec.Text
11 import Data.ByteString.Char8 (readFile, split)
12 import Data.Text (Text, words)
13 import Data.Text.Encoding (decodeUtf8)
14 import Numeric.Units.Dimensional.Prelude (Length, (*~), nano, meter)
16 import Prelude hiding (readFile, words)
18 data Edf = Edf { edf'Lambda :: Length Double
19 , edf'MotorPos :: [Double]
20 , edf'MotorMne :: [Text]
22 deriving (Show)
24 -- commentP :: Parser Text
25 -- commentP = "#" *> takeTill isEndOfLine <* endOfLine <?> "commentP"
27 -- headerP :: Parser [Text]
28 -- headerP = many1 commentP <?> "headerP"
30 -- calibrantP :: Parser Text
31 -- calibrantP = "calibrant: " *> takeTill isEndOfLine <* endOfLine <?> "calibrantP"
33 -- dspacingP :: Parser [Length Double]
34 -- dspacingP = "dspacing:" *> many1 lengthP' <* endOfLine <?> "dspasingP"
36 -- doubleP :: Text -> Parser Double
37 -- doubleP key = string key *> double <* endOfLine <?> "doubleP"
39 -- lengthP' :: Parser (Length Double)
40 -- lengthP' = do
41 -- skipSpace
42 -- value <- double
43 -- pure $ value *~ meter
45 -- lengthP :: Text -> Parser (Length Double)
46 -- lengthP key = do
47 -- value <- doubleP key
48 -- pure $ value *~ meter
50 -- angleP :: Text -> Parser (Angle Double)
51 -- angleP key = do
52 -- value <-doubleP key
53 -- pure $ value *~ radian
55 -- intP :: Text -> Parser Int
56 -- intP key = string key *> decimal <* endOfLine <?> "intP"
58 -- nptPointP :: Parser NptPoint
59 -- nptPointP = NptPoint
60 -- <$> ("point: x=" *> double)
61 -- <*> (" y=" *> double <* endOfLine)
63 -- nptEntryP :: Parser NptEntry
64 -- nptEntryP = NptEntry
65 -- <$> (skipSpace *> intP "New group of points: ")
66 -- <*> angleP "2theta: "
67 -- <*> intP "ring: "
68 -- <*> many nptPointP
70 edf'LambdaP :: Parser (Length Double)
71 edf'LambdaP = do
72 _ <- manyTill anyChar (try $ string "Lambda = ")
73 value <- double
74 pure $ value *~ nano meter
76 edf'MotorPosP :: Parser [Double]
77 edf'MotorPosP = do
78 _ <- manyTill anyChar (try $ string "motor_pos = ")
79 many1 (skipSpace *> double)
81 edf'MotorMneP :: Parser [Text]
82 edf'MotorMneP = do
83 _ <- manyTill anyChar (try $ string "motor_mne = ")
84 vs <- takeTill (\c -> c == ';')
85 return (words vs)
87 edfP :: Parser Edf
88 edfP = Edf
89 <$> edf'LambdaP
90 <*> edf'MotorPosP
91 <*> edf'MotorMneP
92 <?> "edfP"
94 edfFromFile :: FilePath -> IO Edf
95 edfFromFile filename = do
96 content <- readFile filename
97 let header = head (split '}' content)
98 return $ case parseOnly edfP (decodeUtf8 header) of
99 Left _ -> error $ "Can not parse the " ++ filename ++ " edf file"
100 Right a -> a
102 main :: IO ()
103 main = do
104 edf <- edfFromFile "/home/picca/test.edf"
105 print edf
106 return ()