Source code for snake.core.handlers.base

"""Base handler module."""

from __future__ import annotations
import yaml
import dataclasses
from collections import UserList

from ..._meta import MetaDCRegister
from typing import ClassVar, TypeVar, Any

from ..simulation import SimConfig
from ..phantom import Phantom, DynamicData, KspaceDynamicData

T = TypeVar("T")


[docs] class MetaHandler(MetaDCRegister): """MetaClass for Handlers.""" dunder_name = "handler"
[docs] class AbstractHandler(metaclass=MetaHandler): """Handler Interface.""" __registry__: ClassVar[dict[str, type[AbstractHandler]]] __handler_name__: ClassVar[str]
[docs] def get_static(self, phantom: Phantom, sim_conf: SimConfig) -> Phantom: """Get the static information of the handler.""" return phantom
[docs] def get_dynamic(self, phantom: Phantom, sim_conf: SimConfig) -> DynamicData | None: """Get the dynamic information of the handler.""" return None
[docs] def get_dynamic_kspace(self, sim_conf: SimConfig) -> KspaceDynamicData | None: """Get the dynamic kspace information of the handler.""" return None
[docs] def to_yaml(self) -> str: """Show the yaml config associated with the handler.""" return yaml.dump(dataclasses.asdict(self)) # type: ignore
[docs] class HandlerList(UserList): """Represent a Chain of Handler, that needs to be apply to a simulation.""" def __init__(self, *args: AbstractHandler): self.data = list(args)
[docs] @classmethod def from_cfg(cls, cfg: dict[str, Any]) -> HandlerList: """Create a HandlerList from a configuration.""" self = cls() for handler_name, handler_cfg in cfg.items(): handler = get_handler(handler_name) self.append(handler(**handler_cfg)) return self
[docs] def to_yaml(self, filename: str | None = None) -> str: """Serialize the handlerList as a yaml string.""" if filename: with open(filename, "w") as f: yaml.dump(self.serialize(), f) return filename else: return yaml.dump(self.serialize())
[docs] def serialize(self) -> list[dict[str, Any]]: """Serialize the handlerList as a list of dictionary.""" # handlers are dataclasses. return [dataclasses.asdict(h) for h in self.data]
# short alias H = AbstractHandler.__registry__ handler = H
[docs] def list_handlers() -> list[str]: """List all available handlers.""" return list(H.keys())
[docs] def get_handler(name: str) -> type[AbstractHandler]: """Get a handler from its name.""" return H[name]