{- | Module : Data.Matrix.SeitzSymbol Copyright : (c) Jun Narumi 2020 License : MIT Maintainer : narumij@gmail.com Stability : experimental Read and Display Seitz Symbol [References] A. Michael Glazer et al. Seitz symbols Acta Cryst. (2014). A70 ネスポロ マッシモ:日本結晶学会誌 59,210-222(2017). https://www.jstage.jst.go.jp/article/jcrsj/59/5/59_210/_pdf -} module Data.Matrix.SeitzSymbol ( P.SeitzSymbol(..), fromSeitzSymbolS, fromSeitzSymbolHexS, toSeitzSymbolS, ) where import Text.Parsec import Text.Parsec.String (Parser) import Data.Ratio (Ratio(..)) import Data.Matrix (Matrix(..)) import Data.Matrix.AsXYZ (fromXYZ,prettyXYZ) import qualified Data.Matrix.SeitzSymbol.Parser as P (SeitzSymbol(..),seitzSymbol,toMatrix,toSeitzSymbol,toString) import Data.Matrix.SymmetryOperationsSymbols import Data.Matrix.SymmetryOperationsSymbols.Common ( properMatricesForPointGroup, hexagonalMatricesForPointGroup, MatrixForPointGroupCorrespondingSymmetryElement(..) ) parser :: (Integral a, Read a) => [MatrixForPointGroupCorrespondingSymmetryElement a] -> Parser (Matrix (Ratio a)) parser tbl = do s <- P.seitzSymbol case P.toMatrix tbl s of Just m -> return m Nothing -> parserFail "Matrix not found." -- | for cubic, tetragonal, orthorhombic, monoclinic and triclinic crystal systems. -- -- >>> prettyXYZ <$> fromSeitzSymbolS "{ 1 | 0 0 0 }" -- Right "x,y,z" -- >>> prettyXYZ <$> fromSeitzSymbolS "{ 2 010 | 1/2 1/2 1/2 }" -- Right "-x+1/2,y+1/2,-z+1/2" -- >>> prettyXYZ <$> fromSeitzSymbolS "{ 3+ 111 | 1/2 1/2 1/2 }" -- Right "z+1/2,x+1/2,y+1/2" -- >>> prettyXYZ <$> fromSeitzSymbolS "{ -3+ 111 | 1/2 1/2 1/2 }" -- Right "-z+1/2,-x+1/2,-y+1/2" -- >>> prettyXYZ <$> fromSeitzSymbolS "{ m 100 | 0 0 0 }" -- Right "-x,y,z" -- >>> (liftError . fromSeitzSymbolS) "{ 2 010 | 1/2 1/2 1/2 }" >>= fromMatrix -- Right " 2 (0,1/2,0) 1/4,y,1/4" -- >>> (liftError . fromSeitzSymbolS) "{ 3+ 111 | 1/2 1/2 1/2 }" >>= fromMatrix -- Right " 3+(1/2,1/2,1/2) x,x,x" -- >>> (liftError . fromSeitzSymbolS) "{ -3+ 111 | 1/2 1/2 1/2 }" >>= fromMatrix -- Right "-3+ x,x,x; 1/4,1/4,1/4" -- >>> (liftError . fromSeitzSymbolS) "{ m 100 | 0 0 0 }" >>= fromMatrix -- Right " m 0,y,z" -- fromSeitzSymbolS :: (Integral a, Read a) => SourceName -> Either ParseError (Matrix (Ratio a)) fromSeitzSymbolS s = parse (parser properMatricesForPointGroup) s s -- | for hexagonal and trigonal crystal systems. -- -- >>> prettyXYZ <$> fromSeitzSymbolHexS "{ m 100 | 0 0 0 }" -- Right "y-x,y,z" -- >>> prettyXYZ <$> fromSeitzSymbolHexS "{ m 120 | 0 0 0 }" -- Right "x-y,-y,z" -- >>> prettyXYZ <$> fromSeitzSymbolHexS "{ 2 100 | 0 0 0 }" -- Right "x-y,-y,-z" -- >>> (liftError . fromSeitzSymbolHexS) "{ m 100 | 0 0 0 }" >>= fromMatrix -- Right " m x,2x,z" -- >>> (liftError . fromSeitzSymbolHexS) "{ m 120 | 0 0 0 }" >>= fromMatrix -- Right " m x,0,z" -- >>> (liftError . fromSeitzSymbolHexS) "{ 2 100 | 0 0 0 }" >>= fromMatrix -- Right " 2 x,0,0" -- fromSeitzSymbolHexS :: (Integral a, Read a) => String -> Either ParseError (Matrix (Ratio a)) fromSeitzSymbolHexS s = parse (parser hexagonalMatricesForPointGroup) s s -- | -- -- >>> toSeitzSymbolS . fromXYZ $ "x,y,z" -- Just "{ 1 | 0 0 0 }" -- >>> toSeitzSymbolS . fromXYZ $ "-x+1/2,y+1/2,-z+1/2" -- Just "{ 2 010 | 1/2 1/2 1/2 }" -- toSeitzSymbolS :: (Integral a, Show a) => Matrix (Ratio a) -> Maybe String toSeitzSymbolS m = P.toString <$> P.toSeitzSymbol m