Skip to content

Overview

What is a Physics Method?¤

In DisruptionPy, physics methods are methods that produce tabular data in a standardized time base. Physics methods must take a single argument params that is an instance of PhysicsMethodParams.

Built-in Physics Methods¤

While you can define your own, existing built-in physics methods are defined inside of the disruption_py.machine package.

For more information on available methods please see the built-in method documentation pages:

Custom Physics Methods¤

Users of DisruptionPy can create their own custom physics methods by adding the @physics_method decorator to a method. These custom physics methods can then be passed as the custom_physics_methods parameter in RetrievalSettings and their results will be included alongside those returned by the built-in methods. See Physics Method Decorators for more details on decorators.

Physics methods structure¤

All parametrized methods passed to get_shots_data will be called once for every shot retrieved. Decorated methods may call other decorated methods, however, execution order is not guaranteed as calls will be reordered to minimize resource usage based on the physics_method decorator.

PARAMETER DESCRIPTION
params

Parameters passed by disruption_py to the decorated method that should be used to help retrieve the shot data from MDSplus.

TYPE: PhysicsMethodParams

RETURNS DESCRIPTION
dict

Dictionary containing the results of the decorated method, with each returned parameter being a key-value pair. Each of the dictionary's values should be the same length as the timebase (params.times).

Walkthrough¤

The steps for creating a custom physics method are as follows:

  1. Create a function that takes an argument named params of type PhysicsMethodParams and returns a Python dictionary. The method must be decorated with the physics_method decorator. The arguments passed to the decorator are important for DisruptionPy to run efficiently. See physics_method for more details about available arguments.

    from disruption_py.core.physics_method.params import PhysicsMethodParams
    from disruption_py.core.physics_method.decorator import physics_method
    
    @physics_method(...)
    def ***_method(params: PhysicsMethodParams) -> dict:
        ...
    

  2. To retrieve data from MDSplus use the params (PhysicsMethodParams) object. It contains many useful attributes, among which are the following:

    • params.shot_id: the shot id of the shot for which data is being retrieved.
    • params.mds_conn: a wrapper around the MDSplus connection for the process, that makes it easier to get data for a shot. See MDSConnection for details.
    • params.times: the timebase of the shot for which data is being retrieved as a NumPy array of times. A common development pattern is using the params.interpolation_method method (defaults to interp1) to interpolate the retrieved/computed values to the desired timebase.
Shot Data Request Examples
# pylint: disable=duplicate-code
@physics_method(columns=["kappa_area"], tokamak=Tokamak.CMOD)
def _get_kappa_area(params: PhysicsMethodParams):
    aminor = params.mds_conn.get_data(
        r"\efit_aeqdsk:aminor", tree_name="_efit_tree", astype="float64"
    )
    area = params.mds_conn.get_data(
        r"\efit_aeqdsk:area", tree_name="_efit_tree", astype="float64"
    )
    times = params.mds_conn.get_data(
        r"\efit_aeqdsk:time", tree_name="_efit_tree", astype="float64"
    )

    # Ensure aminor and area are not 0 or less than 0
    aminor[aminor <= 0] = 0.001
    area[area <= 0] = 3.14 * 0.001**2
    return {
        "kappa_area": params.interpolation_method(
            times, area / (np.pi * aminor**2), params.times
        )
    }

Warning

When two output columns have the same name, the column that appears in the final dataset is not guaranteed. This issue will be fixed in the near future.

Running Physics Methods¤

Users can use a number of built-in physics methods and/or create their own methods.

For a physics method to be run after calling get_shots_data it must meet the following conditions:

  1. The method must either:

    • be included inside of the disruption_py.machine.method_holders.py list (built-in method)
    • be included inside of the custom_physics_methods argument of RetrievalSettings when getting shot data.
  2. The method must have the physics_method decorator with its tokamak parameter either not set or set to the tokamak that you are retrieving data from.

  3. The method is included to run via either the run_methods, run_tags, or run_columns parameters of the shot settings.

    • To be included via run_methods, the method name must be listed inside of run_methods
    • To be included via run_tags, the method must have a tag listed in the tags parameter of the physics_method decorator that is included in run_tags
    • To be included via run_columns, the method must have a column list in the columns parameter of the physics_method decorator that is included in run_columns

Once all designated methods have been collected, DisruptionPy optimizes their execution order to minimize resource usage by using the information supplied in the physics_method decorator. Once reordering is complete, the methods are run.

disruption_py.core.physics_method.params ¤

Module for defining parameters used in physics methods for DisruptionPy.

PhysicsMethodParams dataclass ¤

Holder for useful variables for the physics methods like an MDSplus connection and the timebase for the data.

Source code in disruption_py/core/physics_method/params.py
18
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
53
54
55
@dataclass
class PhysicsMethodParams:
    """
    Holder for useful variables for the physics methods like an MDSplus connection
    and the timebase for the data.
    """

    logger = logging.getLogger("disruption_py")

    shot_id: int
    tokamak: Tokamak
    disruption_time: float
    mds_conn: MDSConnection
    times: np.ndarray
    cache_data: pd.DataFrame
    pre_filled_shot_data: pd.DataFrame
    interpolation_method: Any  # Fix
    metadata: dict

    cached_results: Dict[str, Any] = field(default_factory=dict)

    @property
    def disrupted(self) -> bool:
        """
        Check if the disruption time is set.

        Returns
        -------
        bool
            True if disruption time is not None, False otherwise.
        """
        return self.disruption_time is not None

    def cleanup(self) -> None:
        """Clean up resources used by the physics method parameters."""
        self.mds_conn.cleanup()
        self.times = None
        self.cached_results.clear()

disrupted property ¤

disrupted: bool

Check if the disruption time is set.

RETURNS DESCRIPTION
bool

True if disruption time is not None, False otherwise.

cleanup ¤

cleanup() -> None

Clean up resources used by the physics method parameters.

Source code in disruption_py/core/physics_method/params.py
51
52
53
54
55
def cleanup(self) -> None:
    """Clean up resources used by the physics method parameters."""
    self.mds_conn.cleanup()
    self.times = None
    self.cached_results.clear()