def create_app(structure: Structure, dos_plot_data, band_plot_data): app = Dash(suppress_callback_exceptions=True, assets_folder=SETTINGS.ASSETS_PATH) structure_component = StructureComponent(structure) comp = structure.composition.reduced_formula band_dos_component = BandDosComponent(dos_plot_data, band_plot_data, id=f"band_dos_{comp}",) symmetrizer = StructureSymmetrizer(structure) delayed_layout = create_ctk(structure_component, symmetry_layout(structure), site_layout(symmetrizer), band_dos_component) ctc.register_crystal_toolkit(layout=delayed_layout, app=app, cache=None) return app
# example layout to demonstrate capabilities of component my_layout = html.Div([ html.H1("TransformationComponent Example"), html.H2("Standard Layout"), transformation_component.layout(), html.H3("Example Input Structure"), structure_component.layout(size="500px"), html.H3("Example Transformed Structure"), structure_component_transformed.layout(size="500px"), html.H3("JSON View of Transformations"), JsonView(id="json"), ]) # tell crystal toolkit about your app and layout ctc.register_crystal_toolkit(app, layout=my_layout) # this is here for to see the JSON representation of # the transformations when running the example app, # it is not necessary for running the component app.clientside_callback( """ function (...args) { return {"transformations": args} } """, Output("json", "src"), [ Input(t.id(), "data") for t in transformation_component.transformations.values() ],
structures = [ Structure(Lattice.cubic(4), ["Na", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]]), Structure(Lattice.cubic(5), ["K", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]]), ] # we show the first structure by default structure_component = ctc.StructureMoleculeComponent(structures[0]) # and we create a button for user interaction my_button = html.Button("Swap Structure", id="change_structure_button") # now we have two entries in our app layout, # the structure component's layout and the button my_layout = html.Div([structure_component.layout(), my_button]) ctc.register_crystal_toolkit(app=app, layout=my_layout, cache=None) # for the interactivity, we use a standard Dash callback @app.callback( Output(structure_component.id(), "data"), [Input("change_structure_button", "n_clicks")], ) def update_structure(n_clicks): # on load, n_clicks will be None, and no update is required # after clicking on the button, n_clicks will be an int and incremented if not n_clicks: raise PreventUpdate return structures[n_clicks % 2]
# favorites_component.notes_layout, ], style={"width": box_size, "max-width": box_size}, ), ], desktop_only=False, centered=False, ), Columns([Column(body_layout)]), ] ), Section(footer), ] ) ctc.register_crystal_toolkit(layout=master_layout, app=app, cache=cache) # endregion ################################################################################ # region SET UP APP-SPECIFIC CALLBACKS ################################################################################ @app.callback(Output(search_component.id("input"), "value"), [Input("url", "href")]) def update_search_term_on_page_load(href: str) -> str: """ If an mpid is provided in the url, load that mpid. Otherwise load a random mpid from the DEFAULT_MPIDS global variable.
def make_defect_formation_energy(args): formula = args.perfect_calc_results.structure.composition.reduced_formula chem_pot_diag = ChemPotDiag.from_yaml(args.cpd_yaml) pcr = args.perfect_calc_results defects, defect_entries, corrections, edge_states = [], [], [], [] for d in args.dirs: if args.skip_shallow: edge_states = BandEdgeStates.from_yaml(d / "band_edge_states.yaml") if edge_states.is_shallow: continue defects.append(loadfn(d / "calc_results.json")) defect_entries.append(loadfn(d / "defect_entry.json")) corrections.append(loadfn(d / "correction.json")) if args.web_gui: from crystal_toolkit.settings import SETTINGS import dash_html_components as html from crystal_toolkit.helpers.layouts import Column import crystal_toolkit.components as ctc import dash edge_states = [] for d in args.dirs: edge_states.append( BandEdgeStates.from_yaml(d / "band_edge_states.yaml")) app = dash.Dash(__name__, suppress_callback_exceptions=True, assets_folder=SETTINGS.ASSETS_PATH, external_stylesheets=[ 'https://codepen.io/chriddyp/pen/bWLwgP.css' ]) cpd_plot_info = CpdPlotInfo(chem_pot_diag) cpd_e_component = CpdEnergyComponent(cpd_plot_info, pcr, defects, defect_entries, corrections, args.unitcell.vbm, args.unitcell.cbm, edge_states) my_layout = html.Div([Column(cpd_e_component.layout)]) ctc.register_crystal_toolkit(app=app, layout=my_layout, cache=None) app.run_server(port=args.port) return abs_chem_pot = chem_pot_diag.abs_chem_pot_dict(args.label) title = " ".join([latexify(formula), "point", args.label]) defect_energies = make_energies(pcr, defects, defect_entries, corrections, abs_chem_pot) if args.print: defect_energies = slide_energy(defect_energies, args.unitcell.vbm) print(" charge E_f correction ") for e in defect_energies: print(e) print("") print("-- cross points -- ") for e in defect_energies: print(e.name) print( e.cross_points(ef_min=args.unitcell.vbm, ef_max=args.unitcell.cbm, base_ef=args.unitcell.vbm)) print("") return plotter = DefectEnergyMplPlotter(title=title, defect_energies=defect_energies, vbm=args.unitcell.vbm, cbm=args.unitcell.cbm, supercell_vbm=pcr.vbm, supercell_cbm=pcr.cbm, y_range=args.y_range, supercell_edge=args.supercell_edge, label_line=args.label_line, add_charges=args.add_charges) plotter.construct_plot() plotter.plt.savefig(f"energy_{args.label}.pdf")
# html.P("We will store no personal data that can identify you."), # ], # ), html.Hr(), html.Footer( "© Laboratory of Molecular Simulation (LSMO), École polytechnique fédérale de Lausanne (EPFL). Web app version {}" .format(__version__)), ], className="container", ), ], className="container", # tag for iframe resizer **{"data-iframe-height": ""}) ctc.register_crystal_toolkit(dash_app, layout=layout) @dash_app.callback( Output("resultdiv", "children"), [Input("memorystore", "modified_timestamp")], [State("memorystore", "data")], ) def run_prediction(_, store): """Returns the prediction table""" dash_app.logger.info("triggering prediction update") try: if store["structure"] is not None: return run_check(store["structure"])