99from dash .dependencies import Component , Input , Output , State
1010from dash .exceptions import PreventUpdate
1111from frozendict import frozendict
12+ from pymatgen .analysis .phase_diagram import PhaseDiagram
1213from pymatgen .analysis .pourbaix_diagram import PREFAC , PourbaixDiagram
1314from pymatgen .core import Composition , Element
15+ from pymatgen .entries .computed_entries import ComputedEntry
1416from pymatgen .util .string import unicodeify
1517from shapely .geometry import Polygon
1618
@@ -614,6 +616,16 @@ def _sub_layouts(self) -> dict[str, Component]:
614616 id = self .id ("comp-panel" ),
615617 style = {"display" : "none" },
616618 ),
619+ html .Div (
620+ [
621+ dcc .ConfirmDialog (
622+ id = self .id ("invalid-conc-alarm" ),
623+ message = f"Illegal concentration entry! Must be between { MIN_CONCENTRATION } and { MAX_CONCENTRATION } M" ,
624+ ),
625+ ],
626+ id = self .id ("comp-panel" ),
627+ style = {"display" : "none" },
628+ ),
617629 html .Div (id = self .id ("element_specific_controls" )),
618630 ctl .Block (html .Div (id = self .id ("display-composition" ))),
619631 ]
@@ -674,11 +686,30 @@ def generate_callbacks(self, app, cache) -> None:
674686 Output (self .id ("heatmap_choice_container" ), "children" ),
675687 Input (self .id (), "data" ),
676688 Input (self .id ("mat-details" ), "data" ),
689+ Input (self .get_kwarg_id ("filter_solids" ), "value" ),
677690 )
678- def update_heatmap_choices (entries , mat_detials ):
691+ def update_heatmap_choices (entries , mat_detials , filter_solids ):
679692 if not entries :
680693 raise PreventUpdate
681694
695+ kwargs = self .reconstruct_kwargs_from_state ()
696+ filter_solids = kwargs ["filter_solids" ]
697+
698+ entries_obj = self .from_data (entries )
699+ solid_entries = [
700+ entry for entry in entries_obj if entry .phase_type == "Solid"
701+ ]
702+ print ("yeee7" )
703+ print (entries )
704+ if filter_solids :
705+ # O is 2.46 b/c pbx entry finds energies referenced to H2O
706+ entries_HO = [ComputedEntry ("H" , 0 ), ComputedEntry ("O" , 2.46 )]
707+ solid_pd = PhaseDiagram (solid_entries + entries_HO )
708+ entries_obj = list (set (solid_pd .stable_entries ) - set (entries_HO ))
709+ entries = [en .as_dict () for en in entries_obj ]
710+ print ("yeee8" )
711+ print (entries )
712+
682713 options = []
683714 for entry in entries :
684715 if entry ["entry_id" ].startswith ("mp" ):
@@ -963,6 +994,7 @@ def get_pourbaix_diagram(pourbaix_entries, **kwargs):
963994 @app .callback (
964995 Output (self .id ("graph" ), "figure" ),
965996 Output (self .id ("invalid-comp-alarm" ), "displayed" ),
997+ Output (self .id ("invalid-conc-alarm" ), "displayed" ),
966998 Input (self .id (), "data" ),
967999 Input (self .id ("display-composition" ), "children" ),
9681000 Input (self .get_all_kwargs_id (), "value" ),
@@ -987,17 +1019,21 @@ def make_figure(
9871019
9881020 if len (raw_comp_list ) != len (elements ):
9891021 logger .error ("Invalid composition input!" )
990- return go .Figure (
991- layout = {** PourbaixDiagramComponent .empty_plot_style }
992- ), True
1022+ return (
1023+ go .Figure (layout = {** PourbaixDiagramComponent .empty_plot_style }),
1024+ True ,
1025+ False ,
1026+ )
9931027 try :
9941028 # avoid direct type casting because string inputs may raise errors
9951029 comp_list = [float (t ) for t in raw_comp_list ]
9961030 except Exception :
9971031 logger .error ("Invalid composition input!" )
998- return go .Figure (
999- layout = {** PourbaixDiagramComponent .empty_plot_style }
1000- ), True
1032+ return (
1033+ go .Figure (layout = {** PourbaixDiagramComponent .empty_plot_style }),
1034+ True ,
1035+ False ,
1036+ )
10011037
10021038 kwargs = self .reconstruct_kwargs_from_state ()
10031039
@@ -1041,6 +1077,15 @@ def make_figure(
10411077 # essentially {slider_name: slider_value}
10421078 for key , val in kwargs .items ():
10431079 if "conc" in key : # keys are encoded like "conc-Ag"
1080+ if val is None :
1081+ return (
1082+ go .Figure (
1083+ layout = {** PourbaixDiagramComponent .empty_plot_style }
1084+ ),
1085+ False ,
1086+ True ,
1087+ )
1088+
10441089 el = key .split ("-" )[1 ]
10451090 conc_dict [el ] = val
10461091 conc_dict = conc_dict or None
@@ -1058,10 +1103,14 @@ def make_figure(
10581103 conc_dict ,
10591104 comp_dict ,
10601105 )
1061- return self .get_figure (
1062- pourbaix_diagram ,
1063- heatmap_entry = heatmap_entry ,
1064- ), False
1106+ return (
1107+ self .get_figure (
1108+ pourbaix_diagram ,
1109+ heatmap_entry = heatmap_entry ,
1110+ ),
1111+ False ,
1112+ False ,
1113+ )
10651114
10661115 # TODO
10671116 # def graph_layout(self):
0 commit comments