Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions disruption_py/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/env python3

"""
Loads configuration settings using Dynaconf for a given tokamak.
"""

import os
from enum import Enum
from typing import Union
Expand All @@ -10,6 +14,19 @@


def config(tokamak: Union[Enum, str] = None):
"""
Load and cache the configuration.

Parameters
----------
tokamak : Union[Enum, str], optional
Tokamak name or Enum. Defaults to "default".

Returns
-------
Dynaconf
Configuration settings.
"""
if tokamak is None:
tokamak = "default"
elif isinstance(tokamak, Enum):
Expand Down
5 changes: 5 additions & 0 deletions disruption_py/core/multiprocess.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#!/usr/bin/env python3

# TODO: https://github.com/MIT-PSFC/disruption-py/pull/271
# pylint: disable=missing-class-docstring
# pylint: disable=missing-function-docstring
# pylint: disable=missing-module-docstring

import multiprocessing
import threading
from enum import Enum
Expand Down
53 changes: 51 additions & 2 deletions disruption_py/core/physics_method/caching.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#!/usr/bin/env python3

"""
This module provides decorators and utility functions for caching the results of
expensive method calls in physics calculations.
"""

import functools
import threading
from typing import Callable, List
Expand All @@ -11,16 +16,22 @@


def cache_method(method: Callable) -> Callable:
"""Decorates a function as a cached method and instantiates its cache.
"""
Decorates a function as a cached method and instantiates its cache.

Cached methods are functions that run expensive operations on data in the shot
and may be reused. The cache is used to store the results of the parameter
method so that it is only calculated once per shot for a given timebase.

Parameters
----------
method: Callable
method : Callable
The method to be cached.

Returns
-------
Callable
The wrapped method with caching functionality.
"""

@functools.wraps(method)
Expand Down Expand Up @@ -51,6 +62,23 @@ def wrapper(*args, **kwargs):
def get_method_cache_key(
method: Callable, times: np.ndarray, other_params: dict = None
):
"""
Generate a cache key for the specified method and parameters.

Parameters
----------
method : Callable
The method for which the cache key is being generated.
times : np.ndarray
An array of time values, where the first and last times are used in the key.
other_params : dict, optional
A dictionary of additional parameters that may affect the cache key. Default is None.

Returns
-------
tuple
A tuple representing the cache key.
"""
current_thread_id = threading.get_ident()
hashable_other_params = frozenset((other_params or {}).items())
return (
Expand All @@ -70,6 +98,27 @@ def manually_cache(
method_name: str,
method_columns: List[str],
) -> bool:
"""
Manually cache results based on the provided DataFrame and method details.

Parameters
----------
physics_method_params : PhysicsMethodParams
The parameters containing the shot ID and logger for logging.
data : pd.DataFrame
The DataFrame containing the data to be cached.
method : Callable
The method for which the results are being cached.
method_name : str
The name of the method being cached, used for logging.
method_columns : List[str]
The list of columns to check and cache.

Returns
-------
bool
True if caching was successful, False if there were missing columns.
"""
if method_columns is None:
return False
if not hasattr(physics_method_params, "cached_results"):
Expand Down
4 changes: 4 additions & 0 deletions disruption_py/core/physics_method/decorator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/env python3

"""
This module provides a decorator to signify methods that calculate physics quantities.
"""

from typing import Callable, List, Union

from disruption_py.core.physics_method.caching import cache_method
Expand Down
39 changes: 32 additions & 7 deletions disruption_py/core/physics_method/metadata.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/env python3

"""
Module for defining metadata classes for physics methods.
"""

from dataclasses import dataclass, fields
from typing import Callable, List, Union

Expand Down Expand Up @@ -32,6 +36,15 @@ def __post_init__(self):

@dataclass(frozen=True)
class BoundMethodMetadata(MethodMetadata):
"""
Metadata for a bound method, extending `MethodMetadata`.

Attributes
----------
bound_method : Callable
The method that is bound to this metadata.
"""

bound_method: Callable

@classmethod
Expand All @@ -42,11 +55,21 @@ def bind(
physics_method_params: PhysicsMethodParams,
):
"""
Evaluate arguments to decorators to usable values.

Some parameters provided to the physics_method decorators can take method
that are evaluated at runtime. `resolve_for` evaluates all of these methods
and returns a new instance of `MethodMetadata`without function parameters.
Bind a method to its metadata and resolve any callable parameters.

Parameters
----------
method_metadata : MethodMetadata
Metadata instance containing the method's unresolved parameters.
bound_method : Callable
The callable method to be bound.
physics_method_params : PhysicsMethodParams
Parameters required for resolving the method.

Returns
-------
BoundMethodMetadata
A new instance of `BoundMethodMetadata` with resolved parameters.
"""
new_method_metadata_params = {}
bind_to = (getattr(bound_method, "__self__", None),)
Expand All @@ -71,7 +94,8 @@ def bind(


def is_parametered_method(method: Callable) -> bool:
"""Returns whether the method is decorated with `physics_method` decorator
"""
Returns whether the method is decorated with `physics_method` decorator

Parameters
----------
Expand All @@ -87,7 +111,8 @@ def is_parametered_method(method: Callable) -> bool:


def get_method_metadata(method: Callable, should_throw: bool = False) -> MethodMetadata:
"""Get method metadata for method
"""
Get method metadata for method

Parameters
----------
Expand Down
23 changes: 19 additions & 4 deletions disruption_py/core/physics_method/params.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/env python3

"""
Module for defining parameters used in physics methods for DisruptionPy.
"""

import logging
from dataclasses import dataclass, field
from typing import Any, Dict
Expand All @@ -13,8 +17,10 @@

@dataclass
class PhysicsMethodParams:
"""Holder for useful variables for the physics methods like an MDSplus connection
and the timebase for the data."""
"""
Holder for useful variables for the physics methods like an MDSplus connection
and the timebase for the data.
"""

logger = logging.getLogger("disruption_py")

Expand All @@ -31,10 +37,19 @@ class PhysicsMethodParams:
cached_results: Dict[str, Any] = field(default_factory=dict)

@property
def disrupted(self):
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):
def cleanup(self) -> None:
"""Clean up resources used by the physics method parameters."""
self.mds_conn.cleanup()
self.times = None
self.cached_results.clear()
Loading