Skip to content

kups.application.mcmc.analysis

Post-simulation analysis for MCMC simulations.

IsMCMCFixedData

Bases: Protocol

Contract for data from the fixed reader group.

Source code in src/kups/application/mcmc/analysis.py
class IsMCMCFixedData(Protocol):
    """Contract for data from the fixed reader group."""

    @property
    def systems(self) -> Table[SystemId, HasTemperature]: ...

IsMCMCStepData

Bases: Protocol

Contract for data from the per_step reader group.

Source code in src/kups/application/mcmc/analysis.py
class IsMCMCStepData(Protocol):
    """Contract for data from the per_step reader group."""

    @property
    def particle_count(self) -> Table[tuple[SystemId, MotifId], Array]: ...
    @property
    def systems(self) -> Table[SystemId, IsMCMCSystemStepData]: ...

IsMCMCSystemStepData

Bases: Protocol

Contract for per-system step data.

Source code in src/kups/application/mcmc/analysis.py
class IsMCMCSystemStepData(Protocol):
    """Contract for per-system step data."""

    @property
    def potential_energy(self) -> Array: ...
    @property
    def guest_stress(self) -> StressResult: ...

MCMCAnalysisResult dataclass

Results from MCMC simulation analysis for a single system.

Attributes:

Name Type Description
energy BlockAverageResult

Average total potential energy with SEM (eV).

loading BlockAverageResult

Average particle count per species with SEM (dimensionless).

heat_of_adsorption BlockAverageResult

Per-species heat of adsorption with SEM (eV).

total_heat_of_adsorption BlockAverageResult

Composition-weighted total heat of adsorption (eV).

Source code in src/kups/application/mcmc/analysis.py
@plain_dataclass
class MCMCAnalysisResult:
    """Results from MCMC simulation analysis for a single system.

    Attributes:
        energy: Average total potential energy with SEM (eV).
        loading: Average particle count per species with SEM (dimensionless).
        heat_of_adsorption: Per-species heat of adsorption with SEM (eV).
        total_heat_of_adsorption: Composition-weighted total heat of adsorption (eV).
    """

    energy: BlockAverageResult
    loading: BlockAverageResult
    heat_of_adsorption: BlockAverageResult
    total_heat_of_adsorption: BlockAverageResult
    stress: BlockAverageResult | None = None
    stress_potential: BlockAverageResult | None = None
    stress_tail_correction: BlockAverageResult | None = None
    stress_ideal_gas: BlockAverageResult | None = None
    pressure: BlockAverageResult | None = None
    pressure_potential: BlockAverageResult | None = None
    pressure_tail_correction: BlockAverageResult | None = None
    pressure_ideal_gas: BlockAverageResult | None = None

WidomAnalysisResult dataclass

Block-averaged Widom outputs for a single system.

Attributes:

Name Type Description
excess_chemical_potential BlockAverageResult

\(\mu^\mathrm{ex}\) with SEM (eV).

henry_coefficient BlockAverageResult

\(K_H\) with SEM (ų/eV).

heat_of_adsorption BlockAverageResult

\(q_\mathrm{st}\) with SEM (eV); Vlugt 2008 eq. 16, test-particle limit.

Source code in src/kups/application/mcmc/analysis.py
@plain_dataclass
class WidomAnalysisResult:
    """Block-averaged Widom outputs for a single system.

    Attributes:
        excess_chemical_potential: $\\mu^\\mathrm{ex}$ with SEM (eV).
        henry_coefficient: $K_H$ with SEM (ų/eV).
        heat_of_adsorption: $q_\\mathrm{st}$ with SEM (eV); Vlugt 2008 eq. 16,
            test-particle limit.
    """

    excess_chemical_potential: BlockAverageResult
    henry_coefficient: BlockAverageResult
    heat_of_adsorption: BlockAverageResult

analyze_mcmc(fixed, per_step, n_blocks=None)

Analyze MCMC simulation results from pre-loaded data.

Computes energy, loading (average particle counts), and heat of adsorption per species using block averaging for error estimation. Analysis is performed independently for each system.

Parameters:

Name Type Description Default
fixed IsMCMCFixedData

Fixed (one-shot) logged data containing system metadata.

required
per_step IsMCMCStepData

Per-step logged data containing energies and particle counts.

required
n_blocks int | None

Number of blocks for error estimation. None uses :func:~kups.core.utils.block_average.optimal_block_average.

None

Returns:

Type Description
dict[SystemId, MCMCAnalysisResult]

Per-system analysis results keyed by SystemId.

Source code in src/kups/application/mcmc/analysis.py
@no_jax_tracing
def analyze_mcmc(
    fixed: IsMCMCFixedData,
    per_step: IsMCMCStepData,
    n_blocks: int | None = None,
) -> dict[SystemId, MCMCAnalysisResult]:
    """Analyze MCMC simulation results from pre-loaded data.

    Computes energy, loading (average particle counts), and heat of adsorption
    per species using block averaging for error estimation. Analysis is
    performed independently for each system.

    Args:
        fixed: Fixed (one-shot) logged data containing system metadata.
        per_step: Per-step logged data containing energies and particle counts.
        n_blocks: Number of blocks for error estimation. ``None`` uses
            :func:`~kups.core.utils.block_average.optimal_block_average`.

    Returns:
        Per-system analysis results keyed by ``SystemId``.
    """
    return _analyze_mcmc(
        fixed.systems.keys,
        fixed.systems.data.temperature,
        per_step.particle_count.keys,
        per_step.particle_count.data,
        per_step.systems.data.potential_energy,
        per_step.systems.data.guest_stress,
        n_blocks,
    )

analyze_mcmc_file(hdf5_path, n_blocks=None)

Analyze MCMC simulation results from an HDF5 file.

Reads only the fields the analysis needs — per-system metadata, particle counts, potential energy, and guest stress — leaving the per-step particle and group tables on disk.

Parameters:

Name Type Description Default
hdf5_path str | Path

Path to HDF5 output file from :func:~kups.application.mcmc.simulation.run_mcmc.

required
n_blocks int | None

Number of blocks for error estimation. None uses :func:~kups.core.utils.block_average.optimal_block_average.

None

Returns:

Type Description
dict[SystemId, MCMCAnalysisResult]

Per-system analysis results keyed by SystemId.

Source code in src/kups/application/mcmc/analysis.py
@no_jax_tracing
def analyze_mcmc_file(
    hdf5_path: str | Path,
    n_blocks: int | None = None,
) -> dict[SystemId, MCMCAnalysisResult]:
    """Analyze MCMC simulation results from an HDF5 file.

    Reads only the fields the analysis needs — per-system metadata, particle
    counts, potential energy, and guest stress — leaving the per-step particle
    and group tables on disk.

    Args:
        hdf5_path: Path to HDF5 output file from
            :func:`~kups.application.mcmc.simulation.run_mcmc`.
        n_blocks: Number of blocks for error estimation. ``None`` uses
            :func:`~kups.core.utils.block_average.optimal_block_average`.

    Returns:
        Per-system analysis results keyed by ``SystemId``.
    """
    with HDF5StorageReader[MCMCLoggedData[Any]](hdf5_path) as reader:
        systems = reader.focus_group(lambda s: s.fixed).read(select=lambda d: d.systems)
        per_step = reader.focus_group(lambda s: s.per_step)
        particle_count = per_step.read(select=lambda d: d.particle_count)
        all_energy, guest_stress = per_step.read(
            select=lambda d: (
                d.systems.data.potential_energy,
                d.systems.data.guest_stress,
            )
        )

    return _analyze_mcmc(
        systems.keys,
        systems.data.temperature,
        particle_count.keys,
        particle_count.data,
        all_energy,
        guest_stress,
        n_blocks,
    )

analyze_widom(fixed, per_step, n_blocks=None)

Block-averaged Widom analysis from pre-loaded HDF5 data.

Parameters:

Name Type Description Default
fixed WidomFixedData

Fixed-group data carrying per-system temperature and cell.

required
per_step Table[SystemId, WidomStatistics]

Cumulative WidomStatistics time series.

required
n_blocks int | None

Number of blocks; None uses optimal_block_average.

None

Returns:

Type Description
dict[SystemId, WidomAnalysisResult]

Per-system Widom results keyed by SystemId.

Source code in src/kups/application/mcmc/analysis.py
def analyze_widom(
    fixed: WidomFixedData,
    per_step: Table[SystemId, WidomStatistics],
    n_blocks: int | None = None,
) -> dict[SystemId, WidomAnalysisResult]:
    """Block-averaged Widom analysis from pre-loaded HDF5 data.

    Args:
        fixed: Fixed-group data carrying per-system temperature and cell.
        per_step: Cumulative ``WidomStatistics`` time series.
        n_blocks: Number of blocks; ``None`` uses ``optimal_block_average``.

    Returns:
        Per-system Widom results keyed by ``SystemId``.
    """
    return _analyze_widom(
        per_step,
        fixed.systems.keys,
        fixed.systems.data.temperature,
        fixed.systems.data.cell.volume,
        n_blocks,
    )

analyze_widom_file(hdf5_path, n_blocks=None)

Analyze a kups_mcmc_widom HDF5 output, reading only system metadata and the per-cycle Widom statistics.

Source code in src/kups/application/mcmc/analysis.py
@no_jax_tracing
def analyze_widom_file(
    hdf5_path: str | Path,
    n_blocks: int | None = None,
) -> dict[SystemId, WidomAnalysisResult]:
    """Analyze a ``kups_mcmc_widom`` HDF5 output, reading only system metadata
    and the per-cycle Widom statistics."""
    with HDF5StorageReader[WidomLoggedData[Any]](hdf5_path) as reader:
        systems = reader.focus_group(lambda s: s.fixed).read(select=lambda d: d.systems)
        per_step = reader.focus_group(lambda s: s.per_step)[...]
    return _analyze_widom(
        per_step,
        systems.keys,
        systems.data.temperature,
        systems.data.cell.volume,
        n_blocks,
    )