Esempio n. 1
0
 def get_transformation(self, molecule):
     atom1, atom2 = self.hinge_atoms
     center = molecule.coordinates[atom1]
     axis = molecule.coordinates[atom1] - molecule.coordinates[atom2]
     axis /= numpy.linalg.norm(axis)
     angle = numpy.random.uniform(-self.max_amplitude, self.max_amplitude)
     return rotation_around_center(center, angle, axis)
Esempio n. 2
0
 def get_transformation(self, molecule):
     atom1, atom2 = self.hinge_atoms
     center = molecule.coordinates[atom1]
     axis = molecule.coordinates[atom1] - molecule.coordinates[atom2]
     axis /= numpy.linalg.norm(axis)
     angle = numpy.random.uniform(-self.max_amplitude, self.max_amplitude)
     return rotation_around_center(center, angle, axis)
Esempio n. 3
0
    def do(self):
        transformation = rotation_around_center(
            self.parameters.center,
            math.pi,
            self.parameters.normal,
            True
        )

        for victim in context.application.cache.translated_nodes:
            primitive.Transform(victim, transformation)
Esempio n. 4
0
 def test_center_ses2(self):
     from molmod.ext import center_ses2
     for i in xrange(1000):
         close1 = numpy.random.uniform(0, 5, 3)
         close1_radius = numpy.random.uniform(0, 5)
         close2 = numpy.random.uniform(0, 5, 3)
         close2_radius = numpy.random.uniform(0, 5)
         probe = numpy.random.uniform(0, 5, 3)
         center = numpy.zeros(3, float)
         result = bool(
             center_ses2(probe, close1, close1_radius, close2,
                         close2_radius, center))
         check_result = ((numpy.linalg.norm(close1 - close2) >
                          close1_radius + close2_radius)
                         or (numpy.linalg.norm(close1 - close2) <
                             abs(close1_radius - close2_radius)))
         self.assertEqual(result, check_result)
         if result == False:
             # test distances
             self.assertAlmostEqual(numpy.linalg.norm(center - close1),
                                    close1_radius)
             self.assertAlmostEqual(numpy.linalg.norm(center - close2),
                                    close2_radius)
             # test coplanarity
             mat = numpy.array([
                 probe - center,
                 probe - close1,
                 probe - close2,
             ])
             self.assertAlmostEqual(numpy.linalg.det(mat), 0)
             # define a rotation of 180 degrees about the close1-close2 axis
             rotation = rotation_around_center(close1, numpy.pi,
                                               close2 - close1)
             new_center = rotation.vector_apply(center)
             # test if the rotated center also satisfies the distances and the coplanarity
             self.assertAlmostEqual(numpy.linalg.norm(new_center - close1),
                                    close1_radius)
             self.assertAlmostEqual(numpy.linalg.norm(new_center - close2),
                                    close2_radius)
             # test coplanarity
             mat = numpy.array([
                 probe - new_center,
                 probe - close1,
                 probe - close2,
             ])
             self.assertAlmostEqual(numpy.linalg.det(mat), 0)
             # test if the center is closes to the probe than new_center
             self.assert_(
                 numpy.linalg.norm(center -
                                   probe) < numpy.linalg.norm(new_center -
                                                              probe))
Esempio n. 5
0
 def get_transformation(self, molecule):
     atom1, atom2, atom3 = self.hinge_atoms
     center = molecule.coordinates[atom2]
     a = molecule.coordinates[atom1] - molecule.coordinates[atom2]
     b = molecule.coordinates[atom3] - molecule.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 rotation_around_center(center, angle, axis)
Esempio n. 6
0
 def get_transformation(self, molecule):
     atom1, atom2, atom3 = self.hinge_atoms
     center = molecule.coordinates[atom2]
     a = molecule.coordinates[atom1] - molecule.coordinates[atom2]
     b = molecule.coordinates[atom3] - molecule.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 rotation_around_center(center, angle, axis)
Esempio n. 7
0
 def test_center_ses2(self):
     from molmod.ext import center_ses2
     for i in xrange(1000):
         close1 = numpy.random.uniform(0, 5, 3)
         close1_radius = numpy.random.uniform(0, 5)
         close2 = numpy.random.uniform(0, 5, 3)
         close2_radius = numpy.random.uniform(0, 5)
         probe = numpy.random.uniform(0, 5, 3)
         center = numpy.zeros(3, float)
         result = bool(center_ses2(probe, close1, close1_radius, close2, close2_radius, center))
         check_result = (
             (numpy.linalg.norm(close1 - close2) > close1_radius + close2_radius) or
             (numpy.linalg.norm(close1 - close2) < abs(close1_radius - close2_radius))
         )
         self.assertEqual(result, check_result)
         if result == False:
             # test distances
             self.assertAlmostEqual(numpy.linalg.norm(center-close1), close1_radius)
             self.assertAlmostEqual(numpy.linalg.norm(center-close2), close2_radius)
             # test coplanarity
             mat = numpy.array([
                 probe - center,
                 probe - close1,
                 probe - close2,
             ])
             self.assertAlmostEqual(numpy.linalg.det(mat), 0)
             # define a rotation of 180 degrees about the close1-close2 axis
             rotation = rotation_around_center(close1, numpy.pi, close2-close1)
             new_center = rotation.vector_apply(center)
             # test if the rotated center also satisfies the distances and the coplanarity
             self.assertAlmostEqual(numpy.linalg.norm(new_center-close1), close1_radius)
             self.assertAlmostEqual(numpy.linalg.norm(new_center-close2), close2_radius)
             # test coplanarity
             mat = numpy.array([
                 probe - new_center,
                 probe - close1,
                 probe - close2,
             ])
             self.assertAlmostEqual(numpy.linalg.det(mat), 0)
             # test if the center is closes to the probe than new_center
             self.assert_(numpy.linalg.norm(center - probe) < numpy.linalg.norm(new_center - probe))
Esempio n. 8
0
def random_dimer(molecule0, molecule1, thresholds, shoot_max, max_tries=1000):
    """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(3)
    rotation = rotation_around_center(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(3)
    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
Esempio n. 9
0
def random_dimer(molecule0, molecule1, thresholds, shoot_max, max_tries=1000):
    """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(3)
    rotation = rotation_around_center(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(3)
    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