Coverage for python/gsfit/database_readers/freegs/setup_flux_loops.py: 0%
38 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 freegs
5import numpy as np
6import numpy.typing as npt
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 freegs_eqs: list[freegs.equilibrium.Equilibrium],
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 freegs_eqs: List of FreeGS equilibrium objects, one for each time-slice
28 **This method is specific to FreeGS.**
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 n_time = len(time)
38 # Let's see how many flux loops there are
39 n_flux_loops = 0
40 for sensor in freegs_eqs[0].tokamak.sensors:
41 if isinstance(sensor, freegs.machine.FluxLoopSensor):
42 n_flux_loops += 1
44 # Collect the measured values
45 measured_values = np.full((n_time, n_flux_loops), np.nan)
46 for i_time in range(n_time):
47 i_sensor = 0
48 for sensor in freegs_eqs[i_time].tokamak.sensors:
49 if isinstance(sensor, freegs.machine.FluxLoopSensor):
50 measured_values[i_time, i_sensor] = sensor.measurement * 2.0 * np.pi
51 i_sensor += 1
53 # Add the sensors to the FluxLoops class
54 i_sensor = 0
55 for sensor in freegs_eqs[0].tokamak.sensors:
56 if isinstance(sensor, freegs.machine.FluxLoopSensor):
57 sensor_name = sensor.name
58 r = sensor.R
59 z = sensor.Z
61 if sensor_name in settings["sensor_weights_flux_loops.json"]:
62 fit_settings_comment = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["comment"]
63 fit_settings_expected_value = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["expected_value"]
64 fit_settings_include = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["include"]
65 fit_settings_weight = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["weight"] / (2.0 * np.pi)
66 else:
67 fit_settings_comment = ""
68 fit_settings_expected_value = np.nan
69 fit_settings_include = False
70 fit_settings_weight = np.nan
72 # Add the sensor to the FluxLoops class
73 flux_loops.add_sensor(
74 name=sensor_name,
75 geometry_r=r,
76 geometry_z=z,
77 fit_settings_comment=fit_settings_comment,
78 fit_settings_expected_value=fit_settings_expected_value,
79 fit_settings_include=fit_settings_include,
80 fit_settings_weight=fit_settings_weight,
81 time=time,
82 measured=measured_values[:, i_sensor],
83 )
85 # Increment the sensor index
86 i_sensor += 1
88 return flux_loops