Source code for CodeEntropy.levels.nodes.conformations
"""Compute conformational states for configurational entropy calculations.
This module defines a static DAG node that scans the selected trajectory frames
and builds conformational state descriptors (united-atom and residue level).
The resulting states are stored in ``shared_data`` for later use by
configurational entropy calculations.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
from CodeEntropy.levels.dihedrals import ConformationStateBuilder
from CodeEntropy.trajectory.frames import FrameSelection
SharedData = dict[str, Any]
ConformationalStates = dict[str, Any]
FlexibleStates = dict[str, Any]
[docs]
@dataclass(frozen=True)
class ConformationalStateConfig:
"""Configuration for conformational state construction.
Attributes:
n_frames: Number of frames to be analysed.
bin_width: Histogram bin width in degrees.
"""
n_frames: int
bin_width: int
[docs]
class ComputeConformationalStatesNode:
"""Static node that computes conformational states from trajectory dihedrals.
Produces:
shared_data["conformational_states"] = {"ua": states_ua, "res": states_res}
shared_data["flexible_dihedrals"] = {"ua": flexible_ua, "res": flexible_res}
Where:
- states_ua is a dict keyed by ``(group_id, local_residue_id)``.
- states_res is a list-like structure indexed by group id.
- flexible_ua is a dict keyed by ``(group_id, local_residue_id)``.
- flexible_res is a list-like structure indexed by group id.
Notes:
Frame selection is provided through ``shared_data["frame_selection"]``.
During the current migration stage, that selection uses local
analysis-universe frame indices because the workflow still physically
frame-slices the universe.
"""
def __init__(self, universe_operations: Any) -> None:
"""Initialize the node.
Args:
universe_operations: Object providing universe selection utilities used
by ``ConformationStateBuilder``.
"""
self._dihedral_analysis = ConformationStateBuilder(
universe_operations=universe_operations
)
[docs]
def run(
self, shared_data: SharedData, *, progress: object | None = None
) -> dict[str, ConformationalStates]:
"""Compute conformational states and store them in shared_data.
Args:
shared_data: Shared data dictionary. Requires:
- ``"reduced_universe"``
- ``"levels"``
- ``"groups"``
- ``"frame_selection"``
- ``"args"`` with attribute ``bin_width``
progress: Optional progress sink provided by ResultsReporter.progress().
Returns:
Dict containing ``"conformational_states"``.
"""
u = shared_data["reduced_universe"]
levels = shared_data["levels"]
groups = shared_data["groups"]
frame_selection: FrameSelection = shared_data["frame_selection"]
bin_width = int(shared_data["args"].bin_width)
states_ua, states_res, flexible_ua, flexible_res = (
self._dihedral_analysis.build_conformational_states(
data_container=u,
levels=levels,
groups=groups,
bin_width=bin_width,
frame_selection=frame_selection,
progress=progress,
)
)
conformational_states: ConformationalStates = {
"ua": states_ua,
"res": states_res,
}
shared_data["conformational_states"] = conformational_states
flexible_states: FlexibleStates = {
"ua": flexible_ua,
"res": flexible_res,
}
shared_data["flexible_dihedrals"] = flexible_states
return {"conformational_states": conformational_states}