from backend.latmathcher.plots import plot_atom_list from backend.latmathcher import atoms_to_greed, generate_xyz_text from backend.latmathcher import PipelineLatMatch from backend.db_utils.utils import structure_ato_list from backend.db_utils.parse_c2db import from_c2db_structure, read_c2db_json from backend.db_utils.structure_database import DBInstance from ase.io import read from CifFile import ReadCif import matplotlib.pyplot as plt import matplotlib.patches as patches import os import shutil import numpy as np import periodictable import ast def create_directory(directory_path): if not os.path.exists(directory_path): os.makedirs(directory_path) print(f"Directory '{directory_path}' created successfully.") else: print(f"Directory '{directory_path}' already exists.") def get_atomic_number(element_symbol): # Find the element in the periodic table and return its atomic number element = getattr(periodictable, element_symbol) return element.number def compute_supercell_a(file_material_a, file_material_b,inter_distance , max_angle, max_strain): # ip = "test_ip" # get_client_ip(response) db_latmatcher_path = "DB/LatMatcher" create_directory("DB") create_directory("DB/LatMatcher") new_directory = db_latmatcher_path + "/{}__ma{}__ms{}_on{}".format(ip, max_angle, max_strain, len(os.listdir(db_latmatcher_path))) create_directory(new_directory) path_to_move = new_directory file1 = process_file(file_material_a, path_to_move+"/") file2 = process_file(file_material_b, path_to_move+"/") file_source_a="."+file1.split(".")[-1] file_source_b = "."+file2.split(".")[-1] print("fa, fb:",file_source_a, file_source_b) if file_source_a == "c2db.json": A_structure = from_c2db_structure(read_c2db_json(file1)) A_cell=A_structure["cell"] if file_source_b == "c2db.json": B_structure = from_c2db_structure(read_c2db_json(file2)) B_cell=B_structure["cell"] if file_source_a == ".xyz": A_structure = extract_from_xyz(file1) A_cell = A_structure["cell"] if file_source_b == ".xyz": B_structure = extract_from_xyz(file2) B_cell=B_structure["cell"] if file_source_a == "bespoke.json": A_structure = extract_from_bespoke(file1) A_cell = A_structure["cell"] if file_source_b == "bespoke.json": B_structure = extract_from_bespoke(file2) B_cell=B_structure["cell"] inter_distance=[0,0,inter_distance] super_xyz, min_supercel, new_structure= compute_supercell(A_cell, B_cell, A_structure, B_structure, inter_distance, max_angle, max_strain ) rez=min_supercel.rez # Write the new file: name = "solution" file12 = path_to_move + "/" + name + ".xyz" xyz_content = f"{len(super_xyz)}\n" xyz_content +="Lattice=\"{}\"".format(np.array2string(new_structure['lattice_vectors'], separator=', ', max_line_width=np.inf).replace("\n"," ").replace("[","").replace("]","").replace(",",""))+" pbc=\"T T F\""+"\n" xyz_content += "\n".join([f"{atom[0]} {' '.join(map(str, atom[1]))}" for atom in super_xyz]) # Write the content to a file with open(file12, 'w') as file: file.write(xyz_content) atoms= atoms_to_greed(super_xyz, lat_v=min_supercel.sc_vec3, dim=(3,3,0)) xyz_content_dd=generate_xyz_text(atoms) plot=plot_supercel(super_xyz, min_supercel) return file12, str(rez[0]), str((rez[1], rez[2])),plot, xyz_content_dd def compute_supercell_b(): pass def compute_supercell(A_cell, B_cell,A_structure,B_structure,inter_distance,min_angle, max_strain): min_angle=min_angle/180*np.pi min_supercel = PipelineLatMatch(A_cell, B_cell, Aatoms3D=structure_ato_list(A_structure), Batoms3D=structure_ato_list(B_structure), dim=(10, 10), optimize_angle=True, optimize_strain=True,min_angle=min_angle, max_strain=max_strain) new_structure = min_supercel.get_new_structure(inter_distance) super_xyz = structure_ato_list(new_structure) return super_xyz, min_supercel, new_structure def plot_supercel(super_xyz, min_supercel): fig = plt.figure() atoms = atoms_to_greed(super_xyz, lat_v=min_supercel.sc_vec3, dim=(10, 10, 0)) plot_atom_list(atoms, marker=".") x = [0.0, min_supercel.sc_vec3[0][0], min_supercel.sc_vec3[0][0] + min_supercel.sc_vec3[0][1], min_supercel.sc_vec3[0][1], 0.0] y = [0.0, min_supercel.sc_vec3[1][0], min_supercel.sc_vec3[1][0] + min_supercel.sc_vec3[1][1], min_supercel.sc_vec3[1][1], 0.0] plt.gca().add_patch(patches.Polygon(xy=list(zip(x, y)), fill=True, alpha=0.4, color="green")) plt.ylim(min(y)-10, max(y)+10) plt.xlim(min(x)-10, max(x)+10) # super_a = [super_xyz[i] for i in range(len(new_structure["host_guest"])) if # new_structure["host_guest"][i] == "host"] # super_b = [super_xyz[i] for i in range(len(new_structure["host_guest"])) if # new_structure["host_guest"][i] == "guest"] # # atoms = atoms_to_greed(super_a, lat_v=min_supercel.sc_vec3, dim=(10, 10, 0)) # plot_atom_list(atoms, marker=".") # atoms = atoms_to_greed(super_b, lat_v=min_supercel.sc_vec3, dim=(10, 10, 0)) # plot_atom_list(atoms, marker="*") # # x = [0.0, min_supercel.sc_vec3[0][0], min_supercel.sc_vec3[0][0] + min_supercel.sc_vec3[0][1], # min_supercel.sc_vec3[0][1], 0.0] # y = [0.0, min_supercel.sc_vec3[1][0], min_supercel.sc_vec3[1][0] + min_supercel.sc_vec3[1][1], # min_supercel.sc_vec3[1][1], 0.0] # plt.gca().add_patch(patches.Polygon(xy=list(zip(x, y)), fill=True, alpha=0.4, color="green")) # plt.ylim(-15, 15) # plt.xlim(-15, 15) return fig # Utility tools for working with files def file_json(file_path): file = file_path.split("/")[-1] ext = file.split(".")[-1] if ext == "json": return True else: return False def get_file_name(file_path): file = file_path.split("/")[-1] file_name = file.split(".")[-2] return file_name def process_file(fileobj, path_to_move): file_path = path_to_move + os.path.basename(fileobj.name) shutil.copyfile(fileobj.name, file_path) return file_path def extract_from_xyz(file): structure={'cell':[], 'atoms':[], 'positions':[], "pbc":[ True, True, False] } atoms = read(file) lattice_vectors = atoms.cell atom_symbols = atoms.get_chemical_symbols() positions = atoms.get_positions() structure["cell"] = np.array([[lattice_vectors[0][0], lattice_vectors[0][1], 0], [lattice_vectors[1][0], lattice_vectors[1][1], 0], [0,0,1]]) structure['atoms'] = [get_atomic_number(element_symbol) for element_symbol in atom_symbols] structure['positions'] = positions print(structure) return structure def extract_from_bespoke(file): read_element = DBInstance().from_json_file(file) structure = read_element.structure structure["cell"]=np.array(structure["cell"]) return structure