Coverage for python/gsfit/database_readers/st40_astra_mdsplus/setup_flux_loops.py: 0%
31 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
1# mypy: ignore-errors
2# TODO: need to fix mypy errors
4import typing
5from typing import TYPE_CHECKING
7import mdsthin
8import numpy as np
9import numpy.typing as npt
10from gsfit_rs import FluxLoops
12from .astra_flux_loop_reader import astra_flux_loop_reader
14if TYPE_CHECKING:
15 from . import DatabaseReader
18def setup_flux_loops(
19 self: "DatabaseReader",
20 pulseNo: int,
21 settings: dict[str, typing.Any],
22) -> FluxLoops:
23 """
24 This method initialises the Rust `FluxLoops` class.
26 :param pulseNo: Pulse number, used to read from the database
27 :param settings: Dictionary containing the JSON settings read from the `settings` directory
29 **This method is specific to ST40's ASTRA stored on MDSplus.**
31 See `python/gsfit/database_readers/interface.py` for more details on how a new database_reader should be implemented.
32 """
34 # Initialise the FluxLoops Rust class
35 flux_loops = FluxLoops()
37 # Extract the astra_run_name from settings
38 astra_run_name = settings["GSFIT_code_settings.json"]["database_reader"]["st40_astra_mdsplus"]["workflow"]["astra"]["run_name"]
40 # Connect to MDSplus
41 conn = mdsthin.Connection("smaug")
42 conn.openTree("ASTRA", pulseNo)
44 # ASTRA flux_loops
45 time = conn.get(f"\\ASTRA::TOP.{astra_run_name}:TIME").data().astype(np.float64)
46 measurements = conn.get(f"\\ASTRA::TOP.{astra_run_name}.FLOOP.ALL:PSI").data().astype(np.float64)
47 names = conn.get(f"\\ASTRA::TOP.{astra_run_name}.FLOOP.ALL:NAME").data().astype(str)
49 # Read flux loop geometry from fl_loop.dat
50 flux_loops_data = astra_flux_loop_reader()
52 for flux_loop_name, data in flux_loops_data.items():
53 sensor_name = flux_loop_name.replace("FLOOP_", "L")
55 if sensor_name in settings["sensor_weights_flux_loops.json"]:
56 fit_settings_comment = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["comment"]
57 fit_settings_expected_value = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["expected_value"]
58 fit_settings_include = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["include"]
59 fit_settings_weight = settings["sensor_weights_flux_loops.json"][sensor_name]["fit_settings"]["weight"] / (2.0 * np.pi)
60 else:
61 fit_settings_comment = ""
62 fit_settings_expected_value = np.nan
63 fit_settings_include = False
64 fit_settings_weight = np.nan
66 # Measured values
67 index = names == flux_loop_name
68 measured = measurements[:, index].squeeze()
70 # Add the sensor to the Rust class
71 flux_loops.add_sensor(
72 name=sensor_name,
73 geometry_r=data["r"],
74 geometry_z=data["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 time=time,
80 measured=measured,
81 )
83 return flux_loops