-
Notifications
You must be signed in to change notification settings - Fork 0
/
plot_dbg_json.py
executable file
·147 lines (119 loc) · 5.21 KB
/
plot_dbg_json.py
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python3
import os
import sys
import json
import argparse
import numpy as np
import matplotlib.pyplot as plt
def plot_dbg_json(json_filename, quantities, surfaces):
# put plots into a folder "plots" next to the given JSON file
json_folder = os.path.normpath(os.path.dirname(json_filename))
plots_folder = os.path.join(json_folder, "plots")
os.makedirs(plots_folder, exist_ok=True)
# assume that the given JSON file was created by educational_VMEC
# --> first item of filename is context in which the corresponding file was created
# --> last item of filename before ".json" is extension of corresponding VMEC run
json_basename = os.path.basename(json_filename)
parts_by_underscore = json_basename.split("_")
dump_context = parts_by_underscore[0]
first_dot_pos = json_basename.find(".")
last_dot_pos = json_basename.rfind(".")
if first_dot_pos < 0 or last_dot_pos < 0:
raise RuntimeError("extension not found in JSON filename")
extension = json_basename[first_dot_pos+1:last_dot_pos]
# read all data from JSON file given as first command-line argument
data = None
with open(json_filename, "r") as f:
data = json.load(f)
# check that if the user specified a subset of quantities to plot,
# all requested quantities are present in the given JSON file
if quantities is not None:
for quantity in quantities:
if quantity not in data:
print(f"ERROR: requested quantity '{quantity}' not found in JSON file '{json_filename}'.")
sys.exit(-1)
# iterate over all quantities in JSON file
plt.figure(figsize=(10,5))
num_keys = len(data.keys())
for index, key in enumerate(data.keys()):
# if a subset of quantities to plot is specified,
# skip all that are not in the user-specified list to be plotted
if quantities is not None and key not in quantities:
continue
value = np.array(data[key])
num_dimensions = len(np.shape(value))
if num_dimensions == 1:
print("plot quantity %s (%d/%d) from context %s in VMEC run %s"%(
key, index, num_keys,
dump_context,
extension
))
plt.clf()
plt.plot(value, ".-")
plt.title(f"{extension} {key}")
plt.tight_layout()
fig_filename = f"{extension}_{dump_context}_{key}.pdf"
plt.savefig(os.path.join(plots_folder, fig_filename))
elif num_dimensions == 2:
print("plot quantity %s (%d/%d) from context %s in VMEC run %s"%(
key, index, num_keys,
dump_context,
extension
))
plt.clf()
plt.imshow(value[:, :].T, origin='upper', cmap='jet')
plt.colorbar()
plt.xlabel("toroidal grid point index")
plt.ylabel("poloidal grid point index")
plt.title(f"{extension} {key}")
plt.tight_layout()
fig_filename = f"{extension}_{dump_context}_{key}.pdf"
plt.savefig(os.path.join(plots_folder, fig_filename))
elif num_dimensions == 3:
# hint: in forces JSON debug output, all arrays are shaped as follows: [ns, nzeta, ntheta3]
ns = value.shape[0]
# iterate over all flux surfaces
for js in range(ns):
# if a subset of surfaces to plot is specified,
# skip all that are not in the user-specified list to be plotted
if surfaces is not None and js not in surfaces:
continue
print("plot quantity '%s' (%d/%d) at flux surface %d/%d from context '%s' in VMEC run '%s'"%(
key, index, num_keys,
js, ns,
dump_context,
extension
))
plt.clf()
plt.imshow(value[js, :, :].T, origin='upper', cmap='jet')
plt.colorbar()
plt.xlabel("toroidal grid point index")
plt.ylabel("poloidal grid point index")
plt.title(f"{extension} {key} js={js}")
plt.tight_layout()
fig_filename = f"{extension}_{dump_context}_{key}_{ns}_{js}.pdf"
plt.savefig(os.path.join(plots_folder, fig_filename))
else:
print(f"skip {key} as it is not a 1D, 2D or 3D array (has {num_dimensions} dimensions)")
continue
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Plot debugging output from JSON output of educational_VMEC"
)
parser.add_argument("filename", type=str, help="The JSON file to inspect.")
parser.add_argument(
"--quantities",
type=str,
nargs="+",
help="The quantities from the JSON file to plot (default: all).",
)
parser.add_argument(
"--surfaces",
type=int,
nargs="+",
help="The flux surface indices (0 is axis, ns-1 is LCFS) to plot for 3D arrays (default: all).",
)
args = parser.parse_args()
plot_dbg_json(json_filename=args.filename,
quantities=args.quantities,
surfaces=args.surfaces)