{-# LANGUAGE FlexibleInstances, CPP #-} {-| Module : Data.Matrix.SymmetryOperationsSymbols Description : Read and Display Geometric representation of symmetry operation Copyright : (c) Jun Narumi, 2018-2020 License : MIT Maintainer : narumij@gmail.com Stability : experimental Haskell Derivation of symbols and coordinate triplets Library [References] 1. W. Fischer. and E. Koch. (2006), Derivation of symbols and coordinate triplets International Tables for Crystallography (2006). Vol. A, Chapter 11.2, pp. 812–816. 2. Wondratschek, H. & Neubu ̈ser, J. (1967). Determination of the symmetry elements of a space group from the ‘general positions’ listed in International Tables for X-ray Crystallography, Vol. I. Acta Cryst. 23, 349–352. -} module Data.Matrix.SymmetryOperationsSymbols ( fromMatrix, fromMatrix', readMatrix, readMatrix', toMatrix, toMatrixHex, notHexagonal, hexagonal, liftError, ) where import Data.Ratio (Ratio) import Data.Matrix (Matrix,detLU,trace,identity) import Text.ParserCombinators.Parsec (ParseError,parse) import Data.Matrix.SymmetryOperationsSymbols.Common import Data.Matrix.SymmetryOperationsSymbols.UnitMatrixCase import Data.Matrix.SymmetryOperationsSymbols.GlideOrReflectionCase import Data.Matrix.SymmetryOperationsSymbols.RotationCase import Data.Matrix.SymmetryOperationsSymbols.RotInversionCase import Data.Matrix.SymmetryOperationsSymbols.Parser import Data.Matrix.SymmetryOperationsSymbols.SymopGeom import Data.Matrix.SymmetryOperationsSymbols.Calc import Data.Matrix.SymmetryOperationsSymbols.PlainText -- for doctest import Data.Matrix.AsXYZ (fromXYZ,prettyXYZ) #if MIN_VERSION_base(4,13,0) import Control.Monad.Fail (MonadFail(..)) instance MonadFail (Either String) where fail = Left #endif -- | Derivation of geometric representation of symmetry operations from given matrix of symmetry operations -- -- jpn) 与えられた対称操作の行列から、対称操作の幾何的表現を導出 -- -- >>> fromMatrix . fromXYZ $ "x,y,z" -- Right " 1 " -- -- >>> fromMatrix . fromXYZ $ "-y,x,-z" -- Right "-4- 0,0,z; 0,0,0" -- fromMatrix :: Integral a => Matrix (Ratio a) -- ^ 3x4 or 4x4 Matrix -> Either String String fromMatrix = fromMatrix' -- | Derivation of geometric representation of symmetry operations from given matrix of symmetry operations -- -- jpn) 与えられた対称操作の行列から、対称操作の幾何的表現を導出 -- #if MIN_VERSION_base(4,13,0) fromMatrix' :: (Integral a, MonadFail f) => Matrix (Ratio a) -> f String #else fromMatrix' :: (Monad m, Integral a) => Matrix (Ratio a) -> m String #endif fromMatrix' m = showAsPlainText <$> readMatrix' m readMatrix :: Integral a => Matrix (Ratio a) -- ^ 3x4 or 4x4 Matrix -> Maybe (SymopGeom a) readMatrix = readMatrix' -- | Derivation of geometric representation of symmetry operations from given matrix of symmetry operations -- -- jpn) 与えられた対称操作の行列から、対称操作の幾何的表現を導出 -- #if MIN_VERSION_base(4,13,0) readMatrix' :: (MonadFail m, Integral a) => Matrix (Ratio a) -> m (SymopGeom a) #else readMatrix' :: (Monad m, Integral a) => Matrix (Ratio a) -> m (SymopGeom a) #endif readMatrix' m -- (i) | rotPart m == identity 3 = unitMatrixCase m -- (ii) (a) | correpondToRotInversion tr det = rotInversionCase m -- -- (ii) (b) | correpondToNFoldRotation tr det = nFoldRotationCase m -- -- (ii) (c) | correpondToGlideOrReflection tr det = glideOrReflectionCase m -- -- | otherwise = fail $ "coordinate triplet '" ++ prettyXYZ m ++ "' is not symmetry operation." where tr = trace (rotPart m) det = detLU (rotPart m) -- | Derivation of matrix representation from a string of geometric representations of symmetric operations -- for cubic, tetragonal, orthorhombic, monoclinic, triclinic or rhombohedral. -- -- jpn) 対称操作の幾何的表現の文字列から行列表現の導出 -- -- >>> prettyXYZ <$> toMatrixHex "-4- 0,0,z; 0,0,0" -- Right "-y,x,-z" -- toMatrix :: Integral a => String -- ^ like " -1 0,0,0" -> Either ParseError (Matrix (Ratio a)) -- ^ 3x4 Matrix toMatrix st = parse notHexagonal st st -- | Derivation of matrix representation from a string of geometric representations of symmetric operations -- for hexagonal. -- -- jpn) 対称操作の幾何的表現の文字列から行列表現の導出(六方晶用) -- -- >>> prettyXYZ <$> toMatrixHex "-3+ 0,0,z; 0,0,0" -- Right "y,y-x,-z" -- toMatrixHex :: Integral a => String -- ^ like " -1 0,0,0" -> Either ParseError (Matrix (Ratio a)) -- ^ 3x4 Matrix toMatrixHex st = parse hexagonal st st #if MIN_VERSION_base(4,13,0) liftError :: MonadFail m => Either ParseError a -> m a #else liftError :: Monad m => Either ParseError a -> m a #endif liftError (Left s) = fail "" liftError (Right m) = return m