Integrate LOBSTER apps into crystal toolkit#459
Conversation
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
StructureMoleculeComponent update
CohpAndDosComponent Features
Example rendered appTodos (Will be worked on once app layout is finalized))
Open questions and things to improve
|
|
@naik-aakash @JaGeo for this to be used on MP's site, we'll need any of the required outputs to be in the LobsterTaskDocument. The client will retrieve a LobsterTaskDocument and then use any fields, like (The client shouldn't depend on lobsterpy / need to call lobsterpy). Also to be clear, crystal toolkit shouldn't depend on emmet, but should use data that is available in the task document The method you implemented is OK to keep as a Can you double check that any data that is required for the app to work is included in the task document model? Any updates to the schema should be made against this branch in emmet (PR link) |
|
Hi @esoteric-ephemera, thanks for the suggestion. I will look at the pinned emmet PR and raise a PR if I find anything is missing. I will also try to make the changes in the client in the PR soon. |
| from crystal_toolkit.settings import SETTINGS | ||
|
|
||
|
|
||
| class CustomVasprun(Vasprun): |
There was a problem hiding this comment.
For this class, I would recommend against copying all of Vasprun.final_energy:
class CustomVasprun(Vasprun):
@property
def final_energy(self):
return float(super().final_energy)
|
Hi @esoteric-ephemera , have one question. So, now the plan is that LobsterPy is already run as part of taskdoc generation, and we simply use the outputs from the taskdoc and render the app? I did it this way because, in our initial discussions, it was emphasized that Postprocessing should not be part of Taskdoc, but rather that this app should handle it. Curious about how the workflow pipeline would be now. Once I start with this, I can better comment on the emmet PR. |
|
Any "heavy" post-processing, or post-processing which requires raw output files like vasprun.xml, should happen in the build process for your data. In the current pipeline, the lobster build would be Ex: all derived MP data is built from Light post-processing can occur in the app (e.g., the oxygen evolution graph drawing in the client) , but this should be Let me know if that makes sense! |
|
Hi @esoteric-ephemera , I made the changes are requested to directly work with taskdoc inputs. Made some tweaks and added some more options to enable more interactive anaylsis. Here is screenshot of updated layout
Also I have an additional code that can create such visualization using plotly and dash. Have attached a short video of it here Screencast.from.06.02.2026.17.03.33.webmI could not figure out to reuse the Let me know what you think? Also if this additional app is desired, It would be great if anyone can help with modifying |
|
Thanks, @naik-aakash! Looking good and perhaps @minhsueh has suggestions on how to modify / work with existing components We can discuss this more, but would this ideally be included as a separate property tab for a material, or in a standalone app? |
Hi @esoteric-ephemera, we think it fits better as a separate tab in properties, as you suggested. Maybe a tab under Electronic structure would be an appropriate place? |
|
This looks great! I think the |
|
Hi @esoteric-ephemera , @minhsueh, I added the LobsterEnv analysis algorithm to Have also added a
Also, not 100%: I didn't break anything in Tagging @JaGeo here just to keep in the loop |
for more information, see https://pre-commit.ci
| import dash_mp_components as mpc | ||
| from dash.dependencies import Component, Input, Output | ||
| from dash.exceptions import PreventUpdate | ||
| from lobsterpy.plotting import InteractiveCohpPlotter |
| trace.line.dash = "dot" | ||
| if trace.line.dash != "dot": | ||
| trace.name = f"{cohp_fig.data[ix].name} (spin ↑)" | ||
| legend_spin_down_name = trace.name.split(" (") |
There was a problem hiding this comment.
Could you add more information to the trace? Specifically, you can see that both Na (spin ↑) and Na1: 6 × Cl-Na (spin ↑) are solid red lines. Users who are familiar with Plotly know that detailed information appears when hovering over a trace. However, users who are new to Plotly may find this behavior confusing, especially when multiple traces overlap, making it difficult to determine which trace is being hovered over.
The simplest solution might be to append (COHP) or (DOS) to the legend labels so users can more easily distinguish the traces.
| struct, | ||
| obj_icohp, | ||
| obj_charge, | ||
| perc_strength_icohp, |
There was a problem hiding this comment.
Could you check and update the logic? I'm seeing that when the cutoff is set below 0.05, the following error message is displayed:
raise LookupError(f"No coordination geometry found with mp_symbol {mp_symbol!r}")
LookupError: No coordination geometry found with mp_symbol '18'
| "noise_cutoff": 1e-3, | ||
| } | ||
|
|
||
| lobsterenv_analysis_options = [ |
There was a problem hiding this comment.
Is there a reason we only allow all and cation-anion? Is it primarily due to computational cost or performance considerations? Totally fine with two options! I am just curious.
There are more options (source):
0 - NO_ADDITIONAL_CONDITION
1 - ONLY_ANION_CATION_BONDS
2 - NO_ELEMENT_TO_SAME_ELEMENT_BONDS
3 - ONLY_ANION_CATION_BONDS_AND_NO_ELEMENT_TO_SAME_ELEMENT_BONDS
4 - ONLY_ELEMENT_TO_OXYGEN_BONDS
5 - DO_NOT_CONSIDER_ANION_CATION_BONDS
6 - ONLY_CATION_CATION_BONDS
| initial_data={"color_scheme": "Jmol", "color_scale": None}, | ||
| ) | ||
| # Create LobsterEnv upload component | ||
| self.lobsterenv_upload = LobsterEnvUploadComponent( |
There was a problem hiding this comment.
Could you add a toggle to disable self.lobsterenv_upload?
One use case on the site has LobsterTaskDoc directly as input, so the upload component would only be needed for local usage.
| "The threshold can be set as a percentage of the strongest ICOHP/ICOBI/ICOOP in the structure, and can be adjusted using the slider below. " | ||
| ) | ||
|
|
||
| lobsterenv_state = { |
There was a problem hiding this comment.
Do we need to define all the subcomponents here, given that they are repeated? Could we call CohpAndDosComponent.layout() directly instead?
| return None | ||
|
|
||
|
|
||
| def _get_lobsterenv_inputs(data: dict): |
There was a problem hiding this comment.
Shouldn’t these two functions, _get_lobsterenv_inputs and _extract_structure_from_data, be moved to cohp.py? They are only used for LOBSTER local-environment analysis, whereas localenv.py should serve as the general factory for all local-environment analyses.
| ) | ||
|
|
||
| struct = self.from_data(struct) | ||
| struct = _extract_structure_from_data(struct) |
There was a problem hiding this comment.
Do we need to replace the original code with _extract_structure_from_data here? These callbacks are for soap_analysis, soap_similarities, chemenv_analysis, and bondinggraph_analysis, so they shouldn’t use a structure-extraction function specific to the LOBSTER analysis.




This is the PR to integrate LOBSTER into the Crystal Toolkit.
See below for a detailed explanation of the PR by @naik-aakash !