Coverage for python/gsfit/database_writers/tokamak_energy_mdsplus/map_results_to_database.py: 66%
172 statements
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-07 13:12 +0000
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-07 13:12 +0000
1from typing import TYPE_CHECKING
3import numpy as np
5# from st40_database import GetData
7if TYPE_CHECKING:
8 from ...gsfit import Gsfit
9 from . import DatabaseWriterTokamakEnergyMDSplus
12def map_results_to_database(
13 self: "DatabaseWriterTokamakEnergyMDSplus",
14 gsfit_controller: "Gsfit",
15) -> None:
16 """Map the results to MDSplus structure.
17 `gsfit_controller.results` is a `NestedDict` object, which is a 1:1 mapping to the MDSplus structure.
18 This function will mutate the `gsfit_controller` object.
19 """
21 # Take class object out of the `gsfit_controller` object
22 pulseNo = gsfit_controller.pulseNo
23 settings = gsfit_controller.settings
24 plasma = gsfit_controller.plasma
25 bp_probes = gsfit_controller.bp_probes
26 flux_loops = gsfit_controller.flux_loops
27 rogowski_coils = gsfit_controller.rogowski_coils
28 passives = gsfit_controller.passives
29 results = gsfit_controller.results
30 pressure_sensors = gsfit_controller.pressure_sensors
32 # Two-d
33 results["TWO_D"]["BR"] = plasma.get_array3(["two_d", "br"])
34 results["TWO_D"]["BT"] = plasma.get_array3(["two_d", "bt"])
35 results["TWO_D"]["BZ"] = plasma.get_array3(["two_d", "bz"])
36 results["TWO_D"]["MASK"] = plasma.get_array3(["two_d", "mask"])
37 results["TWO_D"]["P"] = plasma.get_array3(["two_d", "p"])
38 results["TWO_D"]["PSI"] = plasma.get_array3(["two_d", "psi"])
39 results["TWO_D"]["RGRID"] = plasma.get_array1(["grid", "r"])
40 results["TWO_D"]["ZGRID"] = plasma.get_array1(["grid", "z"])
42 # Global
43 results["GLOBAL"]["BETA_N"] = plasma.get_array1(["global", "beta_n"])
44 results["GLOBAL"]["BETA_P_1"] = plasma.get_array1(["global", "beta_p_1"])
45 results["GLOBAL"]["BETA_P_2"] = plasma.get_array1(["global", "beta_p_2"])
46 results["GLOBAL"]["BETA_P_3"] = plasma.get_array1(["global", "beta_p_3"])
47 results["GLOBAL"]["BETA_T"] = plasma.get_array1(["global", "beta_t"])
48 results["GLOBAL"]["BT_VAC_RGEO"] = plasma.get_array1(["global", "bt_vac_at_r_geo"])
49 results["GLOBAL"]["CHI_MAG"] = plasma.get_array1(["global", "chi_mag"])
50 results["GLOBAL"]["LI_1"] = plasma.get_array1(["global", "li_1"])
51 results["GLOBAL"]["LI_2"] = plasma.get_array1(["global", "li_2"])
52 results["GLOBAL"]["LI_3"] = plasma.get_array1(["global", "li_3"])
53 results["GLOBAL"]["DELTA_Z"] = plasma.get_array1(["global", "delta_z"])
54 results["GLOBAL"]["ELON"] = plasma.get_array1(["global", "elongation"])
55 results["GLOBAL"]["PHI_DIA"] = plasma.get_array1(["global", "phi_dia"])
56 results["GLOBAL"]["GS_ERROR"] = plasma.get_array1(["global", "gs_error"])
57 results["GLOBAL"]["I_ROD"] = plasma.get_array1(["global", "i_rod"])
58 results["GLOBAL"]["IP"] = plasma.get_array1(["global", "ip"])
59 results["GLOBAL"]["N_ITER"] = np.array(plasma.get_vec_usize(["global", "n_iter"])).astype(np.int32)
60 results["GLOBAL"]["P"] = plasma.get_array1(["global", "p"])
61 results["GLOBAL"]["PSI_A"] = plasma.get_array1(["global", "psi_a"])
62 results["GLOBAL"]["PSI_B"] = plasma.get_array1(["global", "psi_b"])
63 results["GLOBAL"]["Q0"] = plasma.get_array1(["global", "q0"])
64 results["GLOBAL"]["Q95"] = plasma.get_array1(["global", "q95"])
65 results["GLOBAL"]["R_CUR"] = plasma.get_array1(["global", "r_cur"])
66 results["GLOBAL"]["Z_CUR"] = plasma.get_array1(["global", "z_cur"])
67 results["GLOBAL"]["R_GEO"] = plasma.get_array1(["global", "r_geo"])
68 results["GLOBAL"]["Z_GEO"] = plasma.get_array1(["global", "z_geo"])
69 results["GLOBAL"]["R_MAG"] = plasma.get_array1(["global", "r_mag"])
70 results["GLOBAL"]["Z_MAG"] = plasma.get_array1(["global", "z_mag"])
71 results["GLOBAL"]["R_MINOR"] = plasma.get_array1(["global", "r_minor"])
72 results["GLOBAL"]["V_LOOP"] = plasma.get_array1(["global", "v_loop"])
73 results["GLOBAL"]["VPLASMA"] = plasma.get_array1(["global", "plasma_volume"])
74 results["GLOBAL"]["W_MHD"] = plasma.get_array1(["global", "w_mhd"])
75 results["GLOBAL"]["XPT_DIVERTED"] = np.array(plasma.get_vec_bool(["global", "xpt_diverted"])).astype(np.int32)
77 # Bp probes (note, this is all the sensors, both the ones we fit and the ones we don't)
78 bp_names = bp_probes.keys() # list of strings; len(bp_names) = n_sensors
79 bp_names = [bp_name.replace("P", "B_BPPROBE_") for bp_name in bp_names]
80 results["CONSTRAINTS"]["BPPROBE"]["NAME"] = np.array(bp_names) # MDSplus requires numpy objects, not lists of strings; shape = [n_sensors]
81 results["CONSTRAINTS"]["BPPROBE"]["CVALUE"] = bp_probes.get_array2(["*", "b", "calculated", "value"]) # shape = [n_time, n_sensors]
82 results["CONSTRAINTS"]["BPPROBE"]["INCLUDE"] = np.array(bp_probes.get_vec_bool(["*", "fit_settings", "include"])).astype(np.int32)
83 results["CONSTRAINTS"]["BPPROBE"]["MVALUE"] = bp_probes.get_array2(["*", "b", "measured", "value"]) # shape = [n_time, n_sensors]
84 results["CONSTRAINTS"]["BPPROBE"]["WEIGHT"] = bp_probes.get_array1(["*", "fit_settings", "weight"]) # shape = [n_sensors]
86 # Flux loops (note, this is all the sensors, both the ones we fit and the ones we don't)
87 fl_names = flux_loops.keys() # list of strings; len(fl_names) = n_sensors
88 fl_names = [fl_name.replace("L", "PSI_FLOOP_") for fl_name in fl_names]
89 results["CONSTRAINTS"]["FLOOP"]["NAME"] = np.array(fl_names) # MDSplus requires numpy objects, not lists of strings; shape = [n_sensors]
90 results["CONSTRAINTS"]["FLOOP"]["CVALUE"] = flux_loops.get_array2(["*", "psi", "calculated", "value"]) # shape = [n_time, n_sensors]
91 results["CONSTRAINTS"]["FLOOP"]["INCLUDE"] = np.array(flux_loops.get_vec_bool(["*", "fit_settings", "include"])).astype(np.int32)
92 results["CONSTRAINTS"]["FLOOP"]["MVALUE"] = flux_loops.get_array2(["*", "psi", "measured", "value"]) # shape = [n_time, n_sensors]
93 results["CONSTRAINTS"]["FLOOP"]["WEIGHT"] = flux_loops.get_array1(["*", "fit_settings", "weight"]) # shape = [n_sensors]
95 # Rogowski coils (note, this is all the sensors, both the ones we fit and the ones we don't)
96 rog_names = rogowski_coils.keys() # list of strings; len(rog_names) = n_sensors
97 rog_names = [f"I_ROG_{rog_name}" for rog_name in rog_names]
98 results["CONSTRAINTS"]["ROG"]["NAME"] = np.array(rog_names) # MDSplus requires numpy objects, not lists of strings; shape = [n_sensors]
99 results["CONSTRAINTS"]["ROG"]["CVALUE"] = rogowski_coils.get_array2(["*", "i", "calculated", "value"]) # shape = [n_time, n_sensors]
100 results["CONSTRAINTS"]["ROG"]["INCLUDE"] = np.array(rogowski_coils.get_vec_bool(["*", "fit_settings", "include"])).astype(np.int32)
101 results["CONSTRAINTS"]["ROG"]["MVALUE"] = rogowski_coils.get_array2(["*", "i", "measured", "value"]) # shape = [n_time, n_sensors]
102 results["CONSTRAINTS"]["ROG"]["WEIGHT"] = rogowski_coils.get_array1(["*", "fit_settings", "weight"]) # shape = [n_sensors]
104 # Plasma boundary
105 results["P_BOUNDARY"]["NBND"] = np.array(plasma.get_vec_usize(["p_boundary", "nbnd"]))
106 results["P_BOUNDARY"]["RBND"] = plasma.get_array2(["p_boundary", "rbnd"])
107 results["P_BOUNDARY"]["ZBND"] = plasma.get_array2(["p_boundary", "zbnd"])
108 results["P_BOUNDARY"]["BOUNDING_R"] = plasma.get_array1(["p_boundary", "bounding_r"])
109 results["P_BOUNDARY"]["BOUNDING_Z"] = plasma.get_array1(["p_boundary", "bounding_z"])
111 # X-points
112 results["XPOINTS"]["UPPER"]["R"] = plasma.get_array1(["xpoints", "upper", "r"])
113 results["XPOINTS"]["UPPER"]["Z"] = plasma.get_array1(["xpoints", "upper", "z"])
114 results["XPOINTS"]["LOWER"]["R"] = plasma.get_array1(["xpoints", "lower", "r"])
115 results["XPOINTS"]["LOWER"]["Z"] = plasma.get_array1(["xpoints", "lower", "z"])
117 # Profiles
118 results["PROFILES"]["RHO"]["AREA"] = plasma.get_array2(["profiles", "area"])
119 results["PROFILES"]["RHO"]["AREA_PRIME"] = plasma.get_array2(["profiles", "area_prime"])
120 results["PROFILES"]["RHO"]["F"] = plasma.get_array2(["profiles", "f"])
121 results["PROFILES"]["RHO"]["FF_PRIME"] = plasma.get_array2(["profiles", "ff_prime"])
122 results["PROFILES"]["RHO"]["FLUX_TOR"] = plasma.get_array2(["profiles", "flux_tor"])
123 results["PROFILES"]["RHO"]["P"] = plasma.get_array2(["profiles", "p"])
124 results["PROFILES"]["RHO"]["P_PRIME"] = plasma.get_array2(["profiles", "p_prime"])
125 results["PROFILES"]["RHO"]["Q"] = plasma.get_array2(["profiles", "q"])
126 results["PROFILES"]["RHO"]["RHO_POL"] = plasma.get_array2(["profiles", "rho_pol"])
127 results["PROFILES"]["RHO"]["RHO_TOR"] = plasma.get_array2(["profiles", "rho_tor"])
128 results["PROFILES"]["RHO"]["PSI_N"] = plasma.get_array1(["profiles", "psi_n"])
129 results["PROFILES"]["RHO"]["VOL"] = plasma.get_array2(["profiles", "vol"])
130 results["PROFILES"]["RHO"]["VOL_PRIME"] = plasma.get_array2(["profiles", "vol_prime"])
132 # Mid-plane profiles
133 results["PROFILES"]["MID_PLANE"]["P"] = plasma.get_array2(["profiles", "mid_plane", "p"])
134 results["PROFILES"]["MID_PLANE"]["R"] = plasma.get_array1(["profiles", "mid_plane", "r"])
136 # Passives
137 for passive_name in passives.keys():
138 if passive_name == "IVC":
139 results["PASSIVES"]["IVC"]["DOF"]["EIG_01"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_01", "calculated"])
140 results["PASSIVES"]["IVC"]["DOF"]["EIG_01"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_01", "current_distribution"])
141 results["PASSIVES"]["IVC"]["DOF"]["EIG_02"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_02", "calculated"])
142 results["PASSIVES"]["IVC"]["DOF"]["EIG_02"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_02", "current_distribution"])
143 results["PASSIVES"]["IVC"]["DOF"]["EIG_03"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_03", "calculated"])
144 results["PASSIVES"]["IVC"]["DOF"]["EIG_03"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_03", "current_distribution"])
145 results["PASSIVES"]["IVC"]["DOF"]["EIG_04"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_04", "calculated"])
146 results["PASSIVES"]["IVC"]["DOF"]["EIG_04"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_04", "current_distribution"])
147 results["PASSIVES"]["IVC"]["DOF"]["EIG_05"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_05", "calculated"])
148 results["PASSIVES"]["IVC"]["DOF"]["EIG_05"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_05", "current_distribution"])
149 results["PASSIVES"]["IVC"]["DOF"]["EIG_06"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_06", "calculated"])
150 results["PASSIVES"]["IVC"]["DOF"]["EIG_06"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_06", "current_distribution"])
151 results["PASSIVES"]["IVC"]["DOF"]["EIG_07"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_07", "calculated"])
152 results["PASSIVES"]["IVC"]["DOF"]["EIG_07"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_07", "current_distribution"])
153 results["PASSIVES"]["IVC"]["DOF"]["EIG_08"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_08", "calculated"])
154 results["PASSIVES"]["IVC"]["DOF"]["EIG_08"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_08", "current_distribution"])
155 results["PASSIVES"]["IVC"]["DOF"]["EIG_09"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_09", "calculated"])
156 results["PASSIVES"]["IVC"]["DOF"]["EIG_09"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_09", "current_distribution"])
157 results["PASSIVES"]["IVC"]["DOF"]["EIG_10"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_10", "calculated"])
158 results["PASSIVES"]["IVC"]["DOF"]["EIG_10"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_10", "current_distribution"])
159 results["PASSIVES"]["IVC"]["DOF"]["EIG_11"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_11", "calculated"])
160 results["PASSIVES"]["IVC"]["DOF"]["EIG_11"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_11", "current_distribution"])
161 results["PASSIVES"]["IVC"]["DOF"]["EIG_12"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_12", "calculated"])
162 results["PASSIVES"]["IVC"]["DOF"]["EIG_12"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_12", "current_distribution"])
163 results["PASSIVES"]["IVC"]["DOF"]["EIG_13"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_13", "calculated"])
164 results["PASSIVES"]["IVC"]["DOF"]["EIG_13"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_13", "current_distribution"])
165 results["PASSIVES"]["IVC"]["DOF"]["EIG_14"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_14", "calculated"])
166 results["PASSIVES"]["IVC"]["DOF"]["EIG_14"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_14", "current_distribution"])
167 results["PASSIVES"]["IVC"]["DOF"]["EIG_15"]["CVALUE"] = passives.get_array1(["IVC", "dof", "eig_15", "calculated"])
168 results["PASSIVES"]["IVC"]["DOF"]["EIG_15"]["I_DIST"] = passives.get_array1(["IVC", "dof", "eig_15", "current_distribution"])
169 results["PASSIVES"]["IVC"]["GEOMETRY"]["ANGLE_1"] = passives.get_array1(["IVC", "geometry", "angle_1"])
170 results["PASSIVES"]["IVC"]["GEOMETRY"]["ANGLE_2"] = passives.get_array1(["IVC", "geometry", "angle_2"])
171 results["PASSIVES"]["IVC"]["GEOMETRY"]["D_R"] = passives.get_array1(["IVC", "geometry", "d_r"])
172 results["PASSIVES"]["IVC"]["GEOMETRY"]["D_Z"] = passives.get_array1(["IVC", "geometry", "d_z"])
173 results["PASSIVES"]["IVC"]["GEOMETRY"]["R"] = passives.get_array1(["IVC", "geometry", "r"])
174 results["PASSIVES"]["IVC"]["GEOMETRY"]["Z"] = passives.get_array1(["IVC", "geometry", "z"])
175 else:
176 results["PASSIVES"][passive_name]["DOF"]["CONSTANT_J"]["CVALUE"] = passives.get_array1(
177 [passive_name, "dof", "constant_current_density", "calculated"]
178 )
179 results["PASSIVES"][passive_name]["DOF"]["CONSTANT_J"]["I_DIST"] = passives.get_array1(
180 [passive_name, "dof", "constant_current_density", "current_distribution"]
181 )
182 results["PASSIVES"][passive_name]["GEOMETRY"]["ANGLE_1"] = passives.get_array1([passive_name, "geometry", "angle_1"])
183 results["PASSIVES"][passive_name]["GEOMETRY"]["ANGLE_2"] = passives.get_array1([passive_name, "geometry", "angle_2"])
184 results["PASSIVES"][passive_name]["GEOMETRY"]["D_R"] = passives.get_array1([passive_name, "geometry", "d_r"])
185 results["PASSIVES"][passive_name]["GEOMETRY"]["D_Z"] = passives.get_array1([passive_name, "geometry", "d_z"])
186 results["PASSIVES"][passive_name]["GEOMETRY"]["R"] = passives.get_array1([passive_name, "geometry", "r"])
187 results["PASSIVES"][passive_name]["GEOMETRY"]["Z"] = passives.get_array1([passive_name, "geometry", "z"])
189 # Scrape off layer (SOL)
190 results["SOL"]["HFS"]["CONTOUR"]["R"] = plasma.get_array2(["sol", "hfs", "contour", "r"]) # shape = [n_time, n_points]
191 results["SOL"]["HFS"]["CONTOUR"]["Z"] = plasma.get_array2(["sol", "hfs", "contour", "z"]) # shape = [n_time, n_points]
192 results["SOL"]["HFS"]["CONTOUR"]["N"] = np.array(plasma.get_vec_usize(["sol", "hfs", "contour", "n"])).astype(np.int32) # shape = [n_time]
193 results["SOL"]["HFS"]["STRIKE_POINT"]["R"] = plasma.get_array1(["sol", "hfs", "strike_point", "r"]) # shape = [n_time]
194 results["SOL"]["HFS"]["STRIKE_POINT"]["Z"] = plasma.get_array1(["sol", "hfs", "strike_point", "z"]) # shape = [n_time]
195 results["SOL"]["LFS"]["CONTOUR"]["R"] = plasma.get_array2(["sol", "lfs", "contour", "r"]) # shape = [n_time, n_points]
196 results["SOL"]["LFS"]["CONTOUR"]["Z"] = plasma.get_array2(["sol", "lfs", "contour", "z"]) # shape = [n_time, n_points]
197 results["SOL"]["LFS"]["CONTOUR"]["N"] = np.array(plasma.get_vec_usize(["sol", "lfs", "contour", "n"])).astype(np.int32) # shape = [n_time]
198 results["SOL"]["LFS"]["STRIKE_POINT"]["R"] = plasma.get_array1(["sol", "lfs", "strike_point", "r"]) # shape = [n_time]
199 results["SOL"]["LFS"]["STRIKE_POINT"]["Z"] = plasma.get_array1(["sol", "lfs", "strike_point", "z"]) # shape = [n_time]
201 if len(pressure_sensors.keys()) > 0:
202 results["CONSTRAINTS"]["PRESSURE"]["RECONSTRUCTED"] = pressure_sensors.get_array2(["*", "pressure", "calculated", "value"]) # shape = [n_time, n_points]
203 results["CONSTRAINTS"]["PRESSURE"]["MEASURED"] = pressure_sensors.get_array2(["*", "pressure", "measured", "value"]) # shape = [n_time, n_points]
204 results["CONSTRAINTS"]["PRESSURE"]["WEIGHT"] = pressure_sensors.get_array1(["*", "fit_settings", "weight"]) # shape = [n_points]
205 results["CONSTRAINTS"]["PRESSURE"]["POSITION"]["R"] = pressure_sensors.get_array1(["*", "geometry", "r"]) # shape = [n_points]
206 results["CONSTRAINTS"]["PRESSURE"]["POSITION"]["Z"] = pressure_sensors.get_array1(["*", "geometry", "z"]) # shape = [n_points]
207 results["CONSTRAINTS"]["PRESSURE"]["POSITION"]["PSI"] = pressure_sensors.get_array2(["*", "pressure", "calculated", "psi"]) # shape = [n_time, n_points]
209 # Store "WORKFLOW"
210 database_reader_method = settings["GSFIT_code_settings.json"]["database_reader"]["method"]
212 code_names = settings["GSFIT_code_settings.json"]["database_reader"][database_reader_method]["workflow"].keys()
214 for code_name in code_names:
215 pulseNo_json = settings["GSFIT_code_settings.json"]["database_reader"][database_reader_method]["workflow"][code_name]["pulseNo"]
216 if pulseNo_json is not None:
217 results["INPUT"]["WORKFLOW"][code_name]["PULSE"] = pulseNo_json
218 else:
219 results["INPUT"]["WORKFLOW"][code_name]["PULSE"] = pulseNo
221 run_name = settings["GSFIT_code_settings.json"]["database_reader"][database_reader_method]["workflow"][code_name]["run_name"]
222 results["INPUT"]["WORKFLOW"][code_name]["RUN"] = run_name
224 usage = settings["GSFIT_code_settings.json"]["database_reader"][database_reader_method]["workflow"][code_name]["usage"]
225 results["INPUT"]["WORKFLOW"][code_name]["USAGE"] = usage