Spaces:
Running
Running
xiaohang07
commited on
Commit
•
d638802
1
Parent(s):
a8c5181
Upload 4 files
Browse files- 1.png +0 -0
- NdSiRu.cif +50 -0
- app.py +118 -0
- requirements.txt +1 -0
1.png
ADDED
NdSiRu.cif
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# generated using pymatgen
|
2 |
+
data_NdSiRu
|
3 |
+
_symmetry_space_group_name_H-M P4/nmm
|
4 |
+
_cell_length_a 4.22194715
|
5 |
+
_cell_length_b 4.22194715
|
6 |
+
_cell_length_c 6.93978618
|
7 |
+
_cell_angle_alpha 90.00000000
|
8 |
+
_cell_angle_beta 90.00000000
|
9 |
+
_cell_angle_gamma 90.00000000
|
10 |
+
_symmetry_Int_Tables_number 129
|
11 |
+
_chemical_formula_structural NdSiRu
|
12 |
+
_chemical_formula_sum 'Nd2 Si2 Ru2'
|
13 |
+
_cell_volume 123.70056259
|
14 |
+
_cell_formula_units_Z 2
|
15 |
+
loop_
|
16 |
+
_symmetry_equiv_pos_site_id
|
17 |
+
_symmetry_equiv_pos_as_xyz
|
18 |
+
1 'x, y, z'
|
19 |
+
2 '-y+1/2, x+1/2, z'
|
20 |
+
3 '-x, -y, z'
|
21 |
+
4 'y+1/2, -x+1/2, z'
|
22 |
+
5 'x+1/2, -y+1/2, -z'
|
23 |
+
6 '-y, -x, -z'
|
24 |
+
7 '-x+1/2, y+1/2, -z'
|
25 |
+
8 'y, x, -z'
|
26 |
+
9 '-x+1/2, -y+1/2, -z'
|
27 |
+
10 'y, -x, -z'
|
28 |
+
11 'x+1/2, y+1/2, -z'
|
29 |
+
12 '-y, x, -z'
|
30 |
+
13 '-x, y, z'
|
31 |
+
14 'y+1/2, x+1/2, z'
|
32 |
+
15 'x, -y, z'
|
33 |
+
16 '-y+1/2, -x+1/2, z'
|
34 |
+
loop_
|
35 |
+
_atom_type_symbol
|
36 |
+
_atom_type_oxidation_number
|
37 |
+
Nd2+ 2.0
|
38 |
+
Si4- -4.0
|
39 |
+
Ru2+ 2.0
|
40 |
+
loop_
|
41 |
+
_atom_site_type_symbol
|
42 |
+
_atom_site_label
|
43 |
+
_atom_site_symmetry_multiplicity
|
44 |
+
_atom_site_fract_x
|
45 |
+
_atom_site_fract_y
|
46 |
+
_atom_site_fract_z
|
47 |
+
_atom_site_occupancy
|
48 |
+
Nd2+ Nd0 2 0.00000000 0.50000000 0.31849090 1
|
49 |
+
Si4- Si1 2 0.00000000 0.50000000 0.82833210 1
|
50 |
+
Ru2+ Ru2 2 0.00000000 0.00000000 0.00000000 1
|
app.py
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from slices.core import SLICES
|
3 |
+
from pymatgen.core.structure import Structure
|
4 |
+
from pymatgen.io.cif import CifWriter
|
5 |
+
from pymatgen.io.ase import AseAtomsAdaptor
|
6 |
+
from ase.io import write as ase_write
|
7 |
+
import tempfile
|
8 |
+
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
|
9 |
+
import os
|
10 |
+
# Initialize SLICES backend
|
11 |
+
backend = SLICES(relax_model="chgnet", fmax=0.4, steps=25)
|
12 |
+
|
13 |
+
def wrap_structure(structure):
|
14 |
+
"""Wrap all atoms back into the unit cell."""
|
15 |
+
for i, site in enumerate(structure):
|
16 |
+
frac_coords = site.frac_coords % 1.0
|
17 |
+
structure.replace(i, species=site.species, coords=frac_coords, coords_are_cartesian=False)
|
18 |
+
return structure
|
19 |
+
|
20 |
+
def get_primitive_structure(structure):
|
21 |
+
"""Convert the structure to its primitive cell."""
|
22 |
+
analyzer = SpacegroupAnalyzer(structure)
|
23 |
+
return analyzer.get_primitive_standard_structure()
|
24 |
+
|
25 |
+
def visualize_structure(structure):
|
26 |
+
"""Generate an image of the structure."""
|
27 |
+
atoms = AseAtomsAdaptor.get_atoms(structure)
|
28 |
+
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as temp_file:
|
29 |
+
ase_write(temp_file.name, atoms, format='png', rotation='10x,10y,10z')
|
30 |
+
return temp_file.name
|
31 |
+
|
32 |
+
def process_structure(structure):
|
33 |
+
"""Wrap and convert to primitive cell."""
|
34 |
+
structure = wrap_structure(structure)
|
35 |
+
return get_primitive_structure(structure)
|
36 |
+
|
37 |
+
def cif_to_slices(cif_file):
|
38 |
+
try:
|
39 |
+
structure = Structure.from_file(cif_file.name)
|
40 |
+
structure = process_structure(structure)
|
41 |
+
slices_string = backend.structure2SLICES(structure)
|
42 |
+
image_file = visualize_structure(structure)
|
43 |
+
return slices_string, image_file, None, slices_string, slices_string # Added another slices_string for aug_slices_input
|
44 |
+
except Exception as e:
|
45 |
+
return str(e), None, None, "", ""
|
46 |
+
|
47 |
+
|
48 |
+
def slices_to_cif(slices_string):
|
49 |
+
try:
|
50 |
+
structure, energy = backend.SLICES2structure(slices_string)
|
51 |
+
structure = process_structure(structure)
|
52 |
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.cif', delete=False) as temp_file:
|
53 |
+
CifWriter(structure).write_file(temp_file.name)
|
54 |
+
image_file = visualize_structure(structure)
|
55 |
+
return temp_file.name, image_file, f"Conversion successful. Energy: {energy:.4f} eV/atom"
|
56 |
+
except Exception as e:
|
57 |
+
return None, None, f"Conversion failed. Error: {str(e)}"
|
58 |
+
|
59 |
+
def augment_and_canonicalize_slices(slices_string, num_augmentations):
|
60 |
+
try:
|
61 |
+
augmented_slices = backend.SLICES2SLICESAug_atom_order(slices_string,num=num_augmentations)
|
62 |
+
unique_augmented_slices = list(set(augmented_slices))
|
63 |
+
canonical_slices = list(set([backend.get_canonical_SLICES(s) for s in unique_augmented_slices]))
|
64 |
+
return augmented_slices, canonical_slices
|
65 |
+
except Exception as e:
|
66 |
+
return [], [], str(e)
|
67 |
+
|
68 |
+
|
69 |
+
|
70 |
+
|
71 |
+
# Gradio interface
|
72 |
+
with gr.Blocks() as iface:
|
73 |
+
gr.Markdown("# Crystal Structure and SLICES Converter", elem_classes=["center"])
|
74 |
+
with gr.Row(elem_classes=["center"]):
|
75 |
+
gr.Image("1.png", label="SLICES Representation", show_label=False, width=600, height=250)
|
76 |
+
gr.Markdown("SLICES provides a text-based encoding of crystal structures, allowing for efficient manipulation and generation of new materials.", elem_classes=["center"])
|
77 |
+
|
78 |
+
with gr.Tab("CIF-SLICES Conversion"):
|
79 |
+
with gr.Row():
|
80 |
+
with gr.Column():
|
81 |
+
cif_input = gr.File(label="Upload CIF file", file_types=[".cif"], value="NdSiRu.cif")
|
82 |
+
convert_cif_button = gr.Button("Convert CIF to SLICES")
|
83 |
+
slices_input = gr.Textbox(label="Enter SLICES String")
|
84 |
+
convert_slices_button = gr.Button("Convert SLICES to CIF")
|
85 |
+
with gr.Column():
|
86 |
+
slices_output = gr.Textbox(label="SLICES String")
|
87 |
+
cif_output = gr.File(label="Download CIF", file_types=[".cif"])
|
88 |
+
conversion_status = gr.Textbox(label="Conversion Status")
|
89 |
+
with gr.Row():
|
90 |
+
cif_image = gr.Image(label="Original Structure")
|
91 |
+
slices_image = gr.Image(label="Converted Structure")
|
92 |
+
|
93 |
+
with gr.Tab("SLICES Augmentation and Canonicalization"):
|
94 |
+
aug_slices_input = gr.Textbox(label="Enter SLICES String")
|
95 |
+
num_augmentations = gr.Slider(minimum=1, maximum=50, step=1, value=10, label="Number of Augmentations")
|
96 |
+
augment_button = gr.Button("Augment and Canonicalize")
|
97 |
+
aug_slices_output = gr.Textbox(label="Augmented SLICES Strings")
|
98 |
+
canon_slices_output = gr.Textbox(label="Canonical SLICES Strings")
|
99 |
+
|
100 |
+
# Event handlers
|
101 |
+
convert_cif_button.click(
|
102 |
+
cif_to_slices,
|
103 |
+
inputs=[cif_input],
|
104 |
+
outputs=[slices_output, cif_image, conversion_status, slices_input, aug_slices_input]
|
105 |
+
)
|
106 |
+
convert_slices_button.click(
|
107 |
+
slices_to_cif,
|
108 |
+
inputs=[slices_input],
|
109 |
+
outputs=[cif_output, slices_image, conversion_status]
|
110 |
+
)
|
111 |
+
augment_button.click(
|
112 |
+
augment_and_canonicalize_slices,
|
113 |
+
inputs=[aug_slices_input, num_augmentations],
|
114 |
+
outputs=[aug_slices_output, canon_slices_output]
|
115 |
+
)
|
116 |
+
|
117 |
+
# Launch the interface
|
118 |
+
iface.launch(share=True)
|
requirements.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
slices==2.0.4
|