dataframe-toolkit 0.7.0__tar.gz → 0.7.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.
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/PKG-INFO +1 -1
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/pyproject.toml +1 -1
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/pyproject.toml.orig +1 -1
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/cli.py +22 -3
- dataframe_toolkit-0.7.1/src/dftk/commands/__init__.py +98 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/eval_cmd.py +47 -37
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/help.py +6 -21
- dataframe_toolkit-0.7.0/src/dftk/commands/__init__.py +0 -105
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/README.md +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/__init__.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/annotate_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/base.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/binx_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/chi_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/clean_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/concat_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/corr_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/dataset_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/describe_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/fit_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/func_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/hist_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/info_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/interp_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/line_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/melt_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/merge_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/pivot_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/print_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/query_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/randvar_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/sample_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/scale_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/scat_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/segid_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/split_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/stat_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/test_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/transpose_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/commands/wstat_cmd.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/common/__init__.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/common/copula.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/common/io.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/common/plot.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/common/seed.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/common/seq.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/common/stats.py +0 -0
- {dataframe_toolkit-0.7.0 → dataframe_toolkit-0.7.1}/src/dftk/io.py +0 -0
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"""
|
|
2
2
|
dftk.cli — entry point for the ``dftk`` command.
|
|
3
3
|
|
|
4
|
-
All subcommands are discovered through the
|
|
4
|
+
All subcommands are discovered through the registry in
|
|
5
5
|
dftk/commands/__init__.py. This file contains no command-specific
|
|
6
6
|
logic and never needs to change when a new subcommand is added.
|
|
7
|
+
|
|
8
|
+
Only the command being run is imported, so e.g. ``dftk print`` does not pay
|
|
9
|
+
for importing scipy, statsmodels or matplotlib. The full set is imported only
|
|
10
|
+
when it is needed: ``dftk --help``, no command, or an unknown command name.
|
|
7
11
|
"""
|
|
8
12
|
|
|
9
13
|
import argparse
|
|
@@ -13,13 +17,28 @@ import signal
|
|
|
13
17
|
import sys
|
|
14
18
|
|
|
15
19
|
from dftk import __version__
|
|
16
|
-
from dftk.commands import
|
|
20
|
+
from dftk.commands import COMMAND_NAMES, load_command, load_command_groups
|
|
21
|
+
from dftk.commands.base import BaseCommand
|
|
17
22
|
from dftk.common.io import DFTK_TMPDIR
|
|
18
23
|
|
|
19
24
|
logger = logging.getLogger("dftk")
|
|
20
25
|
logging.basicConfig(format="%(asctime)s %(module)s %(message)s", level=logging.INFO)
|
|
21
26
|
|
|
22
27
|
|
|
28
|
+
def _commands_for(argv: list[str]) -> list[BaseCommand]:
|
|
29
|
+
"""Return the commands whose subparsers *argv* needs.
|
|
30
|
+
|
|
31
|
+
The top-level parser has no options that take a value, so a valid
|
|
32
|
+
invocation always has the command name first.
|
|
33
|
+
"""
|
|
34
|
+
if argv and argv[0] in COMMAND_NAMES:
|
|
35
|
+
return [load_command(argv[0])]
|
|
36
|
+
# `dftk --help`, no command, or an unknown name: load everything so the
|
|
37
|
+
# command listing and argparse's "invalid choice" message are complete.
|
|
38
|
+
grouped = [cmd for _, cmds in load_command_groups() for cmd in cmds]
|
|
39
|
+
return grouped + [load_command("help")]
|
|
40
|
+
|
|
41
|
+
|
|
23
42
|
def main() -> None:
|
|
24
43
|
parser = argparse.ArgumentParser(
|
|
25
44
|
prog="dftk",
|
|
@@ -40,7 +59,7 @@ def main() -> None:
|
|
|
40
59
|
subparsers = parser.add_subparsers(dest="command", metavar="COMMAND")
|
|
41
60
|
subparsers.required = True
|
|
42
61
|
|
|
43
|
-
for cmd in
|
|
62
|
+
for cmd in _commands_for(sys.argv[1:]):
|
|
44
63
|
cmd_parser = subparsers.add_parser(cmd.name, help=cmd.help)
|
|
45
64
|
cmd.add_arguments(cmd_parser)
|
|
46
65
|
cmd_parser.set_defaults(command_instance=cmd)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# dftk.commands — registry of all dftk subcommands.
|
|
2
|
+
#
|
|
3
|
+
# Commands are registered by name and import path instead of being imported
|
|
4
|
+
# here, so that running one command imports only that command's module and its
|
|
5
|
+
# dependencies (scipy, statsmodels, matplotlib, …), not every command's.
|
|
6
|
+
#
|
|
7
|
+
# To add a new subcommand:
|
|
8
|
+
# 1. Create src/dftk/commands/<name>_cmd.py with a class that inherits
|
|
9
|
+
# from BaseCommand (see base.py for the contract and an example skeleton).
|
|
10
|
+
# 2. Add a ("<name>", "<name>_cmd:<ClassName>") entry to COMMAND_GROUPS below.
|
|
11
|
+
# That's it — cli.py discovers commands solely through this registry.
|
|
12
|
+
# tests/commands/test_registry.py checks that every entry imports and that
|
|
13
|
+
# every *_cmd.py module is registered.
|
|
14
|
+
|
|
15
|
+
import importlib
|
|
16
|
+
|
|
17
|
+
from dftk.commands.base import BaseCommand
|
|
18
|
+
|
|
19
|
+
# Ported subcommands — add as each one is implemented:
|
|
20
|
+
# ("color", "color_cmd:ColorCommand")
|
|
21
|
+
# ("wavelet", "wavelet_cmd:WaveletCommand")
|
|
22
|
+
# ("fisher", ...) — superseded by eval's fisher_test/fisher_OR
|
|
23
|
+
|
|
24
|
+
COMMAND_GROUPS: list[tuple[str, list[tuple[str, str]]]] = [
|
|
25
|
+
(
|
|
26
|
+
"Data transformation",
|
|
27
|
+
[
|
|
28
|
+
("eval", "eval_cmd:EvalCommand"),
|
|
29
|
+
("query", "query_cmd:QueryCommand"),
|
|
30
|
+
("merge", "merge_cmd:MergeCommand"),
|
|
31
|
+
("concat", "concat_cmd:ConcatCommand"),
|
|
32
|
+
("melt", "melt_cmd:MeltCommand"),
|
|
33
|
+
("pivot", "pivot_cmd:PivotCommand"),
|
|
34
|
+
("func", "func_cmd:FuncCommand"),
|
|
35
|
+
("scale", "scale_cmd:ScaleCommand"),
|
|
36
|
+
("interp", "interp_cmd:InterpCommand"),
|
|
37
|
+
("binx", "binx_cmd:BinxCommand"),
|
|
38
|
+
("transpose", "transpose_cmd:TransposeCommand"),
|
|
39
|
+
("segid", "segid_cmd:SegidCommand"),
|
|
40
|
+
],
|
|
41
|
+
),
|
|
42
|
+
(
|
|
43
|
+
"Statistics",
|
|
44
|
+
[
|
|
45
|
+
("stat", "stat_cmd:StatCommand"),
|
|
46
|
+
("wstat", "wstat_cmd:WstatCommand"),
|
|
47
|
+
("fit", "fit_cmd:FitCommand"),
|
|
48
|
+
("test", "test_cmd:TestCommand"),
|
|
49
|
+
("corr", "corr_cmd:CorrCommand"),
|
|
50
|
+
("describe", "describe_cmd:DescribeCommand"),
|
|
51
|
+
("info", "info_cmd:InfoCommand"),
|
|
52
|
+
("randvar", "randvar_cmd:RandvarCommand"),
|
|
53
|
+
],
|
|
54
|
+
),
|
|
55
|
+
(
|
|
56
|
+
"Plots",
|
|
57
|
+
[
|
|
58
|
+
("scat", "scat_cmd:ScatCommand"),
|
|
59
|
+
("line", "line_cmd:LineCommand"),
|
|
60
|
+
("hist", "hist_cmd:HistCommand"),
|
|
61
|
+
("chi", "chi_cmd:ChiCommand"),
|
|
62
|
+
],
|
|
63
|
+
),
|
|
64
|
+
(
|
|
65
|
+
"Utilities",
|
|
66
|
+
[
|
|
67
|
+
("dataset", "dataset_cmd:DatasetCommand"),
|
|
68
|
+
("sample", "sample_cmd:SampleCommand"),
|
|
69
|
+
("split", "split_cmd:SplitCommand"),
|
|
70
|
+
("annotate", "annotate_cmd:AnnotateCommand"),
|
|
71
|
+
("print", "print_cmd:PrintCommand"),
|
|
72
|
+
("clean", "clean_cmd:CleanCommand"),
|
|
73
|
+
],
|
|
74
|
+
),
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
# `help` is a command like the others but is not listed under a group heading.
|
|
78
|
+
_REGISTRY: dict[str, str] = dict(
|
|
79
|
+
[entry for _, entries in COMMAND_GROUPS for entry in entries]
|
|
80
|
+
+ [("help", "help:HelpCommand")]
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
COMMAND_NAMES: list[str] = list(_REGISTRY)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def load_command(name: str) -> BaseCommand:
|
|
87
|
+
"""Import and instantiate the command registered as *name*."""
|
|
88
|
+
module_name, class_name = _REGISTRY[name].split(":")
|
|
89
|
+
module = importlib.import_module(f"dftk.commands.{module_name}")
|
|
90
|
+
return getattr(module, class_name)()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def load_command_groups() -> list[tuple[str, list[BaseCommand]]]:
|
|
94
|
+
"""Import and instantiate every grouped command (slow: imports everything)."""
|
|
95
|
+
return [
|
|
96
|
+
(header, [load_command(name) for name, _ in entries])
|
|
97
|
+
for header, entries in COMMAND_GROUPS
|
|
98
|
+
]
|
|
@@ -19,11 +19,9 @@ from pathlib import Path
|
|
|
19
19
|
|
|
20
20
|
import numpy as np
|
|
21
21
|
import pandas as pd
|
|
22
|
-
from scipy import special as _sp
|
|
23
22
|
|
|
24
23
|
from dftk.commands.base import BaseCommand
|
|
25
24
|
from dftk.common import seq as _seq
|
|
26
|
-
from dftk.common import stats as _stats
|
|
27
25
|
from dftk.common.io import io
|
|
28
26
|
|
|
29
27
|
logger = logging.getLogger(__name__)
|
|
@@ -190,18 +188,23 @@ def _parse_formula(formula: str) -> tuple[str, str, list[str], str]:
|
|
|
190
188
|
# Special functions (used as pandas agg fallback inside -f)
|
|
191
189
|
# ---------------------------------------------------------------------------
|
|
192
190
|
|
|
191
|
+
# The function tables below hold names, not function objects: dftk.common.stats
|
|
192
|
+
# and scipy.special are imported only when a formula actually uses one of them,
|
|
193
|
+
# so plain `dftk eval -f` formulas don't pay scipy's import time.
|
|
194
|
+
|
|
195
|
+
# dftk.common.stats functions, same name in the formula as in the module
|
|
193
196
|
_STATS_DISPATCH = {
|
|
194
|
-
"binom_test"
|
|
195
|
-
"fisher_test"
|
|
196
|
-
"fisher_OR"
|
|
197
|
-
"boschloo_test"
|
|
198
|
-
"boschloo_OR"
|
|
199
|
-
"pval2se"
|
|
200
|
-
"t2pval"
|
|
201
|
-
"chi2_to_neglogp"
|
|
202
|
-
"neglogp_to_chi2"
|
|
203
|
-
"pval_to_chi2"
|
|
204
|
-
"generalized_poisson_nll"
|
|
197
|
+
"binom_test",
|
|
198
|
+
"fisher_test",
|
|
199
|
+
"fisher_OR",
|
|
200
|
+
"boschloo_test",
|
|
201
|
+
"boschloo_OR",
|
|
202
|
+
"pval2se",
|
|
203
|
+
"t2pval",
|
|
204
|
+
"chi2_to_neglogp",
|
|
205
|
+
"neglogp_to_chi2",
|
|
206
|
+
"pval_to_chi2",
|
|
207
|
+
"generalized_poisson_nll",
|
|
205
208
|
}
|
|
206
209
|
|
|
207
210
|
_PATH_FUNCS = {"basename", "dirname", "exists", "getsize", "realpath"}
|
|
@@ -209,35 +212,33 @@ _NP_FUNCS = {"sign", "cbrt", "log1p", "expm1"}
|
|
|
209
212
|
_ROW_AGG_FUNCS = {"sum", "mean", "std", "min", "max", "median"}
|
|
210
213
|
_ROW_IDX_FUNCS = {"idxmax", "idxmin"}
|
|
211
214
|
|
|
212
|
-
# scipy.special single-column functions (element-wise, vectorised)
|
|
215
|
+
# scipy.special single-column functions (element-wise, vectorised):
|
|
216
|
+
# formula name -> scipy.special attribute name
|
|
213
217
|
_SCIPY_SINGLE = {
|
|
214
|
-
"gamma":
|
|
215
|
-
"lgamma":
|
|
216
|
-
"digamma":
|
|
217
|
-
"erf":
|
|
218
|
-
"erfc":
|
|
219
|
-
"erfinv":
|
|
220
|
-
"expit":
|
|
221
|
-
"logit":
|
|
218
|
+
"gamma": "gamma", # Γ(x)
|
|
219
|
+
"lgamma": "gammaln", # log Γ(x)
|
|
220
|
+
"digamma": "digamma", # ψ(x) (log-derivative of Γ)
|
|
221
|
+
"erf": "erf", # error function
|
|
222
|
+
"erfc": "erfc", # complementary error function
|
|
223
|
+
"erfinv": "erfinv", # inverse error function
|
|
224
|
+
"expit": "expit", # logistic sigmoid 1/(1+exp(-x))
|
|
225
|
+
"logit": "logit", # log(x/(1-x))
|
|
222
226
|
# Bessel J (first kind), fixed order
|
|
223
|
-
"j0":
|
|
224
|
-
"j1":
|
|
227
|
+
"j0": "j0",
|
|
228
|
+
"j1": "j1",
|
|
225
229
|
# Bessel Y (second kind), fixed order
|
|
226
|
-
"y0":
|
|
227
|
-
"y1":
|
|
230
|
+
"y0": "y0",
|
|
231
|
+
"y1": "y1",
|
|
228
232
|
# Modified Bessel I, fixed order
|
|
229
|
-
"i0":
|
|
230
|
-
"i1":
|
|
233
|
+
"i0": "i0",
|
|
234
|
+
"i1": "i1",
|
|
231
235
|
# Modified Bessel K, fixed order
|
|
232
|
-
"k0":
|
|
233
|
-
"k1":
|
|
236
|
+
"k0": "k0",
|
|
237
|
+
"k1": "k1",
|
|
234
238
|
}
|
|
235
239
|
|
|
236
240
|
# scipy.special two-column functions: func(col_a, col_b)
|
|
237
|
-
_SCIPY_DUAL = {
|
|
238
|
-
"beta": lambda x: _sp.beta(x[0], x[1]), # B(a, b)
|
|
239
|
-
"betaln": lambda x: _sp.betaln(x[0], x[1]), # log B(a, b)
|
|
240
|
-
}
|
|
241
|
+
_SCIPY_DUAL = {"beta", "betaln"} # B(a, b), log B(a, b)
|
|
241
242
|
|
|
242
243
|
# scipy.special parametric Bessel: func_name(order_literal, col)
|
|
243
244
|
# Covers all-order variants: jn(n,x), yn(n,x), iv(v,x), kv(v,x)
|
|
@@ -365,12 +366,21 @@ def _special_function(formula: str, df_columns: list[str]):
|
|
|
365
366
|
elif func_name in _PATH_FUNCS:
|
|
366
367
|
func = np.frompyfunc(getattr(os.path, func_name), 1, 1)
|
|
367
368
|
elif func_name in _STATS_DISPATCH:
|
|
368
|
-
|
|
369
|
+
from dftk.common import stats as _stats
|
|
370
|
+
|
|
371
|
+
func = getattr(_stats, func_name)
|
|
369
372
|
elif func_name in _SCIPY_SINGLE:
|
|
370
|
-
|
|
373
|
+
from scipy import special as _sp
|
|
374
|
+
|
|
375
|
+
func = getattr(_sp, _SCIPY_SINGLE[func_name])
|
|
371
376
|
elif func_name in _SCIPY_DUAL:
|
|
372
|
-
|
|
377
|
+
from scipy import special as _sp
|
|
378
|
+
|
|
379
|
+
dual = getattr(_sp, func_name)
|
|
380
|
+
func = partial(lambda x: dual(x[0], x[1]))
|
|
373
381
|
elif func_name in _SCIPY_BESSEL_ORDER:
|
|
382
|
+
from scipy import special as _sp
|
|
383
|
+
|
|
374
384
|
try:
|
|
375
385
|
order = float(cols[0])
|
|
376
386
|
except (ValueError, IndexError):
|
|
@@ -7,6 +7,7 @@ dftk.commands.help — the ``dftk help`` subcommand.
|
|
|
7
7
|
|
|
8
8
|
import argparse
|
|
9
9
|
|
|
10
|
+
from dftk.commands import COMMAND_NAMES, load_command, load_command_groups
|
|
10
11
|
from dftk.commands.base import BaseCommand
|
|
11
12
|
|
|
12
13
|
|
|
@@ -16,14 +17,6 @@ class HelpCommand(BaseCommand):
|
|
|
16
17
|
name = "help"
|
|
17
18
|
help = "Show detailed help for a subcommand"
|
|
18
19
|
|
|
19
|
-
def __init__(
|
|
20
|
-
self,
|
|
21
|
-
available_commands: list[BaseCommand] | None = None,
|
|
22
|
-
command_groups: list[tuple[str, list[BaseCommand]]] | None = None,
|
|
23
|
-
) -> None:
|
|
24
|
-
self.available_commands: list[BaseCommand] = available_commands or []
|
|
25
|
-
self.command_groups: list[tuple[str, list[BaseCommand]]] = command_groups or []
|
|
26
|
-
|
|
27
20
|
def add_arguments(self, parser: argparse.ArgumentParser) -> None:
|
|
28
21
|
parser.add_argument(
|
|
29
22
|
"command_name",
|
|
@@ -34,24 +27,16 @@ class HelpCommand(BaseCommand):
|
|
|
34
27
|
|
|
35
28
|
def execute(self, args: argparse.Namespace) -> None:
|
|
36
29
|
if args.command_name is None:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
for cmd in cmds:
|
|
41
|
-
print(f" {cmd.name:<16} {cmd.help}")
|
|
42
|
-
else:
|
|
43
|
-
print("Available commands:")
|
|
44
|
-
for cmd in self.available_commands:
|
|
30
|
+
for header, cmds in load_command_groups():
|
|
31
|
+
print(f"\n{header}:")
|
|
32
|
+
for cmd in cmds:
|
|
45
33
|
print(f" {cmd.name:<16} {cmd.help}")
|
|
46
34
|
print("\nUse 'dftk help <command>' for detailed help on a command.")
|
|
47
35
|
return
|
|
48
36
|
|
|
49
|
-
|
|
50
|
-
(c for c in self.available_commands if c.name == args.command_name),
|
|
51
|
-
None,
|
|
52
|
-
)
|
|
53
|
-
if cmd is None:
|
|
37
|
+
if args.command_name not in COMMAND_NAMES:
|
|
54
38
|
raise ValueError(f"Unknown command: {args.command_name!r}")
|
|
39
|
+
cmd = load_command(args.command_name)
|
|
55
40
|
|
|
56
41
|
# Build a temporary parser for this command so argparse formats the
|
|
57
42
|
# help text exactly as it would appear during normal use.
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# dftk.commands — explicit registry of all dftk subcommands.
|
|
2
|
-
#
|
|
3
|
-
# To add a new subcommand:
|
|
4
|
-
# 1. Create src/dftk/commands/<name>.py with a class that inherits
|
|
5
|
-
# from BaseCommand (see base.py for the contract and an example skeleton).
|
|
6
|
-
# 2. Import the class here and add an instance to command_list below.
|
|
7
|
-
# That's it — cli.py discovers commands solely through this COMMANDS list.
|
|
8
|
-
|
|
9
|
-
from dftk.commands.annotate_cmd import AnnotateCommand
|
|
10
|
-
from dftk.commands.binx_cmd import BinxCommand
|
|
11
|
-
from dftk.commands.chi_cmd import ChiCommand
|
|
12
|
-
from dftk.commands.clean_cmd import CleanCommand
|
|
13
|
-
from dftk.commands.concat_cmd import ConcatCommand
|
|
14
|
-
from dftk.commands.corr_cmd import CorrCommand
|
|
15
|
-
from dftk.commands.dataset_cmd import DatasetCommand
|
|
16
|
-
from dftk.commands.describe_cmd import DescribeCommand
|
|
17
|
-
from dftk.commands.eval_cmd import EvalCommand
|
|
18
|
-
from dftk.commands.fit_cmd import FitCommand
|
|
19
|
-
from dftk.commands.func_cmd import FuncCommand
|
|
20
|
-
from dftk.commands.help import HelpCommand
|
|
21
|
-
from dftk.commands.hist_cmd import HistCommand
|
|
22
|
-
from dftk.commands.info_cmd import InfoCommand
|
|
23
|
-
from dftk.commands.interp_cmd import InterpCommand
|
|
24
|
-
from dftk.commands.line_cmd import LineCommand
|
|
25
|
-
from dftk.commands.melt_cmd import MeltCommand
|
|
26
|
-
from dftk.commands.merge_cmd import MergeCommand
|
|
27
|
-
from dftk.commands.pivot_cmd import PivotCommand
|
|
28
|
-
from dftk.commands.print_cmd import PrintCommand
|
|
29
|
-
from dftk.commands.query_cmd import QueryCommand
|
|
30
|
-
from dftk.commands.randvar_cmd import RandvarCommand
|
|
31
|
-
from dftk.commands.sample_cmd import SampleCommand
|
|
32
|
-
from dftk.commands.scale_cmd import ScaleCommand
|
|
33
|
-
from dftk.commands.scat_cmd import ScatCommand
|
|
34
|
-
from dftk.commands.segid_cmd import SegidCommand
|
|
35
|
-
from dftk.commands.split_cmd import SplitCommand
|
|
36
|
-
from dftk.commands.stat_cmd import StatCommand
|
|
37
|
-
from dftk.commands.test_cmd import TestCommand
|
|
38
|
-
from dftk.commands.transpose_cmd import TransposeCommand
|
|
39
|
-
from dftk.commands.wstat_cmd import WstatCommand
|
|
40
|
-
|
|
41
|
-
# Ported subcommands — uncomment as each one is added:
|
|
42
|
-
# from dftk.commands.color import ColorCommand
|
|
43
|
-
# from dftk.commands.wavelet import WaveletCommand
|
|
44
|
-
# from dftk.commands.fisher import FisherCommand # superseded by eval's
|
|
45
|
-
# # fisher_test/fisher_OR
|
|
46
|
-
|
|
47
|
-
COMMAND_GROUPS: list[tuple[str, list]] = [
|
|
48
|
-
(
|
|
49
|
-
"Data transformation",
|
|
50
|
-
[
|
|
51
|
-
EvalCommand(),
|
|
52
|
-
QueryCommand(),
|
|
53
|
-
MergeCommand(),
|
|
54
|
-
ConcatCommand(),
|
|
55
|
-
MeltCommand(),
|
|
56
|
-
PivotCommand(),
|
|
57
|
-
FuncCommand(),
|
|
58
|
-
ScaleCommand(),
|
|
59
|
-
InterpCommand(),
|
|
60
|
-
BinxCommand(),
|
|
61
|
-
TransposeCommand(),
|
|
62
|
-
SegidCommand(),
|
|
63
|
-
],
|
|
64
|
-
),
|
|
65
|
-
(
|
|
66
|
-
"Statistics",
|
|
67
|
-
[
|
|
68
|
-
StatCommand(),
|
|
69
|
-
WstatCommand(),
|
|
70
|
-
FitCommand(),
|
|
71
|
-
TestCommand(),
|
|
72
|
-
CorrCommand(),
|
|
73
|
-
DescribeCommand(),
|
|
74
|
-
InfoCommand(),
|
|
75
|
-
RandvarCommand(),
|
|
76
|
-
],
|
|
77
|
-
),
|
|
78
|
-
(
|
|
79
|
-
"Plots",
|
|
80
|
-
[
|
|
81
|
-
ScatCommand(),
|
|
82
|
-
LineCommand(),
|
|
83
|
-
HistCommand(),
|
|
84
|
-
ChiCommand(),
|
|
85
|
-
],
|
|
86
|
-
),
|
|
87
|
-
(
|
|
88
|
-
"Utilities",
|
|
89
|
-
[
|
|
90
|
-
DatasetCommand(),
|
|
91
|
-
SampleCommand(),
|
|
92
|
-
SplitCommand(),
|
|
93
|
-
AnnotateCommand(),
|
|
94
|
-
PrintCommand(),
|
|
95
|
-
CleanCommand(),
|
|
96
|
-
],
|
|
97
|
-
),
|
|
98
|
-
]
|
|
99
|
-
|
|
100
|
-
command_list = [cmd for _, cmds in COMMAND_GROUPS for cmd in cmds]
|
|
101
|
-
|
|
102
|
-
# HelpCommand receives the live list and groups so it can introspect any peer.
|
|
103
|
-
help_command = HelpCommand(command_list, COMMAND_GROUPS)
|
|
104
|
-
|
|
105
|
-
COMMANDS = command_list + [help_command]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|