majoplot 0.1.0__py3-none-any.whl
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.
- majoplot/__init__.py +0 -0
- majoplot/__main__.py +25 -0
- majoplot/app/__init__.py +0 -0
- majoplot/app/cli.py +259 -0
- majoplot/app/gui.py +6 -0
- majoplot/config.json +11 -0
- majoplot/domain/base.py +433 -0
- majoplot/domain/importers/PPMS_Resistivity.py +128 -0
- majoplot/domain/importers/VSM.py +109 -0
- majoplot/domain/importers/XRD.py +62 -0
- majoplot/domain/muti_axes_spec.py +172 -0
- majoplot/domain/scenarios/PPMS_Resistivity/RT.py +119 -0
- majoplot/domain/scenarios/VSM/MT.py +131 -0
- majoplot/domain/scenarios/VSM/MT_insert.py +135 -0
- majoplot/domain/scenarios/VSM/MT_reliability_analysis.py +145 -0
- majoplot/domain/scenarios/XRD/Compare.py +104 -0
- majoplot/domain/utils.py +87 -0
- majoplot/gui/__init__.py +0 -0
- majoplot/gui/main.py +529 -0
- majoplot/infra/plotters/matplot.py +337 -0
- majoplot/infra/plotters/origin.py +1006 -0
- majoplot/infra/plotters/origin_utils/originlab_type_library.py +403 -0
- majoplot-0.1.0.dist-info/METADATA +81 -0
- majoplot-0.1.0.dist-info/RECORD +27 -0
- majoplot-0.1.0.dist-info/WHEEL +4 -0
- majoplot-0.1.0.dist-info/entry_points.txt +2 -0
- majoplot-0.1.0.dist-info/licenses/LICENSE +21 -0
majoplot/__init__.py
ADDED
|
File without changes
|
majoplot/__main__.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
|
|
5
|
+
from .app.cli import run_cli
|
|
6
|
+
from .app.gui import run_gui
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main(argv: list[str] | None = None) -> None:
|
|
10
|
+
parser = argparse.ArgumentParser(prog="majoplot")
|
|
11
|
+
group = parser.add_mutually_exclusive_group()
|
|
12
|
+
group.add_argument("--gui", "-g", action="store_true", help="Launch GUI (default)")
|
|
13
|
+
group.add_argument("--cli", "-c", action="store_true", help="Launch CLI")
|
|
14
|
+
args, _ = parser.parse_known_args(argv)
|
|
15
|
+
|
|
16
|
+
if args.cli:
|
|
17
|
+
run_cli()
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
# default GUI (also for --gui/-g)
|
|
21
|
+
run_gui()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
main()
|
majoplot/app/__init__.py
ADDED
|
File without changes
|
majoplot/app/cli.py
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import tkinter as tk
|
|
4
|
+
from tkinter import filedialog
|
|
5
|
+
import importlib
|
|
6
|
+
import pkgutil
|
|
7
|
+
from types import ModuleType
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from ..domain.base import *
|
|
11
|
+
from ..domain.utils import group_into_axes, group_into_figure, pack_into_project
|
|
12
|
+
from ..infra.plotters.origin import OriginCOM
|
|
13
|
+
from ..infra.plotters.origin import plot as oplot
|
|
14
|
+
|
|
15
|
+
def load_named_objects(package: str) -> dict[str, Any]:
|
|
16
|
+
"""
|
|
17
|
+
Import all submodules under `package`, and extract the attribute
|
|
18
|
+
that has the same name as the module.
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
domain.importers.csv -> object named `csv`
|
|
22
|
+
"""
|
|
23
|
+
result: dict[str, Any] = {}
|
|
24
|
+
|
|
25
|
+
pkg = importlib.import_module(package)
|
|
26
|
+
|
|
27
|
+
if not hasattr(pkg, "__path__"):
|
|
28
|
+
raise ValueError(f"{package!r} is not a package")
|
|
29
|
+
|
|
30
|
+
for module_info in pkgutil.iter_modules(pkg.__path__):
|
|
31
|
+
module_name = module_info.name
|
|
32
|
+
full_name = f"{package}.{module_name}"
|
|
33
|
+
|
|
34
|
+
module = importlib.import_module(full_name)
|
|
35
|
+
|
|
36
|
+
if hasattr(module, module_name):
|
|
37
|
+
result[module_name] = getattr(module, module_name)
|
|
38
|
+
else:
|
|
39
|
+
raise AttributeError(
|
|
40
|
+
f"Module {full_name} does not define `{module_name}`"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
return result
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def pick_multiple_files(
|
|
49
|
+
*,
|
|
50
|
+
title: str = "Select files",
|
|
51
|
+
initial_dir: str | Path | None = None,
|
|
52
|
+
filetypes: list[tuple[str, str]] | None = None,
|
|
53
|
+
) -> list[Path]:
|
|
54
|
+
root = tk.Tk()
|
|
55
|
+
root.withdraw()
|
|
56
|
+
root.attributes("-topmost", True)
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
filenames = filedialog.askopenfilenames(
|
|
60
|
+
title=title,
|
|
61
|
+
initialdir=str(Path(initial_dir).resolve()) if initial_dir else None,
|
|
62
|
+
filetypes=filetypes or [("All files", "*.*")],
|
|
63
|
+
)
|
|
64
|
+
return [Path(x).resolve() for x in filenames] # empty list if cancelled
|
|
65
|
+
finally:
|
|
66
|
+
root.destroy()
|
|
67
|
+
|
|
68
|
+
def pick_directory(
|
|
69
|
+
*,
|
|
70
|
+
title: str = "Select directory",
|
|
71
|
+
initial_dir: str | Path | None = None,
|
|
72
|
+
) -> Path | None:
|
|
73
|
+
root = tk.Tk()
|
|
74
|
+
root.withdraw()
|
|
75
|
+
root.attributes("-topmost", True)
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
dirname = filedialog.askdirectory(
|
|
79
|
+
title=title,
|
|
80
|
+
initialdir=str(Path(initial_dir).resolve()) if initial_dir else None,
|
|
81
|
+
mustexist=True,
|
|
82
|
+
)
|
|
83
|
+
if not dirname:
|
|
84
|
+
return None # user cancelled
|
|
85
|
+
return Path(dirname).resolve()
|
|
86
|
+
finally:
|
|
87
|
+
root.destroy()
|
|
88
|
+
|
|
89
|
+
def run_cli():
|
|
90
|
+
"""
|
|
91
|
+
cli is just for test in early and middle development stage
|
|
92
|
+
"""
|
|
93
|
+
print("################")
|
|
94
|
+
print("# MAJOPLOT CLI #")
|
|
95
|
+
print("################")
|
|
96
|
+
importers = load_named_objects("majoplot.domain.importers")
|
|
97
|
+
figures = []
|
|
98
|
+
print("======== Step 1 ========")
|
|
99
|
+
while True:
|
|
100
|
+
print("[Majo]: Now we try to import some raw datas.")
|
|
101
|
+
while True:
|
|
102
|
+
print("[Majo]: Please choose one Importer:")
|
|
103
|
+
print("\n".join(f"\t- {importer}" for importer in importers))
|
|
104
|
+
try:
|
|
105
|
+
chosed_importer_name = input("[You]:").strip()
|
|
106
|
+
chosed_importer = importers[chosed_importer_name]
|
|
107
|
+
except KeyError:
|
|
108
|
+
print(f"[Majo]: Importer '{chosed_importer_name}' not founded. Please try another.")
|
|
109
|
+
continue
|
|
110
|
+
break
|
|
111
|
+
scenarios = load_named_objects(f"majoplot.domain.scenarios.{chosed_importer_name}")
|
|
112
|
+
while True:
|
|
113
|
+
print("[Majo]: Please choose one Scenario:")
|
|
114
|
+
print("\n".join(f"\t- {scenario}" for scenario in scenarios))
|
|
115
|
+
try:
|
|
116
|
+
chosed_scenario_name = input("[You]:").strip()
|
|
117
|
+
chosed_scenario = scenarios[chosed_scenario_name]
|
|
118
|
+
except KeyError:
|
|
119
|
+
print(f"[Majo]: Scenario '{chosed_scenario_name}' not founded. Please try another.")
|
|
120
|
+
continue
|
|
121
|
+
break
|
|
122
|
+
|
|
123
|
+
print("[Majo]: Please choose some raw data files.")
|
|
124
|
+
raw_data_paths = pick_multiple_files(title="Select Raw data files", initial_dir=".")
|
|
125
|
+
print(f"[You]:")
|
|
126
|
+
print("\n".join(f"\t+ {raw_data_path}" for raw_data_path in raw_data_paths))
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# make figures
|
|
130
|
+
raw_datas = []
|
|
131
|
+
for path in raw_data_paths:
|
|
132
|
+
with open(path, encoding="utf-8") as fp:
|
|
133
|
+
raw_data = chosed_importer.fetch_raw_data(fp, path.stem)
|
|
134
|
+
if raw_data is not fail_signal:
|
|
135
|
+
raw_datas.append(raw_data)
|
|
136
|
+
datas = chosed_scenario.preprocess(raw_datas)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
axes_pool = group_into_axes(datas, chosed_scenario)
|
|
140
|
+
figures.extend(group_into_figure(axes_pool, chosed_scenario))
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
print("[Majo]: Ok. Shall we proceed to the next step?")
|
|
144
|
+
print("\t- (Y) Yes.")
|
|
145
|
+
print("\t- (N) No, I want to import more datas.")
|
|
146
|
+
choice = input("[You]:")
|
|
147
|
+
if choice.upper() == "Y":
|
|
148
|
+
break
|
|
149
|
+
|
|
150
|
+
print("======== Step 2 ========")
|
|
151
|
+
while True:
|
|
152
|
+
print("[Majo]: We got these figures:")
|
|
153
|
+
print("\n".join(f"\t ({i}) {figure.spec.name}" for i,figure in enumerate(figures)))
|
|
154
|
+
print("[Majo]: You can choose one figure to manipulate. Or you can input:")
|
|
155
|
+
print("\t- (Y) to get to the next step.")
|
|
156
|
+
print("\t- (W) to write and apply a project_name:folder_path pair to all the figures")
|
|
157
|
+
print("\t- (O) to overwrite and apply a project_name:folder_path pair to all the figures")
|
|
158
|
+
|
|
159
|
+
answer = input("[You]:").upper()
|
|
160
|
+
if answer == "Y":
|
|
161
|
+
break
|
|
162
|
+
elif answer == "W" or answer == "O":
|
|
163
|
+
print("[Majo]: Please input a 'proj_name:folder_path' pair. For example: '20260115:MT/LNO'.")
|
|
164
|
+
try:
|
|
165
|
+
pair = input("[You]:").split(":")
|
|
166
|
+
proj_name, folder_path = pair[0:2]
|
|
167
|
+
if answer == "W":
|
|
168
|
+
for figure in figures:
|
|
169
|
+
figure.proj_folder[proj_name] = folder_path
|
|
170
|
+
else:
|
|
171
|
+
for figure in figures:
|
|
172
|
+
figure.proj_folder = {}
|
|
173
|
+
figure.proj_folder[proj_name] = folder_path
|
|
174
|
+
print("[Majo]: Project name and folder Paths applied.")
|
|
175
|
+
except ValueError:
|
|
176
|
+
print("[Majo]: Wrong Input.")
|
|
177
|
+
continue
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
index = int(answer)
|
|
182
|
+
except ValueError:
|
|
183
|
+
print("[Majo]: Wrong Input.")
|
|
184
|
+
continue
|
|
185
|
+
try:
|
|
186
|
+
chosed_figure = figures[index]
|
|
187
|
+
except IndexError:
|
|
188
|
+
print("[Majo]: You chosed a figure that doesn't exist.")
|
|
189
|
+
continue
|
|
190
|
+
|
|
191
|
+
while True:
|
|
192
|
+
print(f"[Majo]: This figure is chosed: ({index}) {chosed_figure.spec.name}")
|
|
193
|
+
print("[Majo]: What do you want to do now?")
|
|
194
|
+
print("\t- (D) Delete this figure.")
|
|
195
|
+
print("\t- (P) Preview this figure.")
|
|
196
|
+
print("\t- (S) Show current project_name:folder_path pairs.")
|
|
197
|
+
print("\t- (W) to write and apply a project_name:folder_path pair to all the figures")
|
|
198
|
+
print("\t- (O) to overwrite and apply a project_name:folder_path pair to all the figures")
|
|
199
|
+
print("\t- (C) Cancel and come back.")
|
|
200
|
+
choice = input("[You]:")
|
|
201
|
+
match choice.upper():
|
|
202
|
+
case "D":
|
|
203
|
+
del figures[index]
|
|
204
|
+
break
|
|
205
|
+
case "P":
|
|
206
|
+
import matplotlib.pyplot as plt
|
|
207
|
+
from ..infra.plotters.matplot import plot as mplot
|
|
208
|
+
mfigure = mplot(chosed_figure)
|
|
209
|
+
plt.figure(mfigure)
|
|
210
|
+
plt.show()
|
|
211
|
+
case "C":
|
|
212
|
+
break
|
|
213
|
+
case "S":
|
|
214
|
+
print(f"[Majo]: proj_name:folder_path pairs of {chosed_figure.spec.name}:")
|
|
215
|
+
print("\n".join(f"\t- {proj_name}: {folder_path}" for proj_name, folder_path in chosed_figure.proj_folder.items()))
|
|
216
|
+
case "W" | "O":
|
|
217
|
+
print("[Majo]: Please input a 'proj_name:folder_path' pair. For example: '20260115:MT/LNO'.")
|
|
218
|
+
try:
|
|
219
|
+
pair = input("[You]:").split(":")
|
|
220
|
+
proj_name, folder_path = pair[0:2]
|
|
221
|
+
if choice == "W":
|
|
222
|
+
chosed_figure.proj_folder[proj_name] = folder_path
|
|
223
|
+
else:
|
|
224
|
+
chosed_figure.proj_folder = {}
|
|
225
|
+
chosed_figure.proj_folder[proj_name] = folder_path
|
|
226
|
+
print("[Majo]: Project name and folder Paths applied.")
|
|
227
|
+
except ValueError:
|
|
228
|
+
print("[Majo]: Wrong Input.")
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
print("======== Step 3 ========")
|
|
232
|
+
print("[Majo]: Please pick a directory to save opju")
|
|
233
|
+
proj_dir = pick_directory(title="Select the directory of OPJU", initial_dir=".")
|
|
234
|
+
while True:
|
|
235
|
+
print("[Majo]: [A] Attach or [O] Overwrite?")
|
|
236
|
+
choice = input("[You]:")
|
|
237
|
+
match choice.upper():
|
|
238
|
+
case "A":
|
|
239
|
+
overwrite = False
|
|
240
|
+
break
|
|
241
|
+
case "O":
|
|
242
|
+
overwrite = True
|
|
243
|
+
break
|
|
244
|
+
case _:
|
|
245
|
+
print("[Majo]: Wrong Input.")
|
|
246
|
+
|
|
247
|
+
projs = pack_into_project(figures)
|
|
248
|
+
print("[Majo]: Launching OriginCOM...")
|
|
249
|
+
with OriginCOM(visible=False) as og:
|
|
250
|
+
for proj_name, proj in projs.items():
|
|
251
|
+
print(f"[Majo]: ploting in the project {proj_name}...")
|
|
252
|
+
oplot(proj, proj_name, og, proj_dir=proj_dir,overwrite=overwrite)
|
|
253
|
+
for folder_name, folder in proj.items():
|
|
254
|
+
for figure_name in folder:
|
|
255
|
+
print(f"\tPlotted: Figure {figure_name} in folder {folder_name}.")
|
|
256
|
+
print("[Majo]: Done.")
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
majoplot/app/gui.py
ADDED