|
| 1 | +from pathlib import Path |
| 2 | + |
| 3 | +from tempfile import TemporaryDirectory |
| 4 | + |
1 | 5 | from base64 import b64encode
|
2 | 6 |
|
3 | 7 | import json
|
|
7 | 11 | import warnings
|
8 | 12 | from collections import OrderedDict
|
9 | 13 | from itertools import chain, combinations_with_replacement
|
| 14 | +from pymatgen.io.vasp.sets import MPRelaxSet |
10 | 15 | from typing import Dict, Optional, Tuple, Union
|
11 | 16 |
|
12 | 17 | import dash
|
@@ -79,6 +84,7 @@ class StructureMoleculeComponent(MPComponent):
|
79 | 84 | "POSCAR": {"fmt": "poscar"},
|
80 | 85 | "JSON": {"fmt": "json"},
|
81 | 86 | "Prismatic": {"fmt": "prismatic"},
|
| 87 | + "VASP Input Set (MPRelaxSet)": {}, # special |
82 | 88 | }
|
83 | 89 | }
|
84 | 90 |
|
@@ -466,26 +472,53 @@ def download_structure(n_clicks, download_option, data):
|
466 | 472 | if isinstance(structure, StructureGraph):
|
467 | 473 | structure = structure.structure
|
468 | 474 |
|
| 475 | + file_prefix = structure.composition.reduced_formula |
| 476 | + |
469 | 477 | download_option = download_option[0]
|
470 |
| - extension = self.download_options["Structure"][download_option][ |
471 |
| - "download_options" |
472 |
| - ] |
473 |
| - options = self.download_options["Structure"][download_option] |
474 | 478 |
|
475 |
| - try: |
476 |
| - contents = structure.to(**options) |
477 |
| - except Exception as exc: |
478 |
| - # don't fail silently, tell user what went wrong |
479 |
| - contents = exc |
| 479 | + if "VASP" not in download_option: |
480 | 480 |
|
481 |
| - base64 = b64encode(contents.encode("utf-8")).decode("ascii") |
| 481 | + extension = self.download_options["Structure"][download_option][ |
| 482 | + "download_options" |
| 483 | + ] |
| 484 | + options = self.download_options["Structure"][download_option] |
482 | 485 |
|
483 |
| - return { |
484 |
| - "content": base64, |
485 |
| - "base64": True, |
486 |
| - "type": "text/plain", |
487 |
| - "filename": f"{structure.composition.reduced_formula}.{extension}", |
488 |
| - } |
| 486 | + try: |
| 487 | + contents = structure.to(**options) |
| 488 | + except Exception as exc: |
| 489 | + # don't fail silently, tell user what went wrong |
| 490 | + contents = exc |
| 491 | + |
| 492 | + base64 = b64encode(contents.encode("utf-8")).decode("ascii") |
| 493 | + |
| 494 | + download_data = { |
| 495 | + "content": base64, |
| 496 | + "base64": True, |
| 497 | + "type": "text/plain", |
| 498 | + "filename": f"{file_prefix}.{extension}", |
| 499 | + } |
| 500 | + |
| 501 | + else: |
| 502 | + |
| 503 | + if "Relax" in download_option: |
| 504 | + vis = MPRelaxSet(structure) |
| 505 | + expected_filename = "MPRelaxSet.zip" |
| 506 | + else: |
| 507 | + raise ValueError("No other VASP input sets currently supported.") |
| 508 | + |
| 509 | + with TemporaryDirectory() as tmpdir: |
| 510 | + vis.write_input(tmpdir, potcar_spec=True, zip_output=True) |
| 511 | + path = Path(tmpdir) / expected_filename |
| 512 | + bytes = b64encode(path.read_bytes()).decode("ascii") |
| 513 | + |
| 514 | + download_data = { |
| 515 | + "content": bytes, |
| 516 | + "base64": True, |
| 517 | + "type": "application/zip", |
| 518 | + "filename": f"{file_prefix} {expected_filename}", |
| 519 | + } |
| 520 | + |
| 521 | + return download_data |
489 | 522 |
|
490 | 523 | @app.callback(
|
491 | 524 | Output(self.id("title_container"), "children"),
|
|
0 commit comments