Coverage for python/gsfit/database_readers/mock_st40_mdsplus/__init__.py: 0%
55 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-14 15:25 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-14 15:25 +0000
1"""
2`mock_st40_mdsplus` database reader.
4Rebuilds the GSFit Rust objects from a mock of ST40's MDSplus database, frozen to a
5single time-slice, instead of a live database. This lets a reconstruction run in CI
6with no database, network, or `st40_database` dependency.
8The build logic mirrors the `st40_mdsplus` reader, but every `GetData(...).get()` is
9replaced by a lookup into the mock via `MockGetData`.
11Each (tree, pulse) is mocked by a single `.npz`, mirroring how MDSplus itself stores
12one tree per shot (`gsfit_66014427.tree`, `gsfit_66014427.datafile`, ...):
13 `mdsplus_mock_mag_12050.npz`
15Each archive member is named for the bare MDSplus node path, e.g. `BPPROBE.P101.B`,
16because the tree and pulse are already carried by the filename. Capture provenance is
17stored inside the same archive under `__metadata__`, so it cannot drift away from the
18data it describes. The files are produced by `investigation/capture_snapshot.py`.
20Which tree, pulse and run each read maps to comes from the `workflow` settings, exactly
21as it does for the live `st40_mdsplus` reader:
22 settings["GSFIT_code_settings.json"]["database_reader"]["mock_st40_mdsplus"]
23 ["mock_dir"] directory holding the `.npz` files
24 ["workflow"] {workflow_name: {tree_name, pulseNo, run_name, usage}}
25A `pulseNo` of `None` means "use the shot's pulseNo"; the machine-description reads pin
26their own fixed pulse. See `tests/test_02_delta_z_shift_greater_than_d_z` for an example.
27"""
29import typing
31from gsfit_rs import BpProbes
32from gsfit_rs import Coils
33from gsfit_rs import Dialoop
34from gsfit_rs import FluxLoops
35from gsfit_rs import Isoflux
36from gsfit_rs import IsofluxBoundary
37from gsfit_rs import Passives
38from gsfit_rs import Plasma
39from gsfit_rs import Pressure
40from gsfit_rs import RogowskiCoils
41from gsfit_rs import StationaryPoint
42from gsfit_rs import Tf
43from gsfit_rs import Wall
45from ..interface import DatabaseReaderProtocol
46from .setup_bp_probes import setup_bp_probes
47from .setup_coils import setup_coils
48from .setup_dialoop import setup_dialoop
49from .setup_flux_loops import setup_flux_loops
50from .setup_isoflux_boundary_sensors import setup_isoflux_boundary_sensors
51from .setup_isoflux_sensors import setup_isoflux_sensors
52from .setup_passives import setup_passives
53from .setup_plasma import setup_plasma
54from .setup_pressure_sensors import setup_pressure_sensors
55from .setup_rogowski_coils import setup_rogowski_coils
56from .setup_stationary_point_sensors import setup_stationary_point_sensors
57from .setup_tf import setup_tf
58from .setup_wall import setup_wall
61class DatabaseReader(DatabaseReaderProtocol):
62 """
63 This class inherits from the DatabaseReaderProtocol, which defines the inputs and outputs to the class methods.
64 The methods in this class are used to initialise the Rust implementations.
65 Here we are binding the methods to the class.
67 See `python/gsfit/database_readers/interface.py` for the interface definitions.
68 """
70 def setup_bp_probes(self, *args: typing.Any, **kwargs: typing.Any) -> BpProbes:
71 return setup_bp_probes(self, *args, **kwargs)
73 def setup_coils(self, *args: typing.Any, **kwargs: typing.Any) -> Coils:
74 return setup_coils(self, *args, **kwargs)
76 def setup_dialoop(self, *args: typing.Any, **kwargs: typing.Any) -> Dialoop:
77 return setup_dialoop(self, *args, **kwargs)
79 def setup_flux_loops(self, *args: typing.Any, **kwargs: typing.Any) -> FluxLoops:
80 return setup_flux_loops(self, *args, **kwargs)
82 def setup_isoflux_boundary_sensors(self, *args: typing.Any, **kwargs: typing.Any) -> IsofluxBoundary:
83 return setup_isoflux_boundary_sensors(self, *args, **kwargs)
85 def setup_isoflux_sensors(self, *args: typing.Any, **kwargs: typing.Any) -> Isoflux:
86 return setup_isoflux_sensors(self, *args, **kwargs)
88 def setup_stationary_point_sensors(self, *args: typing.Any, **kwargs: typing.Any) -> StationaryPoint:
89 return setup_stationary_point_sensors(self, *args, **kwargs)
91 def setup_tf(self, *args: typing.Any, **kwargs: typing.Any) -> Tf:
92 return setup_tf(self, *args, **kwargs)
94 def setup_wall(self, *args: typing.Any, **kwargs: typing.Any) -> Wall:
95 return setup_wall(self, *args, **kwargs)
97 def setup_passives(self, *args: typing.Any, **kwargs: typing.Any) -> Passives:
98 return setup_passives(self, *args, **kwargs)
100 def setup_plasma(self, *args: typing.Any, **kwargs: typing.Any) -> Plasma:
101 return setup_plasma(self, *args, **kwargs)
103 def setup_pressure_sensors(self, *args: typing.Any, **kwargs: typing.Any) -> Pressure:
104 return setup_pressure_sensors(self, *args, **kwargs)
106 def setup_rogowski_coils(self, *args: typing.Any, **kwargs: typing.Any) -> RogowskiCoils:
107 return setup_rogowski_coils(self, *args, **kwargs)