Skip to content

Integrate LOBSTER apps into crystal toolkit - #459

Open
JaGeo wants to merge 40 commits into
materialsproject:mainfrom
JaGeo:add_lobster_integration
Open

Integrate LOBSTER apps into crystal toolkit#459
JaGeo wants to merge 40 commits into
materialsproject:mainfrom
JaGeo:add_lobster_integration

Conversation

@JaGeo

@JaGeo JaGeo commented Apr 26, 2025

Copy link
Copy Markdown
Member

This is the PR to integrate LOBSTER into the Crystal Toolkit.

See below for a detailed explanation of the PR by @naik-aakash !

@JaGeo JaGeo changed the title Add LobsterNeighbors to list of bonding strategies Integrate LOBSTER apps into crystal toolkit Apr 26, 2025
@naik-aakash

naik-aakash commented May 9, 2025

Copy link
Copy Markdown
Contributor

StructureMoleculeComponent update

  • @JaGeo added option to use LobsterNeighbors in structure visualization

CohpAndDosComponent Features

  • Get relevant bonds interactive cohp plots alongside dos from Lobstery by means of LobsterPy and existing dos plotter in crystaltoolkit
  • Include Bonding analysis summary and calculation quality texts
  • Include visualization of LobsterEnv identified environments
  • Hovering over atoms shows Mulliken charges and edges show the ICOHP values in the visualizer

Example rendered app

App_overview

Todos (Will be worked on once app layout is finalized))

  • Exception handling needs to be implemented
  • Add tests

Open questions and things to improve

  • App loading is currently slow as we pass in completecohp objects (this is quite large) as due to inherent nature of how ploty/dash handles callbacks, lot of time is spent in serialization and deserialization of this object

  • Vasprun.xml file seems to have issues with serialization via plotly so, I think, simple fix would be to just make a small change in pymatgen - Have included temporary workaround for it in the example script here.

  • Icohpcollection object also has serialization issues and currently a fix is a WIP via this Add custom as_dict/from_dict method for proper initialization of attributes of IcohpCollection pymatgen#4391

  • With the current changes LobsterNeighbors can also be used to visualize structure on the Main MP website. Is this desirable ? We think could be nice addition to already exisitng options.
    image

  • Need to agree on what would be best place to visualize LocalEnv identified from LobsterNeighbors, maybe in crystaltoolkit app ? (i.e move this part in localenv.py module ) or could be better to have all LOBSTER related information in one page as in current app layout?

  • What one can query over from MP website using mpid ? If we intend to provide complete taskdoc then we can then add option as in the app.

@esoteric-ephemera

esoteric-ephemera commented Sep 24, 2025

Copy link
Copy Markdown
Collaborator

@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 CalcQualitySummary rather than rerunning Analysis.get_lobster_calc_quality_summary

(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 from_files / from_directory method, but we'd also need something that operates on data after lobster is run

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)

@naik-aakash

Copy link
Copy Markdown
Contributor

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.

Comment thread crystal_toolkit/apps/examples/cohp.py Outdated
from crystal_toolkit.settings import SETTINGS


class CustomVasprun(Vasprun):

@esoteric-ephemera esoteric-ephemera Sep 25, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

@naik-aakash

Copy link
Copy Markdown
Contributor

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.

@esoteric-ephemera

Copy link
Copy Markdown
Collaborator

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 LobsterTaskDocument.from_directory

Ex: all derived MP data is built from TaskDoc objects, and not the raw VASP output - any necessary fields for apps/subsequent builds has to be in TaskDoc. The tasks collection is built from the TaskDoc.from_directory method currently

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!

@naik-aakash

Copy link
Copy Markdown
Contributor

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

image

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.webm

I could not figure out to reuse the Structuremolecule component for this, as I wanted clickable edges. Not sure if we like to have such thing on materials project website. Also as it relies on cohpcar objects, not sure if this can easily work on website. So have not pushed the code here yet.

Let me know what you think? Also if this additional app is desired, It would be great if anyone can help with modifying Structuremolecule component. If it is too much I can simply include it in LobsterPy and we can provide a button to tell users to make use of LobsterPy for more powerful interactive analysis.

@esoteric-ephemera

Copy link
Copy Markdown
Collaborator

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?

@naik-aakash

Copy link
Copy Markdown
Contributor

Hi @esoteric-ephemera , @minhsueh, I added the LobsterEnv analysis algorithm to localenv.py now and I simply reuse it in CohpAndDosComponent

Have also added a LobsterEnvUploadComponent in upload.py module that is part of the layout of the LocalEnv app, but only shows during the LobsterEnv algorithm is selected. It seems to work fine as of now. Maybe I might have overlooked something. Below is snapshot of the app run locally

Screenshot 2026-02-18 at 13-15-13 Crystal Toolkit

Also, not 100%: I didn't break anything in localenv.py. Had made some changes to how other algorithms accessed the data. It would be great if it were tested on your end as well.

Tagging @JaGeo here just to keep in the loop

Comment thread crystal_toolkit/components/cohp.py Outdated
Comment thread crystal_toolkit/components/cohp.py
Comment thread crystal_toolkit/components/cohp.py
Comment thread crystal_toolkit/components/cohp.py Outdated
Comment thread crystal_toolkit/components/localenv.py
Comment thread crystal_toolkit/components/localenv.py Outdated
Comment thread crystal_toolkit/components/localenv.py Outdated
)

struct = self.from_data(struct)
struct = _extract_structure_from_data(struct)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seemed like this to me, because without it I could not make it work.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could not figure out how to do this best way. If you have ideas let me know or if you like to make changes in on this PR or other PR. Also not sure if my changes break anything as there are no specific test cases.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although _extract_structure_from_data falls back to returning the original data, I don't think we need to use it in soap_analysis, soap_similarities, chemenv_analysis, or bondinggraph_analysis, since those seem to be working correctly in the current production. We could keep _extract_structure_from_data specific to the LOBSTER components if needed.

Could you elaborate on what isn't working in your other local environment? I'm not sure I understand the issue.

@naik-aakash naik-aakash Aug 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @minhsueh , so if I do not use this function and try to initialize the app locally with data necessary for lobsterenv option. i.e the structure, icohplist, and charges Python objects in dict form, the chemenv and other options seem to give errors as they expect just the structure object without dict form.

We can see this issue using the added example localenv.py app from the repo and replacing the _extract_structure_from_data with the existing method (self.from_data) in soap_analysis, soap_similarities, chemenv_analysis, or bondinggraph_analysis. Maybe this makes things clearer. I apologize for not being very clear before with explaining the problem.

@naik-aakash

Copy link
Copy Markdown
Contributor

Hi @minhsueh, @JaGeo I have added the test and addressed the review comments that I could. Am confused why the added test is failing here, but it passes locally without any errors.

)

struct = self.from_data(struct)
struct = _extract_structure_from_data(struct)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although _extract_structure_from_data falls back to returning the original data, I don't think we need to use it in soap_analysis, soap_similarities, chemenv_analysis, or bondinggraph_analysis, since those seem to be working correctly in the current production. We could keep _extract_structure_from_data specific to the LOBSTER components if needed.

Could you elaborate on what isn't working in your other local environment? I'm not sure I understand the issue.

@minhsueh

minhsueh commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

@naik-aakash
For the failing test, I haven't been able to reproduce it locally because our environments differ. However, based on the error message:

FAILED crystal_toolkit/apps/examples/tests/test_lobsterenv.py::test_localenv_example_renders_lobsterenv_controls - selenium.common.exceptions.TimeoutException: Message: timeout 30s => waiting for selector [id$='perc_strength_icohp']

My guess is that the LOBSTER analysis is taking longer than expected, causing the page to exceed the 30-second timeout.

One suggestion before directly increasing the timeout: if you're able to reproduce the issue locally, try running the test in headed mode with --slowmo enabled. That should make it easier to see whether the page is simply loading slowly or if another issue appears before the timeout.

python -m pytest --cov=crystal_toolkit --cov-report=xml --color=yes --webdriver Chrome --headed --slowmo 3000 crystal_toolkit/apps/examples/tests/test_lobsterenv.py

@naik-aakash

Copy link
Copy Markdown
Contributor

@naik-aakash For the failing test, I haven't been able to reproduce it locally because our environments differ. However, based on the error message:

FAILED crystal_toolkit/apps/examples/tests/test_lobsterenv.py::test_localenv_example_renders_lobsterenv_controls - selenium.common.exceptions.TimeoutException: Message: timeout 30s => waiting for selector [id$='perc_strength_icohp']

My guess is that the LOBSTER analysis is taking longer than expected, causing the page to exceed the 30-second timeout.

One suggestion before directly increasing the timeout: if you're able to reproduce the issue locally, try running the test in headed mode with --slowmo enabled. That should make it easier to see whether the page is simply loading slowly or if another issue appears before the timeout.

python -m pytest --cov=crystal_toolkit --cov-report=xml --color=yes --webdriver Chrome --headed --slowmo 3000 crystal_toolkit/apps/examples/tests/test_lobsterenv.py

Hi @minhsueh , I created a fresh new environment and installed the same dependencies as in the current CI workflow.

https://github.com/JaGeo/crystaltoolkit/blob/8ac49a781872cc385981116b479f2baba67d7613/.github/workflows/pull-request.yml#L38-L43

It still seems to pass without any issues. The page seemed to load properly and navigate to the expected dropdown option "LobsterEnv" before running the assertions. No errors I could see.

@naik-aakash

Copy link
Copy Markdown
Contributor

@naik-aakash For the failing test, I haven't been able to reproduce it locally because our environments differ. However, based on the error message:

FAILED crystal_toolkit/apps/examples/tests/test_lobsterenv.py::test_localenv_example_renders_lobsterenv_controls - selenium.common.exceptions.TimeoutException: Message: timeout 30s => waiting for selector [id$='perc_strength_icohp']

My guess is that the LOBSTER analysis is taking longer than expected, causing the page to exceed the 30-second timeout.
One suggestion before directly increasing the timeout: if you're able to reproduce the issue locally, try running the test in headed mode with --slowmo enabled. That should make it easier to see whether the page is simply loading slowly or if another issue appears before the timeout.

python -m pytest --cov=crystal_toolkit --cov-report=xml --color=yes --webdriver Chrome --headed --slowmo 3000 crystal_toolkit/apps/examples/tests/test_lobsterenv.py

Hi @minhsueh , I created a fresh new environment and installed the same dependencies as in the current CI workflow.

https://github.com/JaGeo/crystaltoolkit/blob/8ac49a781872cc385981116b479f2baba67d7613/.github/workflows/pull-request.yml#L38-L43

It still seems to pass without any issues. The page seemed to load properly and navigate to the expected dropdown option "LobsterEnv" before running the assertions. No errors I could see.

Seems now the test passed, not sure if it failed yesterday use to issues of github actions yesterday or now it passed cause of my changes here..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants