Skip to content

Commit f95772b

Browse files
Merge pull request #219 from Exabyte-io/update/cif-import
update/cif import
2 parents ed662ac + e559c24 commit f95772b

3 files changed

Lines changed: 111 additions & 50 deletions

File tree

other/materials_designer/import_materials_from_files.ipynb

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
"The following happens in the script below:\n",
2121
"\n",
2222
"1. Install the required packages\n",
23-
"1. The files are extracted from `user_uploads` folder assuming their extensions represent the format - e.g. `SiO2.poscar`.\n",
23+
"1. The files are extracted from `uploads` folder assuming their extensions represent the format - e.g. `SiO2.poscar`, `Ni.pwi`.\n",
2424
"1. Structural information is read from files into ASE Atoms objects.\n",
2525
"1. ASE Atoms objects are converted to `poscar` format \n",
2626
"1. `poscar` structures are converted to ESSE\n",
27-
"1. The results are passed to the outside runtime"
27+
"1. The results are visualized and passed to the outside runtime"
2828
]
2929
},
3030
{
@@ -42,12 +42,15 @@
4242
"source": [
4343
"# Upload files to this folder\n",
4444
"FOLDER_PATH = \"./uploads\"\n",
45-
"# Attempt to guess the format from file extension\n",
46-
"# If set to specific format, it will only accept that format\n",
47-
"ENFORCED_FORMAT = None\n",
45+
"\n",
46+
"# By default, format will be guessed from file extension\n",
47+
"# If set to specific format, notebook will only read that format\n",
48+
"ENFORCED_FORMATS = None # e.g. [\"cif\", \"espresso-in\"]\n",
49+
"\n",
4850
"# If set to true, the file extension will be included in the resulting material name\n",
4951
"USE_FILE_NAME_NO_EXTENSION = False\n",
50-
"# If set to true, the supported formats will be printed below\n",
52+
"\n",
53+
"# If set to true, the supported formats and required extensions will be printed below\n",
5154
"SHOW_SUPPORTED_FORMATS = False"
5255
],
5356
"outputs": [],
@@ -86,7 +89,7 @@
8689
"source": [
8790
"## 3. Data Processing\n",
8891
"\n",
89-
"### 3.1. Read data from files"
92+
"### 3.1. Read data from files in `uploads` folder"
9093
]
9194
},
9295
{
@@ -101,22 +104,26 @@
101104
"from pathlib import Path\n",
102105
"from ase.io import read\n",
103106
"\n",
104-
"materials = []\n",
105-
"unreadable_files = []\n",
107+
"ase_atoms, readable_file_names, unreadable_file_names = [], [], []\n",
106108
"file_names = os.listdir(FOLDER_PATH)\n",
107109
"\n",
108110
"for file_name in file_names:\n",
109111
" file_path = os.path.join(FOLDER_PATH, file_name)\n",
110-
" try:\n",
111-
" atoms = read(file_path, format=ENFORCED_FORMAT)\n",
112+
" formats = ENFORCED_FORMATS or [None]\n",
112113
"\n",
113-
" atoms.info[\"file_name\"] = Path(file_name).stem if USE_FILE_NAME_NO_EXTENSION else file_name\n",
114-
" materials.append(atoms)\n",
115-
" \n",
116-
" except Exception as e:\n",
117-
" print(e)\n",
118-
" unreadable_files.append(file_name)\n",
119-
" continue"
114+
" for fmt in formats:\n",
115+
" try:\n",
116+
" atoms = read(file_path, format=fmt)\n",
117+
" atoms.info[\"file_name\"] = Path(file_name).stem if USE_FILE_NAME_NO_EXTENSION else file_name\n",
118+
" ase_atoms.append(atoms)\n",
119+
" readable_file_names.append(file_name)\n",
120+
" print(\"Successfully read:\", atoms.info[\"file_name\"], \"using format:\", fmt)\n",
121+
" break\n",
122+
" except Exception:\n",
123+
" continue\n",
124+
" else:\n",
125+
" unreadable_file_names.append(file_name)\n",
126+
" print(\"Failed to read:\", file_name)"
120127
],
121128
"outputs": [],
122129
"execution_count": null
@@ -125,17 +132,15 @@
125132
"cell_type": "markdown",
126133
"id": "57b0d358",
127134
"metadata": {},
128-
"source": [
129-
"### 3.2. Preview the data"
130-
]
135+
"source": "### 3.2. List imported the data"
131136
},
132137
{
133138
"cell_type": "code",
134139
"id": "0e34472a",
135140
"metadata": {},
136141
"source": [
137-
"print(f\"Successfully read {len(materials)} files\")\n",
138-
"print(f\"Unreadable files: {unreadable_files}. \")\n"
142+
"print(f\"Successfully read {len(ase_atoms)} files: {readable_file_names}. \")\n",
143+
"print(f\"Unreadable files: {unreadable_file_names}. \")"
139144
],
140145
"outputs": [],
141146
"execution_count": null
@@ -153,12 +158,11 @@
153158
"id": "a771a36a",
154159
"metadata": {},
155160
"source": [
156-
"# Uncomment to see the list of supported formats and their file extensions\n",
157161
"from ase.io.formats import ioformats\n",
158162
"import pandas as pd\n",
159163
"\n",
160-
"if len(unreadable_files) > 0 or SHOW_SUPPORTED_FORMATS:\n",
161-
" print(f\"Unreadable files found: {unreadable_files}. See formats/extensions below.\")\n",
164+
"if len(unreadable_file_names) > 0 or SHOW_SUPPORTED_FORMATS:\n",
165+
" print(f\"Unreadable files found: {unreadable_file_names}. See formats/extensions below.\")\n",
162166
" data = [[frmt.name, frmt.extensions, frmt.description] for frmt in ioformats.values()]\n",
163167
" dataframe = pd.DataFrame(data, columns=[\"Format Name\", \"File Extensions\", \"Description\"])\n",
164168
" print(dataframe.to_markdown())"
@@ -188,37 +192,40 @@
188192
"from express import ExPrESS\n",
189193
"\n",
190194
"def ase_to_poscar(atoms: Atoms):\n",
191-
" \"\"\"\n",
192-
" Converts ase.Atoms object to POSCAR format\n",
193-
"\n",
194-
" Args:\n",
195-
" atoms (ase.Atoms): ase.Atoms object\n",
196-
"\n",
197-
" Returns:\n",
198-
" str: POSCAR string\n",
199-
" \"\"\"\n",
200195
" output = io.StringIO()\n",
201-
" write(output, atoms, format=\"vasp\")\n",
202-
" content = output.getvalue()\n",
203-
" output.close()\n",
196+
" try:\n",
197+
" write(output, atoms, format=\"vasp\")\n",
198+
" content = output.getvalue()\n",
199+
" except Exception as e:\n",
200+
" print(f\"Error converting ASE atoms to POSCAR: {e}\")\n",
201+
" content = None\n",
202+
" finally:\n",
203+
" output.close()\n",
204204
"\n",
205205
" return content\n",
206206
"\n",
207207
"def convert_ase_entry_to_esse(ase_entry):\n",
208-
" poscar = ase_to_poscar(ase_entry)\n",
209-
" kwargs = {\n",
210-
" \"structure_string\": poscar,\n",
211-
" \"structure_format\": \"poscar\"\n",
212-
" }\n",
208+
" try:\n",
209+
" poscar = ase_to_poscar(ase_entry)\n",
210+
" if poscar is None:\n",
211+
" raise ValueError(\"Failed to generate POSCAR string\")\n",
213212
"\n",
214-
" handler = ExPrESS(\"structure\", **kwargs)\n",
215-
" esse = handler.property(\"material\", **kwargs)\n",
216-
" \n",
217-
" esse[\"name\"] = ase_entry.info[\"file_name\"]\n",
218-
" \n",
219-
" return esse\n",
213+
" kwargs = {\n",
214+
" \"structure_string\": poscar,\n",
215+
" \"structure_format\": \"poscar\"\n",
216+
" }\n",
217+
"\n",
218+
" handler = ExPrESS(\"structure\", **kwargs)\n",
219+
" esse = handler.property(\"material\", **kwargs)\n",
220+
"\n",
221+
" esse[\"name\"] = ase_entry.info.get(\"file_name\", \"Unknown\")\n",
222+
"\n",
223+
" return esse\n",
224+
" except Exception as e:\n",
225+
" print(f\"Error processing ASE entry: {e}\")\n",
226+
" return None\n",
220227
"\n",
221-
"esse_entries = list(map(convert_ase_entry_to_esse, materials))"
228+
"esse_entries = [entry for entry in map(convert_ase_entry_to_esse, ase_atoms) if entry is not None]"
222229
],
223230
"outputs": [],
224231
"execution_count": null
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# C, Graphene, HEX (P6/mmm) 2D (Monolayer), 2dm-3993
2+
3+
data_findsym-output
4+
5+
_symmetry_space_group_name_H-M 'P 6/m 2/m 2/m'
6+
_symmetry_Int_Tables_number 191
7+
8+
_cell_length_a 2.46500
9+
_cell_length_b 2.46500
10+
_cell_length_c 19.99700
11+
_cell_angle_alpha 90.00000
12+
_cell_angle_beta 90.00000
13+
_cell_angle_gamma 120.00000
14+
15+
loop_
16+
_space_group_symop_operation_xyz
17+
x,y,z
18+
x-y,x,z
19+
-y,x-y,z
20+
-x,-y,z
21+
-x+y,-x,z
22+
y,-x+y,z
23+
x-y,-y,-z
24+
x,x-y,-z
25+
y,x,-z
26+
-x+y,y,-z
27+
-x,-x+y,-z
28+
-y,-x,-z
29+
-x,-y,-z
30+
-x+y,-x,-z
31+
y,-x+y,-z
32+
x,y,-z
33+
x-y,x,-z
34+
-y,x-y,-z
35+
-x+y,y,z
36+
-x,-x+y,z
37+
-y,-x,z
38+
x-y,-y,z
39+
x,x-y,z
40+
y,x,z
41+
42+
loop_
43+
_atom_site_label
44+
_atom_site_type_symbol
45+
_atom_site_fract_x
46+
_atom_site_fract_y
47+
_atom_site_fract_z
48+
_atom_site_occupancy
49+
C1 C 0.33333 0.66667 0.50000 1.00000
50+
51+
# end_of_file
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:7ad33a418661557756dce79ca7afddfbe54f86a4ede07446918fbfaba1a16755
3+
size 250

0 commit comments

Comments
 (0)