Skip to content

MDSplus Connection

The MDSConnection class should be used for all data retrieval tasks from MDSplus. It is a simple wrapper for the MDSplus thin client.

disruption_py.inout.mds ¤

Module for managing connections to MDSplus.

ProcessMDSConnection ¤

Abstract class for connecting to MDSplus.

Ensure that a single MDSPlus connection is used by each process for all shots retrieved by that process.

Source code in disruption_py/inout/mds.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class ProcessMDSConnection:
    """
    Abstract class for connecting to MDSplus.

    Ensure that a single MDSPlus connection is used by each process for all shots
    retrieved by that process.
    """

    logger = logging.getLogger("disruption_py")

    def __init__(self, conn_string: str):
        self.conn = None
        if conn_string is None:
            return
        # pylint: disable=no-member
        self.conn = MDSplus.Connection(conn_string)
        try:
            self.conn.get("shorten_path()")
        except MDSplus.mdsExceptions.TdiUNKNOWN_VAR:
            self.logger.debug("MDSplus does not support the `shorten_path()` method.")

    @classmethod
    def from_config(cls, tokamak: Tokamak):
        """
        Create instance of the MDS connection based on the connection string
        from the configuration.
        """
        return SharedInstance(ProcessMDSConnection).get_instance(
            config(tokamak).MDSPLUS_CONNECTION_STRING
        )

    def get_shot_connection(self, shot_id: int):
        """Get MDSPlus Connection wrapper for individual shot."""
        return MDSConnection(self.conn, shot_id)
from_config classmethod ¤
from_config(tokamak: Tokamak)

Create instance of the MDS connection based on the connection string from the configuration.

Source code in disruption_py/inout/mds.py
40
41
42
43
44
45
46
47
48
@classmethod
def from_config(cls, tokamak: Tokamak):
    """
    Create instance of the MDS connection based on the connection string
    from the configuration.
    """
    return SharedInstance(ProcessMDSConnection).get_instance(
        config(tokamak).MDSPLUS_CONNECTION_STRING
    )
get_shot_connection ¤
get_shot_connection(shot_id: int)

Get MDSPlus Connection wrapper for individual shot.

Source code in disruption_py/inout/mds.py
50
51
52
def get_shot_connection(self, shot_id: int):
    """Get MDSPlus Connection wrapper for individual shot."""
    return MDSConnection(self.conn, shot_id)

MDSConnection ¤

Wrapper class for MDSPlus Connection class used for handling individual shots.

Source code in disruption_py/inout/mds.py
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
class MDSConnection:
    """
    Wrapper class for MDSPlus Connection class used for handling individual shots.
    """

    logger = logging.getLogger("disruption_py")

    def __init__(
        self, conn: MDSplus.Connection, shot_id: int  # pylint: disable=no-member
    ):
        self.conn = conn
        self.shot_id = shot_id
        self.tree_nickname_funcs = {}
        self.tree_nicknames = {}
        self.last_open_tree = None

    def open_tree(self, tree_name: str):
        """
        Open the specified _name.

        If the specified tree_name is a nickname for a tree_name, will open the tree
        that it is a nickname for.
        """
        if (
            tree_name not in self.tree_nicknames
            and tree_name in self.tree_nickname_funcs
        ):
            self.tree_nicknames[tree_name] = self.tree_nickname_funcs[tree_name]()

        if tree_name in self.tree_nicknames:
            tree_name = self.tree_nicknames[tree_name]

        if self.last_open_tree != tree_name:
            self.conn.openTree(tree_name, self.shot_id)

        self.last_open_tree = tree_name

    def cleanup(self):
        """
        Close all open trees
        """
        self.last_open_tree = None

    def get(self, expression: str, arguments: Any = None, tree_name: str = None) -> Any:
        """
        Evaluate the specified expression.

        The expression is passed as string argument, but may contain optional arguments.
        These arguments are then passed as an array of Data objects.

        Parameters
        ----------
        expression : str
            MDSplus TDI expression. Please see MDSplus documentation for more
            information.
        arguments : Any, optional
            Arguments for MDSplus TDI Expression. Please see MDSplus documentation
            for more information. Default None.
        tree_name : str, optional

        Returns
        -------
        Any
            Result of evaluating TDI expression from MDSplus.
        """
        if tree_name is not None:
            self.open_tree(tree_name)
        if arguments is None:
            return self.conn.get(expression)
        return self.conn.get(expression, arguments)

    # Convenience methods

    def get_data(
        self,
        path: str,
        tree_name: str = None,
        astype: str = None,
        arguments: Any = None,
    ) -> np.ndarray:
        """
        Get data for record at specified path.

        Parameters
        ----------
        path : str
            MDSplus path to record.
        tree_name : str, optional
            The name of the tree that must be open for retrieval.
        astype : str, optional
            The data type for explicit casting.
        arguments : Any, optional
            Arguments for MDSplus TDI Expression. Default None.
            Please see MDSplus documentation for more information.

        Returns
        -------
        np.ndarray
            Returns the node data.
        """

        if tree_name is not None:
            self.open_tree(tree_name)

        data = self.conn.get("_sig=" + path, arguments).data()
        if astype:
            data = safe_cast(data, astype)

        return data

    def get_data_with_dims(
        self,
        path: str,
        tree_name: str = None,
        dim_nums: List = None,
        astype: str = None,
        cast_all: bool = False,
    ) -> Tuple:
        """
        Get data and dimension(s) for record at specified path.

        Parameters
        ----------
        path : str
            MDSplus path to record.
        tree_name : str, optional
            The name of the tree that must be open for retrieval.
        dim_nums : List, optional
            A list of dimensions that should have their size retrieved. Default [0].
        astype : str, optional
            The data type for explicit casting.
        cast_all : bool, optional. Default False.
            Whether to cast both data and dims, or only data.

        Returns
        -------
        Tuple
            Returns the node data, followed by the requested dimensions.
        """

        dim_nums = dim_nums or [0]

        if tree_name is not None:
            self.open_tree(tree_name)

        data = self.conn.get("_sig=" + path).data()
        dims = [self.conn.get(f"dim_of(_sig,{dim_num})").data() for dim_num in dim_nums]

        if astype:
            data = safe_cast(data, astype)
            if cast_all:
                dims = [safe_cast(dim, astype) for dim in dims]

        return data, *dims

    def get_dims(
        self,
        path: str,
        tree_name: str = None,
        dim_nums: List = None,
        astype: str = None,
    ) -> Tuple:
        """
        Get the specified dimensions for record at specified path.

        Parameters
        ----------
        path : str
            MDSplus path to record.
        tree_name : str, optional
            The name of the tree that must be open for retrieval.
        dim_nums : List, optional
            A list of dimensions that should have their size retrieved. Default [0].
        astype : str, optional
            The data type for explicit casting.

        Returns
        -------
        Tuple
            Returns the requested dimensions as a tuple.
        """

        dim_nums = dim_nums or [0]

        if tree_name is not None:
            self.open_tree(tree_name)

        dims = [self.conn.get(f"dim_of({path},{d})").data() for d in dim_nums]

        if astype:
            dims = [safe_cast(dim, astype) for dim in dims]

        return dims

    # nicknames

    def add_tree_nickname_funcs(self, tree_nickname_funcs: Dict[str, Callable]):
        """
        Add tree nickname functions to the connection.

        Required because some tree nickname functions require the connection to exist.
        """
        self.tree_nickname_funcs.update(tree_nickname_funcs)

    def get_tree_name_of_nickname(self, nickname: str):
        """
        Get the tree name that the nickname has been set to or None if the nickname
        was not set.
        """
        if nickname not in self.tree_nicknames and nickname in self.tree_nickname_funcs:
            self.tree_nicknames[nickname] = self.tree_nickname_funcs[nickname]()

        return self.tree_nicknames.get(nickname, None)

    def tree_name(self, for_name: str) -> str:
        """
        The tree name for for_name, whether it is a nickname or tree name itself
        """
        return self.get_tree_name_of_nickname(for_name) or for_name
open_tree ¤
open_tree(tree_name: str)

Open the specified _name.

If the specified tree_name is a nickname for a tree_name, will open the tree that it is a nickname for.

Source code in disruption_py/inout/mds.py
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
def open_tree(self, tree_name: str):
    """
    Open the specified _name.

    If the specified tree_name is a nickname for a tree_name, will open the tree
    that it is a nickname for.
    """
    if (
        tree_name not in self.tree_nicknames
        and tree_name in self.tree_nickname_funcs
    ):
        self.tree_nicknames[tree_name] = self.tree_nickname_funcs[tree_name]()

    if tree_name in self.tree_nicknames:
        tree_name = self.tree_nicknames[tree_name]

    if self.last_open_tree != tree_name:
        self.conn.openTree(tree_name, self.shot_id)

    self.last_open_tree = tree_name
cleanup ¤
cleanup()

Close all open trees

Source code in disruption_py/inout/mds.py
92
93
94
95
96
def cleanup(self):
    """
    Close all open trees
    """
    self.last_open_tree = None
get ¤
get(
    expression: str,
    arguments: Any = None,
    tree_name: str = None,
) -> Any

Evaluate the specified expression.

The expression is passed as string argument, but may contain optional arguments. These arguments are then passed as an array of Data objects.

PARAMETER DESCRIPTION
expression

MDSplus TDI expression. Please see MDSplus documentation for more information.

TYPE: str

arguments

Arguments for MDSplus TDI Expression. Please see MDSplus documentation for more information. Default None.

TYPE: Any DEFAULT: None

tree_name

TYPE: str DEFAULT: None

RETURNS DESCRIPTION
Any

Result of evaluating TDI expression from MDSplus.

Source code in disruption_py/inout/mds.py
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
def get(self, expression: str, arguments: Any = None, tree_name: str = None) -> Any:
    """
    Evaluate the specified expression.

    The expression is passed as string argument, but may contain optional arguments.
    These arguments are then passed as an array of Data objects.

    Parameters
    ----------
    expression : str
        MDSplus TDI expression. Please see MDSplus documentation for more
        information.
    arguments : Any, optional
        Arguments for MDSplus TDI Expression. Please see MDSplus documentation
        for more information. Default None.
    tree_name : str, optional

    Returns
    -------
    Any
        Result of evaluating TDI expression from MDSplus.
    """
    if tree_name is not None:
        self.open_tree(tree_name)
    if arguments is None:
        return self.conn.get(expression)
    return self.conn.get(expression, arguments)
get_data ¤
get_data(
    path: str,
    tree_name: str = None,
    astype: str = None,
    arguments: Any = None,
) -> np.ndarray

Get data for record at specified path.

PARAMETER DESCRIPTION
path

MDSplus path to record.

TYPE: str

tree_name

The name of the tree that must be open for retrieval.

TYPE: str DEFAULT: None

astype

The data type for explicit casting.

TYPE: str DEFAULT: None

arguments

Arguments for MDSplus TDI Expression. Default None. Please see MDSplus documentation for more information.

TYPE: Any DEFAULT: None

RETURNS DESCRIPTION
ndarray

Returns the node data.

Source code in disruption_py/inout/mds.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
def get_data(
    self,
    path: str,
    tree_name: str = None,
    astype: str = None,
    arguments: Any = None,
) -> np.ndarray:
    """
    Get data for record at specified path.

    Parameters
    ----------
    path : str
        MDSplus path to record.
    tree_name : str, optional
        The name of the tree that must be open for retrieval.
    astype : str, optional
        The data type for explicit casting.
    arguments : Any, optional
        Arguments for MDSplus TDI Expression. Default None.
        Please see MDSplus documentation for more information.

    Returns
    -------
    np.ndarray
        Returns the node data.
    """

    if tree_name is not None:
        self.open_tree(tree_name)

    data = self.conn.get("_sig=" + path, arguments).data()
    if astype:
        data = safe_cast(data, astype)

    return data
get_data_with_dims ¤
get_data_with_dims(
    path: str,
    tree_name: str = None,
    dim_nums: List = None,
    astype: str = None,
    cast_all: bool = False,
) -> Tuple

Get data and dimension(s) for record at specified path.

PARAMETER DESCRIPTION
path

MDSplus path to record.

TYPE: str

tree_name

The name of the tree that must be open for retrieval.

TYPE: str DEFAULT: None

dim_nums

A list of dimensions that should have their size retrieved. Default [0].

TYPE: List DEFAULT: None

astype

The data type for explicit casting.

TYPE: str DEFAULT: None

cast_all

Whether to cast both data and dims, or only data.

TYPE: bool, optional. Default False. DEFAULT: False

RETURNS DESCRIPTION
Tuple

Returns the node data, followed by the requested dimensions.

Source code in disruption_py/inout/mds.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
def get_data_with_dims(
    self,
    path: str,
    tree_name: str = None,
    dim_nums: List = None,
    astype: str = None,
    cast_all: bool = False,
) -> Tuple:
    """
    Get data and dimension(s) for record at specified path.

    Parameters
    ----------
    path : str
        MDSplus path to record.
    tree_name : str, optional
        The name of the tree that must be open for retrieval.
    dim_nums : List, optional
        A list of dimensions that should have their size retrieved. Default [0].
    astype : str, optional
        The data type for explicit casting.
    cast_all : bool, optional. Default False.
        Whether to cast both data and dims, or only data.

    Returns
    -------
    Tuple
        Returns the node data, followed by the requested dimensions.
    """

    dim_nums = dim_nums or [0]

    if tree_name is not None:
        self.open_tree(tree_name)

    data = self.conn.get("_sig=" + path).data()
    dims = [self.conn.get(f"dim_of(_sig,{dim_num})").data() for dim_num in dim_nums]

    if astype:
        data = safe_cast(data, astype)
        if cast_all:
            dims = [safe_cast(dim, astype) for dim in dims]

    return data, *dims
get_dims ¤
get_dims(
    path: str,
    tree_name: str = None,
    dim_nums: List = None,
    astype: str = None,
) -> Tuple

Get the specified dimensions for record at specified path.

PARAMETER DESCRIPTION
path

MDSplus path to record.

TYPE: str

tree_name

The name of the tree that must be open for retrieval.

TYPE: str DEFAULT: None

dim_nums

A list of dimensions that should have their size retrieved. Default [0].

TYPE: List DEFAULT: None

astype

The data type for explicit casting.

TYPE: str DEFAULT: None

RETURNS DESCRIPTION
Tuple

Returns the requested dimensions as a tuple.

Source code in disruption_py/inout/mds.py
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
def get_dims(
    self,
    path: str,
    tree_name: str = None,
    dim_nums: List = None,
    astype: str = None,
) -> Tuple:
    """
    Get the specified dimensions for record at specified path.

    Parameters
    ----------
    path : str
        MDSplus path to record.
    tree_name : str, optional
        The name of the tree that must be open for retrieval.
    dim_nums : List, optional
        A list of dimensions that should have their size retrieved. Default [0].
    astype : str, optional
        The data type for explicit casting.

    Returns
    -------
    Tuple
        Returns the requested dimensions as a tuple.
    """

    dim_nums = dim_nums or [0]

    if tree_name is not None:
        self.open_tree(tree_name)

    dims = [self.conn.get(f"dim_of({path},{d})").data() for d in dim_nums]

    if astype:
        dims = [safe_cast(dim, astype) for dim in dims]

    return dims
add_tree_nickname_funcs ¤
add_tree_nickname_funcs(
    tree_nickname_funcs: Dict[str, Callable]
)

Add tree nickname functions to the connection.

Required because some tree nickname functions require the connection to exist.

Source code in disruption_py/inout/mds.py
251
252
253
254
255
256
257
def add_tree_nickname_funcs(self, tree_nickname_funcs: Dict[str, Callable]):
    """
    Add tree nickname functions to the connection.

    Required because some tree nickname functions require the connection to exist.
    """
    self.tree_nickname_funcs.update(tree_nickname_funcs)
get_tree_name_of_nickname ¤
get_tree_name_of_nickname(nickname: str)

Get the tree name that the nickname has been set to or None if the nickname was not set.

Source code in disruption_py/inout/mds.py
259
260
261
262
263
264
265
266
267
def get_tree_name_of_nickname(self, nickname: str):
    """
    Get the tree name that the nickname has been set to or None if the nickname
    was not set.
    """
    if nickname not in self.tree_nicknames and nickname in self.tree_nickname_funcs:
        self.tree_nicknames[nickname] = self.tree_nickname_funcs[nickname]()

    return self.tree_nicknames.get(nickname, None)
tree_name ¤
tree_name(for_name: str) -> str

The tree name for for_name, whether it is a nickname or tree name itself

Source code in disruption_py/inout/mds.py
269
270
271
272
273
def tree_name(self, for_name: str) -> str:
    """
    The tree name for for_name, whether it is a nickname or tree name itself
    """
    return self.get_tree_name_of_nickname(for_name) or for_name