#!/usr/bin/env python

"""
TODO: Modify module doc.
"""

from __future__ import division

__author__ = "Shyue Ping Ong"
__copyright__ = "Copyright 2012, The Materials Project"
__version__ = "0.1"
__maintainer__ = "Shyue Ping Ong"
__email__ = "shyuep@gmail.com"
__date__ = "4/4/14"

from itertools import product, permutations
import numpy as np

#Define the fundamental symmetry matrices

D = {
    "a": [[1, 0, 0],
          [0, 1, 0],
          [0, 0, 1]],
    "b": [[-1, 0, 0],
          [0, -1, 0],
          [0, 0, 1]],
    "c": [[-1, 0, 0],
          [0, 1, 0],
          [0, 0, -1]],
    "d": [[0, 0, 1],
          [1, 0, 0],
          [0, 1, 0]],
    "e": [[0, 1, 0],
          [1, 0, 0],
          [0, 0, -1]],
    "f": [[0, -1, 0],
          [-1, 0, 0],
          [0, 0, -1]],
    "g": [[0, -1, 0],
          [1, 0, 0],
          [0, 0, 1]],
    "h": [[-1, 0, 0],
          [0, -1, 0],
          [0, 0, -1]],
    "i": [[1, 0, 0],
          [0, 1, 0],
          [0, 0, -1]],
    "j": [[1, 0, 0],
          [0, -1, 0],
          [0, 0, 1]],
    "k": [[0, -1, 0],
          [-1, 0, 0],
          [0, 0, 1]],
    "l": [[0, 1, 0],
          [1, 0, 0],
          [0, 0, 1]],
    "m": [[0, 1, 0],
          [-1, 0, 0],
          [0, 0, -1]],
    "n": [[0, -1, 0],
          [1, -1, 0],
          [0, 0, 1]]
}

POINT_GROUP_GENERATORS = {
    "1": "a",
    "-1": "h",
    "2": "c",
    "m": "j",
    "2/m": "ch",
    "222": "bc",
    "mm2": "bj",
    "mmm": "bch",
    "4": "g",
    "-4": "m",
    "4/m": "gh",
    "422": "cg",
    "4mm": "gj",
    "-42m": "cm",
    "4/mmm": "cgh",
    "3": "n",
    "-3": "hn",
    "32": "en",
    "3m": "kn",
    "-3m": "fhn",
    "6": "bn",
    "-6": "in",
    "6/m": "bhn",
    "622": "ben",
    "6mm": "bkn",
    "-6m2": "ikn",
    "6/mmm": "benh",
    "23": "cd",
    "m-3": "cdh",
    "432": "dg",
    "-43m": "dml",
    "m-3m": "dghl"
}

class PointGroup(object):
    """
    Object representing a Point Group, with generators and symmetry operations.
    """

    def __init__(self, int_symbol):
        """
        Initializes a Point Group from its international symbol.

        Args:
            int_symbol (str): International or Hermann-Mauguin Symbol.
        """
        self.generators = [D[c] for c in POINT_GROUP_GENERATORS[int_symbol]]
        symm_ops = []
        symm_ops.extend(self.generators)
        new_ops = self.generators
        while len(new_ops) > 0:
            gen_ops = []
            for g1, g2 in product(new_ops, symm_ops):
                op = np.dot(g1, g2)
                if not in_array_list(symm_ops, op):
                    gen_ops.append(op)
                    symm_ops.append(op)
            new_ops = gen_ops
        self.symmetry_ops = symm_ops

    def get_orbit(self, p):
        orbit = []
        for o in self.symmetry_ops:
            pp = np.dot(o, p)
            if not in_array_list(orbit, pp):
                orbit.append(pp)
        return orbit


def in_array_list(array_list, a):
    if len(array_list) == 0:
        return False
    dim = tuple(range(1, a.ndim + 1))
    return np.any(np.all(np.equal(array_list, a[None, :]), tuple(dim)))


if __name__ == "__main__":
    for k in POINT_GROUP_GENERATORS.keys():
        pg = PointGroup(k)
        print "Order of point group %s is %d" % (k, len(pg.symmetry_ops))

    from sympy import symbols
    x, y, z = symbols("x y z")
    p = [x,y,z]
    pg = PointGroup("m-3m")
    for r in pg.get_orbit(p):
        print r

@@ -2976,16 +2976,251 @@
 st, a):%0A
+    %22%22%22%0A    Extremely efficient nd-array comparison using numpy's broadcasting. This%0A    function checks if a particular array a, is present in a list of arrays.%0A    It works for arrays of any size, e.g., even matrix searches.%0A    %22%22%22%0A
     if l
@@ -3265,19 +3265,20 @@
 lse%0A    
-dim
+axes
  = tuple
@@ -3363,18 +3363,12 @@
 %5D), 
-tuple(dim)
+axes
 ))%0A%0A

Add some doc.