eelsnmf-gui 0.0.4__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 (40) hide show
  1. eelsnmf_gui-0.0.4/.gitignore +81 -0
  2. eelsnmf_gui-0.0.4/LICENSE +28 -0
  3. eelsnmf_gui-0.0.4/MANIFEST.in +5 -0
  4. eelsnmf_gui-0.0.4/PKG-INFO +140 -0
  5. eelsnmf_gui-0.0.4/README.md +85 -0
  6. eelsnmf_gui-0.0.4/pyproject.toml +112 -0
  7. eelsnmf_gui-0.0.4/run_gui.py +5 -0
  8. eelsnmf_gui-0.0.4/setup.cfg +4 -0
  9. eelsnmf_gui-0.0.4/src/eelsnmf_gui/__init__.py +38 -0
  10. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_analysis.py +401 -0
  11. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_export.py +179 -0
  12. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_file_dialog.py +148 -0
  13. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_labels.py +29 -0
  14. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_nmf.py +237 -0
  15. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_plotting.py +985 -0
  16. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_preprocess.py +318 -0
  17. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_processing.py +150 -0
  18. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_results.py +139 -0
  19. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_util.py +34 -0
  20. eelsnmf_gui-0.0.4/src/eelsnmf_gui/_widget.py +2929 -0
  21. eelsnmf_gui-0.0.4/src/eelsnmf_gui/cli.py +47 -0
  22. eelsnmf_gui-0.0.4/src/eelsnmf_gui/session.py +762 -0
  23. eelsnmf_gui-0.0.4/src/eelsnmf_gui.egg-info/PKG-INFO +140 -0
  24. eelsnmf_gui-0.0.4/src/eelsnmf_gui.egg-info/SOURCES.txt +38 -0
  25. eelsnmf_gui-0.0.4/src/eelsnmf_gui.egg-info/dependency_links.txt +1 -0
  26. eelsnmf_gui-0.0.4/src/eelsnmf_gui.egg-info/entry_points.txt +2 -0
  27. eelsnmf_gui-0.0.4/src/eelsnmf_gui.egg-info/requires.txt +3 -0
  28. eelsnmf_gui-0.0.4/src/eelsnmf_gui.egg-info/scm_file_list.json +13 -0
  29. eelsnmf_gui-0.0.4/src/eelsnmf_gui.egg-info/scm_version.json +8 -0
  30. eelsnmf_gui-0.0.4/src/eelsnmf_gui.egg-info/top_level.txt +1 -0
  31. eelsnmf_gui-0.0.4/tests/__init__.py +0 -0
  32. eelsnmf_gui-0.0.4/tests/test_analysis.py +259 -0
  33. eelsnmf_gui-0.0.4/tests/test_cli.py +23 -0
  34. eelsnmf_gui-0.0.4/tests/test_export.py +123 -0
  35. eelsnmf_gui-0.0.4/tests/test_labels.py +40 -0
  36. eelsnmf_gui-0.0.4/tests/test_masks.py +97 -0
  37. eelsnmf_gui-0.0.4/tests/test_preprocess.py +70 -0
  38. eelsnmf_gui-0.0.4/tests/test_session.py +551 -0
  39. eelsnmf_gui-0.0.4/tests/test_version.py +7 -0
  40. eelsnmf_gui-0.0.4/tests/test_widget.py +610 -0
@@ -0,0 +1,81 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ env/
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller
28
+ # Usually these files are written by a python script from a template
29
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .coverage
41
+ .coverage.*
42
+ .cache
43
+ nosetests.xml
44
+ coverage.xml
45
+ *,cover
46
+ .hypothesis/
47
+
48
+ # Translations
49
+ *.mo
50
+ *.pot
51
+
52
+ # Django stuff:
53
+ *.log
54
+ local_settings.py
55
+
56
+ # Flask instance folder
57
+ instance/
58
+
59
+ # Sphinx documentation
60
+ docs/_build/
61
+
62
+ # MkDocs documentation
63
+ /site/
64
+
65
+ # PyBuilder
66
+ target/
67
+
68
+ # Pycharm and VSCode
69
+ .idea/
70
+ venv/
71
+ .vscode/
72
+
73
+ # IPython Notebook
74
+ .ipynb_checkpoints
75
+
76
+ # pyenv
77
+ .python-version
78
+
79
+ # OS
80
+ .DS_Store
81
+
@@ -0,0 +1,28 @@
1
+
2
+ Copyright (c) 2026, jules-vanaret
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ * Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ * Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ * Neither the name of copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,5 @@
1
+ include LICENSE
2
+ include README.md
3
+
4
+ recursive-exclude * __pycache__
5
+ recursive-exclude * *.py[co]
@@ -0,0 +1,140 @@
1
+ Metadata-Version: 2.4
2
+ Name: eelsnmf-gui
3
+ Version: 0.0.4
4
+ Summary: GUI for EELS NMF processing
5
+ Author: jules-vanaret
6
+ Author-email: jules.vanaret@epfl.ch
7
+ License:
8
+ Copyright (c) 2026, jules-vanaret
9
+ All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ * Redistributions of source code must retain the above copyright notice, this
15
+ list of conditions and the following disclaimer.
16
+
17
+ * Redistributions in binary form must reproduce the above copyright notice,
18
+ this list of conditions and the following disclaimer in the documentation
19
+ and/or other materials provided with the distribution.
20
+
21
+ * Neither the name of copyright holder nor the names of its
22
+ contributors may be used to endorse or promote products derived from
23
+ this software without specific prior written permission.
24
+
25
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
+
36
+ Classifier: Development Status :: 2 - Pre-Alpha
37
+ Classifier: Intended Audience :: Developers
38
+ Classifier: License :: OSI Approved :: BSD License
39
+ Classifier: Operating System :: OS Independent
40
+ Classifier: Programming Language :: Python
41
+ Classifier: Programming Language :: Python :: 3
42
+ Classifier: Programming Language :: Python :: 3 :: Only
43
+ Classifier: Programming Language :: Python :: 3.10
44
+ Classifier: Programming Language :: Python :: 3.11
45
+ Classifier: Programming Language :: Python :: 3.12
46
+ Classifier: Programming Language :: Python :: 3.13
47
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
48
+ Requires-Python: >=3.10
49
+ Description-Content-Type: text/markdown
50
+ License-File: LICENSE
51
+ Requires-Dist: numpy
52
+ Requires-Dist: qtpy
53
+ Requires-Dist: openpyxl
54
+ Dynamic: license-file
55
+
56
+ # eelsnmf-gui
57
+
58
+ GUI for [EELS NMF](https://github.com/PauTorru/EELSNMF) processing, including a standalone Qt GUI and
59
+ a scriptable processing API for scripts and batch workflows.
60
+
61
+ ## Features
62
+
63
+ - Qt GUI for end-to-end EELS NMF workflows (preprocess, masking, decomposition,
64
+ plotting, exports).
65
+ - `Session` API (`src/eelsnmf_gui/session.py`) exposing the same pipeline
66
+ stages for scripted usage outside the GUI.
67
+ - Stage-wise caching: preprocessing, masks, and fitted decompositions are
68
+ reused and invalidated automatically when their inputs change.
69
+
70
+ ## Design Notes
71
+
72
+ - The pipeline is split into explicit stages: preprocessing (folder loading,
73
+ ZLP alignment, despiking, common energy axis), mask building, model
74
+ building and decomposition, and result analysis (edges, maps, summaries).
75
+ - `eelsnmf_gui.session.Session` owns the folders and parameters, caches each
76
+ stage, and self-invalidates:
77
+ - changing folders or the median filter size invalidates everything;
78
+ - changing mask parameters invalidates masks and decompositions, but
79
+ keeps preprocessing;
80
+ - changing decomposition parameters (beam, edge ranges, number of
81
+ components, max iterations, W init) invalidates decompositions only;
82
+ - colors never affect the decomposition: recoloring only re-renders.
83
+ - The EELSNMF backend is isolated behind a loader and an engine interface, so
84
+ all other stages run on plain numpy arrays and are testable without
85
+ EELSNMF installed.
86
+ - The GUI is a thin wrapper around the `Session`, keeping behavior consistent
87
+ between interactive and scripted runs.
88
+
89
+ ## Installation
90
+
91
+ Install the EELSNMF backend from source:
92
+ ```
93
+ pip install "EELSNMF[EML] @ git+https://github.com/PauTorru/EELSNMF.git"
94
+ ```
95
+
96
+ Then install package from source:
97
+
98
+ ```
99
+ git clone https://github.com/jules-vanaret/eelsnmf-gui
100
+ cd eelsnmf-gui
101
+ pip install -e .
102
+ ```
103
+
104
+ If you want GPU support, make sure to install [cupy](https://docs.cupy.dev/en/stable/install.html) (we recommend using the conda installer or equivalent to minimize dependency issues):
105
+ ```
106
+ conda install -c conda-forge cupy
107
+ ```
108
+
109
+ ## Run the GUI:
110
+
111
+ Using the console entry point:
112
+ ```
113
+ eelsnmfgui
114
+ ```
115
+ By default the GUI assumes the loaded spectrum images are already
116
+ preprocessed (despiked, ZLP-aligned), hides the preprocessing controls, and
117
+ processes folders individually. To show the preprocessing controls (and
118
+ preprocess the data on load) and/or allow joint processing of several
119
+ folders, use:
120
+ ```
121
+ eelsnmfgui --pre --joint
122
+ ```
123
+ or calling the script directly (make sure to run from the package root):
124
+ ```
125
+ python run_gui.py
126
+ ```
127
+
128
+ ## Testing
129
+
130
+ Run the test suite with:
131
+ ```
132
+ python -m pytest
133
+ ```
134
+ Unit, session, and widget tests run without EELSNMF installed; the
135
+ end-to-end tests marked `integration` run when EELSNMF is available and can
136
+ be skipped with `pytest -m "not integration"`.
137
+
138
+ ## License
139
+
140
+ Distributed under the terms of the BSD-3 license.
@@ -0,0 +1,85 @@
1
+ # eelsnmf-gui
2
+
3
+ GUI for [EELS NMF](https://github.com/PauTorru/EELSNMF) processing, including a standalone Qt GUI and
4
+ a scriptable processing API for scripts and batch workflows.
5
+
6
+ ## Features
7
+
8
+ - Qt GUI for end-to-end EELS NMF workflows (preprocess, masking, decomposition,
9
+ plotting, exports).
10
+ - `Session` API (`src/eelsnmf_gui/session.py`) exposing the same pipeline
11
+ stages for scripted usage outside the GUI.
12
+ - Stage-wise caching: preprocessing, masks, and fitted decompositions are
13
+ reused and invalidated automatically when their inputs change.
14
+
15
+ ## Design Notes
16
+
17
+ - The pipeline is split into explicit stages: preprocessing (folder loading,
18
+ ZLP alignment, despiking, common energy axis), mask building, model
19
+ building and decomposition, and result analysis (edges, maps, summaries).
20
+ - `eelsnmf_gui.session.Session` owns the folders and parameters, caches each
21
+ stage, and self-invalidates:
22
+ - changing folders or the median filter size invalidates everything;
23
+ - changing mask parameters invalidates masks and decompositions, but
24
+ keeps preprocessing;
25
+ - changing decomposition parameters (beam, edge ranges, number of
26
+ components, max iterations, W init) invalidates decompositions only;
27
+ - colors never affect the decomposition: recoloring only re-renders.
28
+ - The EELSNMF backend is isolated behind a loader and an engine interface, so
29
+ all other stages run on plain numpy arrays and are testable without
30
+ EELSNMF installed.
31
+ - The GUI is a thin wrapper around the `Session`, keeping behavior consistent
32
+ between interactive and scripted runs.
33
+
34
+ ## Installation
35
+
36
+ Install the EELSNMF backend from source:
37
+ ```
38
+ pip install "EELSNMF[EML] @ git+https://github.com/PauTorru/EELSNMF.git"
39
+ ```
40
+
41
+ Then install package from source:
42
+
43
+ ```
44
+ git clone https://github.com/jules-vanaret/eelsnmf-gui
45
+ cd eelsnmf-gui
46
+ pip install -e .
47
+ ```
48
+
49
+ If you want GPU support, make sure to install [cupy](https://docs.cupy.dev/en/stable/install.html) (we recommend using the conda installer or equivalent to minimize dependency issues):
50
+ ```
51
+ conda install -c conda-forge cupy
52
+ ```
53
+
54
+ ## Run the GUI:
55
+
56
+ Using the console entry point:
57
+ ```
58
+ eelsnmfgui
59
+ ```
60
+ By default the GUI assumes the loaded spectrum images are already
61
+ preprocessed (despiked, ZLP-aligned), hides the preprocessing controls, and
62
+ processes folders individually. To show the preprocessing controls (and
63
+ preprocess the data on load) and/or allow joint processing of several
64
+ folders, use:
65
+ ```
66
+ eelsnmfgui --pre --joint
67
+ ```
68
+ or calling the script directly (make sure to run from the package root):
69
+ ```
70
+ python run_gui.py
71
+ ```
72
+
73
+ ## Testing
74
+
75
+ Run the test suite with:
76
+ ```
77
+ python -m pytest
78
+ ```
79
+ Unit, session, and widget tests run without EELSNMF installed; the
80
+ end-to-end tests marked `integration` run when EELSNMF is available and can
81
+ be skipped with `pytest -m "not integration"`.
82
+
83
+ ## License
84
+
85
+ Distributed under the terms of the BSD-3 license.
@@ -0,0 +1,112 @@
1
+ [project]
2
+ name = "eelsnmf-gui"
3
+ version = "0.0.4"
4
+ description = "GUI for EELS NMF processing"
5
+ readme = "README.md"
6
+ license = {file = "LICENSE"}
7
+ authors = [
8
+ {name = "jules-vanaret"},
9
+ {email = "jules.vanaret@epfl.ch"},
10
+ ]
11
+ classifiers = [
12
+ "Development Status :: 2 - Pre-Alpha",
13
+ "Intended Audience :: Developers",
14
+ "License :: OSI Approved :: BSD License",
15
+ "Operating System :: OS Independent",
16
+ "Programming Language :: Python",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Scientific/Engineering :: Image Processing",
24
+ ]
25
+ requires-python = ">=3.10"
26
+ dependencies = [
27
+ "numpy",
28
+ "qtpy",
29
+ "openpyxl",
30
+ # "EELSNMF[EML] @ git+https://github.com/PauTorru/EELSNMF.git",
31
+ ]
32
+
33
+ [project.scripts]
34
+ eelsnmfgui = "eelsnmf_gui.cli:main"
35
+
36
+ [dependency-groups]
37
+ dev = [
38
+ "tox-uv",
39
+ "pytest", # https://docs.pytest.org/en/latest/contents.html
40
+ "pytest-cov", # https://pytest-cov.readthedocs.io/en/latest/
41
+ "pytest-qt", # https://pytest-qt.readthedocs.io/en/latest/
42
+ ]
43
+
44
+
45
+
46
+ [build-system]
47
+ requires = ["setuptools>=42.0.0"]
48
+ build-backend = "setuptools.build_meta"
49
+
50
+ [tool.setuptools]
51
+ include-package-data = true
52
+
53
+ [tool.setuptools.packages.find]
54
+ where = ["src"]
55
+
56
+ [tool.pytest.ini_options]
57
+ minversion = "6.0"
58
+ addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
59
+ xfail_strict = true
60
+ # filterwarnings = ["error"] # recommended by PP309; deprecation warnings cause failures so leaving for the user to enable if desired
61
+ log_cli_level = "INFO"
62
+ testpaths = ["tests"]
63
+ markers = [
64
+ "integration: end-to-end tests that require the EELSNMF backend (deselect with '-m \"not integration\"')",
65
+ ]
66
+
67
+ [tool.black]
68
+ line-length = 79
69
+ target-version = ['py310', 'py311', 'py312', 'py313']
70
+
71
+ [tool.ruff]
72
+ line-length = 79
73
+ lint.select = [
74
+ "E", "F", "W", #flake8
75
+ "UP", # pyupgrade
76
+ "I", # isort
77
+ "BLE", # flake8-blind-exception
78
+ "B", # flake8-bugbear
79
+ "A", # flake8-builtins
80
+ "C4", # flake8-comprehensions
81
+ "ISC", # flake8-implicit-str-concat
82
+ "G", # flake8-logging-format
83
+ "PIE", # flake8-pie
84
+ "SIM", # flake8-simplify
85
+ ]
86
+ lint.ignore = [
87
+ "E501", # line too long. let black handle this
88
+ "UP006", "UP007", # type annotation. As using magicgui require runtime type annotation then we disable this.
89
+ ]
90
+
91
+ exclude = [
92
+ ".bzr",
93
+ ".direnv",
94
+ ".eggs",
95
+ ".git",
96
+ ".mypy_cache",
97
+ ".pants.d",
98
+ ".ruff_cache",
99
+ ".svn",
100
+ ".tox",
101
+ ".venv",
102
+ "__pypackages__",
103
+ "_build",
104
+ "buck-out",
105
+ "build",
106
+ "dist",
107
+ "node_modules",
108
+ "venv",
109
+ "*vendored*",
110
+ "*_vendor*",
111
+ ]
112
+ fix = true
@@ -0,0 +1,5 @@
1
+ from eelsnmf_gui.cli import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ main()
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,38 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ __version__ = version("eelsnmf-gui")
5
+ except PackageNotFoundError: # running from source without installation
6
+ __version__ = "unknown"
7
+
8
+ from ._results import (
9
+ BeamParams,
10
+ DecoBundle,
11
+ EdgeCollection,
12
+ EdgeSeries,
13
+ ImageCollection,
14
+ MaskParams,
15
+ MaskResult,
16
+ PreprocessedData,
17
+ PreprocessedSI,
18
+ ProcessFoldersResult,
19
+ ProcessingResult,
20
+ )
21
+ from ._widget import EELSProcessingWidget
22
+ from .session import Session
23
+
24
+ __all__ = (
25
+ "EELSProcessingWidget",
26
+ "Session",
27
+ "BeamParams",
28
+ "MaskParams",
29
+ "PreprocessedData",
30
+ "PreprocessedSI",
31
+ "MaskResult",
32
+ "DecoBundle",
33
+ "ProcessingResult",
34
+ "ProcessFoldersResult",
35
+ "EdgeCollection",
36
+ "EdgeSeries",
37
+ "ImageCollection",
38
+ )