def get_midpoint(structure : Structure, atom_1, atom_2): a = structure.lattice.a b = structure.lattice.b c = structure.lattice.c d = 999 for x in [0,1,-1]: for y in [0,1,-1]: for z in [0,1,-1]: jimage = np.array([x,y,z]) temp_d = structure.get_distance(atom_1, atom_2, jimage=jimage) if temp_d < d: d = temp_d coord = structure[atom_1].frac_coords + structure[atom_2].frac_coords - jimage coord /= 2 if d < a*0.5 and d < b*0.5 and d < c*0.5: return coord return coord
def get_octa_geom( df_coord_i=None, active_site_j=None, atoms=None, octahedra_atoms=None, verbose=False, ): """ """ #| - get_octa_geom octahedra_atoms_i = octahedra_atoms out_dict = dict( active_o_metal_dist=None, ir_o_mean=None, ir_o_std=None, ) process_system = True row_coord_i = df_coord_i[df_coord_i.structure_index == active_site_j] row_coord_i = row_coord_i.iloc[0] nn_info_i = row_coord_i.nn_info # ir_nn = nn_info_i[0] found_active_Ir = False for nn_j in nn_info_i: if nn_j["site"].specie.symbol == "Ir": ir_nn = nn_j found_active_Ir = True mess_i = "Didn't find the Ir atom that the active O is bound to" # assert found_active_Ir, mess_i if not found_active_Ir: process_system = False num_non_H_neigh = 0 for nn_j in nn_info_i: site_j = nn_j["site"] if site_j.specie.name != "H": num_non_H_neigh += 1 if num_non_H_neigh != 1: process_system = False # | - __old__ # if len(nn_info_i) != 1: # if len(nn_info_i) != 1: # active_o_has_1_neigh = True # print("Need to return NaN") # active_o_has_1_neigh = False # # else: # if active_o_has_1_neigh: # __| if process_system: if octahedra_atoms_i is not None: # | - Use octahedra_atoms_i to get info lattice_cell = atoms.cell.tolist() # ##################################################### lattice = Lattice(lattice_cell) atom_Ir = atoms[ir_nn["site_index"]] active_o_metal_dist = None ir_o_distances = [] for O_index_i in octahedra_atoms_i: # if atoms[59].symbol == "O": atom_O_i = atoms[O_index_i] if atom_O_i.symbol == "O": coords = [ atom_Ir.position, atom_O_i.position, ] struct = Structure( lattice, [atom_Ir.symbol, atom_O_i.symbol], coords, coords_are_cartesian=True, ) dist_i = struct.get_distance(0, 1) # print(dist_i) ir_o_distances.append(dist_i) if O_index_i == int(active_site_j): # print(333 * "TMEP | ") active_o_metal_dist = dist_i ir_o_mean = np.mean(ir_o_distances) ir_o_std = np.std(ir_o_distances) # __| else: # ir_coord = ir_nn["site"].coords ir_site_index = ir_nn["site_index"] ir_coord = atoms[ir_site_index].position #| - Calculating the distance between the active O atom and Ir atom_active_o = atoms[int(active_site_j)] ir_coord_tmp = ir_nn["site"].coords # diff_list = atom_active_o.position - ir_coord diff_list = atom_active_o.position - ir_coord_tmp dist_i = (np.sum([i**2 for i in diff_list]))**(1 / 2) # ir_nn["site"].coords # out_dict["active_o_metal_dist"] = dist_i active_o_metal_dist = dist_i #__| #| - Getting stats on all 6 Ir-O bonds row_coord_j = df_coord_i[df_coord_i.structure_index == ir_site_index] row_coord_j = row_coord_j.iloc[0] nn_info_ir = row_coord_j.nn_info ir_o_distances = [] if len(nn_info_ir) != 6: tmp = 42 else: for nn_j in nn_info_ir: diff_list = nn_j["site"].coords - ir_coord dist_i = (np.sum([i**2 for i in diff_list]))**(1 / 2) ir_o_distances.append(dist_i) # ir_o_mean = np.mean(ir_o_distances) # ir_o_std = np.std(ir_o_distances) # out_dict["ir_o_mean"] = ir_o_mean # out_dict["ir_o_std"] = ir_o_std #__| ir_o_mean = np.mean(ir_o_distances) ir_o_std = np.std(ir_o_distances) # ################################################# out_dict["ir_o_mean"] = ir_o_mean out_dict["ir_o_std"] = ir_o_std out_dict["active_o_metal_dist"] = active_o_metal_dist # ################################################# return (out_dict)
def _get_distance_checked_landmarks( good_landmarks: list, metal_radii: dict, metal_substructure: Structure, tolerance_factor_1: float, direction_dict: dict = None, ) -> list: """ Loops over landmarks and checks that the maximum distance in a chain formed by them is smaller than the threshold. Args: good_landmarks (list): list of tuples of the landmarks metal_radii (dict): dictionary with the radius for each metal metal_substructure (pymatgen.Structure): pymatgen.Structure object with only the metallic parts tolerance_factor_1 (float): tolerance for the distance threshold direction_dict (dict): dictionary with the direction (value) each landmark (key) is parallel to Returns: list of landmarks that fullfill the distance criterion. """ distance_checked_landmarks = [] if direction_dict: a = metal_substructure.lattice.a b = metal_substructure.lattice.b c = metal_substructure.lattice.c lattice = np.array([a, b, c]) metal_coord = np.abs(metal_substructure.cart_coords) for landmark in good_landmarks: direction = direction_dict[landmark] if isinstance(direction, (np.ndarray, list)): max_distance = ( metal_radii[metal_substructure[landmark[0]].species_string] * tolerance_factor_1) direction = direction_dict[landmark] maximum_point_translation = lattice * direction # now, project the relevant coordinates coord_0 = metal_coord[landmark[0]] * direction coord_1 = metal_coord[landmark[1]] * direction distance_0 = np.min([norm(coord_0), norm(coord_1)]) distance_1 = np.min([ norm(maximum_point_translation - coord_0), norm(maximum_point_translation - coord_1), ]) distance_2 = metal_substructure.get_distance( landmark[0], landmark[1]) relevant_distance = np.max( [distance_0, distance_1, distance_2]) if relevant_distance < max_distance: logger.debug('%s is within distance threshold of %s', landmark, max_distance) distance_checked_landmarks.append(landmark) else: logger.debug( 'the distance was too large between %s for a threshold of %s', landmark, max_distance, ) else: for landmark in good_landmarks: max_distance = ( metal_radii[metal_substructure[landmark[0]].species_string] * tolerance_factor_1) distance = metal_substructure.get_distance(landmark[0], landmark[1]) if distance < max_distance: logger.debug('%s is within distance threshold of %s', landmark, max_distance) distance_checked_landmarks.append(landmark) else: logger.debug( 'the distance was too large between %s for a threshold of %s', landmark, max_distance, ) return distance_checked_landmarks
def get_ave_drift(atoms_init, atoms_final): """ """ #| - get_ave_drift # atoms_init = atoms_init_data # atoms_final = atoms_sorted_good # # atoms_init.write("__temp__/00_atoms_init.traj") # atoms_final.write("__temp__/00_atoms_final.traj") # ##################################################### # Check that number of atoms are the same num_atoms_init = atoms_init.get_global_number_of_atoms() num_atoms_final = atoms_final.get_global_number_of_atoms() mess_i = "TEMP isdjfisjd" assert num_atoms_init == num_atoms_final, mess_i num_atoms = num_atoms_init # ##################################################### # Check that constraints are the same constr_init = atoms_init.constraints[0] constr_init = list(np.sort(constr_init.index)) constr_final = atoms_final.constraints[0] constr_final = list(np.sort(constr_final.index)) mess_i = "Constraints need to be equal" assert constr_init == constr_final, mess_i constr = constr_init # ##################################################### # Check lattice cells are equal # lattice_cells_equal = np.all(atoms_init.cell == atoms_final.cell) lattice_cells_equal = np.allclose( atoms_init.cell, atoms_final.cell, ) mess_i = "sijfidsifj" assert lattice_cells_equal, mess_i lattice_cell = atoms_init.cell.tolist() # if True: # ind_i = 39 # atom_init = atoms_init[ind_i] # atom_final = atoms_final[ind_i] # ##################################################### data_dict_list = [] # ##################################################### for atom_init, atom_final in zip(atoms_init, atoms_final): # ##################################################### data_dict_i = dict() # ##################################################### pos_round_init = np.round(atom_init.position, 2) pos_round_final = np.round(atom_final.position, 2) # ##################################################### mess_i = "This should always be true" assert atom_init.index == atom_final.index, mess_i index_i = atom_init.index atom_constr_i = index_i in constr # ##################################################### lattice = Lattice(lattice_cell) coords = [ atom_init.position, atom_final.position, ] struct = Structure( lattice, [atom_init.symbol, atom_final.symbol], coords, coords_are_cartesian=True, ) dist_i = struct.get_distance(0, 1) # ##################################################### data_dict_i["index"] = index_i data_dict_i["distance"] = dist_i data_dict_i["distance_round"] = np.round(dist_i, 2) data_dict_i["constrained"] = atom_constr_i data_dict_i["pos_round_init"] = pos_round_init data_dict_i["pos_round_final"] = pos_round_final # ##################################################### data_dict_list.append(data_dict_i) # ##################################################### # #####################################################3### df = pd.DataFrame(data_dict_list) df = df.set_index("index", drop=False) # #####################################################3### ave_dist_pa = df.distance.sum() / num_atoms return (ave_dist_pa)