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

1""" 

2`mock_st40_mdsplus` database reader. 

3 

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. 

7 

8The build logic mirrors the `st40_mdsplus` reader, but every `GetData(...).get()` is 

9replaced by a lookup into the mock via `MockGetData`. 

10 

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` 

14 

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`. 

19 

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""" 

28 

29import typing 

30 

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 

44 

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 

59 

60 

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. 

66 

67 See `python/gsfit/database_readers/interface.py` for the interface definitions. 

68 """ 

69 

70 def setup_bp_probes(self, *args: typing.Any, **kwargs: typing.Any) -> BpProbes: 

71 return setup_bp_probes(self, *args, **kwargs) 

72 

73 def setup_coils(self, *args: typing.Any, **kwargs: typing.Any) -> Coils: 

74 return setup_coils(self, *args, **kwargs) 

75 

76 def setup_dialoop(self, *args: typing.Any, **kwargs: typing.Any) -> Dialoop: 

77 return setup_dialoop(self, *args, **kwargs) 

78 

79 def setup_flux_loops(self, *args: typing.Any, **kwargs: typing.Any) -> FluxLoops: 

80 return setup_flux_loops(self, *args, **kwargs) 

81 

82 def setup_isoflux_boundary_sensors(self, *args: typing.Any, **kwargs: typing.Any) -> IsofluxBoundary: 

83 return setup_isoflux_boundary_sensors(self, *args, **kwargs) 

84 

85 def setup_isoflux_sensors(self, *args: typing.Any, **kwargs: typing.Any) -> Isoflux: 

86 return setup_isoflux_sensors(self, *args, **kwargs) 

87 

88 def setup_stationary_point_sensors(self, *args: typing.Any, **kwargs: typing.Any) -> StationaryPoint: 

89 return setup_stationary_point_sensors(self, *args, **kwargs) 

90 

91 def setup_tf(self, *args: typing.Any, **kwargs: typing.Any) -> Tf: 

92 return setup_tf(self, *args, **kwargs) 

93 

94 def setup_wall(self, *args: typing.Any, **kwargs: typing.Any) -> Wall: 

95 return setup_wall(self, *args, **kwargs) 

96 

97 def setup_passives(self, *args: typing.Any, **kwargs: typing.Any) -> Passives: 

98 return setup_passives(self, *args, **kwargs) 

99 

100 def setup_plasma(self, *args: typing.Any, **kwargs: typing.Any) -> Plasma: 

101 return setup_plasma(self, *args, **kwargs) 

102 

103 def setup_pressure_sensors(self, *args: typing.Any, **kwargs: typing.Any) -> Pressure: 

104 return setup_pressure_sensors(self, *args, **kwargs) 

105 

106 def setup_rogowski_coils(self, *args: typing.Any, **kwargs: typing.Any) -> RogowskiCoils: 

107 return setup_rogowski_coils(self, *args, **kwargs)