def setUp(self):
     self.test_transformations = []
     for i in xrange(20):
         test_transformation = Complete()
         test_transformation.set_rotation_properties(random.random()*math.pi*2, numpy.random.uniform(-3, 3, 3), random.sample([True, False], 1)[0])
         test_transformation.t = numpy.random.uniform(-3, 3, 3)
         self.test_transformations.append(test_transformation)
 def setUp(self):
     self.test_transformations = []
     for i in xrange(20):
         test_transformation = Complete()
         test_transformation.set_rotation_properties(
             random.random() * math.pi * 2, numpy.random.uniform(-3, 3, 3),
             random.sample([True, False], 1)[0])
         test_transformation.t = numpy.random.uniform(-3, 3, 3)
         self.test_transformations.append(test_transformation)
    def test_superpose(self):
        # create a few test sets with random data points, including degenerate
        # situations. (e.g. one point, two points, linear points)
        references = [ # a list of 2-tuples: (points, degenerate)
            (numpy.random.normal(0, 5, (n, 3)), False) for n in xrange(4, 40)
        ] + [
            #(numpy.array([[0,0,1]], float), True),
            #(numpy.array([[0,0,0],[0,0,1]], float), True),
            #(numpy.array([[0,0,0],[0,0,1],[0,0,2]], float), True),
            #(numpy.array([[0,0,0],[0,0,1],[0,0,2],[0,0,4]], float), True),
            #(numpy.random.normal(0, 5, (3, 3)), True)
        ]

        # Do a random transformation on the points
        randomized = []
        for points, degenerate in references:
            #points[:] -= points.mean(axis=0)
            axis = random_unit(3)
            angle = numpy.random.uniform(0, numpy.pi*2)
            transformation = Complete()
            transformation.set_rotation_properties(angle, axis, False)
            transformation.t[:] = numpy.random.normal(0, 5, 3)
            randomized.append((
                numpy.array([transformation.vector_apply(p) for p in points]),
                transformation
            ))

        for (ref_points, degenerate), (tr_points, transf) in zip(references, randomized):
            check_transf = superpose(ref_points, tr_points)
            # check whether the rotation matrix is orthogonal
            self.assertArraysAlmostEqual(numpy.dot(check_transf.r, check_transf.r.transpose()), numpy.identity(3, float), 1e-5)
            # first check whether check_transf brings the tr_points back to the ref_points
            check_points = numpy.dot(tr_points, check_transf.r.transpose()) + check_transf.t
            self.assertArraysAlmostEqual(ref_points, check_points, 1e-5, doabs=True)
            if not degenerate:
                # if the set of points is not degenerate, check whether transf and check_transf
                # are each other inverses
                tmp = Complete()
                tmp.apply_before(transf)
                tmp.apply_before(check_transf)
                self.assertArraysAlmostEqual(numpy.dot(transf.r, check_transf.r), numpy.identity(3, float), 1e-5)
                self.assertArrayAlmostZero(tmp.t, 1e-5)


        # Add some distortion to the transformed points
        randomized = []
        for tr_points, transf in randomized:
            tr_points[:] += numpy.random.normal(0, 1.0, len(tr_points))

        # Do a blind test
        for (ref_points, degenerate), (tr_points, transf) in zip(references, randomized):
            superpose(ref_points, tr_points)
Exemple #4
0
 def read_from_file(cls, filename):
     f = file(filename)
     lines = list(line for line in f if line[0] != '#')
     f.close()
     r = []
     t = []
     for line in lines[:3]:
         values = list(float(word) for word in line.split())
         r.append(values[:3])
         t.append(values[3])
     transformation = Complete()
     transformation.r[:] = r
     transformation.t[:] = t
     affected_atoms = set(int(word) for word in lines[3].split())
     return cls(affected_atoms, transformation)
Exemple #5
0
 def read_from_file(cls, filename):
     f = file(filename)
     lines = list(line for line in f if line[0] != '#')
     f.close()
     r = []
     t = []
     for line in lines[:3]:
         values = list(float(word) for word in line.split())
         r.append(values[:3])
         t.append(values[3])
     transformation = Complete()
     transformation.r[:] = r
     transformation.t[:] = t
     affected_atoms = set(int(word) for word in lines[3].split())
     return cls(affected_atoms, transformation)
Exemple #6
0
 def initnonstate(self):
     GLReferentBase.initnonstate(self)
     self.orientation = Complete()
     self.set_children([
         SpatialReference(prefix="Begin"),
         SpatialReference(prefix="End")
     ])
Exemple #7
0
 def get_transformation(self, coordinates):
     """Construct a transformation object"""
     atom1, atom2 = self.hinge_atoms
     center = coordinates[atom1]
     axis = coordinates[atom1] - coordinates[atom2]
     axis /= np.linalg.norm(axis)
     angle = np.random.uniform(-self.max_amplitude, self.max_amplitude)
     return Complete.about_axis(center, angle, axis)
Exemple #8
0
 def get_transformation(self, coordinates):
     """Construct a transformation object"""
     atom1, atom2 = self.hinge_atoms
     center = coordinates[atom1]
     axis = coordinates[atom1] - coordinates[atom2]
     axis /= numpy.linalg.norm(axis)
     angle = numpy.random.uniform(-self.max_amplitude, self.max_amplitude)
     return Complete.about_axis(center, angle, axis)
Exemple #9
0
    def __init__(self, affected_atoms, transformation):
        """Initialize a new MolecularDistortion object

           Arguments:
             affected_atoms  --  a list of atoms that undergo the transformation
             transformation  --  a transformation object
        """
        self.affected_atoms = affected_atoms
        self.transformation = Complete.cast(transformation)
Exemple #10
0
    def __init__(self, affected_atoms, transformation):
        """Initialize a new MolecularDistortion object

           Arguments:
             affected_atoms  --  a list of atoms that undergo the transformation
             transformation  --  a transformation object
        """
        self.affected_atoms = affected_atoms
        self.transformation = Complete.cast(transformation)
Exemple #11
0
    def __init__(self, affected_atoms, transformation, molecule=None):
        self.affected_atoms = affected_atoms
        self.transformation = Complete()
        if isinstance(transformation, Rotation):
            self.transformation.r[:] = transformation.r
        if isinstance(transformation, Translation):
            self.transformation.t[:] = transformation.t

        if molecule is not None:
            for i in affected_atoms:
                molecule.coordinates[i] = transformation.vector_apply(
                    molecule.coordinates[i])
    def do_test(self, coordinates, masses, expected_is):
        reference = MolecularDescriptorTV1(coordinates, masses)
        self.assert_(reference.inversion_symmetric == expected_is)

        for counter in xrange(3):
            transformation = Complete()
            transformation.set_rotation_properties(
                random.uniform(0, 2*math.pi),
                numpy.random.uniform(-1, 1, (3,)),
                False,
            )
            transformation.t = numpy.random.uniform(-5, 5, (3,))
            new_coordinates = numpy.array([
                transformation.vector_apply(coordinate)
                for coordinate
                in coordinates
            ], float)
            new_descriptor = MolecularDescriptorTV1(new_coordinates, masses)
            self.assert_(reference.compare_structure(new_descriptor))
            self.assert_(not reference.compare_global_rotation(new_descriptor))
            self.assert_(not reference.compare_global_translation(new_descriptor))
Exemple #13
0
 def read_from_file(cls, filename):
     """Construct a MolecularDistortion object from a file"""
     with open(filename) as f:
         lines = list(line for line in f if line[0] != '#')
     r = []
     t = []
     for line in lines[:3]:
         values = list(float(word) for word in line.split())
         r.append(values[:3])
         t.append(values[3])
     transformation = Complete(r, t)
     affected_atoms = set(int(word) for word in lines[3].split())
     return cls(affected_atoms, transformation)
Exemple #14
0
    def do(self):
        cache = context.application.cache
        for node in cache.nodes:
            transformation = Complete()

            translated_children = []
            for child in node.children:
                if isinstance(child, GLTransformationMixin) and isinstance(child.transformation, Translation):
                    if child.get_fixed():
                        translated_children = []
                        break
                    translated_children.append(child)
            if len(translated_children) == 0:
                continue

            mass, com = compute_center_of_mass(yield_particles(node))
            if mass == 0.0:
                continue

            transformation.t = com
            tensor = compute_inertia_tensor(yield_particles(node), com)
            transformation.r = default_rotation_matrix(tensor)
            CenterAlignBase.do(self, node, translated_children, transformation)
Exemple #15
0
 def get_transformation(self, coordinates):
     """Construct a transformation object"""
     atom1, atom2, atom3 = self.hinge_atoms
     center = coordinates[atom2]
     a = coordinates[atom1] - coordinates[atom2]
     b = coordinates[atom3] - coordinates[atom2]
     axis = np.cross(a, b)
     norm = np.linalg.norm(axis)
     if norm < 1e-5:
         # We suppose that atom3 is part of the affected atoms
         axis = random_orthonormal(a)
     else:
         axis /= np.linalg.norm(axis)
     angle = np.random.uniform(-self.max_amplitude, self.max_amplitude)
     return Complete.about_axis(center, angle, axis)
Exemple #16
0
 def get_transformation(self, coordinates):
     """Construct a transformation object"""
     atom1, atom2, atom3 = self.hinge_atoms
     center = coordinates[atom2]
     a = coordinates[atom1] - coordinates[atom2]
     b = coordinates[atom3] - coordinates[atom2]
     axis = numpy.cross(a, b)
     norm = numpy.linalg.norm(axis)
     if norm < 1e-5:
         # We suppose that atom3 is part of the affected atoms
         axis = random_orthonormal(a)
     else:
         axis /= numpy.linalg.norm(axis)
     angle = numpy.random.uniform(-self.max_amplitude, self.max_amplitude)
     return Complete.about_axis(center, angle, axis)
Exemple #17
0
    def do_test(self, coordinates, masses, expected_is):
        reference = MolecularDescriptorTV1(coordinates, masses)
        self.assert_(reference.inversion_symmetric == expected_is)

        for counter in xrange(3):
            transformation = Complete()
            transformation.set_rotation_properties(
                random.uniform(0, 2 * math.pi),
                numpy.random.uniform(-1, 1, (3, )),
                False,
            )
            transformation.t = numpy.random.uniform(-5, 5, (3, ))
            new_coordinates = numpy.array([
                transformation.vector_apply(coordinate)
                for coordinate in coordinates
            ], float)
            new_descriptor = MolecularDescriptorTV1(new_coordinates, masses)
            self.assert_(reference.compare_structure(new_descriptor))
            self.assert_(not reference.compare_global_rotation(new_descriptor))
            self.assert_(
                not reference.compare_global_translation(new_descriptor))
Exemple #18
0
def random_dimer(molecule0, molecule1, thresholds, shoot_max):
    """Create a random dimer.

       molecule0 and molecule1 are placed in one reference frame at random
       relative positions. Interatomic distances are above the thresholds.
       Initially a dimer is created where one interatomic distance approximates
       the threshold value. Then the molecules are given an additional
       separation in the range [0, shoot_max].

       thresholds has the following format:
       {frozenset([atom_number1, atom_number2]): distance}
    """

    # apply a random rotation to molecule1
    center = numpy.zeros(3, float)
    angle = numpy.random.uniform(0, 2*numpy.pi)
    axis = random_unit()
    rotation = Complete.about_axis(center, angle, axis)
    cor1 = numpy.dot(molecule1.coordinates, rotation.r)

    # select a random atom in each molecule
    atom0 = numpy.random.randint(len(molecule0.numbers))
    atom1 = numpy.random.randint(len(molecule1.numbers))

    # define a translation of molecule1 that brings both atoms in overlap
    delta = molecule0.coordinates[atom0] - cor1[atom1]
    cor1 += delta

    # define a random direction
    direction = random_unit()
    cor1 += 1*direction

    # move molecule1 along this direction until all intermolecular atomic
    # distances are above the threshold values
    threshold_mat = numpy.zeros((len(molecule0.numbers), len(molecule1.numbers)), float)
    distance_mat = numpy.zeros((len(molecule0.numbers), len(molecule1.numbers)), float)
    for i1, n1 in enumerate(molecule0.numbers):
        for i2, n2 in enumerate(molecule1.numbers):
            threshold = thresholds.get(frozenset([n1, n2]))
            threshold_mat[i1, i2] = threshold**2
    while True:
        cor1 += 0.1*direction
        distance_mat[:] = 0
        for i in 0, 1, 2:
            distance_mat += numpy.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2
        if (distance_mat > threshold_mat).all():
            break

    # translate over a random distance [0, shoot] along the same direction
    # (if necessary repeat until no overlap is found)
    while True:
        cor1 += direction*numpy.random.uniform(0, shoot_max)
        distance_mat[:] = 0
        for i in 0, 1, 2:
            distance_mat += numpy.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2
        if (distance_mat > threshold_mat).all():
            break

    # done
    dimer = Molecule(
        numpy.concatenate([molecule0.numbers, molecule1.numbers]),
        numpy.concatenate([molecule0.coordinates, cor1])
    )
    dimer.direction = direction
    dimer.atom0 = atom0
    dimer.atom1 = atom1
    return dimer
Exemple #19
0
class Vector(GLReferentBase):

    #
    # State
    #

    def initnonstate(self):
        GLReferentBase.initnonstate(self)
        self.orientation = Complete()
        self.set_children([
            SpatialReference(prefix="Begin"),
            SpatialReference(prefix="End")
        ])

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo("Basic", (0, 2), fields.read.VectorLength(
            label_text="Vector length"
        )),
    ])

    #
    # Draw
    #

    def draw(self):
        self.calc_vector_dimensions()
        context.application.vis_backend.transform(self.orientation)

    #
    # Revalidation
    #

    def revalidate_total_list(self):
        if self.gl_active:
            vb = context.application.vis_backend
            vb.begin_list(self.total_list)
            if self.visible:
                vb.push_name(self.draw_list)
                vb.push_matrix()
                self.draw_selection()
                vb.call_list(self.draw_list)
                vb.pop_matrix()
                vb.pop_name()
            vb.end_list()
            self.total_list_valid = True

    def revalidate_draw_list(self):
        if self.gl_active:
            GLReferentBase.revalidate_draw_list(self)

    def revalidate_boundingbox_list(self):
        if self.gl_active:
            vb = context.application.vis_backend
            #print "Compiling selection list (" + str(self.boundingbox_list) + "): " + str(self.name)
            vb.begin_list(self.boundingbox_list)
            vb.push_matrix()
            vb.transform(self.orientation)
            self.revalidate_bounding_box()
            self.bounding_box.draw()
            vb.pop_matrix()
            vb.end_list()
            self.boundingbox_list_valid = True

    #
    # Frame
    #

    def get_bounding_box_in_parent_frame(self):
        return self.bounding_box.transformed(self.orientation)

    #
    # Vector
    #

    def shortest_vector_relative_to(self, other):
        b = self.children[0].translation_relative_to(other)
        e = self.children[1].translation_relative_to(other)
        if (b is None) or (e is None):
            return None
        else:
            return self.parent.shortest_vector(e - b)

    def calc_vector_dimensions(self):
        relative_translation = self.shortest_vector_relative_to(self.parent)
        if relative_translation is None:
            self.length = 0
        else:
            self.length = math.sqrt(numpy.dot(relative_translation, relative_translation))
            if self.length > 0:
                self.orientation.t = self.children[0].translation_relative_to(self.parent)
                #axis = numpy.cross(relative_translation, numpy.array([1.0, 0.0, 0.0]))
                c = relative_translation[2] / self.length
                if c >= 1.0:
                    self.orientation.set_rotation_properties(0, numpy.array([1.0, 0.0, 0.0]), False)
                elif c <= -1.0:
                    self.orientation.set_rotation_properties(math.pi, numpy.array([1.0, 0.0, 0.0]), False)
                else:
                    x, y = relative_translation[0], relative_translation[1]
                    if abs(x) < abs(y):
                        signy = {True: 1, False: -1}[y >= 0]
                        a = -signy
                        b = signy * x / y
                    else:
                        signx = {True: 1, False: -1}[x >= 0]
                        a = -signx * y / x
                        b = signx
                    self.orientation.set_rotation_properties(math.acos(c), numpy.array([a, b, 0.0]), False)

    def define_target(self, reference, new_target):
        GLReferentBase.define_target(self, reference, new_target)
        self.invalidate_boundingbox_list()
        self.invalidate_draw_list()

    def target_moved(self, reference, target):
        GLReferentBase.target_moved(self, reference, target)
        self.invalidate_boundingbox_list()
        self.invalidate_draw_list()
Exemple #20
0
def random_dimer(molecule0, molecule1, thresholds, shoot_max):
    """Create a random dimer.

       molecule0 and molecule1 are placed in one reference frame at random
       relative positions. Interatomic distances are above the thresholds.
       Initially a dimer is created where one interatomic distance approximates
       the threshold value. Then the molecules are given an additional
       separation in the range [0, shoot_max].

       thresholds has the following format:
       {frozenset([atom_number1, atom_number2]): distance}
    """

    # apply a random rotation to molecule1
    center = np.zeros(3, float)
    angle = np.random.uniform(0, 2 * np.pi)
    axis = random_unit()
    rotation = Complete.about_axis(center, angle, axis)
    cor1 = np.dot(molecule1.coordinates, rotation.r)

    # select a random atom in each molecule
    atom0 = np.random.randint(len(molecule0.numbers))
    atom1 = np.random.randint(len(molecule1.numbers))

    # define a translation of molecule1 that brings both atoms in overlap
    delta = molecule0.coordinates[atom0] - cor1[atom1]
    cor1 += delta

    # define a random direction
    direction = random_unit()
    cor1 += 1 * direction

    # move molecule1 along this direction until all intermolecular atomic
    # distances are above the threshold values
    threshold_mat = np.zeros((len(molecule0.numbers), len(molecule1.numbers)),
                             float)
    distance_mat = np.zeros((len(molecule0.numbers), len(molecule1.numbers)),
                            float)
    for i1, n1 in enumerate(molecule0.numbers):
        for i2, n2 in enumerate(molecule1.numbers):
            threshold = thresholds.get(frozenset([n1, n2]))
            threshold_mat[i1, i2] = threshold**2
    while True:
        cor1 += 0.1 * direction
        distance_mat[:] = 0
        for i in 0, 1, 2:
            distance_mat += np.subtract.outer(molecule0.coordinates[:, i],
                                              cor1[:, i])**2
        if (distance_mat > threshold_mat).all():
            break

    # translate over a random distance [0, shoot] along the same direction
    # (if necessary repeat until no overlap is found)
    while True:
        cor1 += direction * np.random.uniform(0, shoot_max)
        distance_mat[:] = 0
        for i in 0, 1, 2:
            distance_mat += np.subtract.outer(molecule0.coordinates[:, i],
                                              cor1[:, i])**2
        if (distance_mat > threshold_mat).all():
            break

    # done
    dimer = Molecule(np.concatenate([molecule0.numbers, molecule1.numbers]),
                     np.concatenate([molecule0.coordinates, cor1]))
    dimer.direction = direction
    dimer.atom0 = atom0
    dimer.atom1 = atom1
    return dimer
    def test_superpose(self):
        # create a few test sets with random data points, including degenerate
        # situations. (e.g. one point, two points, linear points)
        references = [  # a list of 2-tuples: (points, degenerate)
            (numpy.random.normal(0, 5, (n, 3)), False) for n in xrange(4, 40)
        ] + [
            #(numpy.array([[0,0,1]], float), True),
            #(numpy.array([[0,0,0],[0,0,1]], float), True),
            #(numpy.array([[0,0,0],[0,0,1],[0,0,2]], float), True),
            #(numpy.array([[0,0,0],[0,0,1],[0,0,2],[0,0,4]], float), True),
            #(numpy.random.normal(0, 5, (3, 3)), True)
        ]

        # Do a random transformation on the points
        randomized = []
        for points, degenerate in references:
            #points[:] -= points.mean(axis=0)
            axis = random_unit(3)
            angle = numpy.random.uniform(0, numpy.pi * 2)
            transformation = Complete()
            transformation.set_rotation_properties(angle, axis, False)
            transformation.t[:] = numpy.random.normal(0, 5, 3)
            randomized.append(
                (numpy.array([transformation.vector_apply(p)
                              for p in points]), transformation))

        for (ref_points, degenerate), (tr_points,
                                       transf) in zip(references, randomized):
            check_transf = superpose(ref_points, tr_points)
            # check whether the rotation matrix is orthogonal
            self.assertArraysAlmostEqual(
                numpy.dot(check_transf.r, check_transf.r.transpose()),
                numpy.identity(3, float), 1e-5)
            # first check whether check_transf brings the tr_points back to the ref_points
            check_points = numpy.dot(
                tr_points, check_transf.r.transpose()) + check_transf.t
            self.assertArraysAlmostEqual(ref_points,
                                         check_points,
                                         1e-5,
                                         doabs=True)
            if not degenerate:
                # if the set of points is not degenerate, check whether transf and check_transf
                # are each other inverses
                tmp = Complete()
                tmp.apply_before(transf)
                tmp.apply_before(check_transf)
                self.assertArraysAlmostEqual(
                    numpy.dot(transf.r, check_transf.r),
                    numpy.identity(3, float), 1e-5)
                self.assertArrayAlmostZero(tmp.t, 1e-5)

        # Add some distortion to the transformed points
        randomized = []
        for tr_points, transf in randomized:
            tr_points[:] += numpy.random.normal(0, 1.0, len(tr_points))

        # Do a blind test
        for (ref_points, degenerate), (tr_points,
                                       transf) in zip(references, randomized):
            superpose(ref_points, tr_points)
Exemple #22
0
 def compute_transformation(self, connection):
     transformation = Complete(self.rotation2.r, connection.t)
     del connection.t
     return transformation