def run_algorithm(algorithm, struct): if not struct: raise PreventUpdate if algorithm != "chemenv": return html.Div( "Not available on the web yet, use the pymatgen code to run this analysis." ) struct = self.from_data(struct) if algorithm == "chemenv": description = ( "The Chemenv algorithm is developed by David Waroquiers et al. to analyze " 'local chemical environments. In this interactive app, the "SimplestChemenvStrategy" ' 'and "LightStructureEnvironments" are used. For more powerful analysis, please use ' "the *pymatgen* code.") distance_cutoff = get_float_input( id=self.id("distance_cutoff"), default=1.4, label="Distance cut-off", help= "Defines search radius by considering any atom within a radius " "of the minimum nearest neighbor distance multiplied by the distance " "cut-off.", ) angle_cutoff = get_float_input( id=self.id("angle_cutoff"), default=0.3, label="Angle cut-off", help= "Defines a tolerance whereby a neighbor atom is excluded if the solid angle " "circumscribed by its Voronoi face is smaller than the angle tolerance " "multiplied by the largest solid angle present in the crystal.", ) return html.Div([ dcc.Markdown(description), html.Br(), cite_me( manual_ref= "Chemenv: A fast and robust coordination environment identification tool, " "David Waroquiers et al. (2019)", cite_text="Cite Chemenv Analysis", ), html.Br(), distance_cutoff, angle_cutoff, html.Br(), dcc.Loading(id=self.id("chemenv_analysis"), color=PRIMARY_COLOR), ])
def run_algorithm(algorithm): algorithm = self.reconstruct_kwarg_from_state( callback_context.inputs, "algorithm") if algorithm == "chemenv": state = {"distance_cutoff": 1.4, "angle_cutoff": 0.3} description = ( "The ChemEnv algorithm is developed by David Waroquiers et al. to analyze " 'local chemical environments. In this interactive app, the "SimplestChemenvStrategy" ' 'and "LightStructureEnvironments" are used. For more powerful analysis, please use ' "the *pymatgen* code directly. Note that this analysis determines its own bonds independent " "of those shown in the main crystal visualizer.") distance_cutoff = self.get_numerical_input( label="Distance cut-off", kwarg_label="distance_cutoff", state=state, help_str= "Defines search radius by considering any atom within a radius " "of the minimum nearest neighbor distance multiplied by the distance " "cut-off.", shape=(), ) angle_cutoff = self.get_numerical_input( label="Angle cut-off", kwarg_label="angle_cutoff", state=state, help_str= "Defines a tolerance whereby a neighbor atom is excluded if the solid angle " "circumscribed by its Voronoi face is smaller than the angle tolerance " "multiplied by the largest solid angle present in the crystal.", shape=(), ) return html.Div([ dcc.Markdown(description), html.Br(), cite_me( cite_text="How to cite ChemEnv", doi="10.26434/chemrxiv.11294480.v1", ), html.Br(), distance_cutoff, angle_cutoff, html.Br(), Loading(id=self.id("chemenv_analysis")), ]) elif algorithm == "localenv": description = ( "The LocalEnv algorithm is developed by Nils Zimmerman et al. whereby " "an 'order parameter' is calculated that measures how well that " "environment matches an ideal polyhedra. The order parameter " "is a number from zero to one, with one being a perfect match." ) return html.Div([ dcc.Markdown(description), html.Br(), cite_me( cite_text="How to cite LocalEnv", doi="10.3389/fmats.2017.00034", ), html.Br(), Loading(id=self.id("localenv_analysis")), ]) elif algorithm == "bondinggraph": description = ( "This is an alternative way to display the same bonds present in the " "visualizer. Here, the bonding is displayed as a crystal graph, with " "nodes as atoms and edges as bonds. The graph visualization is shown in an " "abstract two-dimensional space.") return html.Div([ dcc.Markdown(description), html.Br(), Loading(id=self.id("bondinggraph_analysis")), ]) elif algorithm == "soap": state = { "rcut": 5.0, "nmax": 2, "lmax": 2, "sigma": 0.2, "crossover": True, "average": False, "rbf": "gto", "alpha": 0.1, "threshold": 1e-4, "metric": "linear", "normalize_kernel": True, } description = ( 'The "Smooth Overlap of Atomic Positions" (SOAP) descriptor provides information on the local ' "atomic environment by encoding that environment as a power spectrum derived from the " "spherical harmonics of atom-centered gaussian densities. The SOAP formalism is complex but is " "described well in [Bartók et al.](https://doi.org/10.1103/PhysRevB.87.184115) " "and the REMatch similarity kernel in [De et al.](https://doi.org/10.1039/c6cp00415f) " "The implementation of SOAP in this " "web app is provided by [DScribe](https://doi.org/10.1016/j.cpc.2019.106949). " "" "SOAP kernels are commonly used in machine learning applications. This interface is provided to " "help gain intuition and exploration of the behavior of SOAP kernels." ) rcut = self.get_numerical_input( label="Radial cut-off /Å", kwarg_label="rcut", state=state, help_str= "The radial cut-off that defines the local region being considered", shape=(), min=1.0001, ) nmax = self.get_numerical_input( label="N max.", kwarg_label="nmax", state=state, help_str="Number of radial basis functions", shape=(), is_int=True, min=1, max=9, ) lmax = self.get_numerical_input( label="L max.", kwarg_label="lmax", state=state, help_str="Maximum degree of spherical harmonics", shape=(), is_int=True, min=1, max=9, ) sigma = self.get_numerical_input( label="Sigma", kwarg_label="sigma", state=state, help_str= "The standard deviation of gaussians used to build atomic density", shape=(), min=0.00001, ) rbf = self.get_choice_input( label="Radial basis function", kwarg_label="rbf", state=state, help_str= "Polynomial basis is faster, spherical gaussian based was used in original formulation", options=[ { "label": "Spherical gaussian basis", "value": "gto" }, { "label": "Polynomial basis", "value": "polynomial" }, ], style={"width": "16rem"}, # TODO: remove in-line style ) crossover = self.get_bool_input( label="Crossover", kwarg_label="crossover", state=state, help_str= "If enabled, the power spectrum will include all combinations of elements present.", ) average = self.get_bool_input( label="Average", kwarg_label="average", state=state, help_str= "If enabled, the SOAP vector will be averaged across all sites.", ) alpha = self.get_numerical_input( label="Alpha", kwarg_label="alpha", state=state, help_str= "Determines the entropic penalty in the REMatch kernel. As alpha goes to infinity, the " "behavior of the REMatch kernel matches the behavior of the kernel where SOAP vectors " "are averaged across all sites. As alpha goes to zero, the kernel matches the best match " "kernel.", shape=(), min=0.00001, ) threshold = self.get_numerical_input( label="Sinkhorn threshold", kwarg_label="threshold", state=state, help_str= "Convergence threshold for the Sinkhorn algorithm. If values are too small, convergence " "may not be possible, and calculation time will increase.", shape=(), ) metric = self.get_choice_input( label="Metric", kwarg_label="metric", state=state, help_str= 'See scikit-learn\'s documentation on "Pairwise metrics, Affinities and Kernels" ' "for an explanation of available metrics.", options=[ # {"label": "Additive χ2", "value": "additive_chi2"}, # these seem to be unstable # {"label": "Exponential χ2", "value": "chi2"}, { "label": "Linear", "value": "linear" }, { "label": "Polynomial", "value": "polynomial" }, { "label": "Radial basis function", "value": "rbf" }, { "label": "Laplacian", "value": "laplacian" }, { "label": "Sigmoid", "value": "sigmoid" }, { "label": "Cosine", "value": "cosine" }, ], style={"width": "16rem"}, # TODO: remove in-line style ) normalize_kernel = self.get_bool_input( label="Normalize", kwarg_label="normalize_kernel", state=state, help_str= "Whether or not to normalize the resulting similarity kernel.", ) # metric_kwargs = self.get_dict_input() return html.Div([ dcc.Markdown(description), html.Br(), H5("SOAP parameters"), rcut, nmax, lmax, sigma, rbf, crossover, average, html.Br( ), # TODO: remove all html.Br(), add appropriate styles instead html.Br(), html.Div(id=self.id("soap_analysis")), html.Br(), html.Br(), H5("Similarity metric parameters"), html.Div( "This will calculate structural similarity scores from materials in the " "Materials Project in the same chemical system. Note that for large chemical " "systems this step can take several minutes."), html.Br(), alpha, threshold, metric, # normalize_kernel, html.Br(), html.Br(), Loading(id=self.id("soap_similarities")), ])
def run_algorithm(algorithm): algorithm = self.reconstruct_kwarg_from_state( callback_context.inputs, "algorithm") if algorithm == "chemenv": state = {"distance_cutoff": 1.4, "angle_cutoff": 0.3} description = ( "The ChemEnv algorithm is developed by David Waroquiers et al. to analyze " 'local chemical environments. In this interactive app, the "SimplestChemenvStrategy" ' 'and "LightStructureEnvironments" are used. For more powerful analysis, please use ' "the *pymatgen* code directly. Note that this analysis determines its own bonds independent " "of those shown in the main crystal visualizer.") distance_cutoff = self.get_numerical_input( label="Distance cut-off", kwarg_label="distance_cutoff", state=state, help_str= "Defines search radius by considering any atom within a radius " "of the minimum nearest neighbor distance multiplied by the distance " "cut-off.", shape=(), ) angle_cutoff = self.get_numerical_input( label="Angle cut-off", kwarg_label="angle_cutoff", state=state, help_str= "Defines a tolerance whereby a neighbor atom is excluded if the solid angle " "circumscribed by its Voronoi face is smaller than the angle tolerance " "multiplied by the largest solid angle present in the crystal.", shape=(), ) return html.Div([ dcc.Markdown(description), html.Br(), cite_me( cite_text="How to cite ChemEnv", doi="10.26434/chemrxiv.11294480.v1", ), html.Br(), distance_cutoff, angle_cutoff, html.Br(), Loading(id=self.id("chemenv_analysis")), ]) elif algorithm == "localenv": description = ( "The LocalEnv algorithm is developed by Nils Zimmerman et al. whereby " "an 'order parameter' is calculated that measures how well that " "environment matches an ideal polyhedra. The order parameter " "is a number from zero to one, with one being a perfect match." ) return html.Div([ dcc.Markdown(description), html.Br(), cite_me( cite_text="How to cite LocalEnv", doi="10.3389/fmats.2017.00034", ), html.Br(), Loading(id=self.id("localenv_analysis")), ]) elif algorithm == "bondinggraph": description = ( "This is an alternative way to display the same bonds present in the " "visualizer. Here, the bonding is displayed as a crystal graph, with " "nodes as atoms and edges as bonds. The graph visualization is shown in an " "abstract two-dimensional space.") return html.Div([ dcc.Markdown(description), html.Br(), Loading(id=self.id("bondinggraph_analysis")), ])