baderkit 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. baderkit-0.1.1/LICENSE.txt +29 -0
  2. baderkit-0.1.1/PKG-INFO +36 -0
  3. baderkit-0.1.1/README.md +12 -0
  4. baderkit-0.1.1/pyproject.toml +136 -0
  5. baderkit-0.1.1/setup.cfg +4 -0
  6. baderkit-0.1.1/src/baderkit/__init__.py +25 -0
  7. baderkit-0.1.1/src/baderkit/command_line/__init__.py +1 -0
  8. baderkit-0.1.1/src/baderkit/command_line/base.py +136 -0
  9. baderkit-0.1.1/src/baderkit/command_line/tools.py +125 -0
  10. baderkit-0.1.1/src/baderkit/core/__init__.py +19 -0
  11. baderkit-0.1.1/src/baderkit/core/bader.py +1366 -0
  12. baderkit-0.1.1/src/baderkit/core/grid.py +1799 -0
  13. baderkit-0.1.1/src/baderkit/core/numba_functions.py +1174 -0
  14. baderkit-0.1.1/src/baderkit/core/structure.py +156 -0
  15. baderkit-0.1.1/src/baderkit/plotting/__init__.py +2 -0
  16. baderkit-0.1.1/src/baderkit/plotting/core/__init__.py +3 -0
  17. baderkit-0.1.1/src/baderkit/plotting/core/defaults.py +431 -0
  18. baderkit-0.1.1/src/baderkit/plotting/core/plotter.py +1336 -0
  19. baderkit-0.1.1/src/baderkit/plotting/web_gui/panel/README.md +1 -0
  20. baderkit-0.1.1/src/baderkit/plotting/web_gui/panel/sections/__init__.py +6 -0
  21. baderkit-0.1.1/src/baderkit/plotting/web_gui/panel/sections/atom_tab.py +93 -0
  22. baderkit-0.1.1/src/baderkit/plotting/web_gui/panel/sections/bader_tab.py +68 -0
  23. baderkit-0.1.1/src/baderkit/plotting/web_gui/panel/sections/grid_tab.py +111 -0
  24. baderkit-0.1.1/src/baderkit/plotting/web_gui/panel/sections/view_tab.py +90 -0
  25. baderkit-0.1.1/src/baderkit/plotting/web_gui/panel/webapp.py +120 -0
  26. baderkit-0.1.1/src/baderkit/plotting/web_gui/streamlit/__init__.py +1 -0
  27. baderkit-0.1.1/src/baderkit/plotting/web_gui/streamlit/webapp.py +335 -0
  28. baderkit-0.1.1/src/baderkit/tests/__init__.py +1 -0
  29. baderkit-0.1.1/src/baderkit/tests/test_cli.py +78 -0
  30. baderkit-0.1.1/src/baderkit/tests/test_files/README.md +2 -0
  31. baderkit-0.1.1/src/baderkit/tests/test_main.py +92 -0
  32. baderkit-0.1.1/src/baderkit.egg-info/PKG-INFO +36 -0
  33. baderkit-0.1.1/src/baderkit.egg-info/SOURCES.txt +35 -0
  34. baderkit-0.1.1/src/baderkit.egg-info/dependency_links.txt +1 -0
  35. baderkit-0.1.1/src/baderkit.egg-info/entry_points.txt +2 -0
  36. baderkit-0.1.1/src/baderkit.egg-info/requires.txt +24 -0
  37. baderkit-0.1.1/src/baderkit.egg-info/top_level.txt +1 -0
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2021, Jack D. Sundberg
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,36 @@
1
+ Metadata-Version: 2.4
2
+ Name: baderkit
3
+ Version: 0.1.1
4
+ Author-email: "Sam M. Weaver" <sammweaver@gmail.com>
5
+ License: BSD 3-Clause License
6
+ Project-URL: repository, https://github.com/SWeav02/baderkit
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Science/Research
9
+ Classifier: License :: OSI Approved :: BSD License
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ License-File: LICENSE.txt
14
+ Requires-Dist: numpy>=1.26.0
15
+ Requires-Dist: pandas>=2.1.0
16
+ Requires-Dist: typer>=0.6.1
17
+ Requires-Dist: pymatgen>=2022.1.9
18
+ Requires-Dist: scipy>=1.7.2
19
+ Requires-Dist: numba>=0.59.0
20
+ Requires-Dist: pyvista>=0.44.0
21
+ Requires-Dist: streamlit>=1.40.0
22
+ Requires-Dist: rich>=11.0
23
+ Requires-Dist: trame
24
+ Requires-Dist: trame-vtk
25
+ Requires-Dist: trame-vuetify
26
+ Requires-Dist: nest_asyncio
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest; extra == "dev"
29
+ Requires-Dist: black; extra == "dev"
30
+ Requires-Dist: isort; extra == "dev"
31
+ Requires-Dist: mkdocs; extra == "dev"
32
+ Requires-Dist: mkdocs-material; extra == "dev"
33
+ Requires-Dist: mkdocstrings-python; extra == "dev"
34
+ Provides-Extra: extras
35
+ Requires-Dist: spyder; extra == "extras"
36
+ Dynamic: license-file
@@ -0,0 +1,12 @@
1
+ # BaderKit
2
+
3
+ ## About
4
+
5
+ BaderKit is a python implementation of Bader's Atomic Theory of Atoms in Molecules. It is largely based on the algorithms of [Henkelman et. al.](https://theory.cm.utexas.edu/henkelman/code/bader/) at UT Austin. The app is partially part of my PhD at UNC Chapel Hill in the [Warren Lab](https://materials-lab.io/) with funding from the [NSF's GRFP](https://nsfgrfp.org/), but is largely my own passion project aimed at making my life easier when developing other packages.
6
+
7
+ For information on installation and use, see the [docs](https://sweav02.github.io/baderkit/)
8
+
9
+
10
+ ## Contributing
11
+
12
+ If you are interested in this project and have suggestions, please use this repositories Issues or Discussions tab. Any suggestions or discussion would be deeply appreciated!
@@ -0,0 +1,136 @@
1
+
2
+ # This file establishes the info needed to install baderkit via pip, how to
3
+ # upload it to PyPI, and how to run python packages like pytest and coverage.
4
+
5
+ # For more information on this file and how to make similar ones, see:
6
+ # https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
7
+ # https://github.com/pypa/sampleproject
8
+
9
+ # -----------------------------------------------------------------------------
10
+
11
+ [build-system]
12
+ # These are the assumed default build requirements from pip:
13
+ # https://pip.pypa.io/en/stable/reference/pip/#pep-517-and-518-support
14
+ requires = ["setuptools>=64.0.0", "wheel"]
15
+ build-backend = "setuptools.build_meta"
16
+
17
+ # -----------------------------------------------------------------------------
18
+
19
+ [project]
20
+
21
+ # published name for pip install to use
22
+ name="baderkit"
23
+
24
+ # Versions should comply with PEP 440:
25
+ # https://www.python.org/dev/peps/pep-0440/
26
+ # https://semver.org/
27
+ version="0.1.1"
28
+
29
+ # Maintainer info
30
+ authors = [{name = "Sam M. Weaver", email = "sammweaver@gmail.com"}]
31
+
32
+ # General name for our LICENSE file
33
+ license = {text = "BSD 3-Clause License"}
34
+
35
+ # Classifiers help users find your project by categorizing it.
36
+ # For a list of valid classifiers, see https://pypi.org/classifiers/
37
+ classifiers=[
38
+ "Development Status :: 3 - Alpha",
39
+ "Intended Audience :: Science/Research",
40
+ "License :: OSI Approved :: BSD License",
41
+ "Programming Language :: Python :: 3.11",
42
+ "Operating System :: OS Independent",
43
+ ]
44
+
45
+ # Specify which Python versions are supported.
46
+ requires-python=">=3.10"
47
+
48
+ # This field lists other packages that your project depends on to run.
49
+ dependencies=[
50
+ # Core dependencies
51
+ "numpy>=1.26.0",
52
+ "pandas>=2.1.0",
53
+ "typer>=0.6.1",
54
+ "pymatgen>=2022.1.9",
55
+ "scipy>=1.7.2",
56
+ "numba>=0.59.0",
57
+ "pyvista>=0.44.0", # for plotting grid
58
+ "streamlit>=1.40.0", # for web GUI
59
+ # Extra (smaller) dependencies & utilities
60
+ "rich>=11.0", # for coloring CLI outputs and progress bars
61
+ # For webapp plotter html export. Not used directly in the app.
62
+ "trame",
63
+ "trame-vtk",
64
+ "trame-vuetify",
65
+ "nest_asyncio",
66
+ ]
67
+
68
+ # optional dependencies that are not installed by default
69
+ [project.optional-dependencies]
70
+ # For development and testing. Taken straight from simmate
71
+ DEV = [
72
+ "pytest",
73
+ "black",
74
+ "isort",
75
+ "mkdocs",
76
+ "mkdocs-material",
77
+ "mkdocstrings-python",
78
+ # "mkdocs_autorefs",
79
+ ]
80
+
81
+ EXTRAS = [
82
+ "spyder", # IDE for writing/editting
83
+ ]
84
+
85
+ # Link to our homepage. Use github for now.
86
+ [project.urls]
87
+ repository = "https://github.com/SWeav02/baderkit"
88
+
89
+ # Register command line interface
90
+ [project.scripts]
91
+ baderkit = "baderkit.command_line.base:baderkit_app"
92
+
93
+ # -----------------------------------------------------------------------------
94
+
95
+ # Indicate which directory the source coude is in
96
+ [tool.setuptools.packages.find]
97
+ where = ["src"]
98
+
99
+ # All files that aren't *.py need to be defined explicitly. Don't "automate"
100
+ # this to grab all files because this could break installation. This can
101
+ # be effectively the opposite of .gitignore.
102
+ [tool.setuptools]
103
+ include-package-data = true
104
+
105
+ [tool.setuptools.package-data]
106
+ baderkit = [
107
+ "**/*.md",
108
+ "**/*.rst",
109
+ "**/*.json",
110
+ "**/*.csv",
111
+ "**/*.yaml",
112
+ "**/*.html",
113
+ "**/*.svg",
114
+ "**/*.toml",
115
+ "**/*.css",
116
+ "**/*.js",
117
+ ]
118
+ # Note, the default is to include everything, but I don't want to ship test
119
+ # files. I could switch this to use exclude-package-data in the future.
120
+ # https://setuptools.pypa.io/en/latest/userguide/datafiles.html#exclude-package-data
121
+
122
+ # -----------------------------------------------------------------------------
123
+ # Section for pytests
124
+ # -----------------------------------------------------------------------------
125
+ [tool.pytest.ini_options]
126
+ testpaths = ["tests"]
127
+
128
+ # -----------------------------------------------------------------------------
129
+
130
+ # isort is a tool for organizing imports at the top of python files. By default,
131
+ # it conflicts with the black formatter we use, so we need to configure it here.
132
+
133
+ [tool.isort]
134
+ profile = "black"
135
+
136
+ # -----------------------------------------------------------------------------
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ # high level imports
3
+ import importlib.metadata
4
+ import logging
5
+
6
+ from rich.logging import RichHandler
7
+
8
+ from .core import Bader
9
+
10
+ __version__ = importlib.metadata.version("baderkit")
11
+
12
+ # Configure our logger to output timestamps with logs
13
+ # Also changes the logging level to info
14
+ logging.basicConfig(
15
+ format="%(message)s",
16
+ level=logging.INFO,
17
+ datefmt="%Y-%m-%d %H:%M:%S",
18
+ handlers=[
19
+ RichHandler(
20
+ show_path=False,
21
+ markup=True,
22
+ rich_tracebacks=True,
23
+ )
24
+ ],
25
+ )
@@ -0,0 +1 @@
1
+ # -*- coding: utf-8 -*-
@@ -0,0 +1,136 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ Defines the base 'baderkit' command that all other commands stem from.
5
+ """
6
+
7
+ from enum import Enum
8
+ from pathlib import Path
9
+
10
+ import typer
11
+ from typing_extensions import Annotated
12
+
13
+ from baderkit.command_line.tools import tools_app
14
+
15
+ baderkit_app = typer.Typer(rich_markup_mode="markdown")
16
+
17
+
18
+ @baderkit_app.callback(no_args_is_help=True)
19
+ def base_command():
20
+ """
21
+ This is the base command that all baderkit commands stem from
22
+ """
23
+ pass
24
+
25
+
26
+ @baderkit_app.command()
27
+ def version():
28
+ """
29
+ Prints the version of baderkit that is installed
30
+ """
31
+ import baderkit
32
+
33
+ print(f"Installed version: v{baderkit.__version__}")
34
+
35
+
36
+ class Method(str, Enum):
37
+ weight = "weight"
38
+ hybrid_weight = "hybrid-weight"
39
+ ongrid = "ongrid"
40
+ neargrid = "neargrid"
41
+
42
+
43
+ class Format(str, Enum):
44
+ vasp = "vasp"
45
+ cube = "cube"
46
+
47
+
48
+ class PrintOptions(str, Enum):
49
+ all_atoms = "all_atoms"
50
+ sel_atoms = "sel_atoms"
51
+ sum_atoms = "sum_atoms"
52
+ all_basins = "all_basins"
53
+ sel_basins = "sel_basins"
54
+ sum_basins = "sum_basins"
55
+
56
+
57
+ @baderkit_app.command()
58
+ def run(
59
+ charge_file: Path = typer.Argument(
60
+ default=...,
61
+ help="The path to the charge density file",
62
+ ),
63
+ reference_file: Path = typer.Option(
64
+ None,
65
+ "--reference_file",
66
+ "-ref",
67
+ help="The path to the reference file",
68
+ ),
69
+ method: Method = typer.Option(
70
+ Method.weight,
71
+ "--method",
72
+ "-m",
73
+ help="The method to use for separating bader basins",
74
+ case_sensitive=False,
75
+ ),
76
+ format: Format = typer.Option(
77
+ None,
78
+ "--format",
79
+ "-f",
80
+ help="The format of the files",
81
+ case_sensitive=False,
82
+ ),
83
+ print: PrintOptions = typer.Option(
84
+ None,
85
+ "--print",
86
+ "-p",
87
+ help="Optional printing of atom or bader basins",
88
+ case_sensitive=False,
89
+ ),
90
+ indices=typer.Argument(
91
+ default=[],
92
+ help="The indices used for print method. Can be added at the end of the call. For example: `baderkit run CHGCAR -p sel_basins 0 1 2`",
93
+ ),
94
+ # indices: Annotated[
95
+ # list[int],
96
+ # typer.Argument(
97
+ # help="The indices used for print method. Can be added at the end of the call. For example: `baderkit run CHGCAR -p sel_basins 0 1 2`"
98
+ # ),
99
+ # ] = None,
100
+ ):
101
+ """
102
+ Runs a bader analysis on the provided files. File formats are automatically
103
+ parsed based on the name. Current accepted files include VASP's CHGCAR/ELFCAR
104
+ or .cube files.
105
+ """
106
+ from baderkit.core import Bader
107
+
108
+ # instance bader
109
+ bader = Bader.from_dynamic(
110
+ charge_filename=charge_file,
111
+ reference_filename=reference_file,
112
+ method=method,
113
+ format=format,
114
+ )
115
+ # write summary
116
+ bader.write_results_summary()
117
+
118
+ # write basins
119
+ if indices is None:
120
+ indices = []
121
+ if print == "all_atoms":
122
+ bader.write_all_atom_volumes()
123
+ elif print == "all_basins":
124
+ bader.write_all_basin_volumes()
125
+ elif print == "sel_atoms":
126
+ bader.write_atom_volumes(atom_indices=indices)
127
+ elif print == "sel_basins":
128
+ bader.write_basin_volumes(basin_indices=indices)
129
+ elif print == "sum_atoms":
130
+ bader.write_atom_volumes_sum(atom_indices=indices)
131
+ elif print == "sum_basins":
132
+ bader.write_basin_volumes_sum(basin_indices=indices)
133
+
134
+
135
+ # Register other commands
136
+ baderkit_app.add_typer(tools_app, name="tools")
@@ -0,0 +1,125 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import logging
4
+ import os
5
+ import subprocess
6
+ from enum import Enum
7
+ from pathlib import Path
8
+
9
+ import typer
10
+
11
+ tools_app = typer.Typer(rich_markup_mode="markdown")
12
+
13
+
14
+ @tools_app.callback(no_args_is_help=True)
15
+ def base_command():
16
+ """
17
+ A collection of tools for assisting in bader analysis
18
+ """
19
+ pass
20
+
21
+
22
+ @tools_app.command()
23
+ def sum(
24
+ file1: Path = typer.Argument(
25
+ ...,
26
+ help="The path to the first file to sum",
27
+ ),
28
+ file2: Path = typer.Argument(
29
+ ...,
30
+ help="The path to the second file to sum",
31
+ ),
32
+ ):
33
+ """
34
+ A helper function for summing two grids. Note that the output is currently
35
+ always a VASP file.
36
+ """
37
+ from baderkit.core import Grid
38
+
39
+ # make sure files are paths
40
+ file1 = Path(file1)
41
+ file2 = Path(file2)
42
+ logging.info(f"Summing files {file1.name} and {file2.name}")
43
+
44
+ grid1 = Grid.from_dynamic(file1)
45
+ grid2 = Grid.from_dynamic(file2)
46
+ # sum grids
47
+ summed_grid = Grid.sum_grids(grid1, grid2)
48
+ # get name to use
49
+ if "elf" in file1.name.lower():
50
+ file_pre = "ELFCAR"
51
+ else:
52
+ file_pre = "CHGCAR"
53
+ summed_grid.write_file(f"{file_pre}_sum")
54
+
55
+
56
+ class Method(str, Enum):
57
+ weight = "weight"
58
+ hybrid_weight = "hybrid-weight"
59
+ ongrid = "ongrid"
60
+ neargrid = "neargrid"
61
+
62
+
63
+ @tools_app.command()
64
+ def webapp(
65
+ charge_file: Path = typer.Argument(
66
+ ...,
67
+ help="The path to the charge density file",
68
+ ),
69
+ reference_file: Path = typer.Option(
70
+ None,
71
+ "--reference_file",
72
+ "-ref",
73
+ help="The path to the reference file",
74
+ ),
75
+ method: Method = typer.Option(
76
+ "weight",
77
+ "--method",
78
+ "-m",
79
+ help="The method to use for separating bader basins",
80
+ case_sensitive=False,
81
+ ),
82
+ # dev: bool = typer.Option(
83
+ # False,
84
+ # "--dev",
85
+ # "-d",
86
+ # help="Launches panel in development version",
87
+ # )
88
+ ):
89
+ """
90
+ Starts the web interface
91
+ """
92
+ # get this files path
93
+ current_file = Path(__file__).resolve()
94
+ # get relative path to streamlit app
95
+ webapp_path = (
96
+ current_file.parent.parent / "plotting" / "web_gui" / "streamlit" / "webapp.py"
97
+ )
98
+ # set environmental variables
99
+ os.environ["CHARGE_FILE"] = str(charge_file)
100
+ os.environ["BADER_METHOD"] = method
101
+
102
+ if reference_file is not None:
103
+ os.environ["REFERENCE_FILE"] = str(reference_file)
104
+
105
+ args = [
106
+ "streamlit",
107
+ "run",
108
+ str(webapp_path),
109
+ ]
110
+
111
+ process = subprocess.Popen(
112
+ args=args,
113
+ stdin=subprocess.PIPE,
114
+ stdout=subprocess.PIPE,
115
+ stderr=subprocess.STDOUT,
116
+ text=True,
117
+ bufsize=1,
118
+ )
119
+ # Look for prompt and send blank input if needed
120
+ for line in process.stdout:
121
+ print(line, end="") # Optional: show Streamlit output
122
+ if "email" in line:
123
+ process.stdin.write("\n")
124
+ process.stdin.flush()
125
+ break # After this, Streamlit should proceed normally
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from .bader import Bader
4
+ from .grid import Grid
5
+ from .numba_functions import ( # get_hybrid_basin_weights,
6
+ get_basin_charge_volume_from_label,
7
+ get_edges,
8
+ get_maxima,
9
+ get_multi_weight_voxels,
10
+ get_near_grid_assignments,
11
+ get_neighbor_diffs,
12
+ get_neighbor_flux,
13
+ get_single_weight_voxels,
14
+ get_steepest_pointers,
15
+ propagate_edges,
16
+ refine_near_grid_edges,
17
+ unmark_isolated_voxels,
18
+ )
19
+ from .structure import Structure