Ejemplo n.º 1
0
    def distance(self, entry_id, entry_jd):
        """
        Measure of distance for two entries with identifiers 'entry_id' and 'entry_jd'

        :param entry_id: Identifier of first entry
        :param entry_jd: Identifier of second entry
        :return:
        """

        dmat1 = self.get_correlation_params(entry_id)
        dmat2 = self.get_correlation_params(entry_jd)

        euler_angles1 = dmat1['euler_angles']
        euler_angles2 = dmat2['euler_angles']

        uvect1 = unit_vector(
            np.concatenate(
                (np.cos(euler_angles1), np.sin(euler_angles1))).flatten())
        uvect2 = unit_vector(
            np.concatenate(
                (np.cos(euler_angles2), np.sin(euler_angles2))).flatten())

        dist_euler = 1 - np.dot(uvect1, uvect2)

        return dist_euler
Ejemplo n.º 2
0
    def distance(self, entry_id, entry_jd, rcut=50):
        """
        Return a measure of the distance between two clusters by computing
        a n-dimensional vector of the distances between each atom to the
        origin and

        :param rcut:
        :param entry_id: The id of one population entry
        :param entry_jd: The id of another population entry
        :return: (int) The distance between two clusters
        """

        ids_pair = tuple(np.sort([entry_id, entry_jd]))
        distance_entry = self.distancer.get_distance(ids_pair)

        if distance_entry is None:
            fingerprints = {}
            for entry_ijd in [entry_id, entry_jd]:

                if self.fingerprinter.get_fingerprint(entry_ijd) is None:
                    structure = self.get_structure(entry_ijd)
                    analysis = ClusterAnalysis(structure)
                    x, ys = analysis.discrete_radial_distribution_function()
                    fingerprint = {'_id': entry_ijd}
                    for k in ys:
                        atomic_number1 = atomic_number(k[0])
                        atomic_number2 = atomic_number(k[1])
                        pair = '%06d' % min(atomic_number1 * 1000 + atomic_number2,
                                            atomic_number2 * 1000 + atomic_number1)
                        fingerprint[pair] = list(ys[k])

                    if self.fingerprinter.get_fingerprint(entry_ijd) is None:
                        self.fingerprinter.set_fingerprint(fingerprint)
                    else:
                        self.fingerprinter.update(entry_ijd, fingerprint)
                    fingerprints[entry_ijd] = fingerprint
                else:
                    fingerprints[entry_ijd] = self.fingerprinter.get_fingerprint(entry_ijd)

            dij = []
            for pair in fingerprints[entry_id]:
                if pair in fingerprints[entry_jd] and pair != '_id':
                    vect1 = fingerprints[entry_id][pair]
                    vect2 = fingerprints[entry_jd][pair]
                    if len(vect1) < len(vect2):
                        tmp = np.zeros(len(vect2))
                        tmp[:len(vect1)] = vect1
                        vect1 = tmp
                    elif len(vect1) > len(vect2):
                        tmp = np.zeros(len(vect1))
                        tmp[:len(vect2)] = vect2
                        vect2 = tmp
                    uvect1 = unit_vector(vect1)
                    uvect2 = unit_vector(vect2)
                    dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2)))
            distance = float(np.mean(dij))
            self.distancer.set_distance(ids_pair, distance)
        else:
            distance = distance_entry['distance']
        return distance
Ejemplo n.º 3
0
    def distance(self, entry_id, entry_jd, rcut=50):

        ids_pair = [entry_id, entry_jd]
        ids_pair.sort()
        distance_entry = self.pcdb.db.distances.find_one({'pair': ids_pair},
                                                         {'distance': 1})
        self.pcdb.db.distances.create_index([("pair", ASCENDING)])

        if distance_entry is None:
            print('Distance not in DB')
            fingerprints = {}
            for entry_ijd in [entry_id, entry_jd]:

                if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd
                                                       }) is None:
                    structure = self.get_structure(entry_ijd)
                    analysis = StructureAnalysis(structure, radius=rcut)
                    x, ys = analysis.fp_oganov()
                    fingerprint = {'_id': entry_ijd}
                    for k in ys:
                        atomic_number1 = atomic_number(structure.species[k[0]])
                        atomic_number2 = atomic_number(structure.species[k[1]])
                        pair = '%06d' % min(
                            atomic_number1 * 1000 + atomic_number2,
                            atomic_number2 * 1000 + atomic_number1)
                        fingerprint[pair] = list(ys[k])

                    if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd
                                                           }) is None:
                        self.pcdb.db.fingerprints.insert(fingerprint)
                    else:
                        self.pcdb.db.fingerprints.update({'_id': entry_ijd},
                                                         fingerprint)
                    fingerprints[entry_ijd] = fingerprint
                else:
                    fingerprints[
                        entry_ijd] = self.pcdb.db.fingerprints.find_one(
                            {'_id': entry_ijd})

            dij = []
            for pair in fingerprints[entry_id]:
                if pair in fingerprints[entry_jd] and pair != '_id':
                    uvect1 = unit_vector(fingerprints[entry_id][pair])
                    uvect2 = unit_vector(fingerprints[entry_jd][pair])
                    dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2)))
            distance = float(np.mean(dij))
            self.pcdb.db.distances.insert({
                'pair': ids_pair,
                'distance': distance
            })
        else:
            distance = distance_entry['distance']
        return distance
Ejemplo n.º 4
0
    def distance(self, entry_id, entry_jd, rcut=50):

        ids_pair = [entry_id, entry_jd]
        ids_pair.sort()
        distance_entry = self.pcdb.db.distances.find_one({'pair': ids_pair}, {'distance': 1})
        self.pcdb.db.distances.create_index([("pair", pymongo.ASCENDING)])

        if distance_entry is None:
            print('Distance not in DB')
            fingerprints = {}
            for entry_ijd in [entry_id, entry_jd]:

                if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd}) is None:
                    structure = self.get_structure(entry_ijd)
                    analysis = StructureAnalysis(structure, radius=rcut)
                    x, ys = analysis.fp_oganov()
                    fingerprint = {'_id': entry_ijd}
                    for k in ys:
                        atomic_number1 = atomic_number(structure.species[k[0]])
                        atomic_number2 = atomic_number(structure.species[k[1]])
                        pair = '%06d' % min(atomic_number1 * 1000 + atomic_number2,
                                            atomic_number2 * 1000 + atomic_number1)
                        fingerprint[pair] = list(ys[k])

                    if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd}) is None:
                        self.pcdb.db.fingerprints.insert(fingerprint)
                    else:
                        self.pcdb.db.fingerprints.update({'_id': entry_ijd}, fingerprint)
                    fingerprints[entry_ijd] = fingerprint
                else:
                    fingerprints[entry_ijd] = self.pcdb.db.fingerprints.find_one({'_id': entry_ijd})

            dij = []
            for pair in fingerprints[entry_id]:
                if pair in fingerprints[entry_jd] and pair != '_id':
                    uvect1 = unit_vector(fingerprints[entry_id][pair])
                    uvect2 = unit_vector(fingerprints[entry_jd][pair])
                    dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2)))
            distance = float(np.mean(dij))
            self.pcdb.db.distances.insert({'pair': ids_pair, 'distance': distance})
        else:
            distance = distance_entry['distance']
        return distance
Ejemplo n.º 5
0
    def align_with_plane(self, axis=2, round_decimals=14):
        a = self.cell[1]

        if axis == 0:
            p1 = np.array([0, 1, 0])
            p2 = np.array([0, 0, 1])
        elif axis == 1:
            p1 = np.array([0, 0, 1])
            p2 = np.array([1, 0, 0])
        elif axis == 2:
            p1 = np.array([1, 0, 0])
            p2 = np.array([0, 1, 0])
        else:
            raise ValueError('Axis must be an integer in (0,1,2)')

        if np.linalg.norm(np.cross(p1, a)) < 1E-10:
            return
        c = unit_vector(np.cross(p1, a))
        # print c
        # A vector perpendicular to the plane
        vector_plane = unit_vector(np.cross(p1, p2))
        v1_u = unit_vector(vector_plane)
        v2_u = unit_vector(c)
        proj = np.dot(v1_u, v2_u)
        # print 'Projection', proj
        av = np.arccos(proj)
        # import math
        # print 'Angle=', math.degrees(av)
        rotation_matrix = rotation_matrix_around_axis_angle(p1, -av)
        cell = np.dot(rotation_matrix, self.cell.T).T.round(round_decimals)
        # print '-->',cell[1], vector_plane
        # print 'PROJECTION', np.dot(cell[1], vector_plane)
        if np.abs(np.dot(cell[1], vector_plane)) > 1E-10:
            # print 'Failed projection', np.dot(cell[1], vector_plane)
            # print cell
            rotation_matrix = rotation_matrix_around_axis_angle(p1, av)
            cell = np.dot(rotation_matrix, self.cell.T).T.round(round_decimals)
            if np.dot(cell[1], vector_plane) > 1E-10:
                # print 'Failed projection', np.dot(cell[1], vector_plane)
                # print cell
                pass
        self._cell = cell
Ejemplo n.º 6
0
    def align_with_plane(self, axis=2, round_decimals=14):
        a = self.cell[1]

        if axis == 0:
            p1 = np.array([0, 1, 0])
            p2 = np.array([0, 0, 1])
        elif axis == 1:
            p1 = np.array([0, 0, 1])
            p2 = np.array([1, 0, 0])
        elif axis == 2:
            p1 = np.array([1, 0, 0])
            p2 = np.array([0, 1, 0])
        else:
            raise ValueError('Axis must be an integer in (0,1,2)')

        if np.linalg.norm(np.cross(p1, a)) < 1E-10:
            return
        c = unit_vector(np.cross(p1, a))
        # print c
        # A vector perpendicular to the plane
        vector_plane = unit_vector(np.cross(p1, p2))
        v1_u = unit_vector(vector_plane)
        v2_u = unit_vector(c)
        proj = np.dot(v1_u, v2_u)
        # print 'Projection', proj
        av = np.arccos(proj)
        # import math
        # print 'Angle=', math.degrees(av)
        rotation_matrix = rotation_matrix_around_axis_angle(p1, -av)
        cell = np.dot(rotation_matrix, self.cell.T).T.round(round_decimals)
        # print '-->',cell[1], vector_plane
        # print 'PROJECTION', np.dot(cell[1], vector_plane)
        if np.abs(np.dot(cell[1], vector_plane)) > 1E-10:
            # print 'Failed projection', np.dot(cell[1], vector_plane)
            # print cell
            rotation_matrix = rotation_matrix_around_axis_angle(p1, av)
            cell = np.dot(rotation_matrix, self.cell.T).T.round(round_decimals)
            if np.dot(cell[1], vector_plane) > 1E-10:
                # print 'Failed projection', np.dot(cell[1], vector_plane)
                # print cell
                pass
        self._cell = cell
Ejemplo n.º 7
0
    def distance(self, entry_id, entry_jd):
        """
        Measure of distance for two entries with identifiers 'entry_id' and 'entry_jd'

        :param entry_id: Identifier of first entry
        :param entry_jd: Identifier of second entry
        :return:
        """

        dmat1 = self.get_correlation_params(entry_id)
        dmat2 = self.get_correlation_params(entry_jd)

        euler_angles1 = dmat1['euler_angles']
        euler_angles2 = dmat2['euler_angles']

        uvect1 = unit_vector(np.concatenate((np.cos(euler_angles1), np.sin(euler_angles1))).flatten())
        uvect2 = unit_vector(np.concatenate((np.cos(euler_angles2), np.sin(euler_angles2))).flatten())

        dist_euler = 1 - np.dot(uvect1, uvect2)

        return dist_euler
Ejemplo n.º 8
0
 def align_with_axis(self, axis=0, round_decimals=14):
     a = self.cell[0]
     if axis == 0:
         b = np.array([1, 0, 0])
     elif axis == 1:
         b = np.array([0, 1, 0])
     elif axis == 2:
         b = np.array([0, 0, 1])
     else:
         raise ValueError('Axis must be an integer in (0,1,2)')
     if np.linalg.norm(np.cross(a, b)) < 1E-10:
         return
     c = unit_vector(np.cross(a, b))
     av = angle_vector(a, b)
     rotation_matrix = rotation_matrix_around_axis_angle(c, av)
     self._cell = np.dot(rotation_matrix, self.cell.T).T.round(round_decimals)
Ejemplo n.º 9
0
 def align_with_axis(self, axis=0, round_decimals=14):
     a = self.cell[0]
     if axis == 0:
         b = np.array([1, 0, 0])
     elif axis == 1:
         b = np.array([0, 1, 0])
     elif axis == 2:
         b = np.array([0, 0, 1])
     else:
         raise ValueError('Axis must be an integer in (0,1,2)')
     if np.linalg.norm(np.cross(a, b)) < 1E-10:
         return
     c = unit_vector(np.cross(a, b))
     av = angle_vector(a, b)
     rotation_matrix = rotation_matrix_around_axis_angle(c, av)
     self._cell = np.dot(rotation_matrix, self.cell.T).T.round(round_decimals)
Ejemplo n.º 10
0
    def move_random(self, imember, factor=0.2, in_place=False, kind='move'):

        x = np.array(self.db[imember]['x'])
        newx = x
        outside = True
        while outside:
            dx = 2 * np.random.random_sample(self.ndim) - 1
            # print 'Random movement', dx, factor
            dx = unit_vector(dx)
            newx = x + factor * dx
            outside = not self.is_inside(newx)

        if not in_place:
            new_ident = self.new_identifier()
            self.actives.append(new_ident)
            self.members.append(new_ident)
        else:
            new_ident = imember
        self.db[new_ident] = {'x': newx, 'fx': None}
        self.evaluate_entry(new_ident)
        return new_ident
Ejemplo n.º 11
0
    def move_random(self, imember, factor=0.2, in_place=False, kind='move'):

        x = np.array(self.db[imember]['x'])
        newx = x
        outside = True
        while outside:
            dx = 2 * np.random.random_sample(self.ndim) - 1
            # print 'Random movement', dx, factor
            dx = unit_vector(dx)
            newx = x + factor * dx
            outside = not self.is_inside(newx)

        if not in_place:
            new_ident = self.new_identifier()
            self.actives.append(new_ident)
            self.members.append(new_ident)
        else:
            new_ident = imember
        self.db[new_ident] = {'x': newx, 'fx': None}
        self.evaluate_entry(new_ident)
        return new_ident
Ejemplo n.º 12
0
    def distance(self, entry_id, entry_jd, rcut=50):
        """
        Return a measure of the distance between two clusters by computing
        a n-dimensional vector of the distances between each atom to the
        origin and

        :param rcut:
        :param entry_id: The id of one population entry
        :param entry_jd: The id of another population entry
        :return: (int) The distance between two clusters
        """

        ids_pair = tuple(np.sort([entry_id, entry_jd]))
        distance_entry = self.distancer.get_distance(ids_pair)

        if distance_entry is None:
            fingerprints = {}
            for entry_ijd in [entry_id, entry_jd]:

                if self.fingerprinter.get_fingerprint(entry_ijd) is None:
                    structure = self.get_structure(entry_ijd)
                    analysis = ClusterAnalysis(structure)
                    x, ys = analysis.discrete_radial_distribution_function()
                    fingerprint = {'_id': entry_ijd}
                    for k in ys:
                        atomic_number1 = atomic_number(k[0])
                        atomic_number2 = atomic_number(k[1])
                        pair = '%06d' % min(
                            atomic_number1 * 1000 + atomic_number2,
                            atomic_number2 * 1000 + atomic_number1)
                        fingerprint[pair] = list(ys[k])

                    if self.fingerprinter.get_fingerprint(entry_ijd) is None:
                        self.fingerprinter.set_fingerprint(fingerprint)
                    else:
                        self.fingerprinter.update(entry_ijd, fingerprint)
                    fingerprints[entry_ijd] = fingerprint
                else:
                    fingerprints[
                        entry_ijd] = self.fingerprinter.get_fingerprint(
                            entry_ijd)

            dij = []
            for pair in fingerprints[entry_id]:
                if pair in fingerprints[entry_jd] and pair != '_id':
                    vect1 = fingerprints[entry_id][pair]
                    vect2 = fingerprints[entry_jd][pair]
                    if len(vect1) < len(vect2):
                        tmp = np.zeros(len(vect2))
                        tmp[:len(vect1)] = vect1
                        vect1 = tmp
                    elif len(vect1) > len(vect2):
                        tmp = np.zeros(len(vect1))
                        tmp[:len(vect2)] = vect2
                        vect2 = tmp
                    uvect1 = unit_vector(vect1)
                    uvect2 = unit_vector(vect2)
                    dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2)))
            distance = float(np.mean(dij))
            self.distancer.set_distance(ids_pair, distance)
        else:
            distance = distance_entry['distance']
        return distance