msiron commited on
Commit
e6e9684
1 Parent(s): 20d40ec

ruff and isort format

Browse files
Files changed (1) hide show
  1. app.py +117 -58
app.py CHANGED
@@ -1,12 +1,12 @@
1
  import os
2
- from pymatgen.ext.matproj import MPRester
3
- import crystal_toolkit.components as ctc
4
- from crystal_toolkit.settings import SETTINGS
5
 
 
6
  import dash
7
- from dash import html, dcc
 
8
  from dash.dependencies import Input, Output, State
9
  from pymatgen.core import Structure
 
10
 
11
  HF_TOKEN = os.environ.get("HF_TOKEN")
12
 
@@ -34,7 +34,7 @@ dataset = load_dataset(
34
  "functional",
35
  "chemical_formula_reduced",
36
  "chemical_formula_descriptive",
37
- "total_magnetization"
38
  ],
39
  )
40
 
@@ -47,38 +47,78 @@ app = dash.Dash(__name__, assets_folder=SETTINGS.ASSETS_PATH)
47
  server = app.server # Expose the server for deployment
48
 
49
  # Define the app layout
50
- layout = html.Div([
51
- dcc.Markdown("## Interactive Crystal Viewer"),
52
- html.Div([
53
- html.Div([
54
- html.Label("Search by Chemical System (e.g., 'Ac-Cd-Ge')"),
55
- dcc.Input(
56
- id='query-input',
57
- type='text',
58
- value='Ac-Cd-Ge',
59
- placeholder='Ac-Cd-Ge',
60
- style={'width': '100%'}
61
- ),
62
- ], style={'width': '70%', 'display': 'inline-block', 'verticalAlign': 'top'}),
63
- html.Div([
64
- html.Button('Search', id='search-button', n_clicks=0),
65
- ], style={'width': '28%', 'display': 'inline-block', 'paddingLeft': '2%', 'verticalAlign': 'top'}),
66
- ], style={'margin-bottom': '20px'}),
67
- html.Div([
68
- html.Label("Select Material"),
69
- dcc.Dropdown(
70
- id='material-dropdown',
71
- options=[], # Empty options initially
72
- value=None
 
 
 
 
 
 
 
 
 
 
 
 
73
  ),
74
- ], style={'margin-bottom': '20px'}),
75
- html.Button('Display Material', id='display-button', n_clicks=0),
76
- html.Div([
77
- html.Div(id='structure-container', style={'width': '48%', 'display': 'inline-block', 'verticalAlign': 'top'}),
78
- html.Div(id='properties-container',
79
- style={'width': '48%', 'display': 'inline-block', 'paddingLeft': '4%', 'verticalAlign': 'top'}),
80
- ], style={'margin-top': '20px'}),
81
- ])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
 
84
  # Function to search for materials
@@ -90,17 +130,22 @@ def search_materials(query):
90
  [isintersection(l) and isubset(l) for l in train_df.elements.values.tolist()]
91
  ]
92
 
93
- options = [{'label': f"{res.chemical_formula_reduced} ({res.immutable_id}) Calculated with {res.functional}", 'value': n} for n,res in entries_df.iterrows()]
 
 
 
 
 
 
94
  del entries_df
95
  return options
96
 
97
 
98
  # Callback to update the material dropdown based on search
99
  @app.callback(
100
- [Output('material-dropdown', 'options'),
101
- Output('material-dropdown', 'value')],
102
- Input('search-button', 'n_clicks'),
103
- State('query-input', 'value'),
104
  )
105
  def update_material_dropdown(n_clicks, query):
106
  if n_clicks is None or not query:
@@ -108,25 +153,29 @@ def update_material_dropdown(n_clicks, query):
108
  options = search_materials(query)
109
  if not options:
110
  return [], None
111
- return options, options[0]['value']
112
 
113
 
114
  # Callback to display the selected material
115
  @app.callback(
116
- [Output('structure-container', 'children'),
117
- Output('properties-container', 'children')],
118
- Input('display-button', 'n_clicks'),
119
- State('material-dropdown', 'value')
 
 
120
  )
121
  def display_material(n_clicks, material_id):
122
  if n_clicks is None or not material_id:
123
- return '', ''
124
  row = train_df.iloc[material_id]
125
 
126
- structure = Structure([x for y in row['lattice_vectors'] for x in y],
127
- row['species_at_sites'],
128
- row['cartesian_site_positions'],
129
- coords_are_cartesian= True)
 
 
130
 
131
  # Create the StructureMoleculeComponent
132
  structure_component = ctc.StructureMoleculeComponent(structure)
@@ -135,17 +184,27 @@ def display_material(n_clicks, material_id):
135
  properties = {
136
  "Material ID": row.immutable_id,
137
  "Formula": row.chemical_formula_descriptive,
138
- "Energy per atom (eV/atom)": row.energy/len(row.species_at_sites),
139
  "Band Gap (eV)": row.band_gap_direct or row.band_gap_indirect,
140
  "Total Magnetization (μB/f.u.)": row.total_magnetization,
141
  }
142
 
143
  # Format properties as an HTML table
144
- properties_html = html.Table([
145
- html.Tbody([
146
- html.Tr([html.Th(key), html.Td(str(value))]) for key, value in properties.items()
147
- ])
148
- ], style={'border': '1px solid black', 'width': '100%', 'borderCollapse': 'collapse'})
 
 
 
 
 
 
 
 
 
 
149
 
150
  return structure_component.layout(), properties_html
151
 
@@ -153,5 +212,5 @@ def display_material(n_clicks, material_id):
153
  # Register crystal toolkit with the app
154
  ctc.register_crystal_toolkit(app, layout)
155
 
156
- if __name__ == '__main__':
157
  app.run_server(debug=True, port=7860, host="0.0.0.0")
 
1
  import os
 
 
 
2
 
3
+ import crystal_toolkit.components as ctc
4
  import dash
5
+ from crystal_toolkit.settings import SETTINGS
6
+ from dash import dcc, html
7
  from dash.dependencies import Input, Output, State
8
  from pymatgen.core import Structure
9
+ from pymatgen.ext.matproj import MPRester
10
 
11
  HF_TOKEN = os.environ.get("HF_TOKEN")
12
 
 
34
  "functional",
35
  "chemical_formula_reduced",
36
  "chemical_formula_descriptive",
37
+ "total_magnetization",
38
  ],
39
  )
40
 
 
47
  server = app.server # Expose the server for deployment
48
 
49
  # Define the app layout
50
+ layout = html.Div(
51
+ [
52
+ dcc.Markdown("## Interactive Crystal Viewer"),
53
+ html.Div(
54
+ [
55
+ html.Div(
56
+ [
57
+ html.Label("Search by Chemical System (e.g., 'Ac-Cd-Ge')"),
58
+ dcc.Input(
59
+ id="query-input",
60
+ type="text",
61
+ value="Ac-Cd-Ge",
62
+ placeholder="Ac-Cd-Ge",
63
+ style={"width": "100%"},
64
+ ),
65
+ ],
66
+ style={
67
+ "width": "70%",
68
+ "display": "inline-block",
69
+ "verticalAlign": "top",
70
+ },
71
+ ),
72
+ html.Div(
73
+ [
74
+ html.Button("Search", id="search-button", n_clicks=0),
75
+ ],
76
+ style={
77
+ "width": "28%",
78
+ "display": "inline-block",
79
+ "paddingLeft": "2%",
80
+ "verticalAlign": "top",
81
+ },
82
+ ),
83
+ ],
84
+ style={"margin-bottom": "20px"},
85
  ),
86
+ html.Div(
87
+ [
88
+ html.Label("Select Material"),
89
+ dcc.Dropdown(
90
+ id="material-dropdown",
91
+ options=[], # Empty options initially
92
+ value=None,
93
+ ),
94
+ ],
95
+ style={"margin-bottom": "20px"},
96
+ ),
97
+ html.Button("Display Material", id="display-button", n_clicks=0),
98
+ html.Div(
99
+ [
100
+ html.Div(
101
+ id="structure-container",
102
+ style={
103
+ "width": "48%",
104
+ "display": "inline-block",
105
+ "verticalAlign": "top",
106
+ },
107
+ ),
108
+ html.Div(
109
+ id="properties-container",
110
+ style={
111
+ "width": "48%",
112
+ "display": "inline-block",
113
+ "paddingLeft": "4%",
114
+ "verticalAlign": "top",
115
+ },
116
+ ),
117
+ ],
118
+ style={"margin-top": "20px"},
119
+ ),
120
+ ]
121
+ )
122
 
123
 
124
  # Function to search for materials
 
130
  [isintersection(l) and isubset(l) for l in train_df.elements.values.tolist()]
131
  ]
132
 
133
+ options = [
134
+ {
135
+ "label": f"{res.chemical_formula_reduced} ({res.immutable_id}) Calculated with {res.functional}",
136
+ "value": n,
137
+ }
138
+ for n, res in entries_df.iterrows()
139
+ ]
140
  del entries_df
141
  return options
142
 
143
 
144
  # Callback to update the material dropdown based on search
145
  @app.callback(
146
+ [Output("material-dropdown", "options"), Output("material-dropdown", "value")],
147
+ Input("search-button", "n_clicks"),
148
+ State("query-input", "value"),
 
149
  )
150
  def update_material_dropdown(n_clicks, query):
151
  if n_clicks is None or not query:
 
153
  options = search_materials(query)
154
  if not options:
155
  return [], None
156
+ return options, options[0]["value"]
157
 
158
 
159
  # Callback to display the selected material
160
  @app.callback(
161
+ [
162
+ Output("structure-container", "children"),
163
+ Output("properties-container", "children"),
164
+ ],
165
+ Input("display-button", "n_clicks"),
166
+ State("material-dropdown", "value"),
167
  )
168
  def display_material(n_clicks, material_id):
169
  if n_clicks is None or not material_id:
170
+ return "", ""
171
  row = train_df.iloc[material_id]
172
 
173
+ structure = Structure(
174
+ [x for y in row["lattice_vectors"] for x in y],
175
+ row["species_at_sites"],
176
+ row["cartesian_site_positions"],
177
+ coords_are_cartesian=True,
178
+ )
179
 
180
  # Create the StructureMoleculeComponent
181
  structure_component = ctc.StructureMoleculeComponent(structure)
 
184
  properties = {
185
  "Material ID": row.immutable_id,
186
  "Formula": row.chemical_formula_descriptive,
187
+ "Energy per atom (eV/atom)": row.energy / len(row.species_at_sites),
188
  "Band Gap (eV)": row.band_gap_direct or row.band_gap_indirect,
189
  "Total Magnetization (μB/f.u.)": row.total_magnetization,
190
  }
191
 
192
  # Format properties as an HTML table
193
+ properties_html = html.Table(
194
+ [
195
+ html.Tbody(
196
+ [
197
+ html.Tr([html.Th(key), html.Td(str(value))])
198
+ for key, value in properties.items()
199
+ ]
200
+ )
201
+ ],
202
+ style={
203
+ "border": "1px solid black",
204
+ "width": "100%",
205
+ "borderCollapse": "collapse",
206
+ },
207
+ )
208
 
209
  return structure_component.layout(), properties_html
210
 
 
212
  # Register crystal toolkit with the app
213
  ctc.register_crystal_toolkit(app, layout)
214
 
215
+ if __name__ == "__main__":
216
  app.run_server(debug=True, port=7860, host="0.0.0.0")