Repository navigation
Expand file tree
/
Copy pathrun.py
More file actions
131 lines (122 loc) · 6.71 KB
/
Copy pathrun.py
File metadata and controls
131 lines (122 loc) · 6.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"""Run examples, compare handwriting, or open the local analysis workbench."""
import argparse
import hashlib
from pathlib import Path
import subprocess
import sys
import venv
def prepare_environment(root, *, extras=()):
environment = root / ".venv"
python = environment / ("Scripts/python.exe" if sys.platform == "win32" else "bin/python")
if not python.is_file():
print("Creating the project environment...", flush=True)
venv.EnvBuilder(with_pip=True).create(environment)
# Editable installs pick up code edits immediately. Reinstall only when the
# package configuration changes or the installed dependencies are incomplete.
digest = hashlib.sha256()
for filename in ("pyproject.toml", "setup.py"):
digest.update((root / filename).read_bytes())
fingerprint = digest.hexdigest()
base_stamp = environment / ".greytheory-install"
stamp = environment / (f".greytheory-{'-'.join(extras)}-install" if extras else ".greytheory-install")
configured = stamp.is_file() and stamp.read_text().strip() == fingerprint
if configured:
check = "from importlib.metadata import distribution; distribution('greytheory')"
if "images" in extras or "workbench" in extras:
check += "; distribution('Pillow')"
if "workbench" in extras:
check += "; distribution('pywebview')"
installed = subprocess.run(
[str(python), "-c", check],
cwd=root, capture_output=True,
).returncode == 0
healthy = installed and subprocess.run(
[str(python), "-m", "pip", "check"], cwd=root, capture_output=True,
).returncode == 0
else:
healthy = False
if not healthy:
print("Installing project dependencies (internet access may be needed)...", flush=True)
project = f".[{','.join(extras)}]" if extras else "."
subprocess.check_call([str(python), "-m", "pip", "install", "-e", project], cwd=root)
subprocess.check_call([str(python), "-m", "pip", "check"], cwd=root)
stamp.write_text(fingerprint + "\n")
base_stamp.write_text(fingerprint + "\n")
return python
def main(argv=None):
if sys.version_info < (3, 11):
print("GreyTheory needs Python 3.11 or later.", file=sys.stderr)
return 1
root = Path(__file__).resolve().parent
parser = argparse.ArgumentParser(description=__doc__)
commands = parser.add_subparsers(dest="command")
workbench = commands.add_parser("workbench", help="open the local analysis interface")
workbench.add_argument("--request", type=Path)
workbench.add_argument("--output", type=Path)
handwriting = commands.add_parser("handwriting", help="compare one image with a reference folder")
handwriting.add_argument("query", type=Path)
handwriting.add_argument("references", type=Path)
handwriting.add_argument("--output", type=Path, default=root / "artifacts/handwriting")
handwriting.add_argument("--pca", choices=("pca", "sparse", "kernel", "robust", "robust_sparse", "adv"), default="pca")
artwork = commands.add_parser("artwork", help="compare the bundled AI artwork or an aligned image pair")
artwork.add_argument("--reference", type=Path)
artwork.add_argument("--observed", type=Path)
artwork.add_argument("--output", type=Path, default=root / "artifacts/artwork")
artwork.add_argument("--pca", choices=("pca", "sparse", "kernel", "robust", "robust_sparse", "adv"), default="pca")
optimize = commands.add_parser("optimize", help="run stability, calibration, search and Pareto examples")
optimize.add_argument("--output", type=Path, default=root / "artifacts/optimization/report.json")
research = commands.add_parser("research", help="compare experimental RL-FGM, GINN, FGINN and Grey-Fuzzy GPR")
research.add_argument("--output", type=Path, default=root / "artifacts/research_models/report.json")
args = parser.parse_args(argv)
if args.command == "artwork":
if bool(args.reference) != bool(args.observed):
parser.error("provide both --reference and --observed")
for path in (args.reference, args.observed):
if path and not path.is_file():
parser.error(f"image does not exist: {path}")
if args.command == "handwriting":
if not args.query.is_file():
parser.error(f"query image does not exist: {args.query}")
if not args.references.is_dir():
parser.error(f"reference folder does not exist: {args.references}")
if args.command == "workbench" and args.output and not args.request:
parser.error("--output requires --request")
try:
if args.command == "research":
python = prepare_environment(root)
return subprocess.call([
str(python), "-m", "examples.research_models", "--output", str(args.output.resolve()),
], cwd=root)
if args.command == "optimize":
python = prepare_environment(root)
return subprocess.call([
str(python), "-m", "examples.grey_optimization", "--output", str(args.output.resolve()),
], cwd=root)
if args.command == "workbench":
extras = ("images",) if args.request else ("workbench",)
python = prepare_environment(root, extras=extras)
command = [str(python), "-m", "examples.workbench.desktop"]
if args.request:
command.extend(["--request", str(args.request.resolve())])
if args.output:
command.extend(["--output", str(args.output.resolve())])
return subprocess.call(command, cwd=root)
if args.command == "artwork":
python = prepare_environment(root, extras=("images",))
command = [str(python), "-m", "examples.demos.artwork", "--output", str(args.output.resolve()), "--pca", args.pca]
if args.reference:
command.extend(["--reference", str(args.reference.resolve()), "--observed", str(args.observed.resolve())])
return subprocess.call(command, cwd=root)
if args.command == "handwriting":
python = prepare_environment(root, extras=("images",))
return subprocess.call([
str(python), "-m", "greytheory", "handwriting", str(args.query.resolve()),
str(args.references.resolve()), "--output", str(args.output.resolve()), "--pca", args.pca,
])
python = prepare_environment(root)
return subprocess.call([str(python), str(root / "example.py")], cwd=root)
except subprocess.CalledProcessError as error:
print("Setup failed. Check the installation error above, then run this command again.", file=sys.stderr)
return error.returncode
if __name__ == "__main__":
raise SystemExit(main())