batplot 1.8.40__tar.gz → 1.8.42__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.
- batplot-1.8.42/MANIFEST.in +3 -0
- {batplot-1.8.40/batplot.egg-info → batplot-1.8.42}/PKG-INFO +10 -8
- {batplot-1.8.40 → batplot-1.8.42}/README.md +6 -7
- batplot-1.8.42/batplot/__init__.py +74 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/args.py +100 -85
- batplot-1.8.42/batplot/batplot.py +642 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/canvas_interactive.py +7 -7
- {batplot-1.8.40 → batplot-1.8.42}/batplot/color_utils.py +72 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/data/CHANGELOG.md +13 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/dev_upgrade.py +350 -103
- batplot-1.8.42/batplot/ec_common.py +106 -0
- batplot-1.8.42/batplot/modes.py +37 -0
- batplot-1.8.42/batplot/plot_modes/__init__.py +1 -0
- batplot-1.8.42/batplot/plot_modes/common/__init__.py +1 -0
- batplot-1.8.42/batplot/plot_modes/common/axis_state.py +128 -0
- batplot-1.8.42/batplot/plot_modes/common/files.py +42 -0
- batplot-1.8.42/batplot/plot_modes/common/fonts.py +132 -0
- batplot-1.8.42/batplot/plot_modes/common/interactive_state.py +99 -0
- batplot-1.8.42/batplot/plot_modes/common/menu_rendering.py +84 -0
- batplot-1.8.42/batplot/plot_modes/common/menus.py +437 -0
- batplot-1.8.42/batplot/plot_modes/common/palettes.py +215 -0
- batplot-1.8.42/batplot/plot_modes/common/smoothing.py +38 -0
- batplot-1.8.42/batplot/plot_modes/common/sources.py +68 -0
- batplot-1.8.42/batplot/plot_modes/common/spines.py +758 -0
- batplot-1.8.42/batplot/plot_modes/common/terminal.py +128 -0
- batplot-1.8.42/batplot/plot_modes/common/title_offsets.py +65 -0
- batplot-1.8.42/batplot/plot_modes/cpc/__init__.py +5 -0
- batplot-1.8.42/batplot/plot_modes/cpc/actions.py +963 -0
- batplot-1.8.42/batplot/plot_modes/cpc/colors.py +363 -0
- batplot-1.8.42/batplot/plot_modes/cpc/interactive.py +2822 -0
- batplot-1.8.42/batplot/plot_modes/cpc/labels.py +257 -0
- batplot-1.8.42/batplot/plot_modes/cpc/legend.py +480 -0
- batplot-1.8.42/batplot/plot_modes/cpc/menu.py +74 -0
- batplot-1.8.42/batplot/plot_modes/cpc/routing.py +516 -0
- batplot-1.8.42/batplot/plot_modes/cpc/session.py +15 -0
- batplot-1.8.42/batplot/plot_modes/cpc/snapshots.py +119 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/__init__.py +5 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/actions.py +1256 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/colors.py +722 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/dqdv_2d.py +692 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/export.py +65 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/interactive.py +3242 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/labels.py +224 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/legend.py +269 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/legend_order.py +56 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/line_style.py +269 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/menu.py +111 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/routing.py +1540 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/session.py +15 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/spine_colors.py +108 -0
- batplot-1.8.42/batplot/plot_modes/electrochem/style.py +655 -0
- batplot-1.8.42/batplot/plot_modes/operando/__init__.py +5 -0
- batplot-1.8.42/batplot/plot_modes/operando/actions.py +1571 -0
- batplot-1.8.42/batplot/plot_modes/operando/colors.py +174 -0
- batplot-1.8.42/batplot/plot_modes/operando/grid.py +127 -0
- batplot-1.8.42/batplot/plot_modes/operando/interactive.py +3761 -0
- batplot-1.8.42/batplot/plot_modes/operando/ions_axis.py +141 -0
- batplot-1.8.42/batplot/plot_modes/operando/labels.py +173 -0
- batplot-1.8.42/batplot/plot_modes/operando/layout.py +409 -0
- batplot-1.8.42/batplot/plot_modes/operando/line_style.py +103 -0
- batplot-1.8.42/batplot/plot_modes/operando/menu.py +114 -0
- batplot-1.8.42/batplot/plot_modes/operando/peaks.py +289 -0
- batplot-1.8.40/batplot/operando.py → batplot-1.8.42/batplot/plot_modes/operando/plot.py +14 -8
- batplot-1.8.42/batplot/plot_modes/operando/routing.py +148 -0
- batplot-1.8.42/batplot/plot_modes/operando/session.py +15 -0
- batplot-1.8.42/batplot/plot_modes/operando/style.py +389 -0
- batplot-1.8.42/batplot/plot_modes/operando/visibility.py +285 -0
- batplot-1.8.42/batplot/plot_modes/session_routing.py +1072 -0
- batplot-1.8.42/batplot/plot_modes/xy/__init__.py +5 -0
- batplot-1.8.42/batplot/plot_modes/xy/actions.py +483 -0
- batplot-1.8.42/batplot/plot_modes/xy/arrange.py +131 -0
- batplot-1.8.42/batplot/plot_modes/xy/axis_range.py +624 -0
- batplot-1.8.42/batplot/plot_modes/xy/cif.py +466 -0
- batplot-1.8.42/batplot/plot_modes/xy/colors.py +315 -0
- batplot-1.8.42/batplot/plot_modes/xy/data_ops.py +114 -0
- batplot-1.8.42/batplot/plot_modes/xy/derivative.py +128 -0
- batplot-1.8.42/batplot/plot_modes/xy/game.py +125 -0
- batplot-1.8.42/batplot/plot_modes/xy/interactive.py +2481 -0
- batplot-1.8.42/batplot/plot_modes/xy/labels.py +160 -0
- batplot-1.8.42/batplot/plot_modes/xy/line_style.py +257 -0
- batplot-1.8.42/batplot/plot_modes/xy/menu.py +49 -0
- batplot-1.8.42/batplot/plot_modes/xy/peaks.py +174 -0
- batplot-1.8.42/batplot/plot_modes/xy/pipeline.py +1470 -0
- batplot-1.8.42/batplot/plot_modes/xy/session.py +15 -0
- batplot-1.8.42/batplot/plot_modes/xy/smoothing.py +716 -0
- {batplot-1.8.40/batplot → batplot-1.8.42/batplot/plot_modes/xy}/style.py +189 -194
- {batplot-1.8.40 → batplot-1.8.42}/batplot/plotting.py +32 -1
- {batplot-1.8.40 → batplot-1.8.42}/batplot/readers.py +48 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/session.py +584 -255
- {batplot-1.8.40 → batplot-1.8.42}/batplot/showcol.py +8 -7
- batplot-1.8.42/batplot/style.py +19 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/ui.py +0 -2
- {batplot-1.8.40 → batplot-1.8.42/batplot.egg-info}/PKG-INFO +10 -8
- batplot-1.8.42/batplot.egg-info/SOURCES.txt +122 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot.egg-info/entry_points.txt +0 -1
- {batplot-1.8.40 → batplot-1.8.42}/batplot.egg-info/requires.txt +4 -0
- batplot-1.8.42/batplot.egg-info/top_level.txt +1 -0
- {batplot-1.8.40 → batplot-1.8.42}/pyproject.toml +24 -2
- batplot-1.8.42/tests/test_cli_smoke.py +183 -0
- batplot-1.8.42/tests/test_color_utils.py +31 -0
- batplot-1.8.42/tests/test_common_files.py +60 -0
- batplot-1.8.42/tests/test_common_palettes.py +209 -0
- batplot-1.8.42/tests/test_contracts.py +399 -0
- batplot-1.8.42/tests/test_cpc_roundtrip.py +458 -0
- batplot-1.8.42/tests/test_csv_readers.py +38 -0
- batplot-1.8.42/tests/test_dev_upgrade.py +163 -0
- batplot-1.8.42/tests/test_ec_roundtrip.py +553 -0
- batplot-1.8.42/tests/test_interactive_menu_smoke.py +236 -0
- batplot-1.8.42/tests/test_interactive_state.py +822 -0
- batplot-1.8.42/tests/test_operando_roundtrip.py +696 -0
- batplot-1.8.42/tests/test_xy_modules.py +396 -0
- batplot-1.8.42/tests/test_xy_roundtrip.py +267 -0
- batplot-1.8.40/MANIFEST.in +0 -2
- batplot-1.8.40/batplot/__init__.py +0 -5
- batplot-1.8.40/batplot/batplot.py +0 -5107
- batplot-1.8.40/batplot/cpc_interactive.py +0 -5750
- batplot-1.8.40/batplot/data/USER_MANUAL.md +0 -624
- batplot-1.8.40/batplot/electrochem_interactive.py +0 -7601
- batplot-1.8.40/batplot/interactive.py +0 -6342
- batplot-1.8.40/batplot/manual.py +0 -342
- batplot-1.8.40/batplot/modes.py +0 -862
- batplot-1.8.40/batplot/operando_ec_interactive.py +0 -7497
- batplot-1.8.40/batplot.egg-info/SOURCES.txt +0 -40
- batplot-1.8.40/batplot.egg-info/top_level.txt +0 -2
- {batplot-1.8.40 → batplot-1.8.42}/LICENSE +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/NOTICE +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/batch.py +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/cif.py +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/cli.py +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/config.py +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/converters.py +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/utils.py +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot/version_check.py +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/batplot.egg-info/dependency_links.txt +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/setup.cfg +0 -0
- {batplot-1.8.40 → batplot-1.8.42}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: batplot
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.42
|
|
4
4
|
Summary: Interactive plotting tool for material science (1D plot) and electrochemistry (GC, CV, dQ/dV, CPC, operando) with batch processing
|
|
5
5
|
Author-email: Tian Dai <tianda@uio.no>
|
|
6
6
|
License: MIT License
|
|
@@ -47,6 +47,9 @@ Requires-Dist: numpy>=1.21.0
|
|
|
47
47
|
Requires-Dist: matplotlib>=3.5.0
|
|
48
48
|
Requires-Dist: rich>=10.0.0
|
|
49
49
|
Requires-Dist: openpyxl>=3.0.0
|
|
50
|
+
Provides-Extra: test
|
|
51
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
52
|
+
Requires-Dist: basedpyright>=1.28.0; extra == "test"
|
|
50
53
|
Dynamic: license-file
|
|
51
54
|
|
|
52
55
|
# batplot
|
|
@@ -213,7 +216,6 @@ batplot battery.mpt --gc --mass 7.0 --i
|
|
|
213
216
|
|
|
214
217
|
```bash
|
|
215
218
|
batplot cyclic.mpt --cv --i
|
|
216
|
-
batplot cyclic.mpt --cv --i
|
|
217
219
|
```
|
|
218
220
|
|
|
219
221
|
### Differential capacity (dQ/dV)
|
|
@@ -356,12 +358,12 @@ With `--interactive`:
|
|
|
356
358
|
## Help & Documentation
|
|
357
359
|
|
|
358
360
|
```bash
|
|
359
|
-
batplot --
|
|
360
|
-
batplot --
|
|
361
|
-
batplot --
|
|
362
|
-
batplot --
|
|
363
|
-
batplot --
|
|
364
|
-
batplot --
|
|
361
|
+
batplot --h # General help
|
|
362
|
+
batplot --h xy # XY mode guide
|
|
363
|
+
batplot --h ec # Electrochemistry guide
|
|
364
|
+
batplot --h op # Operando guide
|
|
365
|
+
batplot --v # Version and release notes
|
|
366
|
+
batplot --m # Open illustrated manual
|
|
365
367
|
```
|
|
366
368
|
|
|
367
369
|
- [USER_MANUAL.md](USER_MANUAL.md) — Detailed usage and workflows
|
|
@@ -162,7 +162,6 @@ batplot battery.mpt --gc --mass 7.0 --i
|
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
164
|
batplot cyclic.mpt --cv --i
|
|
165
|
-
batplot cyclic.mpt --cv --i
|
|
166
165
|
```
|
|
167
166
|
|
|
168
167
|
### Differential capacity (dQ/dV)
|
|
@@ -305,12 +304,12 @@ With `--interactive`:
|
|
|
305
304
|
## Help & Documentation
|
|
306
305
|
|
|
307
306
|
```bash
|
|
308
|
-
batplot --
|
|
309
|
-
batplot --
|
|
310
|
-
batplot --
|
|
311
|
-
batplot --
|
|
312
|
-
batplot --
|
|
313
|
-
batplot --
|
|
307
|
+
batplot --h # General help
|
|
308
|
+
batplot --h xy # XY mode guide
|
|
309
|
+
batplot --h ec # Electrochemistry guide
|
|
310
|
+
batplot --h op # Operando guide
|
|
311
|
+
batplot --v # Version and release notes
|
|
312
|
+
batplot --m # Open illustrated manual
|
|
314
313
|
```
|
|
315
314
|
|
|
316
315
|
- [USER_MANUAL.md](USER_MANUAL.md) — Detailed usage and workflows
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""batplot: Interactive plotting for battery data visualization."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import importlib
|
|
6
|
+
import importlib.abc
|
|
7
|
+
import importlib.machinery
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
__version__ = "1.8.42"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
_LEGACY_MODULE_ALIASES = {
|
|
14
|
+
"batplot.interactive": "batplot.plot_modes.xy.interactive",
|
|
15
|
+
"batplot.electrochem_interactive": "batplot.plot_modes.electrochem.interactive",
|
|
16
|
+
"batplot.cpc_interactive": "batplot.plot_modes.cpc.interactive",
|
|
17
|
+
"batplot.cpc_menu": "batplot.plot_modes.cpc.menu",
|
|
18
|
+
"batplot.operando_ec_interactive": "batplot.plot_modes.operando.interactive",
|
|
19
|
+
"batplot.operando_layout": "batplot.plot_modes.operando.layout",
|
|
20
|
+
"batplot.operando_menu": "batplot.plot_modes.operando.menu",
|
|
21
|
+
"batplot.operando_style": "batplot.plot_modes.operando.style",
|
|
22
|
+
"batplot.interactive_state": "batplot.plot_modes.common.interactive_state",
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class _LegacyModuleAliasLoader(importlib.abc.Loader):
|
|
27
|
+
"""Lazy compatibility loader for mode modules moved under ``plot_modes``."""
|
|
28
|
+
|
|
29
|
+
def __init__(self, fullname: str, target_name: str):
|
|
30
|
+
self.fullname = fullname
|
|
31
|
+
self.target_name = target_name
|
|
32
|
+
|
|
33
|
+
def create_module(self, spec):
|
|
34
|
+
module = importlib.import_module(self.target_name)
|
|
35
|
+
self._apply_extra_exports(module)
|
|
36
|
+
sys.modules[self.fullname] = module
|
|
37
|
+
parent_name, _, child_name = self.fullname.rpartition(".")
|
|
38
|
+
parent = sys.modules.get(parent_name)
|
|
39
|
+
if parent is not None:
|
|
40
|
+
setattr(parent, child_name, module)
|
|
41
|
+
return module
|
|
42
|
+
|
|
43
|
+
def exec_module(self, module) -> None:
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
def _apply_extra_exports(self, module) -> None:
|
|
47
|
+
if self.fullname == "batplot.cpc_interactive":
|
|
48
|
+
menu = importlib.import_module("batplot.plot_modes.cpc.menu")
|
|
49
|
+
module.print_cpc_menu = menu.print_cpc_menu
|
|
50
|
+
module.build_cpc_menu_columns = menu.build_cpc_menu_columns
|
|
51
|
+
elif self.fullname == "batplot.operando_ec_interactive":
|
|
52
|
+
style = importlib.import_module("batplot.plot_modes.operando.style")
|
|
53
|
+
module.build_operando_ec_style_config_v2 = style.build_operando_ec_style_config_v2
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class _LegacyModuleAliasFinder(importlib.abc.MetaPathFinder):
|
|
57
|
+
def find_spec(self, fullname, path=None, target=None):
|
|
58
|
+
target_name = _LEGACY_MODULE_ALIASES.get(fullname)
|
|
59
|
+
if target_name is None:
|
|
60
|
+
return None
|
|
61
|
+
loader = _LegacyModuleAliasLoader(fullname, target_name)
|
|
62
|
+
spec = importlib.machinery.ModuleSpec(fullname, loader)
|
|
63
|
+
spec.origin = f"legacy-alias:{target_name}"
|
|
64
|
+
return spec
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _install_legacy_alias_finder() -> None:
|
|
68
|
+
if not any(isinstance(finder, _LegacyModuleAliasFinder) for finder in sys.meta_path):
|
|
69
|
+
sys.meta_path.insert(0, _LegacyModuleAliasFinder())
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
_install_legacy_alias_finder()
|
|
73
|
+
|
|
74
|
+
__all__ = ["__version__"]
|
|
@@ -24,6 +24,7 @@ from __future__ import annotations
|
|
|
24
24
|
import argparse
|
|
25
25
|
import sys
|
|
26
26
|
import re
|
|
27
|
+
import webbrowser
|
|
27
28
|
|
|
28
29
|
# ====================================================================
|
|
29
30
|
# HELP OUTPUT
|
|
@@ -169,13 +170,13 @@ def _print_general_help() -> None:
|
|
|
169
170
|
" • More: --help xy / --help ec / --help op\n\n"
|
|
170
171
|
|
|
171
172
|
"More help:\n"
|
|
172
|
-
" batplot --
|
|
173
|
+
" batplot --v # Version and release info (with option to show full release notes)\n"
|
|
173
174
|
" batplot --showcol FILE [FILE...] # Preview column names + first 10 values per column\n"
|
|
174
|
-
" batplot --
|
|
175
|
-
" batplot --
|
|
176
|
-
" batplot --
|
|
177
|
-
" batplot --
|
|
178
|
-
" batplot --
|
|
175
|
+
" batplot --h # This help\n"
|
|
176
|
+
" batplot --h xy # XY file plotting guide\n"
|
|
177
|
+
" batplot --h ec # Electrochemistry (GC/dQdV/CV/CPC) guide\n"
|
|
178
|
+
" batplot --h op # Operando contour guide (also: batplot --help contour)\n"
|
|
179
|
+
" batplot --m # Open the illustrated PDF manual\n\n"
|
|
179
180
|
|
|
180
181
|
"Contact & Updates:\n"
|
|
181
182
|
" Subscribe to batplot-lab@kjemi.uio.no for updates\n"
|
|
@@ -246,10 +247,14 @@ def _print_xy_help() -> None:
|
|
|
246
247
|
" - file:wl : single wavelength (for Q conversion or CIF 2theta calculation)\n"
|
|
247
248
|
" - file:wl1:wl2 : dual wavelength (convert 2theta→Q using wl1, then Q→2theta using wl2)\n"
|
|
248
249
|
" - file.cif:wl : CIF file with wavelength for 2theta tick calculation\n"
|
|
250
|
+
" - file:q : mark file as already in Q (no conversion; implies Q axis)\n"
|
|
251
|
+
" Any file:wl or file:q suffix implies Q mode automatically (no --xaxis q needed);\n"
|
|
252
|
+
" files without wavelength info are then assumed to be already in Q.\n"
|
|
249
253
|
" Examples:\n"
|
|
250
254
|
" batplot data.xye:1.5406 --xaxis 2theta\n"
|
|
251
255
|
" batplot data.xye:0.25:1.54 --xaxis 2theta\n"
|
|
252
256
|
" batplot data.xye pattern.cif:0.25448 --xaxis 2theta\n"
|
|
257
|
+
" batplot scan.xy:0.709 sim.csv:q --stack --i\n"
|
|
253
258
|
" --readcol <x_col> <y_col> : specify which columns to read as x and y (1-indexed)\n"
|
|
254
259
|
" Per-file: file1.xy --readcol 2 3 file2.xy --readcol 4 5 (different cols per file)\n"
|
|
255
260
|
" Multi-curve: file.xy --readcol 1 2 1 3 (plot cols 1,2 and 1,3 as two curves)\n"
|
|
@@ -375,58 +380,10 @@ def _print_op_help() -> None:
|
|
|
375
380
|
_print_help(msg)
|
|
376
381
|
|
|
377
382
|
|
|
378
|
-
def
|
|
379
|
-
"""
|
|
380
|
-
Build the argument parser for batplot command-line interface.
|
|
381
|
-
|
|
382
|
-
HOW ARGUMENT PARSING WORKS:
|
|
383
|
-
--------------------------
|
|
384
|
-
This function creates an ArgumentParser object that defines all valid
|
|
385
|
-
command-line arguments for batplot. When you run 'batplot file.xy --i',
|
|
386
|
-
argparse uses this parser to:
|
|
387
|
-
1. Recognize which arguments are valid
|
|
388
|
-
2. Extract values from the command line
|
|
389
|
-
3. Convert them to appropriate Python types (int, float, bool, etc.)
|
|
390
|
-
4. Store them in a namespace object (args.files, args.interactive, etc.)
|
|
391
|
-
|
|
392
|
-
ARGUMENT TYPES:
|
|
393
|
-
--------------
|
|
394
|
-
- Positional arguments: 'files' - list of file paths (can be 0 or more)
|
|
395
|
-
- Flags (boolean): '--i' - True if present, False if absent
|
|
396
|
-
- Options with values: '--mass 7.0' or '--mass 0.01g' - mass in mg, or grams with a ``g`` suffix
|
|
397
|
-
- Optional arguments: '--help xy' - can have optional value
|
|
398
|
-
|
|
399
|
-
WHY add_help=False?
|
|
400
|
-
-------------------
|
|
401
|
-
We use a custom help system that supports topic-specific help:
|
|
402
|
-
- 'batplot --help' → general help
|
|
403
|
-
- 'batplot --help xy' → XY mode help
|
|
404
|
-
- 'batplot --help ec' → EC mode help
|
|
405
|
-
- 'batplot --help op' → Operando mode help
|
|
406
|
-
|
|
407
|
-
This gives users more targeted help instead of one giant help page.
|
|
408
|
-
|
|
409
|
-
Returns:
|
|
410
|
-
Configured ArgumentParser object ready to parse command-line arguments
|
|
411
|
-
"""
|
|
412
|
-
# Create parser with custom help system (we handle help ourselves)
|
|
413
|
-
parser = argparse.ArgumentParser(add_help=False)
|
|
414
|
-
|
|
415
|
-
# ====================================================================
|
|
416
|
-
# TOPIC-AWARE HELP SYSTEM
|
|
417
|
-
# ====================================================================
|
|
418
|
-
# Instead of standard --help, we support topic-specific help:
|
|
419
|
-
# batplot --help → general help
|
|
420
|
-
# batplot --help xy → XY mode help
|
|
421
|
-
# batplot --help ec → EC mode help
|
|
422
|
-
# batplot --help op → Operando mode help
|
|
423
|
-
#
|
|
424
|
-
# nargs="?" means the argument is optional:
|
|
425
|
-
# - If not provided: const="" (empty string)
|
|
426
|
-
# - If provided: uses the value (e.g., "xy", "ec", "op")
|
|
427
|
-
# ====================================================================
|
|
383
|
+
def _add_help_and_entry_arguments(parser: argparse.ArgumentParser) -> None:
|
|
384
|
+
"""Register help/version/manual flags and positional file inputs."""
|
|
428
385
|
parser.add_argument("--help", nargs="?", const="", metavar="topic",
|
|
429
|
-
help=argparse.SUPPRESS)
|
|
386
|
+
help=argparse.SUPPRESS)
|
|
430
387
|
parser.add_argument("--version", action="store_true", dest="version",
|
|
431
388
|
help="Show version and current release info, then exit.")
|
|
432
389
|
parser.add_argument(
|
|
@@ -435,18 +392,11 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
435
392
|
help=argparse.SUPPRESS,
|
|
436
393
|
)
|
|
437
394
|
parser.add_argument("--manual", action="store_true", help=argparse.SUPPRESS)
|
|
438
|
-
|
|
439
|
-
# ====================================================================
|
|
440
|
-
# POSITIONAL ARGUMENTS (FILE PATHS)
|
|
441
|
-
# ====================================================================
|
|
442
|
-
# 'files' is a positional argument, meaning it doesn't need a flag.
|
|
443
|
-
# nargs="*" means it accepts 0 or more values (list).
|
|
444
|
-
# Examples:
|
|
445
|
-
# batplot file1.xy file2.xy → args.files = ['file1.xy', 'file2.xy']
|
|
446
|
-
# batplot allfiles → args.files = ['allfiles']
|
|
447
|
-
# batplot --i → args.files = [] (empty list)
|
|
448
|
-
# ====================================================================
|
|
449
395
|
parser.add_argument("files", nargs="*", help=argparse.SUPPRESS)
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def _add_xy_arguments(parser: argparse.ArgumentParser) -> None:
|
|
399
|
+
"""Register XY/general plotting arguments."""
|
|
450
400
|
parser.add_argument("--delta", type=float, default=None, help=argparse.SUPPRESS)
|
|
451
401
|
parser.add_argument("--autoscale", action="store_true", help=argparse.SUPPRESS)
|
|
452
402
|
parser.add_argument("--xrange", nargs=2, type=float, help=argparse.SUPPRESS)
|
|
@@ -464,15 +414,29 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
464
414
|
parser.add_argument("--kchik", action="store_true", help=argparse.SUPPRESS)
|
|
465
415
|
parser.add_argument("--k2chik", action="store_true", help=argparse.SUPPRESS)
|
|
466
416
|
parser.add_argument("--k3chik", action="store_true", help=argparse.SUPPRESS)
|
|
417
|
+
parser.add_argument("--1d", action="store_true", dest="derivative_1d", help=argparse.SUPPRESS)
|
|
418
|
+
parser.add_argument("--2d", action="store_true", dest="derivative_2d", help=argparse.SUPPRESS)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
def _add_interactive_export_arguments(parser: argparse.ArgumentParser) -> None:
|
|
422
|
+
"""Register interactive, export, and batch-output arguments."""
|
|
467
423
|
parser.add_argument("--i", "--interactive", action="store_true", dest="interactive", help=argparse.SUPPRESS)
|
|
468
424
|
parser.add_argument("--savefig", type=str, help=argparse.SUPPRESS)
|
|
469
425
|
parser.add_argument("--stack", action="store_true", help=argparse.SUPPRESS)
|
|
470
426
|
parser.add_argument("--ry", action="store_true", help=argparse.SUPPRESS)
|
|
471
427
|
parser.add_argument("--txaxis", action="store_true", help=argparse.SUPPRESS)
|
|
472
|
-
parser.add_argument("--operando", "--contour", action="store_true", dest="operando", help=argparse.SUPPRESS)
|
|
473
|
-
parser.add_argument("--average", type=int, help=argparse.SUPPRESS)
|
|
474
|
-
parser.add_argument("--sum", dest="scan_sum", type=int, help=argparse.SUPPRESS)
|
|
475
428
|
parser.add_argument("--debug", action="store_true", help=argparse.SUPPRESS)
|
|
429
|
+
parser.add_argument("--ro", action="store_true", help=argparse.SUPPRESS)
|
|
430
|
+
parser.add_argument("--all", type=str, nargs='?', const='all', help=argparse.SUPPRESS)
|
|
431
|
+
parser.add_argument("--format", type=str, default='svg',
|
|
432
|
+
choices=['svg', 'png', 'pdf', 'jpg', 'jpeg', 'eps', 'tif', 'tiff'],
|
|
433
|
+
help=argparse.SUPPRESS)
|
|
434
|
+
parser.add_argument("--canvas", action="store_true", dest="canvas",
|
|
435
|
+
help="Canvas mode: combine multiple .pkl sessions into one layout. Use numbers to edit each panel.")
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def _add_electrochem_arguments(parser: argparse.ArgumentParser) -> None:
|
|
439
|
+
"""Register electrochemistry mode arguments."""
|
|
476
440
|
parser.add_argument("--gc", action="store_true", help=argparse.SUPPRESS)
|
|
477
441
|
parser.add_argument("--mass", type=parse_mass_mg_from_cli, action='append', help=argparse.SUPPRESS)
|
|
478
442
|
parser.add_argument("--dqdv", action="store_true", help=argparse.SUPPRESS)
|
|
@@ -486,14 +450,19 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
486
450
|
help=argparse.SUPPRESS)
|
|
487
451
|
parser.add_argument("--anode", action="store_true", help=argparse.SUPPRESS)
|
|
488
452
|
parser.add_argument("--cathode", action="store_true", help=argparse.SUPPRESS)
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def _add_operando_arguments(parser: argparse.ArgumentParser) -> None:
|
|
456
|
+
"""Register operando contour arguments."""
|
|
457
|
+
parser.add_argument("--operando", "--contour", action="store_true", dest="operando", help=argparse.SUPPRESS)
|
|
458
|
+
parser.add_argument("--average", type=int, help=argparse.SUPPRESS)
|
|
459
|
+
parser.add_argument("--sum", dest="scan_sum", type=int, help=argparse.SUPPRESS)
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def _add_read_column_arguments(parser: argparse.ArgumentParser) -> None:
|
|
463
|
+
"""Register column-selection arguments."""
|
|
494
464
|
parser.add_argument("--readcol", nargs=2, type=int, metavar=('X_COL', 'Y_COL'),
|
|
495
465
|
help=argparse.SUPPRESS)
|
|
496
|
-
# Add extension-specific readcol arguments
|
|
497
466
|
parser.add_argument("--readcolxy", nargs=2, type=int, metavar=('X_COL', 'Y_COL'),
|
|
498
467
|
help=argparse.SUPPRESS)
|
|
499
468
|
parser.add_argument("--readcolxye", nargs=2, type=int, metavar=('X_COL', 'Y_COL'),
|
|
@@ -510,10 +479,51 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
510
479
|
help=argparse.SUPPRESS)
|
|
511
480
|
parser.add_argument("--readcols", nargs=2, type=int, metavar=('X_COL', 'Y_COL'),
|
|
512
481
|
help=argparse.SUPPRESS)
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
485
|
+
"""
|
|
486
|
+
Build the argument parser for batplot command-line interface.
|
|
487
|
+
|
|
488
|
+
HOW ARGUMENT PARSING WORKS:
|
|
489
|
+
--------------------------
|
|
490
|
+
This function creates an ArgumentParser object that defines all valid
|
|
491
|
+
command-line arguments for batplot. When you run 'batplot file.xy --i',
|
|
492
|
+
argparse uses this parser to:
|
|
493
|
+
1. Recognize which arguments are valid
|
|
494
|
+
2. Extract values from the command line
|
|
495
|
+
3. Convert them to appropriate Python types (int, float, bool, etc.)
|
|
496
|
+
4. Store them in a namespace object (args.files, args.interactive, etc.)
|
|
497
|
+
|
|
498
|
+
ARGUMENT TYPES:
|
|
499
|
+
--------------
|
|
500
|
+
- Positional arguments: 'files' - list of file paths (can be 0 or more)
|
|
501
|
+
- Flags (boolean): '--i' - True if present, False if absent
|
|
502
|
+
- Options with values: '--mass 7.0' or '--mass 0.01g' - mass in mg, or grams with a ``g`` suffix
|
|
503
|
+
- Optional arguments: '--help xy' - can have optional value
|
|
504
|
+
|
|
505
|
+
WHY add_help=False?
|
|
506
|
+
-------------------
|
|
507
|
+
We use a custom help system that supports topic-specific help:
|
|
508
|
+
- 'batplot --help' → general help
|
|
509
|
+
- 'batplot --help xy' → XY mode help
|
|
510
|
+
- 'batplot --help ec' → EC mode help
|
|
511
|
+
- 'batplot --help op' → Operando mode help
|
|
512
|
+
|
|
513
|
+
This gives users more targeted help instead of one giant help page.
|
|
514
|
+
|
|
515
|
+
Returns:
|
|
516
|
+
Configured ArgumentParser object ready to parse command-line arguments
|
|
517
|
+
"""
|
|
518
|
+
# Create parser with custom help system (we handle help ourselves)
|
|
519
|
+
parser = argparse.ArgumentParser(add_help=False)
|
|
520
|
+
|
|
521
|
+
_add_help_and_entry_arguments(parser)
|
|
522
|
+
_add_xy_arguments(parser)
|
|
523
|
+
_add_interactive_export_arguments(parser)
|
|
524
|
+
_add_operando_arguments(parser)
|
|
525
|
+
_add_electrochem_arguments(parser)
|
|
526
|
+
_add_read_column_arguments(parser)
|
|
517
527
|
return parser
|
|
518
528
|
|
|
519
529
|
|
|
@@ -711,18 +721,23 @@ def parse_args(argv=None):
|
|
|
711
721
|
# weren't in the parser yet when we built it
|
|
712
722
|
ns, _unknown = parser.parse_known_args(argv)
|
|
713
723
|
if getattr(ns, "manual", False):
|
|
724
|
+
manual_url = "https://github.com/chem-plot/batplot/blob/main/batplot_user_manual.pdf"
|
|
714
725
|
try:
|
|
715
|
-
|
|
716
|
-
open_manual_url()
|
|
726
|
+
opened = webbrowser.open(manual_url)
|
|
717
727
|
if _HAS_RICH and _console:
|
|
718
|
-
|
|
728
|
+
if opened:
|
|
729
|
+
_console.print("\n[green]Opened PDF manual in browser[/green]")
|
|
730
|
+
else:
|
|
731
|
+
_console.print(f"\n[yellow]Manual PDF:[/yellow] {manual_url}")
|
|
719
732
|
else:
|
|
720
|
-
print("\nOpened manual in browser")
|
|
733
|
+
print("\nOpened PDF manual in browser" if opened else f"\nManual PDF: {manual_url}")
|
|
721
734
|
except Exception as exc: # pragma: no cover - best effort
|
|
722
735
|
if _HAS_RICH and _console:
|
|
723
736
|
_console.print(f"\n[red]Failed to open manual:[/red] {exc}")
|
|
737
|
+
_console.print(f"[yellow]Manual PDF:[/yellow] {manual_url}")
|
|
724
738
|
else:
|
|
725
739
|
print(f"\nFailed to open manual: {exc}")
|
|
740
|
+
print(f"Manual PDF: {manual_url}")
|
|
726
741
|
sys.exit(0)
|
|
727
742
|
|
|
728
743
|
topic = getattr(ns, 'help', None)
|