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
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
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
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
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
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
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)
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
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