Coverage for python/gsfit/database_readers/freegsnke/setup_flux_loops.py: 87%
30 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
1import typing
2from typing import TYPE_CHECKING
4import numpy as np
5import numpy.typing as npt
6from freegsnke.equilibrium_update import Equilibrium as FreeGsnkeEquilibrium
7from gsfit_rs import FluxLoops
9if TYPE_CHECKING:
10 from . import DatabaseReader
13def setup_flux_loops(
14 self: "DatabaseReader",
15 pulseNo: int,
16 settings: dict[str, typing.Any],
17 time: npt.NDArray[np.float64],
18 freegsnke_eqs: list[FreeGsnkeEquilibrium],
19) -> FluxLoops:
20 """
21 This method initialises the Rust `FluxLoops` class.
23 :param pulseNo: Pulse number, used to read from the database
24 :param settings: Dictionary containing the JSON settings read from the `settings` directory
25 :param time: Measured time vector
26 :param freegsnke_eqs: List of FreeGSNKE equilibrium objects, one for each time-slice
28 **This method is specific to FreeGSNKE.**
30 See `python/gsfit/database_readers/interface.py` for more details on how a new database_reader should be implemented.
31 """
33 # Initialise the FluxLoops Rust class
34 flux_loops = FluxLoops()
36 # We assume that the static data is not changing in time
37 freegsnke_tokamak = freegsnke_eqs[0].tokamak
39 # Get lengths
40 n_time = len(time)
41 n_sensors = len(freegsnke_tokamak.probes.floops)
43 # Loop over time and calculate the pickup values
44 pickups_vals = np.full((n_time, n_sensors), np.nan)
45 for i_time in range(n_time):
46 pickups_vals[i_time, :] = freegsnke_tokamak.probes.calculate_fluxloop_value(freegsnke_eqs[i_time])
48 for i_sensor, sensor in enumerate(freegsnke_tokamak.probes.floops):
49 # Get the sensor name
50 sensor_name = sensor["name"]
52 if sensor_name in settings["sensor_weights_flux_loops.json"]:
53 fit_settings_comment = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["comment"]
54 fit_settings_expected_value = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["expected_value"]
55 fit_settings_include = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["include"]
56 fit_settings_weight = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["weight"] / (2.0 * np.pi)
57 else:
58 fit_settings_comment = ""
59 fit_settings_expected_value = np.nan
60 fit_settings_include = False
61 fit_settings_weight = np.nan
63 # Get the sensor position
64 r = sensor["position"][0]
65 z = sensor["position"][1]
67 # Get the sensor data, all times
68 measured = pickups_vals[:, i_sensor] * 2.0 * np.pi # convert from "weber / (2.0 * pi)" to "weber"
70 # Add the sensor to the FluxLoop class
71 flux_loops.add_sensor(
72 name=sensor_name,
73 geometry_r=r,
74 geometry_z=z,
75 fit_settings_comment=fit_settings_comment,
76 fit_settings_expected_value=fit_settings_expected_value,
77 fit_settings_include=fit_settings_include,
78 fit_settings_weight=fit_settings_weight,
79 measured=measured,
80 time=np.array([0.0, 1.0]),
81 )
83 return flux_loops